CMS 3D CMS Logo

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/Core/interface/DDMaterial.h"
00004 //#include "DetectorDescription/Core/interface/DDSolid.h"
00005 #include "DetectorDescription/Base/interface/DDdebug.h"
00006 
00010 DDExpandedView::DDExpandedView(const DDCompactView & cpv)
00011  : walker_(0),w2_(cpv.graph(),cpv.root()), trans_(DDTranslation()), rot_(DDRotationMatrix()),
00012    depth_(0), worldpos_(0)
00013 {
00014     DCOUT('C', "Building a DDExpandedView" );
00015     static DDPosData s_worldpos = DDPosData(DDTranslation(),DDRotation(),0);     
00016     worldpos_ =  &s_worldpos;//new DDPosData(trans_,DDRotation(DDName("","")),0);    
00017     //const DDLogicalPart & rt = cpv.root(); 
00018     
00019    // w2_ = DDCompactView::walker_type(cpv.graph(), rt);
00020     walker_ = &w2_;
00021 /*                                           
00022     walker_ = new DDCompactView::walker_type(cpv.graph(), 
00023                                              rt);
00024 */    
00025     DCOUT('C', "Walker: current.first=" << (*walker_).current().first);
00026     DCOUT('C', "Walker: current.second=" << (*walker_).current().second);
00027                                              
00028     DDPosData * pd((*walker_).current().second);
00029     if (!pd)
00030       pd = worldpos_;  
00031     DDExpandedNode expn((*walker_).current().first,
00032                       pd,
00033                       trans_,
00034                       rot_,
00035                       0);
00036    
00037    // starting point for position calculations, == root of expanded view
00038    history_.push_back(expn);                                  
00039 }
00040 
00041 
00042 DDExpandedView::~DDExpandedView() 
00043 {
00044   // no deletion, because pointer points to static data in c-tor
00045   //delete worldpos_->rot_.rotation();
00046   //delete worldpos_;
00047 }  
00048 
00049 
00050 const DDLogicalPart & DDExpandedView::logicalPart() const 
00051 { 
00052   return history_.back().logp_;
00053 }
00054 
00055 
00056 const DDTranslation & DDExpandedView::translation() const 
00057 { 
00058   return history_.back().trans_; 
00059 }
00060 
00061 
00062 const DDRotationMatrix & DDExpandedView::rotation() const 
00063 { 
00064   return history_.back().rot_; 
00065 }
00066 
00067 
00068 const DDGeoHistory & DDExpandedView::geoHistory() const 
00069 { 
00070   return history_; 
00071 } 
00072 
00073 
00074 int DDExpandedView::depth() const
00075 {
00076   return depth_;
00077 }
00078 
00079 
00080 int DDExpandedView::copyno() const 
00081 { 
00082   return history_.back().copyno();
00083   //return (*walker_).current().second->copyno_; 
00084 }
00085 
00086   
00087 namespace {
00088 
00089   struct Counter {
00090     int same;
00091     int diff;
00092     ~Counter() {
00093     }
00094 
00095   };
00096 
00097   inline Counter & counter() {
00098     static Counter local;
00099     return local;
00100   }
00101 
00102 
00103 }
00104 
00105 
00111 bool DDExpandedView::nextSibling() 
00112 {
00113   bool result(false);
00114   if (scope_.size() && history_.back() == scope_.back()) {
00115    ; // no-next-sibling, if current node is the root of the scope!
00116   } 
00117   else {
00118     if ((*walker_).nextSibling()) {
00119       DDExpandedNode & expn(history_.back()); // back of history_ is always current node
00120       DDCompactView::walker_type::value_type curr = (*walker_).current();
00121       DDPosData const * posdOld = expn.posd_;
00122       expn.logp_=curr.first;
00123       expn.posd_=curr.second;
00124       
00125       DDGeoHistory::size_type hsize = history_.size();
00126       
00127       
00128       if (hsize>1) {
00129         const DDExpandedNode & expnBefore(history_[hsize-2]);
00130         
00131         // T = T1 + INV[R1] * T2
00132         expn.trans_  = expnBefore.trans_ + (expnBefore.rot_ * expn.posd_->trans_);
00133      
00134         // R = R1*INV[R2]       
00135         // VI in principle we can do this
00136         if ( !(expn.posd_->rot()==posdOld->rot()) ) {
00137           expn.rot_ = expnBefore.rot_ * expn.posd_->rot();//.inverse();
00138           ++counter().diff;
00139         }else ++counter().same;
00140 
00141       }
00142       else {
00143         expn.trans_ = expn.posd_->trans_;
00144         expn.rot_ = expn.posd_->rot();//.inverse();
00145       }   
00146       ++expn.siblingno_;
00147       result = true; 
00148     }
00149   }
00150   return result;
00151 }
00152  
00153  
00158 bool DDExpandedView::firstChild()
00159 {
00160   bool result(false);
00161   bool depthNotReached(true);
00162   
00163   // Check for the depth within the scope ...
00164   if (depth_) {
00165     if ( (history_.size()-scope_.size())==depth_ ) {
00166       depthNotReached=false;
00167     }
00168   }
00169   if (depthNotReached) {
00170     if ((*walker_).firstChild()) {
00171       DDExpandedNode & expnBefore(history_.back());
00172       DDCompactView::walker_type::value_type curr = (*walker_).current();
00173  
00174       DDPosData * newPosd = curr.second;
00175     
00176           // T = ... (see nextSiblinig())
00177       DDTranslation newTrans = expnBefore.trans_ + expnBefore.rot_ * newPosd->trans_;
00178     
00179       // R = ... (see nextSibling())
00180       DDRotationMatrix newRot =  expnBefore.rot_ *  newPosd->rot();//.inverse();
00181     
00182       // create a new Expanded node and push it to the history ...
00183       DDExpandedNode expn(curr.first, curr.second,
00184                           newTrans, newRot, 0);
00185     
00186       history_.push_back(expn);                 
00187     
00188       /* debug output
00189       edm::LogInfo("DDExpandedView")  << "FIRSTCHILD: name=" << expn.logicalPart().ddname() 
00190            << " rot=";
00191          
00192       if (expn.absRotation().isIdentity())
00193         edm::LogInfo("DDExpandedView")  << "[none]" << std::endl;
00194       else
00195         edm::LogInfo("DDExpandedView")  << expn.absRotation() << std::endl;
00196       */
00197     
00198       result = true;                     
00199     } // if firstChild 
00200   } // if depthNotReached
00201   return result;
00202 } 
00203 
00204 
00209 bool DDExpandedView::parent()
00210 {
00211   bool result(false);
00212   bool scopeRoot(false);
00213   
00214   // check for a scope
00215   if (scope_.size()) {
00216     if (scope_.back() == history_.back()) { 
00217       // the current node is the root of the scope
00218       scopeRoot = true;
00219     }  
00220   }
00221   
00222   if (!scopeRoot) {
00223     if ((*walker_).parent()) {
00224       history_.pop_back();
00225       result = true;
00226     }
00227   }   
00228   
00229   return result;  
00230 }
00231 
00232 /*
00233 bool DDExpandedView::hasChildren() const
00234 {
00235   bool result = false;
00236    
00237   return result;
00238 }
00239 */
00240 
00241 // same implementation as in GraphWalker !
00256 bool DDExpandedView::next()
00257 {
00258   bool res(false);
00259   if(firstChild()) 
00260     res=true;
00261   else if(nextSibling())
00262     res=true;
00263   else {
00264    while(parent()) {
00265      //DCOUT('C', "pa=" << logicalPart() );
00266      if(nextSibling()) {
00267        //DCOUT('C', "ns=" << logicalPart() );
00268        res=true;
00269        break;
00270      }  
00271    }
00272    //DCOUT('C', current().first << " "<< current().second );
00273   }
00274   return res;
00275 }
00276 
00277 
00279 bool DDExpandedView::nextB()
00280 {
00281    bool res(false);
00282    return res;  
00283 }
00284 
00285 
00286 void dump(const DDGeoHistory & h)
00287 {
00288    DDGeoHistory::const_iterator it = h.begin();
00289    edm::LogInfo("DDExpandedView")  << "--GeoHistory-Dump--[" << std::endl;
00290    int i=0;
00291    for (; it != h.end(); ++it) {
00292      edm::LogInfo("DDExpandedView")  << " " << i << it->logicalPart() << std::endl;
00293      /*
00294           << "     "  << it->logicalPart().material() << std::endl
00295           << "     "  << it->logicalPart().solid() << std::endl;
00296      */
00297      ++i;         
00298    }
00299    edm::LogInfo("DDExpandedView")  << "]---------" << std::endl;
00300 }
00301 
00309 std::vector< const DDsvalues_type *>  DDExpandedView::specifics() const
00310 {
00311   // backward compatible
00312   std::vector<const DDsvalues_type * > result;
00313   specificsV(result);
00314   return result;
00315 }
00316 
00317 void  DDExpandedView::specificsV(std::vector<const DDsvalues_type * > & result) const
00318 {
00319   unsigned int i(0);
00320   //edm::LogInfo("DDExpandedView")  << " in ::specifics " << std::endl;
00321   const std::vector<std::pair<DDPartSelection*, DDsvalues_type*> > & specs = logicalPart().attachedSpecifics();
00322   if (specs.size()) { // do only if SpecPar has data defined 
00323     //edm::LogInfo("DDExpandedView")  << " found: specifics size=" << specs.size() << std::endl;
00324     result.reserve(specs.size());
00325     for (; i<specs.size(); ++i) {
00326       const std::pair<DDPartSelection*,DDsvalues_type*>& sp = specs[i];
00327       // a part selection
00328       const DDPartSelection & psel = *(sp.first);
00329       //edm::LogInfo("DDExpandedView")  << " partsel.size = " << psel.size() << std::endl;
00330       //edm::LogInfo("DDExpandedView")  << " geohistory   = " << geoHistory() << std::endl;
00331       const DDGeoHistory & hist = geoHistory();
00332       
00333       //dump(hist);
00334       //dump(psel);
00335       
00336       if (DDCompareEqual(hist, psel)()) //edm::LogInfo("DDExpandedView")  << "MATCH!!!!" << std::endl;
00337         result.push_back( sp.second );
00338     }
00339   }  
00340 }
00341                                                            
00342                                                            
00343 DDsvalues_type DDExpandedView::mergedSpecifics() const {
00344   DDsvalues_type merged;
00345   mergedSpecificsV(merged);
00346   return merged;
00347 }
00348 
00349 
00350 void DDExpandedView::mergedSpecificsV(DDsvalues_type & merged) const
00351 {
00352 
00353   merged.clear();
00354   const std::vector<std::pair<DDPartSelection*, DDsvalues_type*> > & specs = logicalPart().attachedSpecifics();
00355   if (specs.empty()) return;
00356   const DDGeoHistory & hist = geoHistory();
00357   for (size_t i=0; i<specs.size(); ++i) {
00358     const std::pair<DDPartSelection*,DDsvalues_type*>& sp = specs[i];
00359     const DDPartSelection & psel = *(sp.first);
00360     if (DDCompareEqual(hist, psel)())
00361       merge(merged,*sp.second);
00362   }
00363   // std::sort(merged.begin(),merged.end());
00364 }
00365 
00366 
00373 const DDGeoHistory & DDExpandedView::scope() const
00374 {
00375    return scope_;
00376 }   
00377 
00378 void DDExpandedView::clearScope()
00379 {
00380   scope_.clear();
00381   depth_=0;
00382 }
00383 
00384 
00385 void DDExpandedView::reset()
00386 {
00387    clearScope();
00388    while(parent()) 
00389      ;
00390 }
00391 
00392 
00403 bool DDExpandedView::setScope(const DDGeoHistory & sc, int depth)
00404 {
00405   bool result(false);
00406   
00407   DDGeoHistory buf = scope_; // save current scope
00408   scope_.clear(); // sets scope to global (full) scope
00409 
00410   while (parent()) ; // move up to the root of the expanded-view
00411   
00412   if (descend(sc)) { // try to move down the given scope-history ...
00413     scope_ = sc;
00414     depth_ = depth;
00415     result = true;
00416   }  
00417   else {
00418     scope_ = buf;
00419   }
00420   
00421   return result;  
00422 }
00423 
00424 
00431 bool DDExpandedView::goToHistory(const DDGeoHistory & pos)
00432 {
00433   bool result = true;
00434   int tempD = depth_;
00435   //DCOUT('G', " goto- target= " << pos );
00436   DDGeoHistory tempScope = scope_;
00437   reset();
00438   DDGeoHistory::size_type s = pos.size();
00439   for( DDGeoHistory::size_type j=1; j<s; ++j) {
00440     if (! firstChild()) {
00441       result = false;
00442       //edm::LogError("DDExpandedView") << " ERROR!  , wrong usage of DDExpandedView::goTo! " << std::endl;
00443       //exit(1);
00444       break;
00445     }  
00446     int i=0;
00447     for (; i<pos[j].siblingno(); ++i) {
00448       if (! nextSibling()) {
00449         //edm::LogError("DDExpandedView") << " ERROR!  , wrong usage of DDExpandedView::goTo! " << std::endl;        
00450         result = false;
00451       } 
00452     }
00453   }
00454   
00455   if (!result) {
00456     reset();
00457     setScope(tempScope, tempD);
00458   } 
00459   else {
00460     scope_ = tempScope;
00461     depth_ = tempD;
00462   }
00463   
00464   //DCOUT('G', " goto-result = " << history_ );
00465   return result;
00466 }
00467 
00469 bool DDExpandedView::descend(const DDGeoHistory & sc) 
00470 {
00471   DDGeoHistory::size_type mxx = sc.size();
00472   DDGeoHistory::size_type cur = 0;
00473   bool result(false);
00474   
00475   /* algo: compare currerent node in expanded-view with current-node in sc
00476            if matching:
00477              (A)go to first child in expanded-view, go one level deeper in sc
00478              iterate over all children in expanded-view until one of them
00479              matches the current node in sc. 
00480              if no one matches, return false
00481              else continue at (A)
00482            else return false
00483   */       
00484   const DDExpandedNode & curNode = history_.back();
00485   
00486   if (sc.size()) {
00487     //DCOUT('x', "curN=" << curNode.logicalPart() << " scope[0]=" << sc[cur].logicalPart() );
00488     if (curNode==sc[cur]) {
00489       bool res(false);
00490       while(cur+1 < mxx && firstChild()) {
00491         ++cur;
00492         //DCOUT('x', "fc-curN=" << history_.back().logicalPart() << " scope[x]=" << sc[cur].logicalPart() );
00493         if (!(history_.back()==sc[cur])) {
00494           while(nextSibling()) {
00495             //DCOUT('x', "ns-curN=" << history_.back().logicalPart() << " scope[x]=" << sc[cur].logicalPart() );
00496             if (history_.back()==sc[cur]) {
00497               res=true;
00498               break;
00499             }  
00500           }
00501         }  
00502         else {
00503           res=true;
00504         }
00505         if (res==false) 
00506           break;  
00507       }
00508       result = res;
00509     }     
00510   }
00511   return result; 
00512 }
00513 
00514 
00515 bool DDExpandedView:: goTo(const nav_type & newpos)
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   nav_type::size_type sz = newpos.size();
00529   nav_type::size_type i = 1;
00530   for (; 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 
00575 std::ostream & operator<<(std::ostream & os, const DDExpandedView::nav_type & n)
00576 {
00577   DDExpandedView::nav_type::const_iterator it = n.begin();
00578   os << '(' ;
00579   for (; it != n.end(); ++it) {
00580     os << *it << ',';
00581   }
00582   os << ')';
00583   return os;
00584 }
00585 
00586 
00587 
00588 //THIS IS WRONG, THIS IS WRONG, THIS IS WRONG (not functional wrong but in any other case!)
00589 //THIS IS WRONG, THIS IS STUPID, i bin a depp ...
00590 /*
00591 void doit(DDGeoHistory& h) {
00592   DDRotationMatrix m1, m2, m3;
00593   DDGeoHistory::size_type s(h.size());
00594   std::vector<DDRotationMatrix> rotVec(s);
00595   std::vector<DDTranslation> transVec(s);
00596   
00597   DDGeoHistory::size_type c(s);
00598   for (int i=0; i<s; ++i) {
00599     rotVec[i]   = h[i].posd_->rot_;
00600     transVec[i] = h[i].posd_->trans_;          
00601   }
00602     
00603   if (s>1) {
00604     for (int i=1; i<s; ++i) {
00605       rotVec[i] = rotVec[i-1]*rotVec[i];
00606       //h[i].rot_ = h[i-1].posd_->rot_ * h[i].posd_->rot_;
00607     }
00608     
00609     for (int i=1; i<s; ++i)
00610        transVec[i] = transVec[i-1] + rotVec[i-1]*transVec[i];
00611        //h[i].trans_ = h[i-1].trans_ + h[i-1].rot_ * h[i]  
00612   }
00613   h[s-1].trans_ = transVec[s-1];
00614   h[s-1].rot_ = rotVec[s-1];
00615 
00616 }
00617 */
00618 

Generated on Tue Jun 9 17:32:11 2009 for CMSSW by  doxygen 1.5.4