/search.css" rel="stylesheet" type="text/css"/> /search.js">
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

AutoPositionerTool.cc
Go to the documentation of this file.
00001 #include "AutoPositionerTool.h"
00002 
00003 #include "GaudiKernel/SmartDataPtr.h"
00004 #include "GaudiKernel/MsgStream.h"
00005 
00006 #include "DetDesc/LVolume.h"
00007 #include "DetDesc/PVolume.h"
00008 #include "DetDesc/SolidBase.h"
00009 #include "DetDesc/DetectorElement.h"
00010 #include "DetDesc/IGeometryInfo.h"
00011 #include "GaudiKernel/Point3DTypes.h"
00012 #include "GaudiKernel/Transform3DTypes.h"
00013 
00014 #include <string>
00015 
00016 AutoPositionerTool::AutoPositionerTool(const std::string& type,
00017                                        const std::string& name,
00018                                        const IInterface* parent)
00019   : GaudiTool(type, name, parent)
00020   , m_detSvc(0)
00021   , m_coordSvc(0)
00022 {
00023   declareProperty("PhysicalVolume",m_physVolName="",
00024                   "Name of the physical volume to add to geometry");
00025   declareProperty("LogicalVolume",m_logVolName="",
00026                   "Name of the logical volume to associate with the physical");
00027   declareProperty("CoordinateDetElem",m_coordDetElemPath="",
00028                   "Name of the detector element used for coordinates");
00029   declareProperty("Position",m_position=std::vector<double>(3,0.),
00030                   "Position of the new volume in the parent coordinates");
00031   double identity[] = {1., 0., 0., 
00032                        0., 1., 0.,
00033                        0., 0., 1.};
00034   declareProperty("Rotation",m_rotation=std::vector<double>(identity,
00035                                                             identity+9),
00036                   "Rotation of the new volume in the parent coordinates");
00037   declareProperty("Element",m_detElemName="",
00038                   "Name of the detector element to place in the TDS");
00039   declareProperty("ElementPath",m_detElemPath="/dd/Structure/DayaBay",
00040                   "Path for the new detector element in the TDS");
00041   declareProperty("SubDetectorElements",
00042                   m_subDetElements=std::vector< std::vector<std::string> >(),
00043                   "Information for defining additional daughter detector elements");
00044 }
00045 
00046 AutoPositionerTool::~AutoPositionerTool()
00047 {
00048 }
00049 
00050 StatusCode AutoPositionerTool::initialize()
00051 {
00052     this->GaudiTool::initialize();
00053 
00054     debug() << "AutoPositionerTool::initialize()" << endreq;
00055     StatusCode sc = service("DetectorDataSvc",m_detSvc,true);
00056     if (sc.isFailure()) return sc;
00057 
00058     sc = service("CoordSysSvc",m_coordSvc,true);
00059     if (sc.isFailure()) return sc;
00060 
00061     return sc;
00062 }
00063 
00064 StatusCode AutoPositionerTool::reinitialize()
00065 {
00066     return StatusCode::SUCCESS;
00067 }
00068 
00069 StatusCode AutoPositionerTool::finalize()
00070 {
00071     m_detSvc->release();
00072     m_coordSvc->release();
00073     return this->GaudiTool::finalize();
00074 }
00075 
00076 StatusCode AutoPositionerTool::queryInterface(const InterfaceID& riid, 
00077                                               void** ppvInterface)
00078 {
00079   StatusCode sc = StatusCode::FAILURE;
00080   if (ppvInterface) {
00081     *ppvInterface = 0;
00082     
00083     if (IPositionerTool::interfaceID().versionMatch(riid)) {
00084       *ppvInterface = static_cast<IPositionerTool*>(this);
00085       sc = StatusCode::SUCCESS;
00086       addRef();
00087     }
00088     else sc = GaudiTool::queryInterface( riid, ppvInterface );    
00089   }
00090   return sc;
00091 }
00092 
00093 
00095 
00097 StatusCode AutoPositionerTool::placeVolume()
00098 {
00099 
00100   // Find placement detector element based on coordinate volume
00101   IDetectorElement* coordDetElem = getDet<IDetectorElement>(m_coordDetElemPath);
00102   if(!coordDetElem){
00103     error() << "AutoPositionerTool::placeVolume(): "
00104             << "could not find detector element at: " << m_coordDetElemPath
00105             << endreq;
00106     return StatusCode::FAILURE;
00107   }
00108 
00109   // Find global coordinates of new volume
00110   Gaudi::XYZPoint referencePosition(m_position[0],m_position[1],m_position[2]);
00111   Gaudi::XYZPoint globalPosition = 
00112     coordDetElem->geometry()->toGlobal( referencePosition );
00113 
00114   info() << "Using " << coordDetElem->name() 
00115          << " as reference system for placement of " << m_detElemName 
00116          << " at local position " << referencePosition 
00117          << " and global position " << globalPosition << endreq;
00118 
00119   // Find parent detector element
00120   IDetectorElement* parentDetElem = m_coordSvc->belongsToDE(globalPosition);
00121   if(!parentDetElem){
00122     error() << "AutoPositionerTool::placeVolume(): "
00123             << "could not find detector element at global position: " 
00124             << globalPosition << endreq;
00125     return StatusCode::FAILURE;
00126   }
00127   info() << "Using " << parentDetElem->name() 
00128          << " as supporting element for placement of " 
00129          << m_detElemName << endreq;
00130 
00131   // Find parent logical volume and relative path
00132   //IGeometryInfo* parentGeometry = 
00133   //  parentDetElem->geometry()->belongsTo(globalPosition, -1);
00134   //std::string npath;
00135   IGeometryInfo* startGeom = parentDetElem->geometry();
00136   ILVolume::PVolumePath pvPath;
00137   StatusCode sc = 
00138     parentDetElem->geometry()->fullGeoInfoForPoint(globalPosition, -1,
00139                                                    startGeom, pvPath);
00140   if(!sc.isSuccess()){
00141     error() << "AutoPositionerTool::placeVolume(): "
00142             << "could not find parent geometry at global position: " 
00143             << globalPosition << endreq;
00144     return StatusCode::FAILURE;
00145   }
00146   info() << "FullGeoInfoForPoint: " << startGeom->lvolumeName() << endreq;
00147   ILVolume::PVolumePath::iterator pvPathIter, pvPathEnd = pvPath.end();
00148   std::string npath;
00149   std::string parentLVolName = startGeom->lvolumeName();
00150   for(pvPathIter = pvPath.begin(); pvPathIter != pvPathEnd; pvPathIter++){
00151     parentLVolName = (*pvPathIter)->lvolumeName();
00152     if( npath.size() > 0 ) npath.append( "/" );
00153     npath.append( (*pvPathIter)->name() );
00154     info() << "  npath: " << npath << endreq;
00155   }
00156   if( npath.size() > 0 ){
00157     error() << "Parent volume " << parentLVolName 
00158             << " must have a defined detector element."
00159             << " Please define a detector element, and then you can place "
00160             <<  m_logVolName << " inside." << endreq;
00161     return StatusCode::FAILURE;
00162   }
00163   info() << "Using " << parentLVolName 
00164          << " as parent volume for placement of " << m_logVolName << endreq;
00165   IGeometryInfo* parentGeometry = parentDetElem->geometry();
00166 
00167   // Find parent logical volume for physical volume
00168   SmartDataPtr<LVolume> parentLogVol(m_detSvc, parentLVolName);
00169   if(!parentLogVol){
00170     error() << "AutoPositionerTool::placeVolume(): "
00171             << "could not find parent volume of name: " << parentLVolName
00172             << endreq;
00173     return StatusCode::FAILURE;
00174   }
00175 
00176   // Check if physical volume already exists in parent logical volume
00177   bool pvolumeExists = false;
00178   ILVolume::PVolumes::const_iterator pvIter = parentLogVol->pvBegin();
00179   for(;pvIter != parentLogVol->pvEnd(); pvIter++){
00180     if((*pvIter)->name() == m_physVolName){
00181       warning() << "AutoPositionerTool::placeVolume(): "
00182                 << "physical volume " << m_physVolName
00183                 << " already exists in parent volume " << parentLVolName
00184                 << endreq;
00185       pvolumeExists = true;
00186       break;
00187     }
00188   }
00189 
00190   if( !pvolumeExists ){
00191     // Place physical volume
00192     // Find placement coordinates in local parent volume
00193     Gaudi::XYZPoint localPosition = parentGeometry->toLocal( globalPosition );
00194     Gaudi::XYZPoint parGlobalPosition = 
00195       parentGeometry->toGlobal( Gaudi::XYZPoint(0.,0.,0.) );
00196     info() << "Parent Global position is " << parGlobalPosition << endreq;
00197     info() << "CoordRef Global position is " << globalPosition << endreq;
00198     info() << "Difference is " << parGlobalPosition - globalPosition << endreq;
00199     info() << "Placing " << m_detElemName 
00200            << " at " << localPosition << " in parent volume " 
00201            << parentLVolName<< endreq;
00202 
00203     // Check if point is inside
00204     if( parentLogVol->isInside(localPosition) ){
00205       info() << "Yep, position " << localPosition
00206              << "is inside " << parentLVolName<< endreq;
00207     }else{
00208       info() << "Ack!  Position " << localPosition
00209              << "is not inside " << parentLVolName << endreq;
00210     }      
00211 
00212     {
00213       const SolidBase* solid = dynamic_cast<const SolidBase*>(parentLogVol->solid());
00214       info() << "X-extent: " << solid->xMin() << " " << solid->xMax() << endreq;
00215       info() << "Y-extent: " << solid->yMin() << " " << solid->yMax() << endreq;
00216       info() << "Z-extent: " << solid->zMin() << " " << solid->zMax() << endreq;
00217     }
00218     {
00219       SmartDataPtr<LVolume> logVol(m_detSvc, m_logVolName);
00220       const SolidBase* solid = dynamic_cast<const SolidBase*>(logVol->solid());
00221       info() << "X-extent: " << solid->xMin() << " " << solid->xMax() << endreq;
00222       info() << "Y-extent: " << solid->yMin() << " " << solid->yMax() << endreq;
00223       info() << "Z-extent: " << solid->zMin() << " " << solid->zMax() << endreq;
00224     }
00225 
00226     // Create the physical volume
00227     Gaudi::Rotation3D rotation(m_rotation.begin(), m_rotation.end());
00228     IPVolume* pv = 
00229       parentLogVol->createPVolume(m_physVolName, m_logVolName,
00230                                   Gaudi::Transform3D(rotation, Gaudi::XYZVector(localPosition)).Inverse() );
00231   
00232     if( 0 == pv ) {
00233       error() << "AutoPositionerTool::placeVolume(): "
00234               << "could not create volume: " << m_physVolName
00235               << endreq;
00236       return StatusCode::FAILURE;
00237     }
00238   }
00239 
00240   if(m_detElemName != ""){
00241     // Add the corresponding detector element if a name is provided
00242     std::string pvPath = npath;
00243     if(pvPath.size() > 0) npath.append( "/" );
00244     pvPath.append( m_physVolName );
00245 
00246     sc = addDetectorElement(m_detElemName, m_detElemPath, m_logVolName,
00247                             parentDetElem->name(), pvPath);
00248     if( !sc.isSuccess() ) return sc; 
00249 
00250     // Add any sub-detector elements below the current detector element
00251     std::vector< std::vector<std::string> >::iterator sdIter, 
00252       sdEnd = m_subDetElements.end(); 
00253     for(sdIter = m_subDetElements.begin(); sdIter != sdEnd; sdIter++){
00254       std::vector<std::string> fields = *sdIter;
00255       if( fields.size() != 4 ){
00256         error() << "Wrong number of sub-detector element fields: " 
00257                 << fields.size() << endreq;
00258         for(int fieldIdx=0; fieldIdx<fields.size(); fieldIdx++){
00259           error() << "  Field " << fieldIdx << ": " << fields[fieldIdx] 
00260                   <<endreq;
00261         }
00262         return StatusCode::FAILURE;
00263       }
00264       std::string subDetElemName = fields[0];
00265       std::string support = fields[1];
00266       std::string logVolName = fields[2];
00267       std::string subPvPath = fields[3];
00268       sc = addDetectorElement(subDetElemName, m_detElemPath, logVolName,
00269                               support, subPvPath);
00270       if( !sc.isSuccess() ) return sc; 
00271     }
00272   }
00273 
00274   return sc;
00275 }
00276 
00277 StatusCode AutoPositionerTool::addDetectorElement(std::string detElemName,
00278                                                   std::string detElemPath, 
00279                                                   std::string logVolName, 
00280                                                   std::string support, 
00281                                                   std::string npath){
00282   // Add the detector element for existing geometry
00283   info() << "Using " << support 
00284          << " as support path for placement of " << detElemName
00285          << " at path " << detElemPath << endreq;  
00286   DetectorElement* detElem = new DetectorElement;
00287   StatusCode sc = m_detSvc->registerObject( detElemPath, detElemName, detElem);
00288   if( sc.isFailure() ){
00289     error() << "Failed to register object with support / name: " 
00290             << support << " / " << detElemName << endreq;
00291     return sc;
00292   }
00293   info() << "Using physical path " << npath 
00294          << "relative to support " << support
00295          << " for placement of " << logVolName << endreq;  
00296   detElem->createGeometryInfo( logVolName, support, npath);
00297   return sc;
00298 }
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Fri May 16 2014 09:56:27 for DetHelpers by doxygen 1.7.4