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
00076
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
00082
00083
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;
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
00138
00139
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
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
00169 IDetectorElement* de = m_lastBelongsTo;
00170
00171
00172 while (de) {
00173
00174
00175 if (!de->geometry()->isInside(globalPoint)) {
00176 de = this->nextHigherCoordSysDE(de);
00177 continue;
00178 }
00179
00180
00181 const ParamValidDataObject* params = de->params();
00182 if (!(params && params->exists(m_CoordSysUserParameter))) {
00183 de = this->nextHigherCoordSysDE(de);
00184 continue;
00185 }
00186
00187
00188 de = this->belongsToDE(globalPoint,de,-1);
00189
00190
00191 de = this->coordSysDE(globalPoint,de,height);
00192 if (de) {
00193 m_lastBelongsTo = de;
00194 return de;
00195 }
00196
00197 }
00198
00199
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 }