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