/search.css" rel="stylesheet" type="text/css"/> /search.js">
00001 #include "CoordSysSvc.h" 00002 #include "GaudiKernel/MsgStream.h" 00003 #include "GaudiKernel/SmartDataPtr.h" 00004 #include "GaudiKernel/IDataProviderSvc.h" 00005 #include "DetDesc/DetectorElement.h" 00006 #include "DetDesc/IGeometryInfo.h" 00007 00008 using namespace std; 00009 00010 CoordSysSvc::CoordSysSvc(const std::string& name, ISvcLocator *svc) 00011 : Service(name,svc) 00012 , m_detSvc(0) 00013 , m_topGI(0) 00014 , m_lastBelongsTo(0) 00015 , m_lastCoordSys(0) 00016 { 00017 declareProperty("CoordSysUserParameter",m_CoordSysUserParameter="CoordinateSystem", 00018 "Name of the user parameter attached to the DetectorElement " 00019 "that has the LVolume that provides the coordinate system."); 00020 declareProperty("TopDetectorElementName", 00021 m_TopDetectorElementName="/dd/Structure/DayaBay", 00022 "Name of the DetectorElement that holds all others"); 00023 00024 } 00025 00026 CoordSysSvc::~CoordSysSvc() 00027 { 00028 } 00029 00030 StatusCode CoordSysSvc::initialize() 00031 { 00032 this->Service::initialize(); 00033 00034 MsgStream msg(msgSvc(),name()); 00035 msg << MSG::DEBUG << "CoordSysSvc::initialize()" << endreq; 00036 00037 StatusCode sc = service("DetectorDataSvc",m_detSvc,true); 00038 if (sc.isFailure()) return sc; 00039 00040 SmartDataPtr<IDetectorElement> topDE(m_detSvc,m_TopDetectorElementName); 00041 if (!topDE) return StatusCode::FAILURE; 00042 00043 m_topGI = topDE->geometry(); 00044 00045 return StatusCode::SUCCESS; 00046 } 00047 StatusCode CoordSysSvc::finalize() 00048 { 00049 m_detSvc->release(); 00050 m_detSvc = 0; 00051 return StatusCode::SUCCESS; 00052 } 00053 StatusCode CoordSysSvc::queryInterface(const InterfaceID& riid, 00054 void** ppvInterface) 00055 { 00056 StatusCode sc = StatusCode::FAILURE; 00057 if (ppvInterface) { 00058 *ppvInterface = 0; 00059 00060 if (ICoordSysSvc::interfaceID().versionMatch(riid)) { 00061 *ppvInterface = static_cast<ICoordSysSvc*>(this); 00062 sc = StatusCode::SUCCESS; 00063 addRef(); 00064 } 00065 else sc = Service::queryInterface( riid, ppvInterface ); 00066 } 00067 return sc; 00068 } 00069 00070 IDetectorElement* CoordSysSvc::belongsToDE(const Gaudi::XYZPoint& globalPoint, 00071 IDetectorElement* start, int depth) 00072 { 00073 MsgStream msg(msgSvc(),name()); 00074 00075 // first check if we can try to optimize a little and get lucky 00076 // starting at last result. 00077 if (!start && depth < 0 && m_lastBelongsTo) { 00078 IGeometryInfo* gi = m_lastBelongsTo->geometry(); 00079 if (gi->isInside(globalPoint)) { 00080 string path = gi->belongsToPath(globalPoint,-1); 00081 //msg << MSG::VERBOSE 00082 // << "cached DE ("<< m_lastBelongsTo->name() 00083 // <<") gives belongsToPath = " << path << endreq; 00084 00085 SmartDataPtr<IDetectorElement> de(m_detSvc,path); 00086 if (!de) { 00087 msg << MSG::ERROR 00088 << "Failed to get DetectorElement " << path << endreq; 00089 return 0; 00090 } 00091 m_lastBelongsTo = de; 00092 return m_lastBelongsTo; 00093 } 00094 m_lastBelongsTo = 0; // bummer 00095 } 00096 00097 IGeometryInfo* gi = m_topGI; 00098 if (start) gi = start->geometry(); 00099 00100 string path = gi->belongsToPath(globalPoint,depth); 00101 if (!gi->isInside(globalPoint)) { 00102 MsgStream msg(msgSvc(),name()); 00103 msg << MSG::DEBUG 00104 << "Failed to get DetectorElement path for point " << globalPoint << endreq; 00105 return 0; 00106 } 00107 00108 SmartDataPtr<IDetectorElement> de(m_detSvc,path); 00109 if (!de) { 00110 MsgStream msg(msgSvc(),name()); 00111 msg << MSG::WARNING 00112 << "No Detector Element at " << path << endreq; 00113 return 0; 00114 } 00115 m_lastBelongsTo = de; 00116 return m_lastBelongsTo; 00117 } 00118 00119 IDetectorElement* CoordSysSvc::nextHigherCoordSysDE(IDetectorElement* csde) 00120 { 00121 do { 00122 csde = csde->parentIDetectorElement(); 00123 if (!csde) return 0; 00124 const ParamValidDataObject* params = csde->params(); 00125 if (params && params->exists(m_CoordSysUserParameter)) 00126 return csde; 00127 } while (csde); 00128 return 0; 00129 } 00130 00131 IDetectorElement* CoordSysSvc::coordSysDE(const Gaudi::XYZPoint& globalPoint, 00132 IDetectorElement* start, int height) 00133 { 00134 00135 IDetectorElement* de = start; 00136 00137 // Start from start and work our way up, require a DE that has a 00138 // matching CoordinateSystem value and contains the global point. 00139 // If not, go to next larger CoordinateSystem DE. 00140 while (de) { 00141 00142 const ParamValidDataObject* params = de->params(); 00143 if (params && params->exists(m_CoordSysUserParameter)) { 00144 int level = params->param<int>(m_CoordSysUserParameter); 00145 if (!height || level == height) { 00146 if (de->geometry()->isInside(globalPoint)) { 00147 m_lastCoordSys = de; 00148 return m_lastCoordSys; 00149 } 00150 } 00151 } 00152 de = this->nextHigherCoordSysDE(de); 00153 } 00154 00155 // reach here, got nuttin. 00156 MsgStream msg(msgSvc(),name()); 00157 msg << MSG::DEBUG 00158 << "Failed to find coord sys DE starting from " 00159 << start->name() << endreq; 00160 Gaudi::XYZPoint lpoint = start->geometry()->toLocal(globalPoint); 00161 msg << "In that frame the point is " << lpoint << endreq; 00162 return 0; 00163 } 00164 00165 IDetectorElement* CoordSysSvc::coordSysDE(const Gaudi::XYZPoint& globalPoint, 00166 int height) 00167 { 00168 // Try to optimize, guess that the last one is right for this one 00169 IDetectorElement* de = m_lastBelongsTo; 00170 00171 // check to see if last found or one of its parents can be reused 00172 while (de) { 00173 00174 // if the DE doesn't contain the point, try its parent 00175 if (!de->geometry()->isInside(globalPoint)) { 00176 de = this->nextHigherCoordSysDE(de); 00177 continue; 00178 } 00179 00180 // if DE doesn't have a CoordinateSystem parameter, keep going higher 00181 const ParamValidDataObject* params = de->params(); 00182 if (!(params && params->exists(m_CoordSysUserParameter))) { 00183 de = this->nextHigherCoordSysDE(de); 00184 continue; 00185 } 00186 00187 // know the DE has a CS parameter and contains the point, so drill down... 00188 de = this->belongsToDE(globalPoint,de,-1); 00189 00190 // and come back up 00191 de = this->coordSysDE(globalPoint,de,height); 00192 if (de) { 00193 m_lastBelongsTo = de; 00194 return de; 00195 } 00196 00197 } 00198 00199 // Got to start from the scratch... 00200 de = this->belongsToDE(globalPoint); 00201 if (!de) { 00202 MsgStream msg(msgSvc(),name()); 00203 msg << MSG::DEBUG 00204 << "Failed to find DE belonging to point " << globalPoint << endreq; 00205 return 0; 00206 } 00207 m_lastBelongsTo = this->coordSysDE(globalPoint,de,height); 00208 if (!m_lastBelongsTo) { 00209 MsgStream msg(msgSvc(),name()); 00210 msg << MSG::DEBUG 00211 << "Failed to find DE starting with " << de->name() 00212 << " and height " << height << " using global point: " << globalPoint 00213 << endreq; 00214 Gaudi::XYZPoint lpoint = de->geometry()->toLocal(globalPoint); 00215 msg << "In that frame the point is " << lpoint << endreq; 00216 } 00217 return m_lastBelongsTo; 00218 }