| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

GtPositionerTool.cc

Go to the documentation of this file.
00001 
00010 #include "GtPositionerTool.h"
00011 
00012 #include "GaudiKernel/IssueSeverity.h"
00013 #include "GaudiKernel/IRndmGenSvc.h"
00014 #include "GaudiKernel/DataObject.h"
00015 #include "GaudiKernel/Point3DTypes.h"
00016 
00017 
00018 #include "DetDesc/SolidBox.h"
00019 #include "DetDesc/ILVolume.h"
00020 #include "DetDesc/IPVolume.h"
00021 #include "DetDesc/IDetectorElement.h"
00022 #include "DetDesc/IGeometryInfo.h"
00023 
00024 #include "HepMC/GenEvent.h"
00025 #include "HepMC/GenVertex.h"
00026 // This may need to change when move to HepMC v2.
00027 #include "CLHEP/Vector/LorentzVector.h"
00028 
00029 GtPositionerTool::GtPositionerTool(const std::string& type,
00030                                    const std::string& name,
00031                                    const IInterface* parent)
00032     : GaudiTool(type,name,parent)
00033     , m_position(3,0)
00034     , m_spread(0)
00035     , m_really_initialized(false)
00036     , m_min(3,0)
00037     , m_max(3,0)
00038     , m_detelem(0)
00039 {
00040     declareInterface<IHepMCEventMutator>(this);
00041 
00042     declareProperty("Volume",m_volume="",
00043                     "Name (TDS path) of physical volume in which to position events");
00044     declareProperty("Strategy",m_strategy="FullVolume",
00045                     "Strategy for positioning events.");
00046     declareProperty("Mode",m_mode="Uniform","Mode for choosing positions.");
00047     declareProperty("Position",m_position,"Fixed/mean point");
00048     declareProperty("Spread",m_spread,"Spread for Gausian/Uniform smearing");
00049     declareProperty("FillVolumes",m_fillVolumes,
00050                     "Logical volume names to fill with generated events");
00051     declareProperty("FillMaterials",m_fillMaterials,
00052                     "Material names to fill with generated events");
00053 }
00054 
00055 GtPositionerTool::~GtPositionerTool()
00056 {
00057 }
00058 
00059 const IDetectorElement* GtPositionerTool::detelem()
00060 {
00061     if (m_detelem) return m_detelem;
00062 
00063     if ("" == m_volume) return 0;
00064 
00065     if (!existDet<IDetectorElement>(m_volume)) return 0;
00066 
00067     m_detelem = getDet<IDetectorElement>(m_volume);
00068     return m_detelem;
00069 }
00070 
00071 StatusCode GtPositionerTool::initialize()
00072 {
00073     return StatusCode::SUCCESS;
00074 }
00075 
00076 StatusCode GtPositionerTool::really_initialize()
00077 {
00078     m_really_initialized = true;
00079 
00080     const IDetectorElement* detelem = this->detelem();
00081     if (!detelem) {
00082         fatal() << "Could not get detector element: \"" << m_volume << "\"" << endreq;
00083         return StatusCode::FAILURE;
00084     }
00085 
00086     // Get volume's solid's bounding box
00087     const ILVolume* lvol = detelem->geometry()->lvolume();
00088     if (!lvol) {
00089         fatal() << "Could not get volume: \"" << m_volume << "\"" << endreq;
00090         return StatusCode::FAILURE;
00091     }
00092 
00093     const SolidBase* solid = dynamic_cast<const SolidBase*>(lvol->solid());
00094     m_min[0] = solid->xMin(); m_max[0] = solid->xMax();
00095     m_min[1] = solid->yMin(); m_max[1] = solid->yMax();
00096     m_min[2] = solid->zMin(); m_max[2] = solid->zMax();
00097 
00098     // sanity check position
00099     for (int ind=0; ind<3; ++ind) {
00100         if (m_min[ind] > m_position[ind] || m_max[ind] < m_position[ind]) {
00101             // Let this be only warning - maybe user wants to do this.
00102             warning() << "GtPositioner tool given position not in detector element "
00103                       << m_volume << "'s logical volume's " << *lvol
00104                       << " bounding box, index " << ind << ": " 
00105                       << m_min[ind] << " ? " << m_position[ind] << " ? " << m_max[ind]
00106                       << endreq;
00107             //return StatusCode::FAILURE;
00108         }
00109     }
00110 
00111 
00112     // Possibly shrink trial range if requested spread is less than
00113     // request uniform spread.
00114     if (m_mode == "Uniform") {
00115         for (int ind=0; ind<3; ++ind) {
00116             if (m_min[ind] < m_position[ind] - m_spread)
00117                 m_min[ind] = m_position[ind] - m_spread;
00118             if (m_max[ind] > m_position[ind] + m_spread)
00119                 m_max[ind] = m_position[ind] + m_spread;
00120         }
00121     }
00122 
00123     // Set up random numbers
00124     IRndmGenSvc *rgs = 0;
00125     if (service("RndmGenSvc",rgs,true).isFailure()) {
00126         fatal() << "Failed to get random service" << endreq;
00127         return StatusCode::FAILURE;        
00128     }
00129     if (m_uni.initialize(rgs, Rndm::Flat(0,1)).isFailure()) {
00130         fatal() << "Failed to initialize uniform random numbers" << endreq;
00131         return StatusCode::FAILURE;
00132     }
00133     if (m_gauss.initialize(rgs, Rndm::Gauss(0,1)).isFailure()) {
00134         fatal() << "Failed to initialize Gaussian random numbers" << endreq;
00135         return StatusCode::FAILURE;
00136     }
00137 
00138     return StatusCode::SUCCESS;
00139 }
00140 
00141 StatusCode GtPositionerTool::finalize()
00142 {
00143     return StatusCode::SUCCESS;
00144 }
00145 
00146 StatusCode GtPositionerTool::mutate(HepMC::GenEvent& event)
00147 {
00148     if (! m_really_initialized) {
00149         info() << "really_initialized with detector element: \"" 
00150                << m_volume << "\"" << endreq;
00151         StatusCode sc = this->really_initialize();
00152         if (sc.isFailure()) return sc;
00153     }
00154 
00155 
00156     // short circuit when in Fixed mode
00157     if ("Fixed" == m_mode or "Relative" == m_mode) {
00158         this->setPosition(m_position,event);
00159         return StatusCode::SUCCESS;
00160     }
00161 
00162 
00163     std::vector<double> local_pos(3,0);
00164     if (this->genPosition(local_pos)) {
00165         this->setPosition(local_pos,event);
00166         return StatusCode::SUCCESS;
00167     }
00168     
00169     fatal() << "Failed to generate position" << endreq;
00170     return StatusCode::FAILURE;
00171 }
00172 
00173 bool GtPositionerTool::getPoint(std::vector<double>& pos)
00174 {
00175     // Keep drawing Gaussians until we get, for each dimension, one
00176     // that is inside the bounds.
00177     if ("Smeared" == m_mode) {
00178         for (int ind=0; ind<3; ++ind) {
00179             do {
00180                 pos[ind] = m_gauss() * m_spread + m_position[ind];
00181             } while(pos[ind] < m_min[ind] || pos[ind] > m_max[ind]);
00182         }
00183         return true;
00184     }
00185 
00186     // Simply draw uniforms 
00187     if ("Uniform" == m_mode) {
00188         for (int ind=0; ind<3; ++ind)
00189             pos[ind] = m_uni() * (m_max[ind]-m_min[ind]) + m_min[ind];
00190         return true;
00191     }
00192 
00193     // Huh, why are we here?
00194     fatal() << "Unknown positioning mode: " << m_mode << endreq;
00195     return false;
00196 }
00197 
00198 // Generate a local position in the logical volume
00199 bool GtPositionerTool::genPosition(std::vector<double>& local_pos)
00200 {
00201     if ("Surface" == m_strategy) {
00202         //generate point on surface, 
00203         // munge event
00204         // return
00205         //...
00206         fatal() << "Surface strategy not yet supported" << endreq;
00207         return false;
00208     }
00209 
00210 
00211     if (!this->getPoint(local_pos)) {
00212         fatal () << "Failed to get local point" << endreq;
00213         return false;
00214     }
00215 
00216     Gaudi::XYZPoint local_point(local_pos[0],local_pos[1],local_pos[2]);
00217 
00218     // Check if inside logical volume
00219     const ILVolume* lvol = m_detelem->geometry()->lvolume();
00220     if (!lvol) {
00221         fatal() << "Could not get volume: \"" << m_volume << "\"" << endreq;
00222         return false;
00223     }
00224 
00225     // not inside, try again
00226     if (!lvol->isInside(local_point)) 
00227         return this->genPosition(local_pos);
00228 
00229     if ("AvoidDaughters" == m_strategy) {
00230         // Place in top-most volume only
00231         ILVolume::ReplicaPath replicaPath;
00232         if (lvol->belongsTo(local_point,1,replicaPath).isFailure()){
00233           fatal() << "Invalid point in " << m_volume << ": " << local_point
00234                   << endreq;
00235         }
00236         // Check if point is inside a daughter volume
00237         if (replicaPath.size() == 0)
00238           return true;
00239         else
00240           return this->genPosition(local_pos);
00241     } else if("VolumeType" == m_strategy || "Material" == m_strategy) {
00242       // Fill by physical volume or material type
00243       //info() << "Starting volume search" << endreq;
00244       ILVolume::PVolumePath pVolumePath;
00245       //info() << "   Local point: " << local_point << endreq;
00246       if (lvol->belongsTo(local_point,-1,pVolumePath).isFailure()){
00247         fatal() << "Invalid point in " << m_volume << ": " << local_point
00248                 << endreq;
00249       }
00250       // Check if point is inside a daughter volume
00251       //info() << "Depth of PVolumes: " <<  pVolumePath.size() << endreq;
00252       //for(unsigned int idx = 0; idx < pVolumePath.size(); idx++){
00253       //        info() << "    PVolume: " << pVolumePath[idx]->name() << endreq;
00254       //}
00255       if (pVolumePath.size() == 0){
00256         // No daughter volumes, so check this volume
00257         if("Material" == m_strategy){
00258           if(std::find(m_fillMaterials.begin(), m_fillMaterials.end(),
00259                        lvol->materialName()) != m_fillMaterials.end()){
00260             debug() << "Placing in " <<  lvol->name() << endreq;
00261             return true;
00262           }
00263         }
00264         if("VolumeType" == m_strategy){
00265           if(std::find(m_fillVolumes.begin(), m_fillVolumes.end(),
00266                        baseName(lvol->name())) == m_fillVolumes.end()){
00267             //info() << "    Not the volume we want" << endreq;
00268             return this->genPosition(local_pos);
00269           }
00270         }
00271         return this->genPosition(local_pos);
00272       }else{
00273         const IPVolume* lastPV = pVolumePath[pVolumePath.size() - 1];
00274         //info() << "    Last PVolume" << endreq;
00275         //info() << "      Name: " << lastPV->name() << endreq;
00276         //info() << "      Material: " << lastPV->lvolume()->materialName() 
00277         //       << endreq;
00278         if("VolumeType" == m_strategy){
00279           if(std::find(m_fillVolumes.begin(), m_fillVolumes.end(),
00280                        baseName(lastPV->lvolumeName())) == m_fillVolumes.end()){
00281             //info() << "    Not the volume we want" << endreq;
00282             return this->genPosition(local_pos);
00283           }
00284         }
00285         if("Material" == m_strategy){
00286           std::string currentMaterial = 
00287             baseName(lastPV->lvolume()->materialName());
00288           //info() << "    Current Material: " << currentMaterial << endreq;
00289           if(std::find(m_fillMaterials.begin(), m_fillMaterials.end(),
00290                        currentMaterial) == m_fillMaterials.end()){
00291             //info() << "    Not the material we want" << endreq;
00292             return this->genPosition(local_pos);
00293           }
00294         }
00295         debug() << "Placing in " <<  lastPV->name() << endreq;
00296         return true;
00297       }
00298     } else if ("FullVolume" == m_strategy) {
00299       return true;
00300     }
00301     
00302     fatal() << "Failed to generate volume using strategy " << m_strategy << endreq;
00303     return false;
00304 }
00305 
00306 std::string GtPositionerTool::baseName(const std::string& path){
00307   size_t pos = path.rfind('/');
00308   if( pos == std::string::npos ) return path;
00309   return path.substr(pos+1);
00310 }
00311 
00312 #include "CLHEP/Units/SystemOfUnits.h"
00313 
00314 void GtPositionerTool::setPosition(std::vector<double>& vpos, HepMC::GenEvent& event)
00315 {
00316     HepMC::FourVector position(vpos[0],vpos[1],vpos[2],0);
00317     debug() << "Setting position: " 
00318             <<position.x()<<","<<position.y()<<","<<position.z()
00319             << endreq;
00320     HepMC::GenEvent::vertex_iterator vtx, done = event.vertices_end();
00321     for (vtx = event.vertices_begin(); vtx != done; ++vtx) {
00322         if ("Relative" == m_mode) {
00323             HepMC::FourVector relative_pos = (*vtx)->position();
00324             (*vtx)->set_position(HepMC::FourVector(position.x()+relative_pos.x(),
00325                                                    position.y()+relative_pos.y(),
00326                                                    position.z()+relative_pos.z(),
00327                                                    position.t()+relative_pos.t()));
00328         }
00329         else{
00330             HepMC::FourVector position4d = position;
00331             position4d.setT((*vtx)->position().t());
00332             (*vtx)->set_position(position4d);
00333             debug() << "\tvertex @ " << "("
00334                     << (*vtx)->position().x()/CLHEP::cm << ","
00335                     << (*vtx)->position().y()/CLHEP::cm << ","
00336                     << (*vtx)->position().z()/CLHEP::cm << ","
00337                     << (*vtx)->position().t()/CLHEP::second << ") [cm,cm,cm,second]" << endreq;
00338 
00339         }
00340     }
00341 }
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:55:36 2011 for GenTools by doxygen 1.4.7