/search.css" rel="stylesheet" type="text/css"/> /search.js">
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

TouchableToDetectorElement.cc
Go to the documentation of this file.
00001 #include "TouchableToDetectorElement.h"
00002 
00003 #include "G4TouchableHistory.hh"
00004 
00005 #include "DetDesc/ILVolume.h"
00006 #include "DetDesc/IPVolume.h"
00007 #include "DetDesc/IDetectorElement.h"
00008 #include "DetDesc/IGeometryInfo.h"
00009 
00010 #include "GaudiKernel/DataObject.h"
00011 #include "GaudiKernel/IRegistry.h"
00012 #include "GaudiKernel/RegistryEntry.h"
00013 #include "GaudiKernel/DataObject.h"
00014 
00015 #include <vector>
00016 
00017 TouchableToDetectorElement::TouchableToDetectorElement(
00018                           const std::string& type,
00019                           const std::string& name,
00020                           const IInterface* parent)
00021        : GaudiTool(type,name,parent)
00022 {
00023   declareInterface<ITouchableToDetectorElement>(this);
00024   
00025 }
00026 
00027 
00028 StatusCode TouchableToDetectorElement::G4VolumeToDetDesc( 
00029         const G4VPhysicalVolume* inVol, 
00030         const IPVolume* &outVol )        
00031 {
00035   ILVolume::ReplicaPath rp;
00036   return G4VolumeToDetDesc(inVol,outVol,rp);
00037 }
00038 
00039 StatusCode TouchableToDetectorElement::G4VolumeToDetDesc( 
00040         const G4VPhysicalVolume* inVol, 
00041         const IPVolume* &outVol,
00042         ILVolume::ReplicaPath& outPath )
00043 {
00053   
00054   if(!inVol) {
00055     return StatusCode::FAILURE;
00056   }
00057   
00058   std::string pvpath = inVol->GetName();
00059   
00060   const ILVolume* lv = 0;
00061   const IPVolume* pv = 0;
00062    // This is a top-level call
00063    // Look for an explicit logical volume name.
00064   std::string lname = pvpath;
00065   std::string::size_type p = pvpath.find_first_of('#');
00066   if(p!= std::string::npos) {
00067     lname = pvpath.substr(0,p);
00068     pvpath.erase(0,p+1); // strip off this part.
00069   } 
00070   
00071   // Find the logical volume.
00072   if(!exist<ILVolume>(detSvc(),lname,false)) {
00073     err() << "Can't find lvolume at path " << lname << " when parsing physvol " << inVol->GetName() << endreq;
00074     return StatusCode::FAILURE;
00075   }    
00076   lv= getDet<ILVolume>(lname);
00077   
00078   // Keep eating the remaining string until we have fully parsed the remaining logical/physical path sequence.
00079   while(pvpath.size() > 0) {
00080     // Make sure the current logical volume is good.
00081     if(!lv) {
00082       err() << "Can't find lvolume." << endreq;
00083       return StatusCode::FAILURE;
00084     }
00085 
00086     // parse out the next bit before a hash mark:
00087     std::string pname = pvpath;
00088     std::string::size_type p = pvpath.find_first_of('#');
00089     if(p != std::string::npos ) {
00090       pname.erase(p,std::string::npos);
00091       pvpath.erase(0,p+1); // Ok, take this stuff off the front.
00092     } else {
00093       pvpath.erase();
00094     }
00095   
00096     ILVolume::ReplicaType replica = 0;
00097     pv = 0;
00098     for ( ILVolume::ReplicaType i = 0; i< lv->noPVolumes(); ++i ){
00099       const IPVolume* apv = lv->pvolume(i);
00100       if(!apv) {
00101         err() << "Bad link to IPVolume from " << lv->name() << endreq;
00102         return StatusCode::FAILURE;
00103       }
00104       // Look for a match.
00105       if(apv->name() == pname){ pv = apv; replica = i; break;}
00106     } // End of loop over physical volumes in lv
00107     
00108     if(!pv) {
00109       err() << "Couldn't find a match for physical volume with name " << pname << " in lvolume name " << lv->name() << endreq;
00110       return StatusCode::FAILURE;
00111     }
00112     // Finally, this is what we were after:
00113     outPath.push_back(replica);      
00114     
00115     // Advance lvolume
00116     lv = pv->lvolume();
00117   }
00118 
00119   outVol = pv;
00120 
00121   return StatusCode::SUCCESS;
00122 }
00123 
00124 
00125 // ---------------------------------------------------------------------------------
00126 template <class T> 
00127 StatusCode TouchableToDetectorElement::FindObjectsInDirectory(
00128                   const std::string& dirname,
00129                   std::vector<const T*>& list
00130                   )
00131 {
00135   info() << "Looking for structures in " << dirname << endreq;
00136   if (!existDet<DataObject>(dirname)) {
00137     err() << "No " << dirname << " in TDS" << endreq;
00138     return StatusCode::FAILURE;
00139   }
00140   const DataObject *d = getDet<DataObject>(dirname);
00141 
00142   const T* t = dynamic_cast<const T*>(d);
00143   if(t) list.push_back(t);
00144 
00145   IRegistry* dr = d->registry();
00146   using namespace DataSvcHelpers;
00147   RegistryEntry* dre = dynamic_cast<RegistryEntry*>(dr);
00148   if (!dre) {
00149     err() << "Failed to get RegistryEntry on DataObject" << d << endreq;
00150     return StatusCode::FAILURE;
00151   }
00152 
00153   RegistryEntry::Iterator it = dre->begin(), done = dre->end();
00154   for (; it != done; ++it) {
00155     std::string id = (*it)->identifier();
00156     StatusCode sc = FindObjectsInDirectory<T>(id,list);
00157     if(sc.isFailure()) return sc;
00158   }
00159 
00160   return StatusCode::SUCCESS;  
00161 }
00162 
00163 
00164 StatusCode TouchableToDetectorElement::GetBestDetectorElement(
00165                           const G4TouchableHistory* inHistory,  // The current particle location
00166                           const std::vector<std::string>& inPaths,// Name(s) of specific detElements, or paths to be searched
00167                           const IDetectorElement* &outElement,  // output: The best element (may be zero!) 
00168                           int& outCompatibility )              // output: the goodness of the match (higher is better)
00169 {
00170   TouchableToDetectorElement::SpecifiedVolume g4place; 
00171   StatusCode sc = GetSpecifiedVolume(inHistory, g4place);
00172   if(sc.isFailure()) return sc;
00173 
00174   // At the moment, the best possible match is to the top Element, which has only basic compatibility.
00175   outCompatibility = 0x7fffffff; // Maximum possible int.
00176   outElement = g4place.mTop;
00177 
00178   // Find a list we want to compare to.
00179   //debug() << "Getting list of elements" << endreq;
00180   std::vector<const IDetectorElement*> elements;
00181   
00182   // Search each path, looking for things.
00183   for(unsigned int i = 0; i< inPaths.size(); ++i) {
00184     sc = FindObjectsInDirectory<IDetectorElement>(inPaths[i],elements);
00185     if(sc.isFailure()) return sc;
00186   }
00187 
00188   // Now compare each one to our current.
00189   for(unsigned int i=0; i<elements.size(); ++i) {
00190     TouchableToDetectorElement::SpecifiedVolume trialVolume;
00191     sc = GetSpecifiedVolume(elements[i], g4place.mTop, trialVolume);
00192     if(sc.isFailure()) continue;
00193 
00194     int compat = Compatability(g4place,trialVolume);
00195     if((compat >= 0) && (compat<outCompatibility)) {
00196       outElement = elements[i];
00197       outCompatibility = compat;
00198     }
00199   }
00200 
00201   return StatusCode::SUCCESS; 
00202 }
00203 
00204 StatusCode TouchableToDetectorElement::GetSpecifiedVolume(
00205             const G4TouchableHistory* inHistory, 
00206             TouchableToDetectorElement::SpecifiedVolume& outVol)
00207 {
00208   //debug() << "Building SpecVol from G4TouchableHistory" << endreq;
00209   if(!inHistory) {
00210     err() << "No good TouchableHistory provided." << endreq;
00211     return StatusCode::FAILURE;
00212   }
00213 
00214   // Try to find the topmost level, which should be a DetectorElement.
00215   G4VPhysicalVolume* top = inHistory->GetVolume(inHistory->GetHistoryDepth()-1);
00216   if(!top) {
00217     err() << "Got null G4VPhysicalVolume pointer in the bottom of G4TouchableHistory. Huh???" << endreq;
00218     return StatusCode::FAILURE;
00219   }
00220   if(!exist<IDetectorElement>(detSvc(),top->GetName()),false) {
00221     err() << "Can't find detector element at the bottom of the G4TouchableHistory, name = " << top->GetName() << endreq;
00222     return StatusCode::FAILURE;
00223   }
00224 
00225   outVol.mTop = getDet<IDetectorElement>(top->GetName());
00226   outVol.mRpath.clear();
00227 
00228    // Ok, now parse the rest of the history.
00229    // This could in principle be sped up by caching the resulting sub-SpecfiedVolumes and storing keyed by
00230    // G4VPhysicalVolume pointer. But that would result in a fair number of things laying around, and it's
00231    // not clear if the speed is important yet.
00232 
00233   for(int ind=inHistory->GetHistoryDepth()-2; ind>=0;  --ind){
00234     G4VPhysicalVolume* g4pv = inHistory->GetVolume(ind);
00235      // Now, parse the volume name.
00236     ILVolume::ReplicaPath subpath;
00237     const IPVolume* pv;
00238     StatusCode sc = G4VolumeToDetDesc(g4pv,pv,subpath);
00239     if(sc.isFailure()) return sc;
00240 
00241     // Tack this onto the end of the list.
00242     outVol.mRpath.insert(outVol.mRpath.end(),subpath.begin(),subpath.end());
00243     
00244   } // End loop over history
00245   
00246   return StatusCode::SUCCESS;
00247 }
00248 
00249 StatusCode TouchableToDetectorElement::GetSpecifiedVolume(const IDetectorElement* inElem,   const IDetectorElement* inTopElem, TouchableToDetectorElement::SpecifiedVolume& outVol)
00250 {
00254   const IGeometryInfo* topGeo = inTopElem->geometry();
00255   const IGeometryInfo* trialGeo = inElem->geometry();
00256 
00257   // Try to build up a full replica path.
00258   outVol.mRpath.clear();
00259   outVol.mTop = 0;
00260   
00261   const IGeometryInfo* curGeo = trialGeo;
00262   while(curGeo!=topGeo) {
00263     //std::string sstart;
00264     //curGeo->location(sstart, rpath);
00265     
00266     ILVolume::ReplicaPath rpath;
00267     IGeometryInfo* nextGeo;
00268     curGeo->location(nextGeo, rpath);
00269     curGeo = nextGeo;
00270     outVol.mRpath.insert(outVol.mRpath.begin(),rpath.begin(),rpath.end());
00271     if(0==curGeo) break;
00272   }
00273   if(curGeo==topGeo) outVol.mTop = inTopElem;
00274   else outVol.mTop = 0; // This is an error, but I don't know how to fix it.. how do you go from GeometryInfo to a detector element, 
00275   // especially if it's an 'orphan' or a 'ghost'? Maybe it doesn't matter, since it isnt' used.
00276   
00277   // debug() << "Built SpecVol from " << inElem->name() << ":" << endreq;
00278   // if(outVol.mTop)
00279   //    debug() << outVol.mTop->name();
00280   // for(unsigned int i=0;i<outVol.mRpath.size();i++) debug() << " [" << outVol.mRpath[i] << "]";
00281   // debug() << endreq;
00282   
00283   return StatusCode::SUCCESS; 
00284 }
00285 
00287 int   TouchableToDetectorElement::Compatability(const TouchableToDetectorElement::SpecifiedVolume& inPlace, const TouchableToDetectorElement::SpecifiedVolume& inContainer)
00288 {
00289   // Check to ensure that they share a top volume. This will fail for DetElements at, for instance, different
00290   // sites than the simulated site.
00291   if(inPlace.mTop != inContainer.mTop) return -1; // They don't match at the top.
00292   
00293   // Check to see that the container is at least as specific as the place. 
00294   // If not, the container specifies a deeper detector element than the place
00295   // e.g. This condition catches container=PMT, place=rock
00296   if(inContainer.mRpath.size() > inPlace.mRpath.size()) return -1;
00297 
00298   // Check through to see if it matches at every level.
00299   for(unsigned int i=0; i< inContainer.mRpath.size(); ++i ){
00300     if(inContainer.mRpath[i] != inPlace.mRpath[i]) return -1; // There's a mismatch, throw this one out.
00301   }
00302   
00303   // Ok, it checks at every level of the container. 
00304   // The goodness of the match is the specificity of the place minus the specificity of the container.
00305   // This is zero for a perfect match.
00306   return inPlace.mRpath.size() - inContainer.mRpath.size();
00307 }
00308 
00309 
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Fri May 16 2014 10:05:42 for G4DataHelpers by doxygen 1.7.4