CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/DetectorDescription/Core/src/DDFilter.cc

Go to the documentation of this file.
00001 #include "DetectorDescription/Core/interface/DDFilter.h"
00002 #include "DetectorDescription/Core/interface/DDExpandedView.h"
00003 
00004 // Message logger.
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 
00007 DDFilter::DDFilter() 
00008 { }
00009 
00010 
00011 DDFilter::~DDFilter()
00012 { }
00013 
00014 
00015 // =======================================================================
00016 // =======================================================================
00017 
00029 namespace {
00030 
00031 
00032 // SpecificsFilterString-comparison (sfs)
00033   inline bool sfs_compare(const DDSpecificsFilter::SpecificCriterion & crit,
00034                           const DDsvalues_type & sv) {
00035     DDsvalues_type::const_iterator it = find(sv,crit.nameVal_.id());
00036     if (it == sv.end()) return false;
00037     switch (crit.comp_) {
00038     case DDSpecificsFilter::equals: case DDSpecificsFilter::matches:
00039       return ( crit.nameVal_.strings() == it->second.strings() );
00040     case DDSpecificsFilter::not_equals: case DDSpecificsFilter::not_matches:
00041       return ( crit.nameVal_.strings() != it->second.strings() );
00042     case DDSpecificsFilter::smaller_equals:
00043       return ( it->second.strings() <= crit.nameVal_.strings() );
00044     case DDSpecificsFilter::smaller:
00045       return ( it->second.strings() < crit.nameVal_.strings() );
00046     case DDSpecificsFilter::bigger_equals:
00047       return ( it->second.strings() >= crit.nameVal_.strings() );
00048     case DDSpecificsFilter::bigger:      
00049       return ( it->second.strings() > crit.nameVal_.strings() );
00050     default:
00051       return false;
00052     }
00053     return false;
00054   }              
00055   
00056   inline bool sfd_compare(const DDSpecificsFilter::SpecificCriterion & crit,
00057                    const DDsvalues_type & sv)
00058   {
00059     DDsvalues_type::const_iterator it = find(sv,crit.nameVal_.id());
00060     if (it == sv.end()) return false;
00061     if (it->second.isEvaluated() ) {
00062       switch (crit.comp_) {
00063       case DDSpecificsFilter::equals: case DDSpecificsFilter::matches:
00064         return (crit.nameVal_.doubles() == it->second.doubles() );
00065       case DDSpecificsFilter::not_equals: case DDSpecificsFilter::not_matches:
00066         return (crit.nameVal_.doubles() != it->second.doubles() );
00067       case DDSpecificsFilter::smaller_equals:
00068         return ( it->second.doubles() <= crit.nameVal_.doubles() );
00069       case DDSpecificsFilter::smaller:
00070         return ( it->second.doubles() < crit.nameVal_.doubles() );
00071       case DDSpecificsFilter::bigger_equals:
00072         return ( it->second.doubles() >= crit.nameVal_.doubles() );
00073       case DDSpecificsFilter::bigger:    
00074         return ( it->second.doubles() > crit.nameVal_.doubles() );
00075       default:
00076         return false;
00077       }
00078     } else {
00079       edm::LogWarning("DD:Filter") << "Attempt to access a DDValue as doubles but DDValue is NOT Evaluated!" 
00080                                    << crit.nameVal_.name();
00081     }
00082     return false;
00083   }              
00084   
00085   inline bool sfs_compare_nm (const DDSpecificsFilter::SpecificCriterion & crit,
00086                        const std::vector<const DDsvalues_type *> & specs)
00087   {
00088     // The meaning of this is defined for each operator below.
00089     bool result = false; 
00090     
00091     std::vector<const DDsvalues_type *>::const_iterator spit = specs.begin();
00092     
00093     // go through all specifics
00094     //   edm::LogInfo("DDFilter") << "Checking all specifics." << std::endl;
00095     for (;  spit != specs.end(); ++spit) {
00096       DDsvalues_type::const_iterator it = (**spit).begin();
00097       
00098       // go through all DDValues of the current specific.     
00099       for (;  it != (**spit).end(); ++it) {
00100         
00101         size_t ci = 0; // criteria values index
00102         size_t si = 0; // specs values index
00103         // compare all the crit values to all the specs values when the name matches.
00104         
00105         while ( !result && ci < crit.nameVal_.strings().size()) {
00106           if (it->second.id() == crit.nameVal_.id()) {  
00107             //     edm::LogInfo("DDFilter") << "  Actually checking " << it->second.name() << std::endl;     
00108             while ( !result && si < it->second.strings().size()) {
00109               //               edm::LogInfo("DDFilter") << "**** is " << crit.nameVal_.strings()[ci] << " = " << it->second.strings()[si] << " ?" << std::endl;
00110               
00111               switch (crit.comp_) {
00112                 // equals means at least one value in crit matches one value
00113                 // in specs.
00114                 //
00115                 // not equals means that no values in crit match no values in specs
00116                 //  (see below the ! (not))
00117                 // 
00118                 // Maybe we should have an 'in' or 'contains' operator and equals would meaning
00119                 // would be changed to mean ALL equal.
00120               case DDSpecificsFilter::equals: 
00121               case DDSpecificsFilter::matches:
00122               case DDSpecificsFilter::not_equals: 
00123               case DDSpecificsFilter::not_matches: 
00124                 result = ( crit.nameVal_.strings()[ci] == it->second.strings()[si] );
00125                 break;
00126                 
00127                 // less than or equals means that ALL values in specs
00128                 // are less than or equals ALL values in crit.  therefore
00129                 // if even ONE is bigger, then this is false.
00130               case DDSpecificsFilter::smaller_equals:
00131                 result = ( it->second.strings()[si] > crit.nameVal_.strings()[ci] );
00132                 break;
00133                 
00134                 // less than means that all are strictly less than, therefore
00135                 // if one is greater than or equal, then this is false
00136               case DDSpecificsFilter::smaller:
00137                 result = ( it->second.strings()[si] >= crit.nameVal_.strings()[ci] );
00138                 break;
00139                 
00140                 // greater or equal to means that all values in specs are
00141                 // greater than or equals to all values in crit.  therefore
00142                 // if even ONE is less than, then this is false
00143               case DDSpecificsFilter::bigger_equals:
00144                 result = ( it->second.strings()[si] < crit.nameVal_.strings()[ci] );
00145                 break;
00146                 
00147                 // greater means that all values in specs are greater than
00148                 // all values in crit.  therefore if even one is less than or
00149                 // equal to crit, then this is false;
00150               case DDSpecificsFilter::bigger:    
00151                 result = ( it->second.strings() <= crit.nameVal_.strings() );
00152               }
00153               //edm::LogInfo("DDFilter") << "       si = " << si << "  result = " << result ;
00154               si ++;
00155             }
00156             //edm::LogInfo("DDFilter") << "  ci = " << ci << std::endl;
00157             
00158             if ( crit.comp_ == DDSpecificsFilter::not_equals 
00159                  || crit.comp_ == DDSpecificsFilter::not_matches
00160                  || crit.comp_ == DDSpecificsFilter::smaller_equals 
00161                  || crit.comp_ == DDSpecificsFilter::smaller
00162                  || crit.comp_ == DDSpecificsFilter::bigger)
00163               result = !result;
00164             
00165             //edm::LogInfo("DDFilter") << "           it = " << it->second.name() << " final result = " << result << std::endl;
00166           }
00167           ++ci;
00168         }
00169       }
00170     }
00171     
00172     return result;
00173   }              
00174   
00175   inline bool sfd_compare_nm(const DDSpecificsFilter::SpecificCriterion & crit,
00176                       const std::vector<const DDsvalues_type *> & specs)
00177   {
00178     // The meaning of this is defined for each operator below.
00179     bool result = false; 
00180     
00181     //   edm::LogInfo("DDFilter") << "specs.size()=" << specs.size() << std::endl;
00182     //   edm::LogInfo("DDFilter") << "crit.nameVal_.doubles().size()=" << crit.nameVal_.doubles().size() << std::endl;
00183     std::vector<const DDsvalues_type *>::const_iterator spit = specs.begin();
00184     
00185     // go through all specifics
00186     for (;  spit != specs.end(); ++spit) {
00187       
00188       DDsvalues_type::const_iterator it = (**spit).begin();
00189       
00190       // go through all DDValues of the current specific.     
00191       for (;  it != (**spit).end(); ++it) {
00192         if ( !it->second.isEvaluated() ) {
00193           edm::LogWarning("DD:Filter") << "(nm) Attempt to access a DDValue as doubles but DDValue is NOT Evaluated!" 
00194                                        << crit.nameVal_.name();
00195           continue; // go on to next one, do not attempt to acess doubles()
00196         }
00197         size_t ci = 0; // criteria values index
00198         size_t si = 0; // specs values index
00199         // compare all the crit values to all the specs values when the name matches.
00200         
00201         while ( !result && ci < crit.nameVal_.doubles().size()) {
00202           
00203           if (it->second.id() == crit.nameVal_.id()) {       
00204             //     edm::LogInfo("DDFilter") << "  Actually checking " << it->second.name() << std::endl;     
00205             while ( !result && si < it->second.doubles().size()) {
00206               //             edm::LogInfo("DDFilter") << "**** is " << crit.nameVal_.doubles()[ci] << " = " << it->second.doubles()[ci] << " ?" << std::endl;
00207               switch (crit.comp_) {
00208                 
00209                 // equals means at least one value in crit matches one value
00210                 // in specs.
00211                 //
00212                 // not equals means that no values in crit match no values in specs
00213                 //  (see below the ! (not))
00214               case DDSpecificsFilter::equals: 
00215               case DDSpecificsFilter::matches:
00216               case DDSpecificsFilter::not_equals: 
00217               case DDSpecificsFilter::not_matches: 
00218                 result = ( crit.nameVal_.doubles()[ci] == it->second.doubles()[si] );
00219                 break;
00220                 
00221                 // less than or equals means that ALL values in specs
00222                 // are less than or equals ALL values in crit.  therefore
00223                 // if even ONE is bigger, then this is false.
00224               case DDSpecificsFilter::smaller_equals:
00225                 result = ( it->second.doubles()[si] > crit.nameVal_.doubles()[ci] );
00226                 break;
00227                 
00228                 // less than means that all are strictly less than, therefore
00229                 // if one is greater than or equal, then this is false
00230               case DDSpecificsFilter::smaller:
00231                 result = ( it->second.doubles()[si] >= crit.nameVal_.doubles()[ci] );
00232                 break;
00233                 
00234                 // greater or equal to means that all values in specs are
00235                 // greater than or equals to all values in crit.  therefore
00236                 // if even ONE is less than, then this is false
00237               case DDSpecificsFilter::bigger_equals:
00238                 result = ( it->second.doubles()[si] < crit.nameVal_.doubles()[ci] );
00239                 break;
00240                 
00241                 // greater means that all values in specs are greater than
00242                 // all values in crit.  therefore if even one is less than or
00243                 // equal to crit, then this is false;
00244               case DDSpecificsFilter::bigger:    
00245                 result = ( it->second.doubles() <= crit.nameVal_.doubles() );
00246               }
00247               //             edm::LogInfo("DDFilter") << "       si = " << si << "  result = " << result ;
00248               si ++;
00249               
00250             }
00251             //     edm::LogInfo("DDFilter") << "  ci = " << ci << std::endl;
00252             
00253             if ( crit.comp_ == DDSpecificsFilter::not_equals 
00254                  || crit.comp_ == DDSpecificsFilter::not_matches
00255                  || crit.comp_ == DDSpecificsFilter::smaller_equals 
00256                  || crit.comp_ == DDSpecificsFilter::smaller
00257                  || crit.comp_ == DDSpecificsFilter::bigger)
00258               result = !result;
00259             
00260             //     edm::LogInfo("DDFilter") << "           it = " << it->second.name() << " final result = " << result << std::endl;
00261             
00262           }
00263           
00264           ++ci;
00265         }
00266       }
00267     }
00268     
00269     return result;
00270   }              
00271   
00272   
00273 
00274 }
00275 
00276 // ================================================================================================
00277 
00278 DDSpecificsFilter::DDSpecificsFilter() 
00279   : DDFilter()
00280 { }
00281 
00282 DDSpecificsFilter::~DDSpecificsFilter() {}
00283 
00284 
00285 void DDSpecificsFilter::setCriteria(const DDValue & nameVal, // name & value of a variable 
00286                    comp_op op, 
00287                    log_op l, 
00288                    bool asStrin, // compare std::strings otherwise doubles
00289                    bool merged // use merged-specifics or simple-specifics
00290                    )
00291 {
00292   criteria_.push_back(SpecificCriterion(nameVal,op,asStrin,merged));
00293   logOps_.push_back(l);
00294  }                 
00295 
00296 bool DDSpecificsFilter::accept(const DDExpandedView & node) const
00297 {
00298   return accept_impl(node);
00299 } 
00300 
00301 
00302 bool DDSpecificsFilter::accept_impl(const DDExpandedView & node) const
00303 {
00304   bool result = true;
00305   criteria_type::const_iterator it = criteria_.begin();
00306   criteria_type::const_iterator crEnd = criteria_.end();
00307   logops_type::const_iterator logOpIt = logOps_.begin();
00308   //logops_type::iterator logOpEnd = logOps_.end();
00309   const DDLogicalPart & logp = node.logicalPart();
00310   DDsvalues_type  sv;
00311   std::vector<const DDsvalues_type *> specs;
00312   for (; it != crEnd; ++it, ++logOpIt) {
00313     // avoid useless evaluations
00314     if ( (   result &&(*logOpIt)==OR ) ||
00315          ( (!result)&&(*logOpIt)==AND) ) continue; 
00316 
00317     bool locres=false;
00318     if (logp.hasDDValue(it->nameVal_)) { 
00319       
00320       if (it->merged_) {
00321         
00322         if (sv.empty())  node.mergedSpecificsV(sv);
00323         
00324         if (it->asString_) { // merged specifics & compare std::strings
00325           locres = sfs_compare(*it,sv); 
00326         }
00327         else { // merged specifics & compare doubles
00328           locres = sfd_compare(*it,sv);
00329         }
00330       }
00331       else {
00332         
00333         if (specs.empty()) node.specificsV(specs);
00334         
00335         if (it->asString_) { // non-merged specifics & compare std::strings
00336           locres = sfs_compare_nm(*it, specs);
00337         }
00338         else { // non-merged specifics & compare doubles
00339           locres = sfd_compare_nm(*it, specs);
00340         }  
00341       }
00342     }
00343     if (*logOpIt==AND) {
00344       result &= locres;
00345     }
00346     else {
00347       result |= locres;
00348     }
00349   }
00350   return result;
00351 }