CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/DetectorDescription/Core/src/DDCheck.cc

Go to the documentation of this file.
00001 #include "DetectorDescription/Core/src/DDCheck.h"
00002 
00003 #include "DetectorDescription/Core/interface/DDCompactView.h"
00004 #include "DetectorDescription/Core/interface/DDExpandedView.h"
00005 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
00006 #include "DetectorDescription/Core/interface/DDSolid.h"
00007 #include "DetectorDescription/Core/interface/DDMaterial.h"
00008 
00009 // Message logger.
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 
00012 
00013 //#include "DetectorDescription/ExprAlgo/interface/ExprEvalSingleton.h"
00014 
00015 bool DDCheckLP(const DDLogicalPart & lp, std::ostream & os)
00016 {
00017    bool result = false;
00018    // is it defined or just declared?
00019    if (!lp) {
00020      os << "LogicalPart: " << lp << " is not defined!" << std::endl;
00021    }
00022    else {
00023      // check solid
00024      if (!lp.solid()) {
00025        os << "LogicalPart: " << lp << "| no solid defined, solid=" 
00026           << lp.solid() << std::endl;
00027      }
00028      else if(lp.solid().shape()==dd_not_init) {
00029        os << "LogicalPart: " << lp << "| solid not init, solid=" 
00030           << lp.solid() << std::endl;
00031      }
00032      // check material
00033      if (!lp.material()) {
00034        os << "LogicalPart: " << lp << "| no material defined, material=" 
00035           << lp.material() << std::endl;
00036      }
00037      else { // check consituents recursively
00038      
00039      }      
00040    }
00041    return result;
00042 }
00043 
00044 
00045 // checks PosData* if it contains sensfull stuff ...
00046 //:void DDCheckPD(const DDLogicalPart & lp, graph_type::neighbour_type & nb, std::ostream & os)
00047 bool DDCheckPD(const DDLogicalPart & lp, DDCompactView::graph_type::edge_range nb, const DDCompactView::graph_type & g, std::ostream & os)
00048 {
00049    bool result = false;
00050    if (nb.first != nb.second) {
00051      for (; nb.first != nb.second; ++(nb.first)) {
00052        if (! nb.first->second ) {
00053          edm::LogInfo ("DDCheck") << "PosData of LogicalPart " << lp.name() << " missing." << std::endl;
00054          edm::LogInfo ("DDCheck") << "  the LogicalPart is meant to be a daughter volume, but its position is missing!" << std::endl;
00055        } 
00056        else { // check for the rotation matrix being present
00057          const DDRotation & r = g.edgeData(nb.first->second)->rot_;
00058          if (! r.isDefined().second ) {
00059          //if (! nb.first->second->rot_.rotation() ) {
00060            const DDRotation & r = g.edgeData(nb.first->second)->rot_;
00061            os << "Rotationmatrix is not defined: " << r << std::endl;
00062          }
00063        }
00064      }  
00065    }
00066    return result;
00067 }   
00068 
00069 
00070 bool DDCheckConnect(const DDCompactView & cpv, std::ostream & os)
00071 {
00072   bool result = false;
00073   os << std::endl << "Checking connectivity of CompactView:" << std::endl;
00074   
00075   // Algorithm:
00076   // Pass 1: walk the whole graph, mark every visited LogicalPart-node
00077   // Pass 2: iterate over all nodes, check with marked nodes from Pass 1
00078   
00079   // Pass 1:
00080   std::map<DDLogicalPart,bool> visited;
00081   //  walker_type wkr = DDCompactView().walker();
00082   walker_type wkr = cpv.walker();
00083   visited[wkr.current().first]=true;
00084   while(wkr.next()) {
00085     //    std::cout << "DDCheck" << "   " << wkr.current().first << std::endl;
00086     visited[wkr.current().first]=true;
00087   }
00088   os << " CompactView has " << visited.size() 
00089      << " (multiple-)connected LogicalParts with root=" << cpv.root().ddname() << std::endl;
00090   
00091   // Pass 2:
00092   DDCompactView::graph_type & g = const_cast<DDCompactView::graph_type&>(cpv.graph());
00093 
00094   int uc = 0;
00095   DDCompactView::graph_type::adj_list::size_type it = 0;
00096   
00097   for(; it < g.size(); ++it) { 
00098     if (! visited[g.nodeData(it)] ) {
00099       ++uc;
00100       os << " " << g.nodeData(it).ddname();
00101     }
00102   }
00103   os << std::endl;
00104   os << " There were " << uc << " unconnected nodes found." << std::endl << std::endl;  
00105   if (uc) {
00106     os << std::endl;
00107     os << " ****************************************************************************" << std::endl;
00108     os << " WARNING: The geometrical hierarchy may not be complete. " << std::endl
00109        << "          Expect unpredicted behaviour using DDCore/interface (i.e. SEGFAULT)"
00110        << std::endl;
00111     os << " ****************************************************************************" << std::endl;
00112     os << std::endl;    
00113        
00114   }  
00115   return result;
00116 }
00117 
00118 // iterates over the whole compactview and chechs whether the posdata
00119 // (edges in the acyclic graph ..) are complete
00120 bool DDCheckAll(const DDCompactView & cpv, std::ostream & os)
00121 {
00122    bool result = false;
00123    // const_cast because graph_type does not provide const_iterators!
00124    DDCompactView::graph_type & g = const_cast<DDCompactView::graph_type&>(cpv.graph());
00125    
00126    // basic debuggger
00127    std::map< std::pair<std::string,std::string>, int > lp_names;
00128    
00129    DDCompactView::graph_type::adj_list::size_type it = 0;
00130    for(; it < g.size(); ++it) { 
00131      const DDLogicalPart & lp = g.nodeData(it);
00132      lp_names[std::make_pair(lp.name().ns(),lp.name().name())]++;
00133    }
00134    std::map< std::pair<std::string,std::string>, int >::iterator mit = lp_names.begin();
00135    
00136    
00137    for (; mit != lp_names.end(); ++ mit) {
00138      if (mit->second >1) {
00139        os << "interesting: " << mit->first.first << ":" << mit->first.second
00140           << " counted " << mit->second << " times!" << std::endl;
00141        os << " Names of LogicalParts seem not to be unique!" << std::endl << std::endl;   
00142        result = true;
00143             
00144      }
00145      //os << "registered: " << mit->first.first << ":" << mit->first.second << std::endl;
00146    
00147    }
00148    // iterate over all nodes in the graph (nodes are logicalparts,
00149    // edges are posdata*
00150    for(it=0; it < g.size(); ++it) { 
00151      const DDLogicalPart & lp = g.nodeData(it);
00152      result |= DDCheckLP(lp,os);
00153      result |= DDCheckPD(lp ,g.edges(it), g, os);
00154    }
00155    
00156    // Check the connectivity of the graph..., takes quite some time & memory
00157    result |= DDCheckConnect(cpv, os);
00158    return result;
00159    
00160 }
00161 
00162 
00163 // comprehensive check, very cpu intensive!
00164 // - expands the compact-view
00165 // - detects cyclic containment of parts (not yet)
00166 // - checks for completeness of solid & material definition / logical-part
00167 bool DDCheck(std::ostream&os)
00168 {
00169    bool result = false;
00170    os << "DDCore: start comprehensive checking" << std::endl;
00171    DDCompactView cpv; // THE one and only (prototype restriction) CompactView
00172    DDExpandedView exv(cpv);
00173    
00174    //   result |= DDCheckMaterials(os);
00175    //DDCheckLP(exv.logicalPart(),os);
00176    result |=  DDCheckAll(cpv,os);
00177    
00178    // done
00179    os << "DDCore: end of comprehensive checking" << std::endl;
00180    
00181    if (result) { // at least one error found
00182      edm::LogError("DDCheck") << std::endl << "DDD:DDCore:DDCheck: found inconsistency problems!" << std::endl;
00183 //      edm::LogError("DDCheck") << "To continue press 'y' ... " << std::endl;
00184 //      char c;
00185 //      cin >> c;
00186 //      if (c != 'y') {
00187 //        edm::LogError("DDCheck") << " terminating ..." << std::endl; exit(1);
00188 // (Mike Case) should we throw instead? OR is an if (DDCheck) the best way?
00189 //     throw(DDException(std::string("DDD:DDCore:DDCheck: found inconsistency problems!"));
00190    }
00191           
00192    return result;
00193 }
00194 
00195 bool DDCheck(const DDCompactView& cpv, std::ostream&os)
00196 {
00197    bool result = false;
00198    os << "DDCore: start comprehensive checking" << std::endl;
00199    //   DDCompactView cpv; // THE one and only (prototype restriction) CompactView
00200    DDExpandedView exv(cpv);
00201    
00202    //   result |= DDCheckMaterials(os);
00203    //DDCheckLP(exv.logicalPart(),os);
00204    result |=  DDCheckAll(cpv,os);
00205    
00206    // done
00207    os << "DDCore: end of comprehensive checking" << std::endl;
00208    
00209    if (result) { // at least one error found
00210      edm::LogError("DDCheck") << std::endl << "DDD:DDCore:DDCheck: found inconsistency problems!" << std::endl;
00211 //      edm::LogError("DDCheck") << "To continue press 'y' ... " << std::endl;
00212 //      char c;
00213 //      cin >> c;
00214 //      if (c != 'y') {
00215 //        edm::LogError("DDCheck") << " terminating ..." << std::endl; exit(1);
00216 // (Mike Case) should we throw instead? OR is an if (DDCheck) the best way?
00217 //     throw(DDException(std::string("DDD:DDCore:DDCheck: found inconsistency problems!"));
00218    }
00219           
00220    return result;
00221 }