CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/SimG4CMS/EcalTestBeam/src/EcalTBMCInfoProducer.cc

Go to the documentation of this file.
00001 /*
00002  * \file EcalTBMCInfoProducer.cc
00003  *
00004  * $Id: EcalTBMCInfoProducer.cc,v 1.12 2009/04/03 09:38:15 fabiocos Exp $
00005  *
00006 */
00007 
00008 #include "SimG4CMS/EcalTestBeam/interface/EcalTBMCInfoProducer.h"
00009 #include "FWCore/ServiceRegistry/interface/Service.h"
00010 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00011 #include "CLHEP/Random/RandFlat.h"
00012 #include "FWCore/Utilities/interface/Exception.h"
00013 
00014 #include "DataFormats/Math/interface/Point3D.h"
00015 
00016 using namespace std;
00017 using namespace cms;
00018 
00019 EcalTBMCInfoProducer::EcalTBMCInfoProducer(const edm::ParameterSet& ps) : flatDistribution_(0) {
00020   
00021   produces<PEcalTBInfo>();
00022 
00023   edm::FileInPath CrystalMapFile = ps.getParameter<edm::FileInPath>("CrystalMapFile");
00024   GenVtxLabel = ps.getUntrackedParameter<string>("moduleLabelVtx","source");
00025   double fMinEta = ps.getParameter<double>("MinEta");
00026   double fMaxEta = ps.getParameter<double>("MaxEta");
00027   double fMinPhi = ps.getParameter<double>("MinPhi");
00028   double fMaxPhi = ps.getParameter<double>("MaxPhi");
00029   beamEta = (fMaxEta+fMinEta)/2.;
00030   beamPhi = (fMaxPhi+fMinPhi)/2.;
00031   beamTheta = 2.0*atan(exp(-beamEta));
00032   beamXoff = ps.getParameter<double>("BeamMeanX");
00033   beamYoff = ps.getParameter<double>("BeamMeanX");
00034    
00035   string fullMapName = CrystalMapFile.fullPath();
00036   theTestMap = new EcalTBCrystalMap(fullMapName);
00037   crysNumber = 0;
00038 
00039   double deltaEta = 999.;
00040   double deltaPhi = 999.;
00041   for ( int cryIndex = 1; cryIndex <= EcalTBCrystalMap::NCRYSTAL; ++cryIndex) {
00042     double eta = 0;
00043     double phi = 0.;
00044     theTestMap->findCrystalAngles(cryIndex, eta, phi);
00045     if ( fabs(beamEta - eta) < deltaEta && fabs(beamPhi - phi) < deltaPhi ) {
00046       deltaEta = fabs(beamEta - eta);
00047       deltaPhi = fabs(beamPhi - phi);
00048       crysNumber = cryIndex;
00049     }
00050     else if (fabs(beamEta - eta)<deltaEta && fabs(beamPhi - phi)>deltaPhi ) {
00051       if ( fabs(beamPhi - phi) < 0.017 ) {
00052         deltaEta = fabs(beamEta - eta);
00053         deltaPhi = fabs(beamPhi - phi);
00054         crysNumber = cryIndex;
00055       }
00056     }
00057     else if (fabs(beamEta - eta)>deltaEta && fabs(beamPhi - phi)<deltaPhi ) {
00058       if ( fabs(beamEta - eta) < 0.017 ) {
00059         deltaEta = fabs(beamEta - eta);
00060         deltaPhi = fabs(beamPhi - phi);
00061         crysNumber = cryIndex;
00062       }
00063     }
00064   }
00065 
00066   edm::LogInfo("EcalTBInfo") << "Initialize TB MC ECAL info producer with parameters: \n"
00067                              << "Crystal map file:  " << CrystalMapFile << "\n"
00068                              << "Beam average eta = " << beamEta << "\n"
00069                              << "Beam average phi = " << beamPhi << "\n"
00070                              << "Corresponding to crystal number = " << crysNumber << "\n"
00071                              << "Beam X offset =    " << beamXoff << "\n"
00072                              << "Beam Y offset =    " << beamYoff;
00073 
00074   // rotation matrix to move from the CMS reference frame to the test beam one
00075 
00076   double xx = -cos(beamTheta)*cos(beamPhi);
00077   double xy = -cos(beamTheta)*sin(beamPhi);
00078   double xz = sin(beamTheta);
00079   
00080   double yx = sin(beamPhi);
00081   double yy = -cos(beamPhi);
00082   double yz = 0.;
00083   
00084   double zx = sin(beamTheta)*cos(beamPhi);
00085   double zy = sin(beamTheta)*sin(beamPhi);
00086   double zz = cos(beamTheta);
00087 
00088   fromCMStoTB = new ROOT::Math::Rotation3D(xx, xy, xz, yx, yy, yz, zx, zy, zz);
00089 
00090   // random number
00091   edm::Service<edm::RandomNumberGenerator> rng;
00092    if ( ! rng.isAvailable()) {
00093      throw cms::Exception("Configuration")
00094        << "EcalTBMCInfoProducer requires the RandomNumberGeneratorService\n"
00095           "which is not present in the configuration file.  You must add the service\n"
00096           "in the configuration file or remove the modules that require it.";
00097    }
00098    CLHEP::HepRandomEngine& engine = rng->getEngine();
00099    flatDistribution_ = new CLHEP::RandFlat(engine);
00100 
00101 }
00102  
00103 EcalTBMCInfoProducer::~EcalTBMCInfoProducer() {
00104 
00105   delete flatDistribution_;
00106   delete theTestMap;
00107   
00108 }
00109 
00110  void EcalTBMCInfoProducer::produce(edm::Event & event, const edm::EventSetup& eventSetup)
00111 {
00112   auto_ptr<PEcalTBInfo> product(new PEcalTBInfo());
00113 
00114   // Fill the run information
00115 
00116   product->setCrystal(crysNumber);
00117 
00118   product->setBeamDirection(beamEta, beamPhi);
00119   product->setBeamOffset(beamXoff, beamYoff);
00120 
00121   // Compute the event x,y vertex coordinates in the beam reference system
00122   // e.g. in the place orthogonal to the beam average direction
00123 
00124   partXhodo = partYhodo = 0.;
00125 
00126   edm::Handle<edm::HepMCProduct> GenEvt;
00127   event.getByLabel(GenVtxLabel,GenEvt);
00128 
00129   const HepMC::GenEvent* Evt = GenEvt->GetEvent() ;
00130   HepMC::GenEvent::vertex_const_iterator Vtx = Evt->vertices_begin();
00131 
00132   math::XYZPoint eventCMSVertex((*Vtx)->position().x(),
00133                                 (*Vtx)->position().y(),
00134                                 (*Vtx)->position().z());
00135   
00136   LogDebug("EcalTBInfo") << "Generated vertex position = " 
00137                          << eventCMSVertex.x() << " " 
00138                          << eventCMSVertex.y() << " " 
00139                          << eventCMSVertex.z();
00140 
00141   math::XYZPoint eventTBVertex = (*fromCMStoTB)*eventCMSVertex;
00142 
00143   LogDebug("EcalTBInfo") << "Rotated vertex position   = "
00144                          << eventTBVertex.x() << " " 
00145                          << eventTBVertex.y() << " " 
00146                          << eventTBVertex.z();
00147 
00148   partXhodo = eventTBVertex.x();
00149   partYhodo = eventTBVertex.y();
00150 
00151   product->setBeamPosition(partXhodo, partYhodo);
00152 
00153   // Asynchronous phase shift
00154   double thisPhaseShift = flatDistribution_->fire();
00155 
00156   product->setPhaseShift(thisPhaseShift);
00157   LogDebug("EcalTBInfo") << "Asynchronous Phaseshift = " << thisPhaseShift;
00158 
00159   // store the object in the framework event
00160 
00161   event.put(product);
00162 }
00163 
00164