CMS 3D CMS Logo

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