CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/DetectorDescription/Core/src/DDExpandedView.cc

Go to the documentation of this file.
00001 #include "DetectorDescription/Core/interface/DDExpandedView.h"
00002 #include "DetectorDescription/Core/interface/DDComparator.h"
00003 #include "DetectorDescription/Base/interface/DDdebug.h"
00004 
00008 DDExpandedView::DDExpandedView(const DDCompactView & cpv)
00009  : walker_(0),w2_(cpv.graph(),cpv.root()), trans_(DDTranslation()), rot_(DDRotationMatrix()),
00010    depth_(0), worldpos_(0)
00011 {
00012   //  std::cout << "Building a DDExpandedView" << std::endl;
00013   // MEC:2010-02-08 - consider the ROOT as where you want to start LOOKING at
00014   // the DDD, and worldpos_ as the "real" root node of the graph.  MOVE all this 
00015   // logic to DDCompactView.  This should really be just the traverser...
00016   DDRotation::StoreT::instance().setReadOnly(false);
00017   worldpos_ = new DDPosData(DDTranslation(),DDRotation(),0);     
00018   DDRotation::StoreT::instance().setReadOnly(true);
00019   
00020   walker_ = &w2_;
00021 
00022   //  std::cout << "Walker: current.first=" << (*walker_).current().first << std::endl;
00023   //  std::cout << "Walker: current.second=" << (*walker_).current().second << std::endl;
00024   
00025   DDPosData * pd((*walker_).current().second);
00026   if (!pd)
00027     pd = worldpos_;  
00028   DDExpandedNode expn((*walker_).current().first,
00029                       pd,
00030                       trans_,
00031                       rot_,
00032                       0);
00033   
00034   // starting point for position calculations, == root of expanded view
00035   history_.push_back(expn);                                   
00036 }
00037 
00038 
00039 DDExpandedView::~DDExpandedView() { }  
00040 
00041 
00042 const DDLogicalPart & DDExpandedView::logicalPart() const 
00043 { 
00044   return history_.back().logp_;
00045 }
00046 
00047 
00048 const DDTranslation & DDExpandedView::translation() const 
00049 { 
00050   return history_.back().trans_; 
00051 }
00052 
00053 
00054 const DDRotationMatrix & DDExpandedView::rotation() const 
00055 { 
00056   return history_.back().rot_; 
00057 }
00058 
00059 
00060 const DDGeoHistory & DDExpandedView::geoHistory() const 
00061 { 
00062   return history_; 
00063 } 
00064 
00065 
00066 int DDExpandedView::depth() const
00067 {
00068   return depth_;
00069 }
00070 
00071 
00072 int DDExpandedView::copyno() const 
00073 { 
00074   return history_.back().copyno();
00075   //return (*walker_).current().second->copyno_; 
00076 }
00077 
00078   
00079 namespace {
00080 
00081   struct Counter {
00082     int same;
00083     int diff;
00084     ~Counter() {
00085     }
00086 
00087   };
00088 
00089   inline Counter & counter() {
00090     static Counter local;
00091     return local;
00092   }
00093 
00094 
00095 }
00096 
00097 
00103 bool DDExpandedView::nextSibling() 
00104 {
00105   bool result(false);
00106   if (scope_.size() && history_.back() == scope_.back()) {
00107    ; // no-next-sibling, if current node is the root of the scope!
00108   } 
00109   else {
00110     if ((*walker_).nextSibling()) {
00111       DDExpandedNode & expn(history_.back()); // back of history_ is always current node
00112       DDCompactView::walker_type::value_type curr = (*walker_).current();
00113       DDPosData const * posdOld = expn.posd_;
00114       expn.logp_=curr.first;
00115       expn.posd_=curr.second;
00116       
00117       DDGeoHistory::size_type hsize = history_.size();
00118       
00119       
00120       if (hsize>1) {
00121         const DDExpandedNode & expnBefore(history_[hsize-2]);
00122         
00123         // T = T1 + INV[R1] * T2
00124         expn.trans_  = expnBefore.trans_ + (expnBefore.rot_ * expn.posd_->trans_);
00125      
00126         // R = R1*INV[R2]       
00127         // VI in principle we can do this
00128         if ( !(expn.posd_->rot()==posdOld->rot()) ) {
00129           expn.rot_ = expnBefore.rot_ * expn.posd_->rot();//.inverse();
00130           ++counter().diff;
00131         }else ++counter().same;
00132 
00133       }
00134       else {
00135         expn.trans_ = expn.posd_->trans_;
00136         expn.rot_ = expn.posd_->rot();//.inverse();
00137       }   
00138       ++expn.siblingno_;
00139       result = true; 
00140     }
00141   }
00142   return result;
00143 }
00144  
00145  
00150 bool DDExpandedView::firstChild()
00151 {
00152   bool result(false);
00153   bool depthNotReached(true);
00154   
00155   // Check for the depth within the scope ...
00156   if (depth_) {
00157     if ( (history_.size()-scope_.size())==depth_ ) {
00158       depthNotReached=false;
00159     }
00160   }
00161   if (depthNotReached) {
00162     if ((*walker_).firstChild()) {
00163       DDExpandedNode & expnBefore(history_.back());
00164       DDCompactView::walker_type::value_type curr = (*walker_).current();
00165  
00166       DDPosData * newPosd = curr.second;
00167     
00168           // T = ... (see nextSiblinig())
00169       DDTranslation newTrans = expnBefore.trans_ + expnBefore.rot_ * newPosd->trans_;
00170     
00171       // R = ... (see nextSibling())
00172       DDRotationMatrix newRot =  expnBefore.rot_ *  newPosd->rot();//.inverse();
00173     
00174       // create a new Expanded node and push it to the history ...
00175       DDExpandedNode expn(curr.first, curr.second,
00176                           newTrans, newRot, 0);
00177     
00178       history_.push_back(expn);                 
00179     
00180       /* debug output
00181       edm::LogInfo("DDExpandedView")  << "FIRSTCHILD: name=" << expn.logicalPart().ddname() 
00182            << " rot=";
00183          
00184       if (expn.absRotation().isIdentity())
00185         edm::LogInfo("DDExpandedView")  << "[none]" << std::endl;
00186       else
00187         edm::LogInfo("DDExpandedView")  << expn.absRotation() << std::endl;
00188       */
00189     
00190       result = true;                     
00191     } // if firstChild 
00192   } // if depthNotReached
00193   return result;
00194 } 
00195 
00196 
00201 bool DDExpandedView::parent()
00202 {
00203   bool result(false);
00204   bool scopeRoot(false);
00205   
00206   // check for a scope
00207   if (scope_.size()) {
00208     if (scope_.back() == history_.back()) { 
00209       // the current node is the root of the scope
00210       scopeRoot = true;
00211     }  
00212   }
00213   
00214   if (!scopeRoot) {
00215     if ((*walker_).parent()) {
00216       history_.pop_back();
00217       result = true;
00218     }
00219   }   
00220   
00221   return result;  
00222 }
00223 
00224 /*
00225 bool DDExpandedView::hasChildren() const
00226 {
00227   bool result = false;
00228    
00229   return result;
00230 }
00231 */
00232 
00233 // same implementation as in GraphWalker !
00248 bool DDExpandedView::next()
00249 {
00250   bool res(false);
00251   if(firstChild()) 
00252     res=true;
00253   else if(nextSibling())
00254     res=true;
00255   else {
00256    while(parent()) {
00257      //DCOUT('C', "pa=" << logicalPart() );
00258      if(nextSibling()) {
00259        //DCOUT('C', "ns=" << logicalPart() );
00260        res=true;
00261        break;
00262      }  
00263    }
00264    //DCOUT('C', current().first << " "<< current().second );
00265   }
00266   return res;
00267 }
00268 
00269 
00271 bool DDExpandedView::nextB()
00272 {
00273    bool res(false);
00274    return res;  
00275 }
00276 
00277 
00278 void dump(const DDGeoHistory & h)
00279 {
00280    DDGeoHistory::const_iterator it = h.begin();
00281    edm::LogInfo("DDExpandedView")  << "--GeoHistory-Dump--[" << std::endl;
00282    int i=0;
00283    for (; it != h.end(); ++it) {
00284      edm::LogInfo("DDExpandedView")  << " " << i << it->logicalPart() << std::endl;
00285      /*
00286           << "     "  << it->logicalPart().material() << std::endl
00287           << "     "  << it->logicalPart().solid() << std::endl;
00288      */
00289      ++i;         
00290    }
00291    edm::LogInfo("DDExpandedView")  << "]---------" << std::endl;
00292 }
00293 
00302 std::vector< const DDsvalues_type *>  DDExpandedView::specifics() const
00303 {
00304   // backward compatible
00305   std::vector<const DDsvalues_type * > result;
00306   specificsV(result);
00307   return result;
00308 }
00309 
00310 void  DDExpandedView::specificsV(std::vector<const DDsvalues_type * > & result) const
00311 {
00312   unsigned int i(0);
00313   //edm::LogInfo("DDExpandedView")  << " in ::specifics " << std::endl;
00314   const std::vector<std::pair<DDPartSelection*, DDsvalues_type*> > & specs = logicalPart().attachedSpecifics();
00315   if (specs.size()) { // do only if SpecPar has data defined 
00316     //edm::LogInfo("DDExpandedView")  << " found: specifics size=" << specs.size() << std::endl;
00317     result.reserve(specs.size());
00318     for (; i<specs.size(); ++i) {
00319       const std::pair<DDPartSelection*,DDsvalues_type*>& sp = specs[i];
00320       // a part selection
00321       const DDPartSelection & psel = *(sp.first);
00322       //edm::LogInfo("DDExpandedView")  << " partsel.size = " << psel.size() << std::endl;
00323       //edm::LogInfo("DDExpandedView")  << " geohistory   = " << geoHistory() << std::endl;
00324       const DDGeoHistory & hist = geoHistory();
00325       
00326       //dump(hist);
00327       //dump(psel);
00328       
00329       if (DDCompareEqual(hist, psel)()) //edm::LogInfo("DDExpandedView")  << "MATCH!!!!" << std::endl;
00330         result.push_back( sp.second );
00331     }
00332   }  
00333 }
00334                                                            
00335                                                            
00336 DDsvalues_type DDExpandedView::mergedSpecifics() const {
00337   DDsvalues_type merged;
00338   mergedSpecificsV(merged);
00339   return merged;
00340 }
00341 
00342 
00343 void DDExpandedView::mergedSpecificsV(DDsvalues_type & merged) const
00344 {
00345 
00346   merged.clear();
00347   const std::vector<std::pair<DDPartSelection*, DDsvalues_type*> > & specs = logicalPart().attachedSpecifics();
00348   if (specs.empty()) return;
00349   const DDGeoHistory & hist = geoHistory();
00350   for (size_t i=0; i<specs.size(); ++i) {
00351     const std::pair<DDPartSelection*,DDsvalues_type*>& sp = specs[i];
00352     const DDPartSelection & psel = *(sp.first);
00353     if (DDCompareEqual(hist, psel)())
00354       merge(merged,*sp.second);
00355   }
00356   // std::sort(merged.begin(),merged.end());
00357 }
00358 
00359 
00366 const DDGeoHistory & DDExpandedView::scope() const
00367 {
00368    return scope_;
00369 }   
00370 
00371 void DDExpandedView::clearScope()
00372 {
00373   scope_.clear();
00374   depth_=0;
00375 }
00376 
00377 
00378 void DDExpandedView::reset()
00379 {
00380    clearScope();
00381    while(parent()) 
00382      ;
00383 }
00384 
00385 
00396 bool DDExpandedView::setScope(const DDGeoHistory & sc, int depth)
00397 {
00398   bool result(false);
00399   
00400   DDGeoHistory buf = scope_; // save current scope
00401   scope_.clear(); // sets scope to global (full) scope
00402 
00403   while (parent()) ; // move up to the root of the expanded-view
00404   
00405   if (descend(sc)) { // try to move down the given scope-history ...
00406     scope_ = sc;
00407     depth_ = depth;
00408     result = true;
00409   }  
00410   else {
00411     scope_ = buf;
00412   }
00413   
00414   return result;  
00415 }
00416 
00417 
00424 bool DDExpandedView::goToHistory(const DDGeoHistory & pos)
00425 {
00426   bool result = true;
00427   int tempD = depth_;
00428   //DCOUT('G', " goto- target= " << pos );
00429   DDGeoHistory tempScope = scope_;
00430   reset();
00431   DDGeoHistory::size_type s = pos.size();
00432   for( DDGeoHistory::size_type j=1; j<s; ++j) {
00433     if (! firstChild()) {
00434       result = false;
00435       //edm::LogError("DDExpandedView") << " ERROR!  , wrong usage of DDExpandedView::goTo! " << std::endl;
00436       //exit(1);
00437       break;
00438     }  
00439     int i=0;
00440     for (; i<pos[j].siblingno(); ++i) {
00441       if (! nextSibling()) {
00442         //edm::LogError("DDExpandedView") << " ERROR!  , wrong usage of DDExpandedView::goTo! " << std::endl;        
00443         result = false;
00444       } 
00445     }
00446   }
00447   
00448   if (!result) {
00449     reset();
00450     setScope(tempScope, tempD);
00451   } 
00452   else {
00453     scope_ = tempScope;
00454     depth_ = tempD;
00455   }
00456   
00457   //DCOUT('G', " goto-result = " << history_ );
00458   return result;
00459 }
00460 
00462 bool DDExpandedView::descend(const DDGeoHistory & sc) 
00463 {
00464   DDGeoHistory::size_type mxx = sc.size();
00465   DDGeoHistory::size_type cur = 0;
00466   bool result(false);
00467   
00468   /* algo: compare currerent node in expanded-view with current-node in sc
00469            if matching:
00470              (A)go to first child in expanded-view, go one level deeper in sc
00471              iterate over all children in expanded-view until one of them
00472              matches the current node in sc. 
00473              if no one matches, return false
00474              else continue at (A)
00475            else return false
00476   */       
00477   const DDExpandedNode & curNode = history_.back();
00478   
00479   if (sc.size()) {
00480     //DCOUT('x', "curN=" << curNode.logicalPart() << " scope[0]=" << sc[cur].logicalPart() );
00481     if (curNode==sc[cur]) {
00482       bool res(false);
00483       while(cur+1 < mxx && firstChild()) {
00484         ++cur;
00485         //DCOUT('x', "fc-curN=" << history_.back().logicalPart() << " scope[x]=" << sc[cur].logicalPart() );
00486         if (!(history_.back()==sc[cur])) {
00487           while(nextSibling()) {
00488             //DCOUT('x', "ns-curN=" << history_.back().logicalPart() << " scope[x]=" << sc[cur].logicalPart() );
00489             if (history_.back()==sc[cur]) {
00490               res=true;
00491               break;
00492             }  
00493           }
00494         }  
00495         else {
00496           res=true;
00497         }
00498         if (res==false) 
00499           break;  
00500       }
00501       result = res;
00502     }     
00503   }
00504   return result; 
00505 }
00506 
00507 
00508 bool DDExpandedView::goTo(const nav_type & newpos) {
00509   return goTo(&newpos.front(),newpos.size());
00510 
00511 }
00512 
00513 bool DDExpandedView::goTo(NavRange newpos) {
00514   return goTo(newpos.first,newpos.second);
00515 }
00516 
00517 bool DDExpandedView::goTo(int const * newpos, size_t sz)
00518 {
00519   bool result(false);
00520   
00521   // save the current position
00522   //nav_type savedPos = navPos(); 
00523   DDGeoHistory savedPos = history_;
00524    
00525   // reset to root node 
00526   //FIXME: reset to root of scope!!
00527   reset();
00528   
00529   // try to navigate down to the newpos
00530   for (size_t i = 1; i < sz; ++i) {
00531     result = firstChild();
00532     if (result) {
00533       int pos = newpos[i];
00534       for(int k=0; k<pos; ++k) {
00535         result = nextSibling();
00536       }
00537     }
00538     else {
00539       break;
00540     }   
00541   }
00542   
00543   if (!result) {
00544     goToHistory(savedPos);
00545   }
00546   return result;
00547 }
00548 
00549 
00550 DDExpandedView::nav_type DDExpandedView::navPos() const
00551 {
00552   DDGeoHistory::size_type i=0;
00553   DDGeoHistory::size_type j=history_.size();
00554   nav_type pos(j);  
00555   
00556   for (;i<j;++i)
00557     pos[i] = history_[i].siblingno();
00558     
00559   return pos;   
00560 }
00561 
00562 DDExpandedView::nav_type DDExpandedView::copyNumbers() const
00563 {
00564   DDGeoHistory::size_type it = 0;
00565   DDGeoHistory::size_type sz = history_.size();
00566   nav_type result(sz);
00567   
00568   for (; it < sz; ++it) {
00569     result[it] = history_[it].copyno();
00570   }
00571   return result;
00572 }
00573 
00574 std::ostream & printNavType(std::ostream & os, int const * n, size_t sz){
00575   os << '(' ;
00576   for (int const * it=n; it != n+sz; ++it) {
00577     os << *it << ',';
00578   }
00579   os << ')';
00580   return os;
00581 }
00582 
00583 
00584 
00585 //THIS IS WRONG, THIS IS WRONG, THIS IS WRONG (not functional wrong but in any other case!)
00586 //THIS IS WRONG, THIS IS STUPID, i bin a depp ...
00587 /*
00588 void doit(DDGeoHistory& h) {
00589   DDRotationMatrix m1, m2, m3;
00590   DDGeoHistory::size_type s(h.size());
00591   std::vector<DDRotationMatrix> rotVec(s);
00592   std::vector<DDTranslation> transVec(s);
00593   
00594   DDGeoHistory::size_type c(s);
00595   for (int i=0; i<s; ++i) {
00596     rotVec[i]   = h[i].posd_->rot_;
00597     transVec[i] = h[i].posd_->trans_;          
00598   }
00599     
00600   if (s>1) {
00601     for (int i=1; i<s; ++i) {
00602       rotVec[i] = rotVec[i-1]*rotVec[i];
00603       //h[i].rot_ = h[i-1].posd_->rot_ * h[i].posd_->rot_;
00604     }
00605     
00606     for (int i=1; i<s; ++i)
00607        transVec[i] = transVec[i-1] + rotVec[i-1]*transVec[i];
00608        //h[i].trans_ = h[i-1].trans_ + h[i-1].rot_ * h[i]  
00609   }
00610   h[s-1].trans_ = transVec[s-1];
00611   h[s-1].rot_ = rotVec[s-1];
00612 
00613 }
00614 */
00615