00001
00002
00003
00004 #include "GaudiKernel/SvcFactory.h"
00005 #include "GaudiKernel/MsgStream.h"
00006 #include "GaudiKernel/IDataProviderSvc.h"
00007 #include "DetDesc/IDetectorElement.h"
00008 #include "DetDesc/IGeometryInfo.h"
00009 #include "DetDesc/ILVolume.h"
00010 #include "DetDesc/IPVolume.h"
00011
00012
00013 #include "DetElemFinder.h"
00014
00015 DECLARE_SERVICE_FACTORY( DetElemFinder );
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 DetElemFinder::DetElemFinder( const std::string& name, ISvcLocator* svcloc ):
00027 Service(name,svcloc)
00028 {
00029 declareProperty( "DetectorDataSvc", m_detDataSvcName = "DetectorDataSvc" );
00030 declareProperty( "RootElement", m_rootElement = "/dd/Structure/LHCb" );
00031 declareProperty( "DumpMap", m_dumpMap = false );
00032 }
00033
00034
00035
00036 DetElemFinder::~DetElemFinder() {}
00037
00038
00039
00040
00041 StatusCode DetElemFinder::queryInterface(const InterfaceID& riid, void** ppvUnknown){
00042 if ( IID_IDetElemFinder.versionMatch(riid) ) {
00043 *ppvUnknown = (IDetElemFinder*)this;
00044 addRef();
00045 return StatusCode::SUCCESS;
00046 }
00047 return Service::queryInterface(riid,ppvUnknown);
00048 }
00049
00050
00051
00052
00053 const IDetectorElement * DetElemFinder::detectorElementForPath(const std::string &path) const
00054 {
00055 return m_map(path);
00056 }
00057
00058
00059
00060
00061
00062 StatusCode DetElemFinder::initialize ( )
00063 {
00064
00065 StatusCode sc = Service::initialize();
00066 if (!sc.isSuccess()) return sc;
00067
00068
00069 MsgStream log(msgSvc(),name());
00070 log << MSG::DEBUG << "--- initialize ---" << endmsg;
00071
00072 IDataProviderSvc *detSvc = 0;
00073 sc = service(m_detDataSvcName,detSvc,true);
00074 if (!sc.isSuccess()) {
00075 log << MSG::ERROR << "Unable to get a handle to the detector data service ("
00076 << m_detDataSvcName << ")" << endmsg;
00077 return sc;
00078 }
00079
00080 DataObject *obj;
00081 sc = detSvc->retrieveObject(m_rootElement,obj);
00082 if (!sc.isSuccess()) {
00083 log << MSG::ERROR << "Unable to retrieve object '" << m_rootElement << "'" << endmsg;
00084 detSvc->release();
00085 return sc;
00086 }
00087 IDetectorElement *de = dynamic_cast<IDetectorElement *>(obj);
00088 if (!de) {
00089 log << MSG::ERROR << "Object '" << m_rootElement << "' is not a DetectorElement" << endmsg;
00090 detSvc->release();
00091 return sc;
00092 }
00093
00094
00095 detSvc->release();
00096
00097
00098 return insert(de);
00099 }
00100
00101
00102
00103 StatusCode DetElemFinder::finalize ( )
00104 {
00105
00106 MsgStream log(msgSvc(),name());
00107 log << MSG::DEBUG << "--- finalize ---" << endmsg;
00108
00109
00110 if ( m_dumpMap ) {
00111 for ( map_type::iterator i = m_map.begin(); i != m_map.end(); ++i ){
00112
00113 log << MSG::ALWAYS << i->first << " -> " << i->second->name() << endmsg;
00114 }
00115 }
00116
00117
00118 return Service::finalize();
00119 }
00120
00121
00122
00123
00124 StatusCode DetElemFinder::detector_element_path(const IDetectorElement *de, std::string &path, const std::string &parent_path)
00125 {
00126 StatusCode sc = StatusCode::SUCCESS;
00127
00128
00129 path = parent_path;
00130
00131
00132 IGeometryInfo* sgi = de->geometry()->supportIGeometryInfo();
00133
00134 if (NULL == sgi) {
00135 return sc;
00136 }
00137
00138
00139 if (parent_path.empty()){
00140 if (de->parentIDetectorElement()) {
00141 sc = detector_element_path(de->parentIDetectorElement(),path);
00142 if (!sc.isSuccess()) {
00143 return sc;
00144 }
00145 } else {
00146 return sc;
00147 }
00148 }
00149
00150
00151 const ILVolume* lv = sgi->lvolume();
00152
00153
00154
00155 ILVolume::PVolumePath volumePath;
00156
00157
00158 sc = lv->traverse( de->geometry()->supportPath().begin(),
00159 de->geometry()->supportPath().end(),
00160 volumePath );
00161 if (!sc.isSuccess()) {
00162 MsgStream log(msgSvc(),name());
00163 log << MSG::ERROR << "Cannot traverse the support path" << endmsg;
00164 return sc;
00165 }
00166
00167
00168 for ( ILVolume::PVolumePath::iterator pv = volumePath.begin(); pv != volumePath.end(); ++pv ) {
00169 path += "/" + (*pv)->name();
00170 }
00171 return sc;
00172 }
00173
00174
00175
00176
00177
00178 StatusCode DetElemFinder::insert ( const IDetectorElement *de, const std::string &parent_path) {
00179
00180 MsgStream log(msgSvc(),name());
00181 log << MSG::DEBUG << "Preocessing detector element " << de->name() << endmsg;
00182
00183 StatusCode sc = StatusCode::SUCCESS;
00184
00185 std::string path;
00186
00187
00188 sc = detector_element_path(de,path,parent_path);
00189 if ( ! sc.isSuccess() ) {
00190 return sc;
00191 }
00192
00193 map_type::iterator x = m_map.find(path);
00194 if ( x != m_map.end() ) {
00195 log << MSG::ERROR << "Cannot insert duplicated path \"" << path << "\" for \"" << de->name() << "\"" << endmsg;
00196 log << MSG::ERROR << "Already used for \"" << x->second->name() << "\"" << endmsg;
00197 return StatusCode::FAILURE;
00198 }
00199 else {
00200 log << MSG::DEBUG << "Insert path \"" << path << "\"" << endmsg;
00201 m_map[path] = de;
00202 }
00203
00204
00205 IDetectorElement::IDEContainer::const_iterator child;
00206 for ( child = de->childBegin(); sc.isSuccess() && child != de->childEnd(); ++child ){
00207 sc = insert(*child,path);
00208 if ( ! sc.isSuccess() ) {
00209 return sc;
00210 }
00211 }
00212 return sc;
00213 }
00214