CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_7_hltpatch2/src/IOMC/NtupleConverter/src/Ntuple2HepMCFiller.cc

Go to the documentation of this file.
00001 
00005 #include "IOMC/NtupleConverter/interface/Ntuple2HepMCFiller.h"
00006 
00007 #include<iostream>
00008 #include "IOMC/NtupleConverter/interface/NtupleROOTFile.h"  
00009 using namespace std;
00010 using namespace HepMC;
00011 
00012 Ntuple2HepMCFiller * Ntuple2HepMCFiller::instance_=0;
00013 //-------------------------------------------------------------------------
00014 Ntuple2HepMCFiller * Ntuple2HepMCFiller::instance(){    
00015         
00016         if (instance_== 0) {
00017                 instance_ = new Ntuple2HepMCFiller();
00018         }
00019         return instance_;
00020 }
00021 
00022 
00023 Ntuple2HepMCFiller::Ntuple2HepMCFiller(): 
00024    initialized_(false), input_(0),
00025    index_to_particle(3996),evtid(1),ntpl_id(1) { 
00026         cout << "Constructing a new Ntuple2HepMCFiller" << endl;
00027         if(instance_ == 0) instance_ = this;    
00028 } 
00029 
00030 //-------------------------------------------------------------------------
00031 Ntuple2HepMCFiller::~Ntuple2HepMCFiller(){ 
00032         cout << "Destructing Ntuple2HepMCFiller" << endl;       
00033         if(input_) {
00034                 delete input_;
00035         }
00036         instance_=0;    
00037 }
00038 //-------------------------------------------------------------------------
00039 
00040 void Ntuple2HepMCFiller::setInitialized(bool value){initialized_=value;}
00041 
00042 //-------------------------------------------------------------------------
00043 void Ntuple2HepMCFiller::initialize(const string & filename, int id){
00044         
00045         if (initialized_) {
00046                 cout << "Ntuple2HepMCFiller was already initialized... reinitializing it " << endl;
00047                 if(input_) {
00048                         delete input_;
00049                 }               
00050         }       
00051         
00052         cout<<"Ntuple2HepMCFiller::initialize : Opening file "<<filename<<endl;
00053         ntpl_id=id;
00054         input_ = new NtupleROOTFile( filename, id);
00055         initialized_ = true;   
00056 }
00057 
00058 //-------------------------------------------------------------------------
00059 
00060 bool Ntuple2HepMCFiller::isInitialized(){
00061         
00062         return initialized_;
00063 }
00064 
00065 //-------------------------------------------------------------------------
00066 bool  Ntuple2HepMCFiller::readCurrentEvent() {
00067         bool filter=false;
00068         // 1. create an empty event container
00069         HepMC::GenEvent* event = new HepMC::GenEvent();
00070         input_ ->setEvent(evtid);
00071         // 2. fill the evt container - if the read is successful, set the pointer
00072         if ( this->toGenEvent( evtid, event ) ) evt=event;
00073         if (evt){ 
00074                 cout <<"| --- Ntuple2HepMCFiller: Event Nr. "  <<evt->event_number() <<" with " <<evt->particles_size()<<" particles --- !" <<endl;             
00075                 //      printHepMcEvent();      
00076                 filter=true;
00077         }
00078         if (!evt) {
00079                 cout <<  "Ntuple2HepMCFiller: Got no event :-(" <<endl;
00080                 filter=false;
00081                 delete  evt;  // @@@
00082         }       
00083         if (evtid > input_->getNevhep()) filter = false; 
00084         evtid++;
00085         return filter;
00086 }
00087 
00088 //-------------------------------------------------------------------------
00089 bool Ntuple2HepMCFiller::setEvent(unsigned int event){
00090   evtid= event;
00091   return true;
00092 }
00093 
00094 //-------------------------------------------------------------------------
00095 
00096 bool Ntuple2HepMCFiller::printHepMcEvent() const{
00097         if (evt!=0) evt->print();       
00098         return true;
00099 }
00100 
00101 //-------------------------------------------------------------------------
00102 HepMC::GenEvent * Ntuple2HepMCFiller::fillCurrentEventData(){
00103   if (readCurrentEvent())return evt;
00104   else return NULL;
00105   
00106 }
00107 
00108 
00109 //-------------------------------------------------------------------
00110 bool Ntuple2HepMCFiller::toGenEvent( int evtnum, HepMC::GenEvent* evt ){
00111         // Written according to HepMC /fio/ IO_HEPEVT.cc( hepmc-01-26 tag at Savannah)
00112         // 1. set event number
00113         // evt->set_event_number( input_->getNevhep());
00114         evt->set_event_number( evtnum ) ; 
00115         // these do not have the correct defaults if hepev4 is not filled
00116         //evt->set_event_scale( hepev4()->scalelh[1] );
00117         //evt->set_alphaQCD( hepev4()->alphaqcdlh );
00118         //evt->set_alphaQED( hepev4()->alphaqedlh ); 
00119         std::vector<HepMC::GenParticle*> hepevt_particle(input_->getNhep()+1 );
00120         //2. create a particle instance for each HEPEVT entry and fill a map
00121         //    create a vector which maps from the HEPEVT particle index to the 
00122         //    GenParticle address
00123         //    (+1 in size accounts for hepevt_particle[0] which is unfilled)
00124         hepevt_particle[0] = 0;
00125         for ( int i1 = 1; i1 <= input_->getNhep(); ++i1 ) {
00126                 hepevt_particle[i1] = createParticle(i1);
00127         }       
00128         std::set<HepMC::GenVertex*> new_vertices; 
00129         
00130         // 3.+4. loop over HEPEVT particles AGAIN, this time creating vertices
00131         for ( int i = 1; i <= input_->getNhep(); ++i ) {
00132                 // We go through and build EITHER the production or decay 
00133                 // vertex for each entry in hepevt
00134                 // Note: since the HEPEVT pointers are bi-directional, it is
00136                 buildProductionVertex( i, hepevt_particle, evt, 1 );
00137         }
00138         //      hepevt_particle.clear();
00139         return true;
00140 }
00141 
00142 //-------------------------------------------------------
00143 HepMC::GenParticle* Ntuple2HepMCFiller::createParticle( int index ) {
00144         
00145         // Builds a particle object corresponding to index in HEPEVT
00146         HepMC::GenParticle* p 
00147         = new HepMC::GenParticle(FourVector( input_->getPhep(index,0), 
00148         input_->getPhep(index,1), 
00149         input_->getPhep(index,2), 
00150         input_->getPhep(index,3)),
00151         input_->getIdhep(index), 
00152         input_->getIsthep(index));
00153         p->setGeneratedMass( input_->getPhep(index, 4) );
00154         p->suggest_barcode( index );
00155         return p;
00156 }
00157 
00158 //-------------------------------------------------------
00159 void Ntuple2HepMCFiller::buildProductionVertex( int i, 
00160 std::vector<HepMC::GenParticle*>& hepevt_particle, 
00161 HepMC::GenEvent* evt, bool printInconsistencyErrors )
00162 {
00163         // 
00164         // for particle in HEPEVT with index i, build a production vertex
00165         // if appropriate, and add that vertex to the event
00166         HepMC::GenParticle* p = hepevt_particle[i];
00167         // a. search to see if a production vertex already exists
00168         int mother = input_->getJmohep(i,0);
00169         // this is dangerous.  Copying null pointer and attempting to fill 
00170         //  information in prod_vtx......
00171         HepMC::GenVertex* prod_vtx = p->production_vertex();
00172         //  no production vertex and mother exist -> produce vertex
00173         while ( !prod_vtx && mother > 0 ) {
00174                 prod_vtx = hepevt_particle[mother]->end_vertex();
00175                 if ( prod_vtx ) prod_vtx->add_particle_out( p );
00176                 // increment mother for next iteration
00177                 if ( ++mother > input_->getJmohep(i,1) ) mother = 0;
00178         }
00179         // b. if no suitable production vertex exists - and the particle
00180         // has atleast one mother or position information to store - 
00181         // make one@@@
00182         FourVector prod_pos( input_->getVhep(i,0), input_->getVhep(i,1), 
00183         input_->getVhep(i,2), input_->getVhep(i,3));
00184         // orginal:
00185         if ( !prod_vtx && (number_parents(i)>0  || prod_pos!=FourVector(0,0,0,0) )){
00186                 prod_vtx = new HepMC::GenVertex();      
00187                 prod_vtx->add_particle_out( p );
00188                 evt->add_vertex( prod_vtx );
00189         }
00190         // c. if prod_vtx doesn't already have position specified, fill it
00191         if ( prod_vtx && prod_vtx->position()==FourVector(0,0,0,0) ) {
00192                 prod_vtx->set_position( prod_pos );
00193         }
00194         // d. loop over mothers to make sure their end_vertices are
00195         //     consistent
00196         mother = input_->getJmohep(i,0);
00197         while ( prod_vtx && mother > 0 ) {
00198                 if ( !hepevt_particle[mother]->end_vertex() ) {
00199                         // if end vertex of the mother isn't specified, do it now
00200                         prod_vtx->add_particle_in( hepevt_particle[mother] );
00201                 } 
00202                 else if (hepevt_particle[mother]->end_vertex() != prod_vtx ) {
00203                         // problem scenario --- the mother already has a decay
00204                         // vertex which differs from the daughter's produciton 
00205                         // vertex. This means there is internal
00206                         // inconsistency in the HEPEVT event record. Print an
00207                         // error
00208                         // Note: we could provide a fix by joining the two 
00209                         //       vertices with a dummy particle if the problem
00210                         //       arrises often with any particular generator.
00211                         if ( printInconsistencyErrors ) std::cerr
00212                                 << "Ntuple2HepMCFiller:: inconsistent mother/daughter "
00213                         << "information in HEPEVT event " 
00214                         << input_->getNevhep()
00215                         << std::endl;
00216                 }
00217                 if ( ++mother > input_->getJmohep(i,1) ) mother = 0;
00218         }
00219 }
00220 
00221 
00222 //-------------------------------------------------------
00223 int Ntuple2HepMCFiller::number_children( int index )
00224 {
00225         int firstchild = input_->getJdahep(index,0);
00226         return ( firstchild>0 ) ? 
00227         ( 1+input_->getJdahep(index,1)-firstchild ) : 0;
00228 }
00229 
00230 //-------------------------------------------------------       
00231 int Ntuple2HepMCFiller::number_parents( int index ) {
00232 
00233         // Fix for cmkin single particle ntpls 
00234         if (input_->getNhep()==1) return 1;
00235         // Fix for cmkindouble particle ntpls
00236         if (input_->getNhep()==2) return 1;     
00237         int firstparent = input_->getJmohep(index,0);
00238         if( firstparent <= 0 ) return 0;
00239         int secondparent = input_->getJmohep(index,1);
00240         if( secondparent <= 0 ) return 1;
00241         return secondparent - firstparent + 1;
00242         
00243 } 
00244 
00245 /*************************************************************************************
00246 NEVHEP = event number
00247 NHEP   = number of entries (particles, partons)
00248 ISTHEP = status code
00249 IDHEP  = PDG identifier
00250 JMOHEP = position of 1st and 2nd  mother
00251 JDAHEP = position of 1st and last daughter
00252 PHEP   = 4-momentum and mass            (single precision in ntuple file)
00253 VHEP   = vertex xyz and production time (single precision in ntuple file)
00254 
00255 
00256 IRNMCP      = run number
00257 IEVMCP         = event number
00258 WGTMCP         = event weight
00259 XSECN          = cross section equivalent
00260 IFILTER        = filter pattern
00261 NVRMCP         = number of additional variables
00262 VARMCP(NMXMCP) = list of additional variables
00263 Note: VARMCP(1) = PARI(17) (=s_hat) is reserved.
00264 
00265 There are the following default values:
00266 
00267 IRNMCP = 1
00268 IEVMCP = NEVHEP
00269 WGTMCP = 1.0
00270 XSECN  = IFILTER = 0
00271 NVRMCP = 1
00272 *****************************************************************************************/