CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/DetectorDescription/Core/src/DDCheck.cc

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