00001
00010 #include "GenHists.h"
00011
00012 #include "Event/GenHeader.h"
00013
00014 #include "DetDesc/IGeometryInfo.h"
00015 #include "DetDesc/DetectorElement.h"
00016 #include "DetDesc/SolidBase.h"
00017
00018 #include "GaudiKernel/ITHistSvc.h"
00019
00020 #include "CLHEP/Vector/LorentzVector.h"
00021 #include "CLHEP/Units/SystemOfUnits.h"
00022
00023 #include "HepMC/GenEvent.h"
00024
00025 #include "TH1F.h"
00026 #include "TH2F.h"
00027 #include "TH1I.h"
00028
00029 #include <string>
00030 using namespace std;
00031
00032
00033 GenHists::GenHists(const std::string& name, ISvcLocator* pSvcLocator)
00034 : GaudiAlgorithm(name,pSvcLocator)
00035 , m_hsvc(0)
00036 , m_nKineParts(0)
00037 , m_kineEnergy(0)
00038 , m_xy(0), m_yz(0), m_xz(0)
00039 {
00040 declareProperty("Location",m_location=DayaBay::GenHeaderLocation::Default,
00041 "Location in the TES to get GenHeader");
00042 declareProperty("Volume",m_volume="",
00043 "TDS path of volume used to generated vertices");
00044 declareProperty("FilePath",m_filepath="/file1/gen/",
00045 "File path with with to register histograms.");
00046 declareProperty("MaxEnergy",m_maxEnergy = 10*CLHEP::MeV,
00047 "Maximum energy for plot bounds.");
00048 declareProperty("EnergyUnits",m_energyUnits = CLHEP::MeV,
00049 "Energy units for plot bounds.");
00050 }
00051
00052 GenHists::~GenHists()
00053 {
00054 }
00055
00056
00057 #define REG1D(type,p,name,title,n,min,max) \
00058 do { \
00059 p = new type(name,title,n,min,max); \
00060 string path = m_filepath + name; \
00061 if (m_hsvc->regHist(path.c_str(),p).isFailure()) { \
00062 error() << "Could not register \"" << path << endreq; \
00063 delete p; p=0; \
00064 return StatusCode::FAILURE; \
00065 } \
00066 } while(false)
00067 #define REG2D(type,p,name,title,nx,minx,maxx,ny,miny,maxy) \
00068 do { \
00069 p = new type(name,title,nx,minx,maxx,ny,miny,maxy); \
00070 string path = m_filepath + name; \
00071 if (m_hsvc->regHist(path.c_str(),p).isFailure()) { \
00072 error() << "Could not register \"" << path << endreq; \
00073 delete p; p=0; \
00074 return StatusCode::FAILURE; \
00075 } \
00076 } while(false)
00077
00078 StatusCode GenHists::initialize()
00079 {
00080 this->GaudiAlgorithm::initialize();
00081
00082
00083 if ( service("THistSvc", m_hsvc).isFailure()) {
00084 error() << " No THistSvc available." << endreq;
00085 return StatusCode::FAILURE;
00086 }
00087
00088
00089
00090 REG1D(TH1I,m_nKineParts,"nKineParts","Total number of primaries",10,0,10);
00091 REG1D(TH1F,m_kineEnergy,"kineEnergy","Particle Energy (MeV)",100,0,m_maxEnergy);
00092 REG1D(TH1F,m_vtxTime,"kineVtxTime","Times of vertices (seconds)",1500,0,15*60);
00093 return this->BookVertices();
00094 }
00095
00096 StatusCode GenHists::BookVertices()
00097 {
00098
00099 DetectorElement* detelem=0;
00100 if ("" == m_volume) {
00101 warning() << "No Volume property set, guessing at volume bounds." << endreq;
00102 }
00103 if (!existDet<DetectorElement>(m_volume)) {
00104 warning() << "Failed to get detector element " << m_volume
00105 << ", will guess at volume bounds" << endreq;
00106 }
00107 else {
00108 detelem = getDet<DetectorElement>(m_volume);
00109 }
00110
00111 double minx = -25*CLHEP::meter, maxx = +25*CLHEP::meter;
00112 double miny = -25*CLHEP::meter, maxy = +25*CLHEP::meter;
00113 double minz = -25*CLHEP::meter, maxz = +25*CLHEP::meter;
00114 if (detelem) {
00115 m_geo = detelem->geometry();
00116 const ILVolume* lvol = m_geo->lvolume();
00117 if (!lvol) {
00118 error() << "Could not get logical volume for: \"" << m_volume << "\"" << endreq;
00119 return StatusCode::FAILURE;
00120 }
00121
00122 const SolidBase* solid = dynamic_cast<const SolidBase*>(lvol->solid());
00123 minx = solid->xMin(); maxx = solid->xMax();
00124 miny = solid->yMin(); maxy = solid->yMax();
00125 minz = solid->zMin(); maxz = solid->zMax();
00126 info () << "Volume bounded by: "
00127 << "X: [" << minx/CLHEP::meter << " " << maxx/CLHEP::meter << "], "
00128 << "Y: [" << miny/CLHEP::meter << " " << maxy/CLHEP::meter << "], "
00129 << "Z: [" << minz/CLHEP::meter << " " << maxz/CLHEP::meter << "]"
00130 << endreq;
00131 }
00132 REG2D(TH2F,m_xy,"kineVertexXY","Primary Vertices, X-Y",
00133 100,minx/CLHEP::meter,maxx/CLHEP::meter,100,miny/CLHEP::meter,maxy/CLHEP::meter);
00134 REG2D(TH2F,m_yz,"kineVertexYZ","Primary Vertices, Y-Z",
00135 100,miny/CLHEP::meter,maxy/CLHEP::meter,100,minz/CLHEP::meter,maxz/CLHEP::meter);
00136 REG2D(TH2F,m_xz,"kineVertexXZ","Primary Vertices, Z-X",
00137 100,minx/CLHEP::meter,maxx/CLHEP::meter,100,minz/CLHEP::meter,maxz/CLHEP::meter);
00138
00139 return StatusCode::SUCCESS;
00140 }
00141
00142 StatusCode GenHists::execute()
00143 {
00144 DayaBay::GenHeader* header = get<DayaBay::GenHeader>(m_location);
00145
00146 HepMC::GenEvent* genevt = header->event();
00147 if (!genevt) {
00148 warning() << "No event, giving up" << endreq;
00149
00150 return StatusCode::SUCCESS;
00151 }
00152
00153 HepMC::GenVertex* genvtx = genevt->signal_process_vertex();
00154 m_nKineParts->Fill(genvtx->particles_out_size());
00155
00156 HepMC::GenVertex::particles_out_const_iterator
00157 it = genvtx->particles_out_const_begin(),
00158 done = genvtx->particles_out_const_end();
00159
00160 double energy=0;
00161 for (; it != done; ++it) {
00162 HepMC::GenParticle* part = *it;
00163 HepMC::FourVector momentum = part->momentum();
00164 energy += momentum.e();
00165 m_kineEnergy->Fill(momentum.e()/m_energyUnits);
00166 }
00167
00168 HepMC::FourVector r4 = genvtx->position();
00169
00170 Gaudi::XYZPoint gp(r4.x(),r4.y(),r4.z());
00171 Gaudi::XYZPoint lp = m_geo->toLocal(gp);
00172
00173 m_vtxTime->Fill(r4.t()/CLHEP::second);
00174 m_xy->Fill(lp.x()/CLHEP::meter,lp.y()/CLHEP::meter);
00175 m_yz->Fill(lp.y()/CLHEP::meter,lp.z()/CLHEP::meter);
00176 m_xz->Fill(lp.x()/CLHEP::meter,lp.z()/CLHEP::meter);
00177
00178 return StatusCode::SUCCESS;
00179 }
00180
00181 StatusCode GenHists::finalize()
00182 {
00183
00184 return this->GaudiAlgorithm::finalize();
00185 }
00186