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