| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

PmtGeomInfoSvc.cc

Go to the documentation of this file.
00001 #include "PmtGeomInfoSvc.h"
00002 #include "PmtGeomInfo.h"
00003 
00004 #include "DetDesc/IDetectorElement.h"
00005 #include "DetDesc/ParamValidDataObject.h"
00006 #include "Conventions/Detectors.h"
00007 
00008 #include "GaudiKernel/SmartDataPtr.h"
00009 #include "GaudiKernel/MsgStream.h"
00010 
00011 using namespace std;
00012 
00013 PmtGeomInfoSvc::PmtGeomInfoSvc(const std::string& name, ISvcLocator *svc)
00014     : Service(name,svc)
00015     , m_detSvc(0)
00016     , m_detector(0)
00017 {
00018     declareProperty("SiteIdUserParameter",m_SiteIdUserParameter="SiteID",
00019                     "Name of the user parameter attached to Site detector "
00020                     "elements that gives the packed Site ID number.");
00021     declareProperty("DetectorIdUserParameter", 
00022                     m_DetectorIdUserParameter="DetectorID",
00023                     "Name of the user parameter attached to Detector "
00024                     "detector elements that gives the fully qualified "
00025                     "packed Detector ID.");
00026     declareProperty("PmtIdUserParameter",m_PmtIdUserParameter="PmtID",
00027                     "Name of the user parameter attached to PMT detector "
00028                     "elements that gives the fully qualified packed PMT ID");
00029     declareProperty("StreamItems",m_StreamItems,
00030                     "List of top level Detector Elements.");
00031     declareProperty("EnableSabGeometry",m_enableSabGeometry=true,
00032                     "Workaround to allow for non-existent SAB geometry");
00033 }
00034 
00035 PmtGeomInfoSvc::~PmtGeomInfoSvc()
00036 {
00037 }
00038 
00039 
00040 
00041 StatusCode PmtGeomInfoSvc::initialize()
00042 {
00043     this->Service::initialize();
00044 
00045     MsgStream msg(msgSvc(),name());
00046     msg << MSG::DEBUG << "PmtGeomInfoSvc::initialize()" << endreq;
00047 
00048     StatusCode sc = service("DetectorDataSvc",m_detSvc,true);
00049     if (sc.isFailure()) return sc;
00050 
00051     msg << MSG::DEBUG << "Using IDs:"
00052         << " site: " << m_SiteIdUserParameter
00053         << " det: " << m_DetectorIdUserParameter
00054         << " pmt: " << m_PmtIdUserParameter
00055         << endreq;
00056 
00057     if (! m_StreamItems.size()) {
00058         msg << MSG::WARNING << "did not get any StreamItems, can not lookup PMTs" << endreq;
00059         return StatusCode::FAILURE;
00060     }
00061     for (size_t ind=0; ind<m_StreamItems.size(); ++ind) {
00062         string dename = m_StreamItems[ind];
00063         SmartDataPtr<IDetectorElement> obj(m_detSvc,dename);
00064         if (!obj) {
00065             MsgStream msg(msgSvc(),name());
00066             msg << MSG::WARNING << "Failed to get top Detector Element: \"" 
00067                 << dename << "\", skipping" << endreq;
00068             sc = StatusCode::FAILURE;
00069             continue;
00070         }
00071         msg << MSG::DEBUG << "Adding top level Detector Element: \"" 
00072             << dename << endreq;
00073         m_topDEs.push_back(obj);
00074     }
00075     return sc;
00076 }
00077 
00078 StatusCode PmtGeomInfoSvc::reinitialize()
00079 {
00080     return StatusCode::SUCCESS;
00081 }
00082 
00083 StatusCode PmtGeomInfoSvc::finalize()
00084 {
00085     m_detSvc->release();
00086 
00087     // Delete all PmtGeomInfo's.....
00088 
00089     return StatusCode::SUCCESS;
00090 }
00091 
00093 IPmtGeomInfo* PmtGeomInfoSvc::get(std::string structure_path)
00094 {
00095     MsgStream msg(msgSvc(),name());
00096     msg << MSG::DEBUG << "PmtGeomInfoSvc::get(path "<<structure_path<<")" << endreq;
00097 
00098     IPmtGeomInfo* pmtinfo = m_byPath[structure_path];
00099     if (pmtinfo) return pmtinfo;
00100 
00101     SmartDataPtr<IDetectorElement> obj(m_detSvc,structure_path);
00102     if (!obj) return 0;
00103 
00104     unsigned int pmtid = obj->params()->param<int>(m_PmtIdUserParameter);
00105     if (!pmtid) return 0;
00106     
00107     return this->add(pmtid,structure_path,obj);
00108 }
00109 
00111 IPmtGeomInfo* PmtGeomInfoSvc::get(IDetectorElement* pmtde)
00112 {
00113     MsgStream msg(msgSvc(),name());
00114     msg << MSG::DEBUG << "PmtGeomInfoSvc::get(IDetectorElement "<<pmtde->name()<<")" << endreq;
00115 
00116     IPmtGeomInfo* pmtinfo = m_byDE[pmtde];
00117     if (pmtinfo) return pmtinfo;
00118 
00119     unsigned int pmtid = pmtde->params()->param<int>(m_PmtIdUserParameter);
00120     if (!pmtid) return 0;
00121 
00122     return this->add(pmtid,"",pmtde);
00123 }
00124 
00126 IPmtGeomInfo* PmtGeomInfoSvc::get(unsigned int pmtid)
00127 {
00128     MsgStream msg(msgSvc(),name());
00129     msg << MSG::DEBUG << "PmtGeomInfoSvc::get(int "<<(void*)pmtid<<")" << endreq;
00130     
00131 
00132     /*
00133       algorithm: 
00134 
00135       * add site/detector values into high level detector elements in
00136       XML.
00137 
00138       * add isCompatible() method to Detectors.h, Returns true if bits
00139       * match, but not including fully zero'd bytes.
00140 
00141       * Search down /dd/Structure, check each DetectorElement for a
00142       * PmtID user parameter.  Failing that look for a DetectorID
00143       * parameter and if found check if value isCompatible() and
00144       * abandon branch if it isn't. Quit if DetectorElements are
00145       * exhausted or if one is found that matches the PMTID.
00146 
00147      */
00148 
00149     if(m_enableSabGeometry){
00150       // If site is SAB, use DYB near site instead.
00151       DayaBay::DetectorSensor sensor(pmtid);
00152       if(sensor.site() == Site::kSAB){
00153         static bool beenWarned = false;
00154         if(!beenWarned){
00155           msg << MSG::WARNING << "Using Near site PMT positions for SAB" 
00156               << endreq;
00157           beenWarned = true;
00158         }
00159         DayaBay::DetectorSensor tempSensor(sensor.sensorId(),
00160                                            Site::kDayaBay,
00161                                            sensor.detectorId());
00162         pmtid = tempSensor.fullPackedData();
00163       }
00164     }
00165 
00166     // Have we seen you before?
00167     IPmtGeomInfo* pmtinfo = m_byId[pmtid];
00168     if (pmtinfo) {
00169         msg << MSG::DEBUG << "Found "<< (void*)pmtid << ", seen before"<<endreq;
00170         return pmtinfo;
00171     }
00172 
00173     // Let's first do a quick check in the last detector we saw
00174     if (m_detector) {
00175         msg << MSG::DEBUG << "Looking for "<< (void*)pmtid 
00176             << " in "<< m_detector->name() << endreq;
00177         pmtinfo = this->find(pmtid,m_detector);
00178         if (pmtinfo) {
00179             msg << MSG::DEBUG << "Found "<< (void*)pmtid
00180                 << " after quick check"<<endreq;
00181             return pmtinfo;
00182         }
00183         m_detector = 0;
00184     }
00185 
00186     // No luck, do a full search starting from top level DEs
00187     for (size_t ind=0; ind<m_topDEs.size(); ++ind) {
00188         msg << MSG::DEBUG << "Looking for "<< (void*)pmtid 
00189             << " in "<< m_topDEs[ind]->name() << endreq;
00190         pmtinfo = this->find(pmtid,m_topDEs[ind]);
00191         if (pmtinfo) {
00192             msg << MSG::DEBUG << "Found "<< (void*)pmtid
00193                 << " after full search"<<endreq;
00194             return pmtinfo;
00195         }
00196     }
00197     msg << MSG::DEBUG << "Failed to find PMT ID "<< (void*)pmtid << endreq;
00198     return 0;
00199 }
00200 
00201 IPmtGeomInfo* PmtGeomInfoSvc::find(unsigned int pmtid, IDetectorElement* de)
00202 {
00203     MsgStream msg(msgSvc(),name());
00204     msg << MSG::DEBUG << "PmtGeomInfoSvc::find(int "<<(void*)pmtid
00205         <<","<<de->name()<<")" << endreq;
00206 
00207     const ParamValidDataObject* params = de->params();
00208     // Check if DE is a PMT.  If current DE has a PmtID we are done
00209     // for good or bad.
00210     if (de->params()->exists(m_PmtIdUserParameter)) {
00211         unsigned int this_pmtid = (unsigned int)(params->param<int>(m_PmtIdUserParameter));
00212         if (pmtid == this_pmtid) {
00213             msg << MSG::DEBUG << "found PMT ID " << (void*)pmtid << endreq;
00214             return this->add(pmtid,"",de);
00215         }
00216         msg << MSG::DEBUG << "got PMT ID but wrong one "
00217             << (void*)this_pmtid << " != " << (void*)pmtid << endreq;
00218         return 0;
00219     }
00220 
00221     // Check if DE is a Detector.  If current DE has a DetectorID we
00222     // check for compatibility and cache or bail out.
00223     if (de->params()->exists(m_DetectorIdUserParameter)) {
00224         unsigned int detid = 
00225             (unsigned int)(params->param<int>(m_DetectorIdUserParameter));
00226         msg << MSG::DEBUG << "checking Detector ID "
00227             << (void*)detid << " =?= " << (void*)(pmtid) << endreq;
00228 
00229         if ( (pmtid&0xffff0000) == detid) { 
00230             msg << MSG::DEBUG << "found Detector ID "
00231                 << (void*)detid << " for " << (void*)(pmtid) << endreq;
00232             m_detector = de;    // We have a winner!
00233         }
00234         else {                  // We have a detector, but the wrong one
00235             msg << MSG::DEBUG << "got Detector ID but wrong one "
00236                 << (void*)detid << " != " << (void*)(pmtid&0xffff0000) << endreq;
00237         }
00238     }
00239 
00240     // Check if DE is a Site.  If current DE has a SiteID we bail out
00241     // if it isn't compatible.
00242     if (params->exists(m_SiteIdUserParameter)) {
00243         unsigned int siteid = 
00244             (unsigned int)(params->param<int>(m_SiteIdUserParameter));
00245         if ( (pmtid&0xff000000) != siteid) {
00246             msg << MSG::DEBUG << "got Site ID but wrong one "
00247                 << (void*)siteid << " != " << (void*)(pmtid&0xff000000) << endreq;
00248             return 0;
00249         }
00250     }
00251 
00252     // We get here we know we are still on the right track
00253     IDetectorElement::IDEContainer& child = de->childIDetectorElements();
00254     for (size_t ind=0; ind < child.size(); ++ind) {
00255         IPmtGeomInfo *pgi = this->find(pmtid,child[ind]);
00256         if (pgi) return pgi;
00257     }
00258     msg << MSG::DEBUG << "failed to find pmtid " << (void*)pmtid << endreq;
00259     return 0;
00260 }
00261 
00262 
00263 IDetectorElement* PmtGeomInfoSvc::findParent(unsigned int pmtid,
00264                                              IDetectorElement* currentDE)
00265 {
00266     // Find the parent detector element for this PMT, starting the
00267     // search at the current detector element.  If currentDE==0, then
00268     // the entire geometry will be searched.
00269 
00270     MsgStream msg(msgSvc(),name());
00271     msg << MSG::DEBUG << "PmtGeomInfoSvc::find(int "<<(void*)pmtid;
00272     if (currentDE) msg <<","<<currentDE->name();
00273     msg << ")"<< endreq;
00274 
00275     if (!currentDE) {
00276       // If current detector element is undefined, check the usual suspects
00277       // First, check the cached detector
00278       if (m_detector) {
00279         IDetectorElement* parent = findParent(pmtid, m_detector);
00280         if(parent) return parent;
00281         m_detector = 0; // Unset incorrect cached detector
00282       }
00283       // Next, check the top-level detector elements
00284       for (size_t ind=0; ind<m_topDEs.size(); ++ind) {
00285         if (m_topDEs[ind]){
00286           IDetectorElement* parent = findParent(pmtid, m_topDEs[ind]);
00287           if(parent) return parent;
00288         }
00289       }
00290       // Failed to find parent detector
00291       msg << MSG::DEBUG << "failed to find parent detector for pmtid "
00292         << (void*)pmtid << endreq;
00293       return 0;
00294     }
00295 
00296     msg << MSG::DEBUG << "Looking for "<< (void*)pmtid 
00297         << " in "<< currentDE->name() << endreq;
00298     const ParamValidDataObject* params = currentDE->params();
00299 
00300     // Check if current detector element is the pmt parent detector
00301     if (params->exists(m_DetectorIdUserParameter)) {
00302       unsigned int detid = 
00303         (unsigned int)(params->param<int>(m_DetectorIdUserParameter));
00304       msg << MSG::DEBUG << "checking Detector ID "
00305           << (void*)detid << " =?= " << (void*)(pmtid) << endreq;
00306       if ( (pmtid&0xffff0000) == detid) { 
00307         msg << MSG::DEBUG << "found Detector ID "
00308             << (void*)detid << " for " << (void*)(pmtid) << endreq;
00309         return currentDE;    // We have a winner!
00310       }
00311     }
00312 
00313     // Check if current detector element is the correct site
00314     if (params->exists(m_SiteIdUserParameter)) {
00315       unsigned int siteid = 
00316         (unsigned int)(params->param<int>(m_SiteIdUserParameter));
00317       if ( (pmtid&0xff000000) != siteid) {
00318         msg << MSG::DEBUG << "got Site ID but wrong one "
00319             << (void*)siteid << " != " << (void*)(pmtid&0xff000000) << endreq;
00320         return 0;
00321       }
00322     }
00323     
00324     // Check detector element children
00325     // We get here we know we are still on the right track
00326     IDetectorElement::IDEContainer& child = currentDE->childIDetectorElements();
00327     for (size_t ind=0; ind < child.size(); ++ind) {
00328         IDetectorElement* parent = this->findParent(pmtid,child[ind]);
00329         if (parent) return parent;
00330     }
00331     msg << MSG::DEBUG 
00332         << "failed to find parent detector for pmtid "
00333         << (void*)pmtid << " in current branch" << endreq;
00334     return 0;    
00335 }
00336 
00337 
00338 IPmtGeomInfo* PmtGeomInfoSvc::add(unsigned int pmtid, const std::string& path,
00339                                   IDetectorElement* de)
00340 {
00341     MsgStream msg(msgSvc(), name());
00342 
00343     if (!de) {
00344         msg << MSG::ERROR 
00345             << "Given NULL DetectorElement (pmtid=" 
00346             << (void*)pmtid << endreq;
00347         return 0;
00348     }
00349     IDetectorElement* parent = findParent(pmtid,0);
00350     if (!parent) {
00351         msg << MSG::ERROR 
00352             << "No parent detector, cannot add DetectorElement with pmtid=" 
00353             << (void*)pmtid << endreq;
00354         return 0;
00355     }
00356 
00357     msg << MSG::DEBUG
00358         << "Adding pmtid " << (void*)pmtid << " at \"" << path <<"\""
00359         << endreq;
00360 
00361     PmtGeomInfo* gpi = new PmtGeomInfo(pmtid,de,parent);
00362 
00363     if (path == "") m_byPath[de->name()] = gpi;
00364     else m_byPath[path] = gpi;
00365     m_byDE[de] = gpi;
00366     m_byId[pmtid] = gpi;
00367 
00368     return gpi;
00369 }
00370 StatusCode PmtGeomInfoSvc::queryInterface(const InterfaceID& riid, 
00371                                           void** ppvInterface)
00372 {
00373     StatusCode sc = StatusCode::FAILURE;
00374     if (ppvInterface) {
00375         *ppvInterface = 0;
00376     
00377         if (IPmtGeomInfoSvc::interfaceID().versionMatch(riid)) {
00378             *ppvInterface = static_cast<IPmtGeomInfoSvc*>(this);
00379             sc = StatusCode::SUCCESS;
00380             addRef();
00381         }
00382         else sc = Service::queryInterface( riid, ppvInterface );    
00383     }
00384     return sc;
00385 }
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:15:09 2011 for DetHelpers by doxygen 1.4.7