Exemple #1
0
void Rivet_Interface::SetEventWeight(const Rivet_Scale_Variation* rsv,
                                     HepMC::GenEvent& evt, const int& idx)
{
  double wgt(idx<0?rsv->Weight():rsv->Weight(idx));
  DEBUG_FUNC(rsv->Name()<<": "<<wgt);
  evt.weights()[0]=wgt;
#ifdef HEPMC_HAS_CROSS_SECTION
  evt.cross_section()->set_cross_section(rsv->TotalXS(),rsv->TotalErr());
#endif
}
int
DirectPhotonPythia::process_event(PHCompositeNode *topNode)
{
  _ievent ++;

  PHHepMCGenEventMap * geneventmap = findNode::getClass<PHHepMCGenEventMap>(topNode, "PHHepMCGenEventMap");
  if (!geneventmap)
  {
    std::cout <<PHWHERE<<" - Fatal error - missing node PHHepMCGenEventMap"<<std::endl;
    return Fun4AllReturnCodes::ABORTRUN;
  }

  PHHepMCGenEvent *genevt = geneventmap->get(_embedding_id);
  if (!genevt)
  {
    std::cout <<PHWHERE<<" - Fatal error - node PHHepMCGenEventMap missing subevent with embedding ID "<<_embedding_id;
    std::cout <<". Print PHHepMCGenEventMap:";
    geneventmap->identify();
    return Fun4AllReturnCodes::ABORTRUN;
  }

  HepMC::GenEvent* theEvent = genevt->getEvent();
  

for (HepMC::GenEvent::particle_const_iterator p = theEvent->particles_begin();
      p != theEvent->particles_end(); ++p)
    {
      TParticlePDG * pdg_p = TDatabasePDG::Instance()->GetParticle(
          (*p)->pdg_id());
      if (pdg_p)
        {
          if (TString(pdg_p->GetName()) == "gamma")
            {
              // cout <<"Find gamma at eta = "<< (*p)->momentum().pseudoRapidity() <<endl;

	      if((*p)->momentum().perp()>5.) _h2->Fill((*p)->momentum().perp(), (*p)->momentum().pseudoRapidity());
              if((*p)->momentum().perp()>5.) _h1->Fill((*p)->momentum().perp());
              
              if((*p)->momentum().perp()>5.) {
		const float px = (*p)->momentum().x(), 
                            py = (*p)->momentum().y(), 
                            pz = (*p)->momentum().z(),
		            pt = (*p)->momentum().perp(), 
                           eta = (*p)->momentum().pseudoRapidity(),
                           phi = (*p)->momentum().phi();
                float shower_data[70] = {(float)_ievent,px,py,pz,pt,eta,phi};
               
                _ntp_gamma -> Fill(shower_data);
             }
            }
        }
      }

      return 0;;
}
Exemple #3
0
void Output_Delphes::AnalyseEvent
(ExRootTreeBranch *branch,const HepMC::GenEvent& evt,
 const Long64_t eventNumber,const double weight)
{
  TRootLHEFEvent *element;
  element = static_cast<TRootLHEFEvent*>(branch->NewEntry());
  element->Number = eventNumber;
  element->Nparticles = evt.particles_size();
  element->ProcessID = evt.signal_process_id();
  element->Weight = weight;
  element->ScalePDF = evt.event_scale();
  element->CouplingQED = evt.alphaQED();
  element->CouplingQCD = evt.alphaQCD();
}
/// Smearing function
StatusCode GaussSmearVertex::smearVertex(HepMC::GenEvent& theEvent) {

  double dx = m_gaussDist() * sqrt(m_xsig) + m_xmean;
  double dy = m_gaussDist() * sqrt(m_ysig) + m_ymean;
  double dz = m_gaussDist() * sqrt(m_zsig) + m_zmean;
  double dt = m_gaussDist() * sqrt(m_tsig) + m_tmean;

  Gaudi::LorentzVector dpos(dx, dy, dz, dt);

  debug() << "Smearing vertices by " << dpos << endmsg;

  for (auto vit = theEvent.vertices_begin(); vit != theEvent.vertices_end(); ++vit) {
    Gaudi::LorentzVector pos((*vit)->position());
    pos += dpos;
    (*vit)->set_position(HepMC::FourVector(pos.x(), pos.y(), pos.z(), pos.t()));
  }

  return StatusCode::SUCCESS;
}
Exemple #5
0
int main(int argc, char *argv[]){

  TFile* fout = new TFile("cascade.result.root","RECREATE");

  HepMC::IO_GenEvent fin("../CASCADE_HEPMC/bin/example_test_out.dat",std::ios::in);
  
  HepMC::GenEvent* evt = new HepMC::GenEvent;

  TTree *tree = new TTree("tree","cascade result");
  tree->Branch("event",&evt);

  Int_t nevt = 0;

  while (evt = fin.read_next_event() ) {

    nevt++;

    if(debug){ 
      cout<<"nevt: "<<nevt<<endl;
      getchar();
      evt->print();
    }

    tree->Fill();
  }

  tree->Print();

  fout->cd();
  tree->Write();
  fout->Close();
  
  delete fout;

  return(0);  
}
Exemple #6
0
StatusCode ConstPtParticleGun::getNextEvent(HepMC::GenEvent& theEvent) {
  Gaudi::LorentzVector theFourMomentum;
  Gaudi::LorentzVector origin;
  // note: pgdid is set in function generateParticle
  int thePdgId;
  generateParticle(theFourMomentum, origin, thePdgId);

  // create HepMC Vertex --
  // by calling add_vertex(), the hepmc event is given ownership of the vertex
  HepMC::GenVertex* v = new HepMC::GenVertex(HepMC::FourVector(origin.X(), origin.Y(), origin.Z(), origin.T()));
  // create HepMC particle --
  // by calling add_particle_out(), the hepmc vertex is given ownership of the particle
  HepMC::GenParticle* p = new HepMC::GenParticle(
      HepMC::FourVector(theFourMomentum.Px(), theFourMomentum.Py(), theFourMomentum.Pz(), theFourMomentum.E()),
      thePdgId,
      1);  // hepmc status code for final state particle

  v->add_particle_out(p);

  theEvent.add_vertex(v);
  theEvent.set_signal_process_vertex(v);

  return StatusCode::SUCCESS;
}
StatusCode EDMToHepMCConverter::execute() {

  const fcc::MCParticleCollection* particles = m_genphandle.get();
  // ownership of event given to data service at the end of execute
  HepMC::GenEvent* event = new HepMC::GenEvent;

  // conversion of units to EDM standard units:
  // First cover the case that hepMC file is not in expected units and then convert to EDM default
  double hepmc2EdmLength = conversion_factor(event->length_unit(), gen::hepmcdefault::length) * gen::hepmc2edm::length;
  double hepmc2EdmEnergy =
      conversion_factor(event->momentum_unit(), gen::hepmcdefault::energy) * gen::hepmc2edm::energy;

  for (auto p : *(particles)) {
    if (p.status() == 1) {  // only final state particles
      GenParticle* pHepMC =
          new GenParticle(HepMC::FourVector(p.p4().px, p.p4().py, p.p4().pz, p.p4().mass / hepmc2EdmEnergy),
                          p.pdgId(),
                          p.status());  // hepmc status code for final state particle

      fcc::ConstGenVertex vStart = p.startVertex();
      if (p.startVertex().isAvailable()) {
        HepMC::GenVertex* v =
            new HepMC::GenVertex(HepMC::FourVector(vStart.position().x / hepmc2EdmLength,
                                                   vStart.position().y / hepmc2EdmLength,
                                                   vStart.position().z / hepmc2EdmLength,
                                                   vStart.ctau() / Gaudi::Units::c_light / hepmc2EdmLength));

        v->add_particle_out(pHepMC);
        event->add_vertex(v);
      }
    }
  }

  m_hepmchandle.put(event);
  return StatusCode::SUCCESS;
}
Exemple #8
0
void Output_Delphes::AnalyseParticles(ExRootTreeBranch *branch, const HepMC::GenEvent& evt)
{
  TRootC::GenParticle *element;
  TLorentzVector momentum;
  Double_t signPz;
  ReadStats();
  for(int n=1; n<=evt.particles_size(); n++) {
    int mo1, mo2, da1, da2, status, pid;
    getStatsFromTuple(mo1,mo2,da1,da2,status,pid,n);
    element = static_cast<TRootC::GenParticle*>(branch->NewEntry());
    element->PID = pid;
    element->Status = status;
    element->M1 = mo1 - 1; // added -1 as the numbering in the tree starts from 0
    element->M2 = mo2 - 1;
    element->D1 = da1 - 1;
    element->D2 = da2 - 1;
    element->E = index_to_particle[n]->momentum().e();
    element->Px = index_to_particle[n]->momentum().px();
    element->Py = index_to_particle[n]->momentum().py();
    element->Pz = index_to_particle[n]->momentum().pz();
    element->PT = sqrt(pow(element->Px,2)+pow(element->Py,2));
    momentum.SetPxPyPzE(element->Px, element->Py, element->Pz, element->E);
    signPz = (element->Pz >= 0.0) ? 1.0 : -1.0;
    element->Eta = element->PT < 1e-6 ? signPz*999.9 : momentum.Eta();
    element->Phi = index_to_particle[n]->momentum().phi();
    HepMC::GenVertex* vrtI = (index_to_particle[n])->production_vertex();
    HepMC::GenVertex::particles_in_const_iterator partI;
    if(vrtI) {
      element->T = vrtI->position().t();
      element->X = vrtI->position().x();
      element->Y = vrtI->position().y();
      element->Z = vrtI->position().z();
    }
    else {
      element->T = 0.;
      element->X = 0.;
      element->Y = 0.;
      element->Z = 0.;
    }  
  }
}
Exemple #9
0
int PHSartre::process_event(PHCompositeNode *topNode) {

  if (verbosity > 1) cout << "PHSartre::process_event - event: " << _eventcount << endl;
  
  bool passedTrigger = false;
  Event *event = NULL;

  TLorentzVector *eIn     = NULL;
  TLorentzVector *pIn     = NULL;
  TLorentzVector *eOut    = NULL;
  TLorentzVector *gamma   = NULL;
  TLorentzVector *vm      = NULL;
  TLorentzVector *PomOut  = NULL;
  TLorentzVector *pOut    = NULL;
  TLorentzVector *vmDecay1 = NULL; 
  TLorentzVector *vmDecay2 = NULL; 
  unsigned int preVMDecaySize = 0; 

  while (!passedTrigger) {
    ++_gencount;

    // Generate a Sartre event
    event = _sartre->generateEvent();
        
    //
    //  If Sartre is run in UPC mode, half of the events needs to be
    //  rotated around and axis perpendicular to z:
    //  (only for symmetric events)
    //
    if(settings->UPC() and settings->A()==settings->UPCA()){
      randomlyReverseBeams(event);
    }
	
    // for sPHENIX/RHIC p+Au
    // (see comments in ReverseBeams)
    // reverse when the proton emits the virtual photon
	
    if(settings->UPC() and settings->A()==197){
      ReverseBeams(event);
    }

    // Set pointers to the parts of the event we will need:

    eIn     = &event->particles[0].p;
    pIn     = &event->particles[1].p;
    eOut    = &event->particles[2].p;
    gamma   = &event->particles[3].p;
    vm      = &event->particles[4].p;
    PomOut  = &event->particles[5].p;
    pOut    = &event->particles[6].p;

    // To allow the triggering to work properly, we need to decay the vector meson here

    preVMDecaySize = event->particles.size(); 

    if(doPerformDecay) {

      if( decay->SetDecay(*vm, 2, daughterMasses) ){
	double weight = decay->Generate(); // weight is always 1 here
	if ( (weight-1) > FLT_EPSILON) {
	  cout << "PHSartre: Warning decay weight != 1, weight = " << weight << endl;
	}
	TLorentzVector *vmDaughter1 = decay->GetDecay(0);
	TLorentzVector *vmDaughter2 = decay->GetDecay(1);

	event->particles[4].status = 2; // set VM status

	Particle vmDC1; 
	vmDC1.index = event->particles.size(); 
	vmDC1.pdgId =  daughterID; 
	vmDC1.status = 1; // final state
	vmDC1.p = *vmDaughter1; 
	vmDC1.parents.push_back(4);	
	event->particles.push_back(vmDC1); 
	vmDecay1 = &event->particles[event->particles.size()-1].p;

	Particle vmDC2; 
	vmDC2.index = event->particles.size(); 
	vmDC2.pdgId =  -daughterID; 
	vmDC2.status = 1; // final state
	vmDC2.p = *vmDaughter2; 
	vmDC2.parents.push_back(4);	
	event->particles.push_back(vmDC2); 
	vmDecay2 = &event->particles[event->particles.size()-1].p;

      }
      else {
	cout << "PHSartre: WARNING: Kinematics of Vector Meson does not allow decay!" << endl;
      }

    }

    // test trigger logic
    
    bool andScoreKeeper = true;
    if (verbosity > 2) {
      cout << "PHSartre::process_event - triggersize: " << _registeredTriggers.size() << endl;
    }

    for (unsigned int tr = 0; tr < _registeredTriggers.size(); tr++) { 
      bool trigResult = _registeredTriggers[tr]->Apply(event);

      if (verbosity > 2) {
	cout << "PHSartre::process_event trigger: "
	     << _registeredTriggers[tr]->GetName() << "  " << trigResult << endl;
      }

      if (_triggersOR && trigResult) {
	passedTrigger = true;
	break;
      } else if (_triggersAND) {
	andScoreKeeper &= trigResult;
      }
      
      if (verbosity > 2 && !passedTrigger) {
	cout << "PHSartre::process_event - failed trigger: "
	     << _registeredTriggers[tr]->GetName() <<  endl;
      }
    }

    if ((andScoreKeeper && _triggersAND) || (_registeredTriggers.size() == 0)) {
      passedTrigger = true;
    }

  }

  // fill HepMC object with event
  
  HepMC::GenEvent *genevent = new HepMC::GenEvent(HepMC::Units::GEV, HepMC::Units::MM);

  // add some information to the event
  genevent->set_event_number(_eventcount);

  // Set the PDF information
  HepMC::PdfInfo pdfinfo;
  pdfinfo.set_scalePDF(event->Q2);
  genevent->set_pdf_info(pdfinfo); 

  // We would also like to save:
  //
  // event->t;
  // event->x;
  // event->y;
  // event->s;
  // event->W;
  // event->xpom;
  // (event->polarization == transverse ? 0 : 1);
  // (event->diffractiveMode == coherent ? 0 : 1);
  // 
  // but there doesn't seem to be a good place to do so 
  // within the HepMC event information?
  //
  // t, W and Q^2 form a minial set of good variables for diffractive events
  // Maybe what I do is record the input particles to the event at the HepMC
  // vertices and reconstruct the kinematics from there? 
  
  // Create HepMC vertices and add final state particles to them

  // First, the emitter(electron)-virtual photon vertex:

  HepMC::GenVertex* egammavtx = new HepMC::GenVertex(CLHEP::HepLorentzVector(0.0,0.0,0.0,0.0));
  genevent->add_vertex(egammavtx); 

  egammavtx->add_particle_in( 
			 new HepMC::GenParticle( CLHEP::HepLorentzVector(eIn->Px(),
									 eIn->Py(),
									 eIn->Pz(),
									 eIn->E()), 
						 event->particles[0].pdgId, 
						 3 ) 
			  );

  HepMC::GenParticle *hgamma =  new HepMC::GenParticle( CLHEP::HepLorentzVector(gamma->Px(),
									 gamma->Py(),
									 gamma->Pz(),
									 gamma->E()), 
						event->particles[3].pdgId, 
						3 ); 

  egammavtx->add_particle_out(hgamma);

  egammavtx->add_particle_out( 
			 new HepMC::GenParticle( CLHEP::HepLorentzVector(eOut->Px(),
									 eOut->Py(),
									 eOut->Pz(),
									 eOut->E()), 
						 event->particles[2].pdgId, 
						 1 ) 
			  );

  // Next, the hadron-pomeron vertex:

  HepMC::GenVertex* ppomvtx = new HepMC::GenVertex(CLHEP::HepLorentzVector(0.0,0.0,0.0,0.0));
  genevent->add_vertex(ppomvtx); 


  ppomvtx->add_particle_in( 
			 new HepMC::GenParticle( CLHEP::HepLorentzVector(pIn->Px(),
									 pIn->Py(),
									 pIn->Pz(),
									 pIn->E()), 
						 event->particles[1].pdgId, 
						 3 ) 
			     );

  HepMC::GenParticle *hPomOut = new HepMC::GenParticle( CLHEP::HepLorentzVector(PomOut->Px(),
									 PomOut->Py(),
									 PomOut->Pz(),
									 PomOut->E()), 
						 event->particles[5].pdgId, 
						 3 ); 

  ppomvtx->add_particle_out(hPomOut); 

  // If this is a nuclear breakup, add in the nuclear fragments
  // Otherwise, add in the outgoing hadron
        
  //If the event is incoherent, and nuclear breakup is enabled, fill the remnants to the tree
  if(settings->enableNuclearBreakup() and event->diffractiveMode == incoherent){
    for(unsigned int iParticle=7; iParticle < preVMDecaySize; iParticle++){
      if(event->particles[iParticle].status == 1) {  // Final-state particle
	const Particle& particle = event->particles[iParticle];	  
	ppomvtx->add_particle_out( 
			       new HepMC::GenParticle( CLHEP::HepLorentzVector(particle.p.Px(),
								 particle.p.Py(),
								 particle.p.Pz(),
								 particle.p.E()), 
						particle.pdgId, 
						1 ) 
				);
      }  
    }  
  }
  else{

    ppomvtx->add_particle_out( 
			      new HepMC::GenParticle( CLHEP::HepLorentzVector(pOut->Px(),
									      pOut->Py(),
									      pOut->Pz(),
									      pOut->E()), 
						      event->particles[6].pdgId, 
						      1 ) 
			       );
  }

  // The Pomeron-Photon vertex

  HepMC::GenVertex* gammapomvtx = new HepMC::GenVertex(CLHEP::HepLorentzVector(0.0,0.0,0.0,0.0));
  genevent->add_vertex(gammapomvtx); 
  
  gammapomvtx->add_particle_in(hgamma); 
  gammapomvtx->add_particle_in(hPomOut); 

  int isVMFinal = 1; 
  if(doPerformDecay) isVMFinal = 2; 

  HepMC::GenParticle *hvm = new HepMC::GenParticle( CLHEP::HepLorentzVector(vm->Px(),
									    vm->Py(),
									    vm->Pz(),
									    vm->E()), 
						   event->particles[4].pdgId, 
						   isVMFinal ) ; 

  gammapomvtx->add_particle_out( hvm );
 
  // Add the VM decay to the event

  if(doPerformDecay) {

    if(vmDecay1 && vmDecay2){

      HepMC::GenVertex* fvtx = new HepMC::GenVertex(CLHEP::HepLorentzVector(0.0,0.0,0.0,0.0));
      genevent->add_vertex(fvtx); 

      fvtx->add_particle_in( hvm ); 

      fvtx->add_particle_out( 
			 new HepMC::GenParticle( CLHEP::HepLorentzVector(vmDecay1->Px(),
							   vmDecay1->Py(),
							   vmDecay1->Pz(),
							   vmDecay1->E()), 
					  daughterID, 
					  1 ) 
			  );
      fvtx->add_particle_out( 
			 new HepMC::GenParticle( CLHEP::HepLorentzVector(vmDecay2->Px(),
							   vmDecay2->Py(),
							   vmDecay2->Pz(),
							   vmDecay2->E()), 
					  -daughterID, 
					  1 ) 
			  );

    }
    else {
      cout << "PHSartre: WARNING: Kinematics of Vector Meson does not allow decay!" << endl;
    }

  }

  // pass HepMC to PHNode
  
  PHHepMCGenEvent * success = hepmc_helper . insert_event(genevent);
  if (!success) {
    cout << "PHSartre::process_event - Failed to add event to HepMC record!" << endl;
    return Fun4AllReturnCodes::ABORTRUN;
  }


  // print outs
  
  if (verbosity > 2) cout << "PHSartre::process_event - FINISHED WHOLE EVENT" << endl;

  ++_eventcount;
  return Fun4AllReturnCodes::EVENT_OK;
}
int main(int argc, char* argv[])
{
  TApplication theApp(srcName.Data(), &argc, argv);
//=============================================================================

  if (argc<5) return -1;
  TString sPath = argv[1]; if (sPath.IsNull()) return -1;
  TString sFile = argv[2]; if (sFile.IsNull()) return -1;
  TString sJetR = argv[3]; if (sJetR.IsNull()) return -1;
  TString sSjeR = argv[4]; if (sSjeR.IsNull()) return -1;
//=============================================================================

  sPath.ReplaceAll("#", "/");
//=============================================================================

  double dJetR = -1.;
  if (sJetR=="JetR02") dJetR = 0.2;
  if (sJetR=="JetR03") dJetR = 0.3;
  if (sJetR=="JetR04") dJetR = 0.4;
  if (sJetR=="JetR05") dJetR = 0.5;

  if (dJetR<0.) return -1;
  cout << "Jet R = " << dJetR << endl;
//=============================================================================

  double dSjeR = -1.;
  if (sSjeR=="SjeR01") dSjeR = 0.1;
  if (sSjeR=="SjeR02") dSjeR = 0.2;
  if (sSjeR=="SjeR03") dSjeR = 0.3;
  if (sSjeR=="SjeR04") dSjeR = 0.4;

  if (dSjeR<0.) return -1;
  cout << "Sub-jet R = " << dSjeR << endl;
//=============================================================================

  const double dJetsPtMin  = 0.001;
  const double dCutEtaMax  = 1.6;
  const double dJetEtaMax  = 1.;
  const double dJetAreaRef = TMath::Pi() * dJetR * dJetR;

  fastjet::GhostedAreaSpec areaSpc(dCutEtaMax);
  fastjet::JetDefinition   jetsDef(fastjet::antikt_algorithm, dJetR, fastjet::BIpt_scheme, fastjet::Best);
  fastjet::AreaDefinition  areaDef(fastjet::active_area_explicit_ghosts,areaSpc);

  fastjet::Selector selectJet = fastjet::SelectorAbsEtaMax(dJetEtaMax);
  fastjet::JetDefinition subjDef(fastjet::kt_algorithm, dSjeR, fastjet::BIpt_scheme, fastjet::Best);
//=============================================================================

  std::vector<fastjet::PseudoJet> fjInput;
  const Double_t dCut = TMath::TwoPi() / 3.;
//=============================================================================

  enum { kWgt, kXsc, kLje, kLjr, kLtk, kLtr, kJet, kAje, kMje, k1sz, k1sA, k1sm, k1sr, k2sz, k2sA, k2sm, k2sr, kDsm, kDsr, kVar };

  TFile *file = TFile::Open(Form("%s.root",sFile.Data()), "NEW");
  TNtuple *nt = new TNtuple("nt", "", "fWgt:fXsc:fLje:fLjr:fLtk:fLtr:fJet:fAje:fMje:f1sj:f1sA:f1sm:f1sr:f2sj:f2sA:f2sm:f2sr:fDsm:fDsr");
//=============================================================================

  HepMC::IO_GenEvent ascii_in(Form("%s/%s.hepmc",sPath.Data(),sFile.Data()), std::ios::in);
  HepMC::GenEvent *evt = ascii_in.read_next_event();

  while (evt) {
    fjInput.resize(0);

    double dLtk = -1.;
    TVector3 vPar, vLtk;
    for (HepMC::GenEvent::particle_const_iterator p=evt->particles_begin(); p!=evt->particles_end(); ++p) if ((*p)->status()==1) {
      double dEta = (*p)->momentum().eta(); if (TMath::Abs(dEta)>dCutEtaMax) continue;

      double dTrk = (*p)->momentum().perp();
      double dPhi = (*p)->momentum().phi();
      vPar.SetPtEtaPhi(dTrk, dEta, dPhi);
      fjInput.push_back(fastjet::PseudoJet(vPar.Px(), vPar.Py(), vPar.Pz(), vPar.Mag()));
      if (dTrk>dLtk) { dLtk = dTrk; vLtk.SetPtEtaPhi(dTrk, dEta, dPhi); }
    }
//=============================================================================

    fastjet::ClusterSequenceArea clustSeq(fjInput, jetsDef, areaDef);
    std::vector<fastjet::PseudoJet> includJets = clustSeq.inclusive_jets(dJetsPtMin);
    std::vector<fastjet::PseudoJet> selectJets = selectJet(includJets);
//=============================================================================

    if (selectJets.size()>0) {
      std::vector<fastjet::PseudoJet> sortedJets = fastjet::sorted_by_pt(selectJets);
      TVector3 vLje; vLje.SetPtEtaPhi(sortedJets[0].pt(), sortedJets[0].eta(), sortedJets[0].phi());

      TVector3 vJet;
      int kJrl = -1; double dJrl = -1.;
      int kTrl = -1; double dTrl = -1.;
      for (int j=0; j<sortedJets.size(); j++) {
        double dJet = sortedJets[j].pt();
        sortedJets[j].set_user_index(-1);
        vJet.SetPtEtaPhi(dJet, sortedJets[j].eta(), sortedJets[j].phi());
        if (TMath::Abs(vJet.DeltaPhi(vLje))>dCut) { sortedJets[j].set_user_index(1); if (dJet>dJrl) { dJrl = dJet; kJrl = j; } }
        if (TMath::Abs(vJet.DeltaPhi(vLtk))>dCut) { sortedJets[j].set_user_index(2); if (dJet>dTrl) { dTrl = dJet; kTrl = j; } }
      }
//=============================================================================

      TVector3 v1sj, v2sj;
      for (int j=0; j<sortedJets.size(); j++) {
        Float_t dVar[kVar]; for (Int_t i=0; i<kVar; i++) dVar[i] = -1.;
        dVar[kWgt] = 1.; dVar[kXsc] = 1.;
        vJet.SetPtEtaPhi(sortedJets[j].pt(), sortedJets[j].eta(), sortedJets[j].phi());
//=============================================================================

        dVar[kLje] = vLje.Pt(); if (sortedJets[j].user_index()==1) { dVar[kLjr] = ((kJrl==j) ? 1.5 : 0.5); }
        dVar[kLtk] = vLtk.Pt(); if (sortedJets[j].user_index()==2) { dVar[kLtr] = ((kTrl==j) ? 1.5 : 0.5); }
//=============================================================================

        dVar[kJet] = sortedJets[j].pt();
        dVar[kAje] = sortedJets[j].area();
        dVar[kMje] = sortedJets[j].m();
//=============================================================================

        fastjet::Filter trimmer(subjDef, fastjet::SelectorPtFractionMin(0.));
        fastjet::PseudoJet trimmdJet = trimmer(sortedJets[j]);
        std::vector<fastjet::PseudoJet> trimmdSj = trimmdJet.pieces();

        double d1sj = -1.; int k1sj = -1;
        double d2sj = -1.; int k2sj = -1;
        for (int i=0; i<trimmdSj.size(); i++) {
          double dIsj = trimmdSj[i].pt(); if (dIsj<0.001) continue;

          if (dIsj>d1sj) {
            d2sj = d1sj; k2sj = k1sj;
            d1sj = dIsj; k1sj = i;
          } else if (dIsj>d2sj) {
            d2sj = dIsj; k2sj = i;
          }
        }
//=============================================================================

        if (d1sj>0.) {
          v1sj.SetPtEtaPhi(d1sj, trimmdSj[k1sj].eta(), trimmdSj[k1sj].phi());
          dVar[k1sz] = d1sj;
          dVar[k1sA] = trimmdSj[k1sj].area();
          dVar[k1sm] = trimmdSj[k1sj].m();
          dVar[k1sr] = v1sj.DeltaR(vJet);
        }

        if (d2sj>0.) {
          v2sj.SetPtEtaPhi(d2sj, trimmdSj[k2sj].eta(), trimmdSj[k2sj].phi());
          dVar[k2sz] = d2sj;
          dVar[k2sA] = trimmdSj[k2sj].area();
          dVar[k2sm] = trimmdSj[k2sj].m();
          dVar[k2sr] = v2sj.DeltaR(vJet);
        }

        if ((d1sj>0.) && (d2sj>0.)) dVar[kDsr] = v2sj.DeltaR(v1sj);

        nt->Fill(dVar);
      }
    }
//=============================================================================

    delete evt;
    ascii_in >> evt;
  }
//=============================================================================

  file->cd(); nt->Write(); file->Close();
//=============================================================================

  TString sXsec = sFile; sXsec.ReplaceAll("out", "xsecs");
  file = TFile::Open(Form("%s/xsecs/%s.root",sPath.Data(),sXsec.Data()), "READ");
  TH1D *hPtHat        = (TH1D*)file->Get("hPtHat");        hPtHat->SetDirectory(0);
  TH1D *hWeightSum    = (TH1D*)file->Get("hWeightSum");    hWeightSum->SetDirectory(0);
  TProfile *hSigmaGen = (TProfile*)file->Get("hSigmaGen"); hSigmaGen->SetDirectory(0);
  file->Close();
//=============================================================================

  sFile.ReplaceAll("out", "wgt");
  file = TFile::Open(Form("%s.root",sFile.Data()), "NEW");
  hPtHat->Write();
  hWeightSum->Write();
  hSigmaGen->Write();
  file->Close();
//=============================================================================

  cout << "DONE" << endl;
//=============================================================================

  return 0;
}
Exemple #11
0
int main(int argc, char* argv[])
{
  TApplication theApp(srcName.Data(), &argc, argv);
//=============================================================================

  if (argc<5) return -1;
  TString sPath = argv[1]; if (sPath.IsNull()) return -1;
  TString sFile = argv[2]; if (sFile.IsNull()) return -1;
  TString sJetR = argv[3]; if (sJetR.IsNull()) return -1;
  TString sSjeR = argv[4]; if (sSjeR.IsNull()) return -1;
//=============================================================================

  sPath.ReplaceAll("#", "/");
//=============================================================================

  double dJetR = -1.;
  if (sJetR=="JetR02") dJetR = 0.2;
  if (sJetR=="JetR03") dJetR = 0.3;
  if (sJetR=="JetR04") dJetR = 0.4;
  if (sJetR=="JetR05") dJetR = 0.5;

  if (dJetR<0.) return -1;
  cout << "Jet R = " << dJetR << endl;
//=============================================================================

  double dSjeR = -1.;
  if (sSjeR=="SjeR01") dSjeR = 0.1;
  if (sSjeR=="SjeR02") dSjeR = 0.2;
  if (sSjeR=="SjeR03") dSjeR = 0.3;
  if (sSjeR=="SjeR04") dSjeR = 0.4;

  if (dSjeR<0.) return -1;
  cout << "Sub-jet R = " << dSjeR << endl;
//=============================================================================

  const double dJetsPtMin  = 0.001;
  const double dCutEtaMax  = 1.6;
  const double dJetEtaMax  = 1.;
  const double dJetAreaRef = TMath::Pi() * dJetR * dJetR;

  fastjet::GhostedAreaSpec areaSpc(dCutEtaMax);
  fastjet::JetDefinition   jetsDef(fastjet::antikt_algorithm, dJetR, fastjet::E_scheme, fastjet::Best);

//fastjet::AreaDefinition  areaDef(fastjet::active_area,areaSpc);
  fastjet::AreaDefinition  areaDef(fastjet::active_area_explicit_ghosts,areaSpc);

//fastjet::JetDefinition   bkgsDef(fastjet::kt_algorithm, 0.2, fastjet::BIpt_scheme, fastjet::Best);
//fastjet::AreaDefinition  aBkgDef(fastjet::active_area_explicit_ghosts, areaSpc);

  fastjet::Selector selectJet = fastjet::SelectorAbsEtaMax(dJetEtaMax);
//fastjet::Selector selectRho = fastjet::SelectorAbsEtaMax(dCutEtaMax-0.2);
//fastjet::Selector selecHard = fastjet::SelectorNHardest(2);
//fastjet::Selector selectBkg = selectRho * (!(selecHard));
//fastjet::JetMedianBackgroundEstimator bkgsEstimator(selectBkg, bkgsDef, aBkgDef);
//fastjet::Subtractor                   bkgSubtractor(&bkgsEstimator);

  fastjet::JetDefinition subjDef(fastjet::kt_algorithm, dSjeR, fastjet::E_scheme, fastjet::Best);
//=============================================================================

  std::vector<fastjet::PseudoJet> fjInput;
  const double dMass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
//=============================================================================

  TList *list = new TList();
  TH1D *hJet = new TH1D("hJet", "", 1000, 0., 1000.); hJet->Sumw2(); list->Add(hJet);

  enum                    {  kJet,   kMje,   kDsz,   kIsm,   kZsm,   kDsr, kVar };
  const TString sHist[] = { "aJet", "aMje", "aDsz", "aIsm", "aZsm", "aDsr" };
  const Int_t      nv[] = {   1000,    150,  120,      150,    150,    500 };
  const Double_t dMin[] = {     0.,     0.,   0.,       0.,     0.,     0. };
  const Double_t dMax[] = {  1000.,   150.,  1.2,     150.,    1.5,     5. };

  THnSparseD *hs = new THnSparseD("hs", "", kVar, nv, dMin, dMax); hs->Sumw2();
  for (Int_t i=0; i<kVar; i++) hs->GetAxis(i)->SetName(sHist[i].Data()); list->Add(hs);
//=============================================================================

  HepMC::IO_GenEvent ascii_in(Form("%s/%s.hepmc",sPath.Data(),sFile.Data()), std::ios::in);
  HepMC::GenEvent *evt = ascii_in.read_next_event();

  while (evt) {
    fjInput.resize(0);

    TLorentzVector vPar;
    for (HepMC::GenEvent::particle_const_iterator p=evt->particles_begin(); p!=evt->particles_end(); ++p) if ((*p)->status()==1) {
      vPar.SetPtEtaPhiM((*p)->momentum().perp(), (*p)->momentum().eta(), (*p)->momentum().phi(), dMass);

      if ((TMath::Abs(vPar.Eta())<dCutEtaMax)) {
        fjInput.push_back(fastjet::PseudoJet(vPar.Px(), vPar.Py(), vPar.Pz(), vPar.E()));
      }
    }
//=============================================================================

    fastjet::ClusterSequenceArea clustSeq(fjInput, jetsDef, areaDef);
    std::vector<fastjet::PseudoJet> includJets = clustSeq.inclusive_jets(dJetsPtMin);
//  std::vector<fastjet::PseudoJet> subtedJets = bkgSubtractor(includJets);
    std::vector<fastjet::PseudoJet> selectJets = selectJet(includJets);
//  std::vector<fastjet::PseudoJet> sortedJets = fastjet::sorted_by_pt(selectJets);

    for (int j=0; j<selectJets.size(); j++) {
      double dJet = selectJets[j].pt();

      hJet->Fill(dJet);
//=============================================================================

      fastjet::Filter trimmer(subjDef, fastjet::SelectorPtFractionMin(0.));
      fastjet::PseudoJet trimmdJet = trimmer(selectJets[j]);
      std::vector<fastjet::PseudoJet> trimmdSj = trimmdJet.pieces();

      double d1sj = -1.; int k1sj = -1;
      double d2sj = -1.; int k2sj = -1;
      for (int i=0; i<trimmdSj.size(); i++) {
        double dIsj = trimmdSj[i].pt(); if (dIsj<0.001) continue;

        if (dIsj>d1sj) {
          d2sj = d1sj; k2sj = k1sj;
          d1sj = dIsj; k1sj = i;
        } else if (dIsj>d2sj) {
          d2sj = dIsj; k2sj = i;
        }
      }

      if ((d1sj>0.) && (d2sj>0.)) {
        TLorentzVector v1sj; v1sj.SetPtEtaPhiM(d1sj, trimmdSj[k1sj].eta(), trimmdSj[k1sj].phi(), trimmdSj[k1sj].m());
        TLorentzVector v2sj; v2sj.SetPtEtaPhiM(d2sj, trimmdSj[k2sj].eta(), trimmdSj[k2sj].phi(), trimmdSj[k2sj].m());
        TLorentzVector vIsj = v1sj + v2sj;

        Double_t dIsm = vIsj.M();
        Double_t dMje = selectJets[j].m();
        Double_t dVar[] = { dJet, dMje, (d1sj-d2sj)/dJet, dIsm, dIsm/dMje, v1sj.DeltaR(v2sj)/2./dJetR };

        hs->Fill(dVar);
      }
    }
//=============================================================================

    delete evt;
    ascii_in >> evt;
  }
//=============================================================================

  TString sXsec = sFile; sXsec.ReplaceAll("out", "xsecs");
  TFile *file = TFile::Open(Form("%s/xsecs/%s.root",sPath.Data(),sXsec.Data()), "READ");
  TH1D *hPtHat        = (TH1D*)file->Get("hPtHat");        hPtHat->SetDirectory(0);
  TH1D *hWeightSum    = (TH1D*)file->Get("hWeightSum");    hWeightSum->SetDirectory(0);
  TProfile *hSigmaGen = (TProfile*)file->Get("hSigmaGen"); hSigmaGen->SetDirectory(0);
  file->Close();
//=============================================================================

  file = TFile::Open(Form("%s.root",sFile.Data()), "NEW");
  hPtHat->Write();
  hWeightSum->Write();
  hSigmaGen->Write();
  list->Write();
  file->Close();
//=============================================================================

  cout << "DONE" << endl;
  return 0;
}
Exemple #12
0
int main(int argc, char* argv[])
{
  TApplication theApp(srcName.Data(), &argc, argv);
//=============================================================================

  if (argc<5) return -1;
  TString sPath = argv[1]; if (sPath.IsNull()) return -1;
  TString sFile = argv[2]; if (sFile.IsNull()) return -1;
  TString sJetR = argv[3]; if (sJetR.IsNull()) return -1;
  TString sSjeR = argv[4]; if (sSjeR.IsNull()) return -1;
//=============================================================================

  sPath.ReplaceAll("#", "/");
//=============================================================================

  double dJetR = -1.;
  if (sJetR=="JetR02") dJetR = 0.2;
  if (sJetR=="JetR03") dJetR = 0.3;
  if (sJetR=="JetR04") dJetR = 0.4;
  if (sJetR=="JetR05") dJetR = 0.5;

  if (dJetR<0.) return -1;
  cout << "Jet R = " << dJetR << endl;
//=============================================================================

  double dSjeR = -1.;
  if (sSjeR=="SjeR01") dSjeR = 0.1;
  if (sSjeR=="SjeR02") dSjeR = 0.2;
  if (sSjeR=="SjeR03") dSjeR = 0.3;
  if (sSjeR=="SjeR04") dSjeR = 0.4;

  if (dSjeR<0.) return -1;
  cout << "Sub-jet R = " << dSjeR << endl;
//=============================================================================

  const double dJetsPtMin  = 0.1;
  const double dJetEtaMax  = 2.;
  const double dCutEtaMax  = 2.6;

  fastjet::GhostedAreaSpec areaSpc(dCutEtaMax);
  fastjet::JetDefinition   jetsDef(fastjet::antikt_algorithm, dJetR, fastjet::BIpt_scheme, fastjet::Best);
  fastjet::AreaDefinition  areaDef(fastjet::active_area_explicit_ghosts,areaSpc);

  fastjet::Selector selectJet = fastjet::SelectorAbsEtaMax(dJetEtaMax);
  fastjet::JetDefinition subjDef(fastjet::kt_algorithm, dSjeR, fastjet::BIpt_scheme, fastjet::Best);
//=============================================================================

  std::vector<fastjet::PseudoJet> fjInput;
//=============================================================================

  TFile *file = TFile::Open(Form("%s.root",sFile.Data()), "NEW");
  TList *list = new TList();

  TH1D *hWeightSum = new TH1D("hWeightSum", "", 1, 0., 1.); list->Add(hWeightSum);

  TH2D *hTrkPtEta = new TH2D("hTrkPtEta", "", 1000, 0., 500., 60, -3., 3.); hTrkPtEta->Sumw2(); list->Add(hTrkPtEta);
  TH2D *hTrkPtPhi = new TH2D("hTrkPtPhi", "", 1000, 0., 500., 20, -1., 1.); hTrkPtPhi->Sumw2(); list->Add(hTrkPtPhi);

  TH2D *hJetPtNsj = new TH2D("hJetPtNsj", "", 1000, 0., 1000., 100, -0.5, 99.5); hJetPtNsj->Sumw2(); list->Add(hJetPtNsj);


  TH2D *hJetPtEta = new TH2D("hJetPtEta", "", 1000, 0., 1000., 60, -3., 3.); hJetPtEta->Sumw2(); list->Add(hJetPtEta);
  TH2D *hJetPtPhi = new TH2D("hJetPtPhi", "", 1000, 0., 1000., 20, -1., 1.); hJetPtPhi->Sumw2(); list->Add(hJetPtPhi);

  TH2D *hLjePtEta = new TH2D("hLjePtEta", "", 1000, 0., 1000., 60, -3., 3.); hLjePtEta->Sumw2(); list->Add(hLjePtEta);
  TH2D *hLjePtPhi = new TH2D("hLjePtPhi", "", 1000, 0., 1000., 20, -1., 1.); hLjePtPhi->Sumw2(); list->Add(hLjePtPhi);

  TH2D *hNjePtEta = new TH2D("hNjePtEta", "", 1000, 0., 1000., 60, -3., 3.); hNjePtEta->Sumw2(); list->Add(hNjePtEta);
  TH2D *hNjePtPhi = new TH2D("hNjePtPhi", "", 1000, 0., 1000., 20, -1., 1.); hNjePtPhi->Sumw2(); list->Add(hNjePtPhi);


  TH2D *hJe2PtEta = new TH2D("hJe2PtEta", "", 1000, 0., 1000., 60, -3., 3.); hJe2PtEta->Sumw2(); list->Add(hJe2PtEta);
  TH2D *hJe2PtPhi = new TH2D("hJe2PtPhi", "", 1000, 0., 1000., 20, -1., 1.); hJe2PtPhi->Sumw2(); list->Add(hJe2PtPhi);

  TH2D *hLj2PtEta = new TH2D("hLj2PtEta", "", 1000, 0., 1000., 60, -3., 3.); hLj2PtEta->Sumw2(); list->Add(hLj2PtEta);
  TH2D *hLj2PtPhi = new TH2D("hLj2PtPhi", "", 1000, 0., 1000., 20, -1., 1.); hLj2PtPhi->Sumw2(); list->Add(hLj2PtPhi);

  TH2D *hNj2PtEta = new TH2D("hNj2PtEta", "", 1000, 0., 1000., 60, -3., 3.); hNj2PtEta->Sumw2(); list->Add(hNj2PtEta);
  TH2D *hNj2PtPhi = new TH2D("hNj2PtPhi", "", 1000, 0., 1000., 20, -1., 1.); hNj2PtPhi->Sumw2(); list->Add(hNj2PtPhi);
//=============================================================================

  HepMC::IO_GenEvent ascii_in(Form("%s/%s.hepmc",sPath.Data(),sFile.Data()), std::ios::in);
  HepMC::GenEvent *evt = ascii_in.read_next_event();

  while (evt) {
    fjInput.resize(0);
    double dWeight = evt->weights().back();
    double dXsect  = evt->cross_section()->cross_section() / 1e9;
    double dNorm   = dWeight * dXsect;
    hWeightSum->Fill(0.5, dWeight);

    TVector3 vTrk;
    for (HepMC::GenEvent::particle_const_iterator p=evt->particles_begin(); p!=evt->particles_end(); ++p) if ((*p)->status()==1) {
      double dTrkPt  = (*p)->momentum().perp(); if (dTrkPt<0.5) continue;
      double dTrkEta = (*p)->momentum().eta();  if (TMath::Abs(dTrkEta)>dCutEtaMax) continue;
      double dTrkPhi = (*p)->momentum().phi();  vTrk.SetPtEtaPhi(dTrkPt, dTrkEta, dTrkPhi);
      double dTrkCos = TMath::Cos(dTrkPhi); if (dTrkCos==1.) dTrkCos = 1. - 1e-6;

      fjInput.push_back(fastjet::PseudoJet(vTrk.Px(), vTrk.Py(), vTrk.Pz(), vTrk.Mag()));

      hTrkPtEta->Fill(dTrkPt, dTrkEta, dNorm);
      hTrkPtPhi->Fill(dTrkPt, dTrkCos, dNorm);
    }
//=============================================================================

    fastjet::ClusterSequenceArea clustSeq(fjInput, jetsDef, areaDef);
    std::vector<fastjet::PseudoJet> includJets = clustSeq.inclusive_jets(dJetsPtMin);
    std::vector<fastjet::PseudoJet> selectJets = selectJet(includJets);
    std::vector<fastjet::PseudoJet> sortedJets = fastjet::sorted_by_pt(selectJets);
//=============================================================================

    for (int j=0; j<sortedJets.size(); j++) {
      double dJetPt  = sortedJets[j].pt();
      double dJetEta = sortedJets[j].eta();
      double dJetPhi = sortedJets[j].phi();
      double dJetCos = TMath::Cos(dJetPhi);
      if (dJetCos==1.) dJetCos = 1. - 1e-6;

      fastjet::Filter trimmer(subjDef, fastjet::SelectorPtFractionMin(0.));
      fastjet::PseudoJet trimmdJet = trimmer(sortedJets[j]);
      std::vector<fastjet::PseudoJet> trimmdSj = trimmdJet.pieces();

      int nSje = 0;
      for (int i=0; i<trimmdSj.size(); i++) if (trimmdSj[i].pt()>0.1) { nSje += 1; }
      hJetPtNsj->Fill(dJetPt, nSje, dNorm);

      hJetPtEta->Fill(dJetPt, dJetEta, dNorm); hJetPtPhi->Fill(dJetPt, dJetCos, dNorm);
      if (j==0) { hLjePtEta->Fill(dJetPt, dJetEta, dNorm); hLjePtPhi->Fill(dJetPt, dJetCos, dNorm); }
      if (j==1) { hNjePtEta->Fill(dJetPt, dJetEta, dNorm); hNjePtPhi->Fill(dJetPt, dJetCos, dNorm); }

      if (nSje>=2) {
        hJe2PtEta->Fill(dJetPt, dJetEta, dNorm); hJe2PtPhi->Fill(dJetPt, dJetCos, dNorm);
        if (j==0) { hLj2PtEta->Fill(dJetPt, dJetEta, dNorm); hLj2PtPhi->Fill(dJetPt, dJetCos, dNorm); }
        if (j==1) { hNj2PtEta->Fill(dJetPt, dJetEta, dNorm); hNj2PtPhi->Fill(dJetPt, dJetCos, dNorm); }
      }
    }
//=============================================================================

    delete evt;
    ascii_in >> evt;
  }
//=============================================================================

  file->cd(); list->Write(); file->Close();
//=============================================================================

  cout << "DONE" << endl;
//=============================================================================

  return 0;
}
Exemple #13
0
bool HepMC2_Interface::Sherpa2HepMC(ATOOLS::Blob_List *const blobs,
                                    HepMC::GenEvent& event, double weight)
{
#ifdef USING__HEPMC2__UNITS
  event.use_units(HepMC::Units::GEV,
                  HepMC::Units::MM);
#endif
  event.set_event_number(ATOOLS::rpa->gen.NumberOfGeneratedEvents());
  size_t decid(11);
  std::map<size_t,size_t> decids;
  Blob *sp(blobs->FindFirst(btp::Signal_Process));
  if (sp) {
    Blob_Data_Base *info((*sp)["Decay_Info"]);
    if (info) {
      DecayInfo_Vector decs(info->Get<DecayInfo_Vector>());
      for (size_t i(0);i<decs.size();++i) decids[decs[i]->m_id]=++decid;
    }
  }
  m_blob2genvertex.clear();
  m_particle2genparticle.clear();
  HepMC::GenVertex * vertex;
  std::vector<HepMC::GenParticle*> beamparticles;
  for (ATOOLS::Blob_List::iterator blit=blobs->begin();
       blit!=blobs->end();++blit) {
    if (Sherpa2HepMC(*(blit),vertex,decids)) {
      event.add_vertex(vertex);
      if ((*blit)->Type()==ATOOLS::btp::Signal_Process) {
        if ((**blit)["NLO_subeventlist"]) {
          THROW(fatal_error,"Events containing correlated subtraction events"
                +std::string(" cannot be translated into the full HepMC event")
                +std::string(" format.\n")
                +std::string("   Try 'EVENT_OUTPUT=HepMC_Short' instead."));
        }
        event.set_signal_process_vertex(vertex);
        if((*blit)->NInP()==2) {
          kf_code fl1=(*blit)->InParticle(0)->Flav().HepEvt();
          kf_code fl2=(*blit)->InParticle(1)->Flav().HepEvt();
          double x1=(*blit)->InParticle(0)->Momentum()[0]/rpa->gen.PBeam(0)[0];
          double x2=(*blit)->InParticle(1)->Momentum()[0]/rpa->gen.PBeam(1)[0];
          double q(0.0), p1(0.0), p2(0.0);
          Blob_Data_Base *facscale((**blit)["Factorisation_Scale"]);
	  if (facscale) q=sqrt(facscale->Get<double>());
	  Blob_Data_Base *xf1((**blit)["XF1"]);
          Blob_Data_Base *xf2((**blit)["XF2"]);
          if (xf1) p1=xf1->Get<double>();
          if (xf2) p2=xf2->Get<double>();
	  HepMC::PdfInfo pdfinfo(fl1, fl2, x1, x2, q, p1, p2);
          event.set_pdf_info(pdfinfo);
        }
      }
      else if ((*blit)->Type()==ATOOLS::btp::Beam || 
	       (*blit)->Type()==ATOOLS::btp::Bunch) {
        for (HepMC::GenVertex::particles_in_const_iterator 
	       pit=vertex->particles_in_const_begin();
             pit!=vertex->particles_in_const_end(); ++pit) {
          if ((*pit)->production_vertex()==NULL) {
            beamparticles.push_back(*pit);
          }
        }
      }
    }
  }
  if (beamparticles.size()==2) {
    event.set_beam_particles(beamparticles[0],beamparticles[1]);
  }
  std::vector<double> weights;
  weights.push_back(weight);
  if (sp) {
    Blob_Data_Base *info((*sp)["MEWeight"]);
    if (!info) THROW(fatal_error,"Missing weight info.");
    double meweight(info->Get<double>());
    weights.push_back(meweight);
    Blob_Data_Base *ofni((*sp)["Weight_Norm"]);
    if (!ofni) THROW(fatal_error,"Missing weight normalisation.");
    double weightnorm(ofni->Get<double>());
    weights.push_back(weightnorm);
    ofni=(*sp)["Trials"];
    if (!ofni) THROW(fatal_error,"Missing nof trials.");
    double trials(ofni->Get<double>());
    weights.push_back(trials);
  }
  event.weights()=weights;
  return true;
}
Exemple #14
0
bool HepMC2_Interface::Sherpa2ShortHepMC(ATOOLS::Blob_List *const blobs,
                                         HepMC::GenEvent& event, double weight)
{
#ifdef USING__HEPMC2__UNITS
  event.use_units(HepMC::Units::GEV,
                  HepMC::Units::MM);
#endif
  event.set_event_number(ATOOLS::rpa->gen.NumberOfGeneratedEvents());
  HepMC::GenVertex * vertex=new HepMC::GenVertex();
  std::vector<HepMC::GenParticle*> beamparticles;
  std::vector<std::pair<HepMC::FourVector,int> > beamparts,
                                                 remnantparts1, remnantparts2;
  Blob *sp(blobs->FindFirst(btp::Signal_Process));
  NLO_subevtlist* subevtlist(NULL);
  ME_wgtinfo* wgtinfo(0);
  
  if (sp) {
    Blob_Data_Base* seinfo=(*sp)["ME_wgtinfo"];
    if (seinfo) wgtinfo=seinfo->Get<ME_wgtinfo*>();
   
    Blob_Data_Base * bdb((*sp)["NLO_subeventlist"]);
    if (bdb) subevtlist=bdb->Get<NLO_subevtlist*>();
  }
  for (ATOOLS::Blob_List::iterator blit=blobs->begin();
       blit!=blobs->end();++blit) {
    Blob* blob=*blit;
    for (int i=0;i<blob->NInP();i++) {
      if (blob->InParticle(i)->ProductionBlob()==NULL) {
        Particle* parton=blob->InParticle(i);
        ATOOLS::Vec4D mom  = parton->Momentum();
        HepMC::FourVector momentum(mom[1],mom[2],mom[3],mom[0]);
        HepMC::GenParticle* inpart = 
	  new HepMC::GenParticle(momentum,parton->Flav().HepEvt(),2);
        vertex->add_particle_in(inpart);
        // distinct because SHRIMPS has no bunches for some reason
        if (blob->Type()==btp::Beam || blob->Type()==btp::Bunch) {
          beamparticles.push_back(inpart);
          beamparts.push_back(std::make_pair(momentum,parton->Flav().HepEvt()));
        }
      }
    }
    for (int i=0;i<blob->NOutP();i++) {
      if (blob->OutParticle(i)->DecayBlob()==NULL) {
        Particle* parton=blob->OutParticle(i);
        ATOOLS::Vec4D mom  = parton->Momentum();
        HepMC::FourVector momentum(mom[1],mom[2],mom[3],mom[0]);
        HepMC::GenParticle* outpart = 
	  new HepMC::GenParticle(momentum,parton->Flav().HepEvt(),1);
        vertex->add_particle_out(outpart);
        if (blob->Type()==btp::Beam) {
          if      (mom[3]>0) 
	    remnantparts1.push_back(std::make_pair(momentum,
						   parton->Flav().HepEvt()));
          else if (mom[3]<0) 
	    remnantparts2.push_back(std::make_pair(momentum,
						   parton->Flav().HepEvt()));
          else THROW(fatal_error,"Ill defined beam remnants.");
        }
      }
    }
    
    if ((*blit)->Type()==ATOOLS::btp::Signal_Process) {
      if((*blit)->NInP()==2) {
        kf_code fl1=(*blit)->InParticle(0)->Flav().HepEvt();
        kf_code fl2=(*blit)->InParticle(1)->Flav().HepEvt();
        double x1=(*blit)->InParticle(0)->Momentum()[0]/rpa->gen.PBeam(0)[0];
        double x2=(*blit)->InParticle(1)->Momentum()[0]/rpa->gen.PBeam(1)[0];
        double q(0.0), p1(0.0), p2(0.0);
        Blob_Data_Base *facscale((**blit)["Factorisation_Scale"]);
        if (facscale) q=sqrt(facscale->Get<double>());
	Blob_Data_Base *xf1((**blit)["XF1"]);
        Blob_Data_Base *xf2((**blit)["XF2"]);
        if (xf1) p1=xf1->Get<double>();
        if (xf2) p2=xf2->Get<double>();
	HepMC::PdfInfo pdfinfo(fl1, fl2, x1, x2, q, p1, p2);
	event.set_pdf_info(pdfinfo);
      }
    }
  }
  event.add_vertex(vertex);
  if (beamparticles.size()==2) {
    event.set_beam_particles(beamparticles[0],beamparticles[1]);
  }
  std::vector<double> weights; weights.push_back(weight);
  if (sp && !subevtlist) {
    Blob_Data_Base *info;
    info=((*sp)["MEWeight"]);
    if (!info) THROW(fatal_error,"Missing weight info.");
    double meweight(info->Get<double>());
    weights.push_back(meweight);
    info=((*sp)["Weight_Norm"]);
    if (!info) THROW(fatal_error,"Missing weight normalisation.");
    double weightnorm(info->Get<double>());
    weights.push_back(weightnorm);
    info=(*sp)["Trials"];
    if (!info) THROW(fatal_error,"Missing nof trials.");
    double trials(info->Get<double>());
    weights.push_back(trials);
    //alphaS value && power
    double rscale2 = (*sp)["Renormalization_Scale"]->Get<double>();
    double alphaS = MODEL::s_model->ScalarFunction("alpha_S",rscale2);
    event.set_alphaQCD(alphaS);
    double aSpower = ((*sp)["OQCD"])->Get<int>();
    weights.push_back(aSpower);
    
    if (wgtinfo) {
      //dump weight_0
      weights.push_back(wgtinfo->m_w0);
      //dump number of usr weights
      weights.push_back(wgtinfo->m_nx);
      //store xprimes
      weights.push_back(wgtinfo->m_y1);
      weights.push_back(wgtinfo->m_y2);
      //fill in usr weights
      for (int i=0;i<wgtinfo->m_nx;i++) {
	weights.push_back(wgtinfo->p_wx[i]);
      }
    }
  }
  
  event.weights()=weights;

  if (subevtlist) {
    // build GenEvent for all subevts (where only the signal is available)
    // use stored beam & remnant particles from above
    // sub->m_flip==1 -> momenta need to be inverted for analyses
    for (size_t i(0);i<subevtlist->size();++i) {
      NLO_subevt * sub((*subevtlist)[i]);
      if (sub->m_result==0.) continue;
      HepMC::GenVertex * subvertex(new HepMC::GenVertex());
      HepMC::GenEvent * subevent(new HepMC::GenEvent());
      // assume that only 2->(n-2) processes
      HepMC::GenParticle *beam[2];
      if (beamparts.size()==2) {
        for (size_t j(0);j<beamparts.size();++j) {
          beam[j] = new HepMC::GenParticle(beamparts[j].first,
                                           beamparts[j].second,2);
          subvertex->add_particle_in(beam[j]);
        }
      }
      else {
        const ATOOLS::Vec4D *mom(sub->p_mom);
        const ATOOLS::Flavour *fl(sub->p_fl);
        for (size_t j(0);j<2;++j) {
          HepMC::FourVector momentum;
          momentum.set( mom[j][1], mom[j][2], mom[j][3],mom[j][0]);
          ATOOLS::Flavour flc(fl[j]);
          HepMC::GenParticle* inpart
              = new HepMC::GenParticle(momentum,flc.HepEvt(),2);
          subvertex->add_particle_in(inpart);
        }
      }
      const ATOOLS::Vec4D *mom(sub->p_mom);
      const ATOOLS::Flavour *fl(sub->p_fl);
      for (size_t j(2);j<(*subevtlist)[i]->m_n;++j) {
        HepMC::FourVector momentum;
	momentum.set( mom[j][1], mom[j][2], mom[j][3],mom[j][0]);
        ATOOLS::Flavour flc(fl[j]);
        HepMC::GenParticle* outpart
            = new HepMC::GenParticle(momentum,flc.HepEvt(),1);
        subvertex->add_particle_out(outpart);
      }
      // if beamremnants are present:
      // scale beam remnants of real event for energy momentum conservation :
      //   flavours might not add up properly for sub events,
      //   but who cares. they go down the beam pipe.
      // also assume they are all massless :
      //   this will give momentum conservation violations
      //   which are collider dependent only
      //
      //   for real event (as constructed in BRH) :
      //
      //     P = p + \sum r_i  with  P^2 = m^2  and  r_i^2 = p^2 = 0
      //
      //     further  P  = ( P^0 , 0 , 0 , P^z )
      //              p  = (  p  , 0 , 0 ,  p  )
      //             r_i = ( r_i , 0 , 0 , r_i )
      //
      //     => P^0 = p + \sum r_i
      //        P^z = \sqrt{(P^0)^2 - m^2} <  p + \sum r_i
      //
      // in a mass-symmetric collider, the excess is the same for both beams
      // ensuring momentum conservation
      //
      //   for sub event (constructed here):
      //
      //     P = p~ + \sum r_i~ = p~ + \sum u*r_i
      //
      //     where u = ( P^0 - p^0~ ) / \sum r_i^0
      //
      //     again, the r_i~ = u*r_i are constructed such that
      //
      //     => P^0 = p~ + \sum u*r_i
      //        P^z = \sqrt{(P^0)^2 - m^2} <  p~ + \sum u*r_i =  p + \sum r_i
      //
      //     leading to the same momentum conservation violations per beam
      //
      if (remnantparts1.size()!=0 && remnantparts2.size()!=0) {
        double res1(0.),res2(0.);
        for (size_t j(0);j<remnantparts1.size();++j) {
          res1+=remnantparts1[j].first.e();
        }
        for (size_t j(0);j<remnantparts2.size();++j) {
          res2+=remnantparts2[j].first.e();
        }
        ATOOLS::Vec4D hardparton[2];
        for (size_t j(0);j<2;++j) {
	  hardparton[j]=ATOOLS::Vec4D(mom[j][0],Vec3D( mom[j]));
        }
        // incoming partons might need to be flipped due to particle sorting
        bool flip(hardparton[0][3]<0);
        double u1((beamparts[0].first.e()-hardparton[flip?1:0][0])/res1);
        double u2((beamparts[1].first.e()-hardparton[flip?0:1][0])/res2);
        // filling
        for (size_t j(0);j<remnantparts1.size();++j) {
          HepMC::FourVector momentum(u1*remnantparts1[j].first.px(),
                                     u1*remnantparts1[j].first.py(),
                                     u1*remnantparts1[j].first.pz(),
                                     u1*remnantparts1[j].first.e());
          HepMC::GenParticle* outpart
              = new HepMC::GenParticle(momentum,remnantparts1[j].second,1);
          subvertex->add_particle_out(outpart);
        }
        for (size_t j(0);j<remnantparts2.size();++j) {
          HepMC::FourVector momentum(u2*remnantparts2[j].first.px(),
                                     u2*remnantparts2[j].first.py(),
                                     u2*remnantparts2[j].first.pz(),
                                     u2*remnantparts2[j].first.e());
          HepMC::GenParticle* outpart
              = new HepMC::GenParticle(momentum,remnantparts2[j].second,1);
          subvertex->add_particle_out(outpart);
        }
        if (beamparticles.size()==2) {
          subevent->set_beam_particles(beam[0],beam[1]);
        }
      }
      subevent->add_vertex(subvertex);
      // not enough info in subevents to set PDFInfo properly,
      // so set only flavours, x1, x2, and q from the Signal_Process
      HepMC::PdfInfo subpdfinfo(*event.pdf_info());
      double q = sqrt(sub->m_mu2[stp::fac]);
      if (q!=0. && q != subpdfinfo.scalePDF()) 
        subpdfinfo.set_scalePDF(q);
      if (sub->m_xf1) subpdfinfo.set_pdf1(sub->m_xf1);
      if (sub->m_xf2) subpdfinfo.set_pdf2(sub->m_xf2);
      subevent->set_pdf_info(subpdfinfo);
      // add weight
      std::vector<double> subweight; subweight.push_back(sub->m_result);
      Blob_Data_Base *info;
      info=((*sp)["MEWeight"]);
      if (!info) THROW(fatal_error,"Missing weight info.");
      double meweight(info->Get<double>());
      subweight.push_back(meweight);
      info=((*sp)["Weight_Norm"]);
      if (!info) THROW(fatal_error,"Missing weight normalisation.");
      double weightnorm(info->Get<double>());
      subweight.push_back(weightnorm);
      info=(*sp)["Trials"];
      if (!info) THROW(fatal_error,"Missing nof trials.");
      double trials(info->Get<double>());
      subweight.push_back(trials);
      //alphaS value && power
      double alphaS = MODEL::s_model->ScalarFunction("alpha_S",sub->m_mu2[stp::ren]);
      subevent->set_alphaQCD(alphaS);
      double aSpower = ((*sp)["OQCD"])->Get<int>();
      subweight.push_back(aSpower);
      subweight.push_back(sub->m_mewgt);
      
      if (wgtinfo) {
	//dump number of usr weights
	subweight.push_back(wgtinfo->m_nx);
	//store xprimes
	subweight.push_back(wgtinfo->m_y1);
	subweight.push_back(wgtinfo->m_y2);
	//fill in usr weights
	for (int i=0;i<wgtinfo->m_nx;i++) {
	  subweight.push_back(wgtinfo->p_wx[i]);
	}
      }
      //
      subevent->weights()=subweight;
      // set the event number (could be used to identify correlated events)
      subevent->set_event_number(ATOOLS::rpa->gen.NumberOfGeneratedEvents());
      m_subeventlist.push_back(subevent);
    }
  }
  return true;
}
Exemple #15
0
int main(int argc, char* argv[])
{
  TApplication theApp(srcName.Data(), &argc, argv);
//=============================================================================

  if (argc<5) return -1;
  TString sPath = argv[1]; if (sPath.IsNull()) return -1;
  TString sFile = argv[2]; if (sFile.IsNull()) return -1;
  TString sJetR = argv[3]; if (sJetR.IsNull()) return -1;
  TString sSjeR = argv[4]; if (sSjeR.IsNull()) return -1;
//=============================================================================

  sPath.ReplaceAll("#", "/");
//=============================================================================

  double dJetR = -1.;
  if (sJetR=="JetR02") dJetR = 0.2;
  if (sJetR=="JetR03") dJetR = 0.3;
  if (sJetR=="JetR04") dJetR = 0.4;
  if (sJetR=="JetR05") dJetR = 0.5;

  if (dJetR<0.) return -1;
  cout << "Jet R = " << dJetR << endl;
//=============================================================================

  double dSjeR = -1.;
  if (sSjeR=="SjeR01") dSjeR = 0.1;
  if (sSjeR=="SjeR02") dSjeR = 0.2;
  if (sSjeR=="SjeR03") dSjeR = 0.3;
  if (sSjeR=="SjeR04") dSjeR = 0.4;

  if (dSjeR<0.) return -1;
  cout << "Sub-jet R = " << dSjeR << endl;
//=============================================================================

  const double dJetsPtMin  = 0.001;
  const double dCutEtaMax  = 1.6;
  const double dJetEtaMax  = 1.;
  const double dJetAreaRef = TMath::Pi() * dJetR * dJetR;

  fastjet::GhostedAreaSpec areaSpc(dCutEtaMax);
  fastjet::JetDefinition   jetsDef(fastjet::antikt_algorithm, dJetR, fastjet::E_scheme, fastjet::Best);
  fastjet::AreaDefinition  areaDef(fastjet::active_area_explicit_ghosts,areaSpc);


  fastjet::Selector selectJet = fastjet::SelectorAbsEtaMax(dJetEtaMax);
  fastjet::JetDefinition subjDef(fastjet::kt_algorithm, dSjeR, fastjet::E_scheme, fastjet::Best);
//=============================================================================

  std::vector<fastjet::PseudoJet> fjInput;
  const double dMass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
//=============================================================================

  enum { kWgt, kJet, kAje, kMje, k1sz, k1sA, k1sr, k1sm, k2sz, k2sA, k2sr, k2sm, kDsr, kIsm, kVar };

  TFile *file = TFile::Open(Form("%s.root",sFile.Data()), "NEW");
  TNtuple *nt = new TNtuple("nt", "", "fWgt:fJet:fAje:fMje:f1sj:f1sA:f1sr:f1sm:f2sj:f2sA:f2sr:f2sm:fDsr:fIsm");
//=============================================================================

  HepMC::IO_GenEvent ascii_in(Form("%s/%s.hepmc",sPath.Data(),sFile.Data()), std::ios::in);
  HepMC::GenEvent *evt = ascii_in.read_next_event();

  while (evt) {
    fjInput.resize(0);

    TLorentzVector vPar;
    for (HepMC::GenEvent::particle_const_iterator p=evt->particles_begin(); p!=evt->particles_end(); ++p) if ((*p)->status()==1) {
      vPar.SetPtEtaPhiM((*p)->momentum().perp(), (*p)->momentum().eta(), (*p)->momentum().phi(), dMass);

      if ((TMath::Abs(vPar.Eta())<dCutEtaMax)) {
        fjInput.push_back(fastjet::PseudoJet(vPar.Px(), vPar.Py(), vPar.Pz(), vPar.E()));
      }
    }
//=============================================================================

    fastjet::ClusterSequenceArea clustSeq(fjInput, jetsDef, areaDef);
    std::vector<fastjet::PseudoJet> includJets = clustSeq.inclusive_jets(dJetsPtMin);
    std::vector<fastjet::PseudoJet> selectJets = selectJet(includJets);

    TLorentzVector vJet, v1sj, v2sj, vIsj;
    for (int j=0; j<selectJets.size(); j++) {
      double dJet = selectJets[j].pt();
      vJet.SetPtEtaPhiM(dJet, selectJets[j].eta(), selectJets[j].phi(), selectJets[j].m());

      fastjet::Filter trimmer(subjDef, fastjet::SelectorPtFractionMin(0.));
      fastjet::PseudoJet trimmdJet = trimmer(selectJets[j]);
      std::vector<fastjet::PseudoJet> trimmdSj = trimmdJet.pieces();

      double d1sj = -1.; int k1sj = -1;
      double d2sj = -1.; int k2sj = -1;
      for (int i=0; i<trimmdSj.size(); i++) {
        double dIsj = trimmdSj[i].pt(); if (dIsj<0.001) continue;

        if (dIsj>d1sj) {
          d2sj = d1sj; k2sj = k1sj;
          d1sj = dIsj; k1sj = i;
        } else if (dIsj>d2sj) {
          d2sj = dIsj; k2sj = i;
        }
      }
//=============================================================================

      Float_t dVar[] = { 1., dJet, selectJets[j].area(), selectJets[j].m(), d1sj, -1., -1., -1., d2sj, -1., -1., -1., -1., -1. };

      if (d1sj>0.) {
        v1sj.SetPtEtaPhiM(d1sj, trimmdSj[k1sj].eta(), trimmdSj[k1sj].phi(), trimmdSj[k1sj].m());
        dVar[k1sr] = v1sj.DeltaR(vJet);
        dVar[k1sm] = trimmdSj[k1sj].m();
        dVar[k1sA] = trimmdSj[k1sj].area();
      }

      if (d2sj>0.) {
        v2sj.SetPtEtaPhiM(d2sj, trimmdSj[k2sj].eta(), trimmdSj[k2sj].phi(), trimmdSj[k2sj].m());
        dVar[k2sr] = v2sj.DeltaR(vJet);
        dVar[k2sm] = trimmdSj[k2sj].m();
        dVar[k2sA] = trimmdSj[k2sj].area();
      }

      if ((d1sj>0.) && (d2sj>0.)) {
        vIsj = v1sj + v2sj;
        dVar[kIsm] = vIsj.M();
        dVar[kDsr] = v2sj.DeltaR(v1sj);
      }

      nt->Fill(dVar);
    }
//=============================================================================

    delete evt;
    ascii_in >> evt;
  }
//=============================================================================

  file->cd(); nt->Write(); file->Close();
//=============================================================================

  TString sXsec = sFile; sXsec.ReplaceAll("out", "xsecs");
  file = TFile::Open(Form("%s/xsecs/%s.root",sPath.Data(),sXsec.Data()), "READ");
  TH1D *hPtHat        = (TH1D*)file->Get("hPtHat");        hPtHat->SetDirectory(0);
  TH1D *hWeightSum    = (TH1D*)file->Get("hWeightSum");    hWeightSum->SetDirectory(0);
  TProfile *hSigmaGen = (TProfile*)file->Get("hSigmaGen"); hSigmaGen->SetDirectory(0);
  file->Close();
//=============================================================================

  sFile.ReplaceAll("out", "wgt");
  file = TFile::Open(Form("%s.root",sFile.Data()), "NEW");
  hPtHat->Write();
  hWeightSum->Write();
  hSigmaGen->Write();
  file->Close();
//=============================================================================

  cout << "DONE" << endl;
  return 0;
}
Exemple #16
0
bool Rivet_Interface::Run(ATOOLS::Blob_List *const bl)
{
  DEBUG_FUNC("");
  Particle_List pl=bl->ExtractParticles(1);
  for (Particle_List::iterator it=pl.begin(); it!=pl.end(); ++it) {
    if ((*it)->Momentum().Nan()) {
      msg_Error()<<METHOD<<" encountered NaN in momentum. Ignoring event:"
                 <<endl<<*bl<<endl;
      return false;
    }
  }

  double weight(bl->Weight());
  HepMC::GenEvent event;
  if (m_usehepmcshort)  m_hepmc2.Sherpa2ShortHepMC(bl, event, weight);
  else                  m_hepmc2.Sherpa2HepMC(bl, event, weight);
  std::vector<HepMC::GenEvent*> subevents(m_hepmc2.GenSubEventList());
#ifdef HEPMC_HAS_CROSS_SECTION
  // leave this, although will be overwritten later
  HepMC::GenCrossSection xs;
  xs.set_cross_section(p_eventhandler->TotalXS(), p_eventhandler->TotalErr());
  event.set_cross_section(xs);
  for (size_t i(0);i<subevents.size();++i) {
    subevents[i]->set_cross_section(xs);
  }
#endif

  // 1st event build index map, thereafter only lookup
  ExtractVariations(event,subevents);
  for (RivetScaleVariationMap::iterator it(m_rivet.begin());
       it!=m_rivet.end();++it) {
    msg_Debugging()<<"Running rivet for "<<it->first<<" with "
                   <<it->second->RivetMap().size()<<" histograms."<<std::endl;
    Rivet_Map& rivetmap(it->second->RivetMap());
    if (subevents.size()) {
      it->second->SynchroniseCrossSection();
      for (size_t i(0);i<subevents.size();++i) {
        SetEventWeight(it->second,*subevents[i],i);
        GetRivet(rivetmap,"", 0)->analyze(*subevents[i]);
      }
    }
    else {
      SetEventWeight(it->second,event);
      GetRivet(rivetmap,"",0)->analyze(event);
      Blob *sp(bl->FindFirst(btp::Signal_Process));
      size_t parts=0;
      if (sp) {
        std::string multi(sp?sp->TypeSpec():"");
        if (multi[3]=='_') multi=multi.substr(2,1);
        else multi=multi.substr(2,2);
        parts=ToType<size_t>(multi);
      }
      if (m_splitjetconts && sp) {
        GetRivet(rivetmap,"",parts)->analyze(event);
      }
      if (m_splitcoreprocs && sp) {
        GetRivet(rivetmap,GetCoreProc(sp->TypeSpec()),0)
            ->analyze(event);
        if (m_splitjetconts) {
          GetRivet(rivetmap,GetCoreProc(sp->TypeSpec()),parts)
              ->analyze(event);
        }
      }
      if (m_splitSH && sp) {
        std::string typespec=sp->TypeSpec();
        typespec=typespec.substr(typespec.length()-2, 2);
        std::string type="";
        if (typespec=="+S") type="S";
        else if (typespec=="+H") type="H";

        if (type!="") {
          GetRivet(rivetmap,type,0)->analyze(event);
          if (m_splitjetconts) {
            GetRivet(rivetmap,type,parts)->analyze(event);
          }
        }
      }
    }
  }
  if (subevents.size()) {
    ResetRivetScaleVariationMapRSWeights();
    m_hepmc2.DeleteGenSubEventList();
  }

  ++m_nevt;
  for (RivetScaleVariationMap::iterator it(m_rivet.begin());
       it!=m_rivet.end();++it) {
    msg_Debugging()<<"Checking rivet for "<<it->first<<" with "
                   <<it->second->RivetMap().size()<<" histograms."<<std::endl;
  }
  if (m_evtbyevtxs) {
    for (RivetScaleVariationMap::iterator mit(m_rivet.begin());
         mit!=m_rivet.end();++mit) {
      std::string out=m_outpath;
      if (mit->first!="" && mit->first!="nominal") out += "."+mit->first;
      std::string namestr(m_rivet.size()>1?" for "+mit->first:"");
      std::string output(std::string("**  Total XS")+namestr
                         +std::string(" = ( ")
                         +ToString(mit->second->TotalXS(),m_xsoutputprecision)
                         +std::string(" +- ")
                         +ToString(mit->second->TotalErr(),m_xsoutputprecision)
                         +std::string(" ) pb **"));
      std::string astline(output.size(),'*');
      msg_Info()<<astline<<"\n"<<output<<"\n"<<astline<<std::endl;
    }
  }
  return true;
}
Exemple #17
0
void Rivet_Interface::ExtractVariations(const HepMC::GenEvent& evt)
{
  DEBUG_FUNC("");
  const HepMC::WeightContainer& wc(evt.weights());
  std::map<std::string,double> wgtmap;
  double ntrials(1.);
  size_t xstype(0);
#ifdef HEPMC_HAS_NAMED_WEIGHTS
#ifdef HEPMC_HAS_WORKING_NAMED_WEIGHTS // replace by final HepMC-2.07 variable
  std::vector<std::string> keys(wc.keys());
  msg_Debugging()<<keys<<std::endl;
  for (size_t i(0);i<keys.size();++i) {
    std::string cur(keys[i]);
    if (m_splitvariations && cur.find("MUR")!=std::string::npos &&
                             cur.find("MUF")!=std::string::npos &&
                             cur.find("PDF")!=std::string::npos) {
      wgtmap[cur]=wc[cur];
    }
    else if (cur=="Weight")  wgtmap["nominal"]=wc[cur];
    else if (cur=="NTrials") ntrials=wc[cur];
    else if (cur=="Reweight_Type" && wc[cur]&64) xstype=1;
  }
#else
  // lookup all evt-wgts with name "MUR<fac>_MUF<fac>_PDF<id>"
  // at the moment the only way to do that is to filter the printout
  // accuracy limited to print out accu of 6 digits, must suffice
  MyStrStream str;
  str.precision(m_hepmcoutputprecision);
  wc.print(str);

  // need a temp object first, as we need to get ntrials first
  while (str) {
    double wgt(0.);
    std::string cur("");
    str>>cur;
    if (cur.length()==0) continue;
    // weight is between "," and trailing bracket
    // name is between leading bracket and ","
    wgt=ToType<double>(cur.substr(cur.find(",")+1,cur.find(")")-1));
    cur=cur.substr(1,cur.find(",")-1);
    if (m_splitvariations && cur.find("MUR")!=std::string::npos &&
                             cur.find("MUF")!=std::string::npos &&
                             cur.find("PDF")!=std::string::npos) {
      wgtmap[cur]=wgt;
    }
    else if (cur=="Weight")  wgtmap["nominal"]=wgt;
    else if (cur=="NTrials") ntrials=wgt;
    else if (cur=="Reweight_Type" && ((int)wgt)&64) xstype=1;
  }
#endif /* HEPMC_HAS_WORKING_NAMED_WEIGHTS */
#else
  wgtmap["nominal"]=wc[0];
  ntrials=wc[3];
  xstype=(((wc.size()==5&&((int)wc[4]&64))||(wc.size()==11&&((int)wc[10]&64)))?1:0);
#endif /* HEPMC_HAS_NAMED_WEIGHTS */
  if (msg_LevelIsDebugging()) {
    for (std::map<std::string,double>::iterator wit(wgtmap.begin());
         wit!=wgtmap.end();++wit)
      msg_Out()<<wit->first<<" : "<<wit->second<<std::endl;
  }
  // now construct or fill into the scale variation map
  for (std::map<std::string,double>::iterator wit(wgtmap.begin());
       wit!=wgtmap.end();++wit) {
    RivetScaleVariationMap::iterator rit=m_rivet.find(wit->first);
    if (rit==m_rivet.end()) {
      msg_Debugging()<<"creating new entry in m_rivet"<<std::endl;
      m_rivet[wit->first]=new Rivet_Scale_Variation(wit->first);
      m_rivet[wit->first]->AddPoint(wit->second,ntrials,xstype);
    }
    else rit->second->AddPoint(wit->second,ntrials,xstype);
  }
  if (msg_LevelIsDebugging()) {
    for (RivetScaleVariationMap::iterator rit(m_rivet.begin());
         rit!=m_rivet.end();++rit)
      msg_Out()<<rit->first<<" : "<<rit->second->Weight()<<std::endl;
  }
}
Exemple #18
0
int main(int argc, char ** argv) {

  std::cout << " -- Starting program..." << std::endl;

  const unsigned nZ = 100;
  const unsigned z0 = 100;
  const unsigned step = 2;

  //TFile *fout = TFile::Open("PLOTS/output_hepmc_vtxorig_MB.root","RECREATE");
  //TFile *fout = TFile::Open("PLOTS/output_hepmc_vtxmodif.root","RECREATE");
  TFile *fout = TFile::Open("PLOTS/output_hepmc_hggmodif.root","RECREATE");
  fout->cd();
  TH1F *hvtx_x = new TH1F("hvtx_x",";x (mm);vertices",1000,-10,10);
  TH1F *hvtx_y = new TH1F("hvtx_y",";y (mm);vertices",1000,-10,10);
  TH1F *hvtx_z = new TH1F("hvtx_z",";z (mm);vertices",1000,-500,500);
  TH1F *hvtx_t = new TH1F("hvtx_t",";t (ns);vertices",20000,-100,100);
  TH2F *hvtx_tvsz = new TH2F("hvtx_tvsz",";z (mm); t (ps);vertices",1000,-200,200,1200,-600,600);
  TH1F *hvtx_t_z[nZ];
  for (unsigned i(0);i<nZ;++i){
    std::ostringstream label;
    int zmin = -1*z0+i*step;
    int zmax = -1*z0+(i+1)*step;
    label << "hvtx_t_z_" << zmin << "_" << zmax;
    hvtx_t_z[i] = new TH1F(label.str().c_str(),";t (ps);vertices",120,-600,600);
  }
  TH1F *hProton = new TH1F("hProton",";p (GeV);particles",1000,0,100);
  TH1F *hNeutron = new TH1F("hNeutron",";p (GeV);particles",1000,0,100);
  TH1F *hPipm = new TH1F("hPipm",";p (GeV);particles",1000,0,100);
  TH1F *hProtonLog = new TH1F("hProtonLog",";log(p) (log(GeV));particles",100,-2,2);
  TH1F *hNeutronLog = new TH1F("hNeutronLog",";log(p) (log(GeV));particles",100,-2,2);
  TH1F *hPipmLog = new TH1F("hPipmLog",";log(p) (log(GeV));particles",100,-2,2);

  const unsigned nFiles = 1;//6;

  for (unsigned i(0);i<nFiles;++i){

    // specify an input file
    std::ostringstream lname;
    //lname << "/afs/cern.ch/work/p/pdauncey/public/Pythia140305_";
    //if (i==0) lname << "000000";
    //else if (i<10) lname << "00000" << i;
    //else if (i<100) lname << "0000" << i;
    //else if (i<1000) lname << "000" << i;
    //else if (i<10000) lname << "00" << i;
    //else if (i<100000) lname << "0" << i;
    //else lname << i;
    //lname << ".dat";
    //lname << "/afs/cern.ch/work/a/amagnan/public/HepMCFiles/ggHgg_origVtx.dat";
    //lname << "/afs/cern.ch/work/a/amagnan/public/HepMCFiles/ggHgg_modifyVtx.dat";
    //lname << "/afs/cern.ch/work/a/amagnan/public/HepMCFiles/vertexHLLHC.dat";
    //lname << "/afs/cern.ch/work/p/pdauncey/public/Pythia140305_000000.dat";
    lname << "/afs/cern.ch/work/a/amagnan/public/HepMCFiles/ggHgg_1428658356.dat";
    HepMC::IO_GenEvent ascii_in(lname.str().c_str(),std::ios::in);
    
    // get the first event
    HepMC::GenEvent* evt = ascii_in.read_next_event();
    // loop until we run out of events
    while ( evt ) {
      unsigned ievt =  evt->event_number();
      if (ievt%10000==0) std::cout << "Processing Event Number "
				 << ievt
				 << std::endl;


      GenVertex * parent = 0;
      HepMC::GenEvent::vertex_const_iterator q = evt->vertices_begin();

      //for (; q != evt->vertices_end(); ++q ){

	//if ((*q)->position().x()!=0 || (*q)->position().y()!=0) continue;

      double z = (*q)->position().z();
      double t = (*q)->position().t();
      hvtx_x->Fill((*q)->position().x());
      hvtx_y->Fill((*q)->position().y());
      hvtx_z->Fill(z);
      hvtx_t->Fill(t);
      //hvtx_tvsz->Fill(z,t*1000);
      hvtx_tvsz->Fill(z,t);

      if (fabs(z)<z0){
	unsigned idx = static_cast<unsigned>((z+z0)*1./step);
	if (idx>(nZ-1)) continue;
	hvtx_t_z[idx]->Fill(t*1000);
      }

	/*std::cout << " -- vtx pos: " << (*q)->position().x() << " " << (*q)->position().y() << " " << (*q)->position().z() << " nParticles: in=" << (*q)->particles_in_size() << " " << (*q)->particles_out_size()
		  << std::endl;
	for ( HepMC::GenVertex::particles_in_const_iterator p
		= (*q)->particles_in_const_begin(); p != (*q)->particles_in_const_end(); ++p ){

	  std::cout << " ---- in particle " << (*p)->pdg_id() << " status " << (*p)->status()
		    << std::endl;
	  
	}
 	for ( HepMC::GenVertex::particles_out_const_iterator p
		= (*q)->particles_out_const_begin(); p != (*q)->particles_out_const_end(); ++p ){

	  std::cout << " ---- out particle " << (*p)->pdg_id() << " status " << (*p)->status()
		    << std::endl;
	  
	}*/
	//}

      /*
      // analyze the event
      HepMC::GenEvent::particle_const_iterator lPart = evt->particles_begin();
      //unsigned counter = 0;
      
      //std::cout << " -- Number of particles: " << evt->particles_size()
      //<< std::endl;
      
      for (; lPart!=evt->particles_end();++lPart){
	//std::cout << counter << " " 
	//<< (*lPart)->pdg_id() <<  " " 
	//<< (*lPart)->status() 
	//<< std::endl;
	//counter++;
	if ((*lPart)->status()!=1) continue;
	double p = sqrt(pow((*lPart)->momentum().px(),2)+pow((*lPart)->momentum().py(),2)+pow((*lPart)->momentum().pz(),2));
	//if (fabs((*lPart)->momentum().eta())>2.8 && fabs((*lPart)->momentum().eta())<3.0){
	if (fabs((*lPart)->momentum().eta())<2.5){
	  if (fabs((*lPart)->pdg_id())==2212) {hProton->Fill(p);hProtonLog->Fill(log10(p));}
	  else if (fabs((*lPart)->pdg_id())==2112) {hNeutron->Fill(p);hNeutronLog->Fill(log10(p));}
	  else if (fabs((*lPart)->pdg_id())==211) {hPipm->Fill(p);hPipmLog->Fill(log10(p));}
	}
      }
      */

      // delete the created event from memory
      delete evt;
      // read the next event
      ascii_in >> evt;
      ievt++;
    }
  }

  fout->Write();
  
  return 0;

}//main
int main(int argc, char* argv[])
{
  TApplication theApp(srcName.Data(), &argc, argv);
//=============================================================================

  if (argc<5) return -1;
  TString sPath = argv[1]; if (sPath.IsNull()) return -1;
  TString sFile = argv[2]; if (sFile.IsNull()) return -1;
  TString sJetR = argv[3]; if (sJetR.IsNull()) return -1;
  TString sSjeR = argv[4]; if (sSjeR.IsNull()) return -1;
//=============================================================================

  sPath.ReplaceAll("#", "/");
//=============================================================================

  double dJetR = -1.;
  if (sJetR=="JetR02") dJetR = 0.2;
  if (sJetR=="JetR03") dJetR = 0.3;
  if (sJetR=="JetR04") dJetR = 0.4;
  if (sJetR=="JetR05") dJetR = 0.5;

  if (dJetR<0.) return -1;
  cout << "Jet R = " << dJetR << endl;
//=============================================================================

  double dSjeR = -1.;
  if (sSjeR=="SjeR01") dSjeR = 0.1;
  if (sSjeR=="SjeR02") dSjeR = 0.2;
  if (sSjeR=="SjeR03") dSjeR = 0.3;
  if (sSjeR=="SjeR04") dSjeR = 0.4;

  if (dSjeR<0.) return -1;
  cout << "Sub-jet R = " << dSjeR << endl;
//=============================================================================

  const double dJetsPtMin  = 0.001;
  const double dCutEtaMax  = 1.6;
  const double dJetEtaMax  = 1.;
  const double dJetAreaRef = TMath::Pi() * dJetR * dJetR;

  fastjet::GhostedAreaSpec areaSpc(dCutEtaMax);
  fastjet::JetDefinition   jetsDef(fastjet::antikt_algorithm, dJetR, fastjet::BIpt_scheme, fastjet::Best);

//fastjet::AreaDefinition  areaDef(fastjet::active_area,areaSpc);
  fastjet::AreaDefinition  areaDef(fastjet::active_area_explicit_ghosts,areaSpc);

//fastjet::JetDefinition   bkgsDef(fastjet::kt_algorithm, 0.2, fastjet::BIpt_scheme, fastjet::Best);
//fastjet::AreaDefinition  aBkgDef(fastjet::active_area_explicit_ghosts, areaSpc);

  fastjet::Selector selectJet = fastjet::SelectorAbsEtaMax(dJetEtaMax);
//fastjet::Selector selectRho = fastjet::SelectorAbsEtaMax(dCutEtaMax-0.2);
//fastjet::Selector selecHard = fastjet::SelectorNHardest(2);
//fastjet::Selector selectBkg = selectRho * (!(selecHard));
//fastjet::JetMedianBackgroundEstimator bkgsEstimator(selectBkg, bkgsDef, aBkgDef);
//fastjet::Subtractor                   bkgSubtractor(&bkgsEstimator);

  fastjet::JetDefinition subjDef(fastjet::antikt_algorithm, dSjeR, fastjet::BIpt_scheme, fastjet::Best);
//=============================================================================

  std::vector<fastjet::PseudoJet> fjInput;
//=============================================================================

  TList *list = new TList();
  TH1D *hWeightSum = new TH1D("hWeightSum", "", 1, 0., 1.); list->Add(hWeightSum);

  TH1D *hJet = new TH1D("hJet", "", 1000, 0., 1000.); hJet->Sumw2(); list->Add(hJet);
  TH2D *hJetNsj = new TH2D("hJetNsj", "", 1000, 0., 1000., 101, -0.5, 100.5); hJetNsj->Sumw2(); list->Add(hJetNsj);

  TH2D *hJetIsj = new TH2D("hJetIsj", "", 1000, 0., 1000., 1000, 0., 1000.); hJetIsj->Sumw2(); list->Add(hJetIsj);
  TH2D *hJet1sj = new TH2D("hJet1sj", "", 1000, 0., 1000., 1000, 0., 1000.); hJet1sj->Sumw2(); list->Add(hJet1sj);
  TH2D *hJet2sj = new TH2D("hJet2sj", "", 1000, 0., 1000., 1000, 0., 1000.); hJet2sj->Sumw2(); list->Add(hJet2sj);
  TH2D *hJetDsj = new TH2D("hJetDsj", "", 1000, 0., 1000., 1000, 0., 1000.); hJetDsj->Sumw2(); list->Add(hJetDsj);

  TH2D *hJetIsz = new TH2D("hJetIsz", "", 1000, 0., 1000., 120, 0., 1.2); hJetIsz->Sumw2(); list->Add(hJetIsz);
  TH2D *hJet1sz = new TH2D("hJet1sz", "", 1000, 0., 1000., 120, 0., 1.2); hJet1sz->Sumw2(); list->Add(hJet1sz);
  TH2D *hJet2sz = new TH2D("hJet2sz", "", 1000, 0., 1000., 120, 0., 1.2); hJet2sz->Sumw2(); list->Add(hJet2sz);
  TH2D *hJetDsz = new TH2D("hJetDsz", "", 1000, 0., 1000., 120, 0., 1.2); hJetDsz->Sumw2(); list->Add(hJetDsz);
//=============================================================================

  HepMC::IO_GenEvent ascii_in(Form("%s/%s.hepmc",sPath.Data(),sFile.Data()), std::ios::in);
  HepMC::GenEvent *evt = ascii_in.read_next_event();

  while (evt) {
    fjInput.resize(0);
    double dXsect  = evt->cross_section()->cross_section() / 1e9;
    double dWeight = evt->weights().back();
    double dNorm = dWeight * dXsect;
    hWeightSum->Fill(0.5, dWeight);

    TVector3 vPar;
    for (HepMC::GenEvent::particle_const_iterator p=evt->particles_begin(); p!=evt->particles_end(); ++p) if ((*p)->status()==1) {
      vPar.SetXYZ((*p)->momentum().px(), (*p)->momentum().py(), (*p)->momentum().pz());

      if ((TMath::Abs(vPar.Eta())<dCutEtaMax)) {
        fjInput.push_back(fastjet::PseudoJet(vPar.Px(), vPar.Py(), vPar.Pz(), vPar.Mag()));
      }
    }
//=============================================================================

    fastjet::ClusterSequenceArea clustSeq(fjInput, jetsDef, areaDef);
    std::vector<fastjet::PseudoJet> includJets = clustSeq.inclusive_jets(dJetsPtMin);
//  std::vector<fastjet::PseudoJet> subtedJets = bkgSubtractor(includJets);
    std::vector<fastjet::PseudoJet> selectJets = selectJet(includJets);
//  std::vector<fastjet::PseudoJet> sortedJets = fastjet::sorted_by_pt(selectJets);

    for (int j=0; j<selectJets.size(); j++) {
      double dJet = selectJets[j].pt();

      hJet->Fill(dJet, dNorm);
//=============================================================================

      fastjet::Filter trimmer(subjDef, fastjet::SelectorPtFractionMin(0.));
      fastjet::PseudoJet trimmdJet = trimmer(selectJets[j]);
      std::vector<fastjet::PseudoJet> trimmdSj = trimmdJet.pieces();

      double nIsj = 0.;
      double d1sj = -1.; int k1sj = -1;
      double d2sj = -1.; int k2sj = -1;
      for (int i=0; i<trimmdSj.size(); i++) {
        double dIsj = trimmdSj[i].pt(); if (dIsj<0.001) continue;

        hJetIsj->Fill(dJet, dIsj, dNorm);
        hJetIsz->Fill(dJet, dIsj/dJet, dNorm);

        if (dIsj>d1sj) {
          d2sj = d1sj; k2sj = k1sj;
          d1sj = dIsj; k1sj = i;
        } else if (dIsj>d2sj) {
          d2sj = dIsj; k2sj = i;
        } nIsj += 1.;
      }

      hJetNsj->Fill(dJet, nIsj, dNorm);
      if (d1sj>0.) { hJet1sj->Fill(dJet, d1sj, dNorm); hJet1sz->Fill(dJet, d1sj/dJet, dNorm); }
      if (d2sj>0.) { hJet2sj->Fill(dJet, d2sj, dNorm); hJet2sz->Fill(dJet, d2sj/dJet, dNorm); }

      if ((d1sj>0.) && (d2sj>0.)) {
        double dsj = d1sj - d2sj;
        double dsz = dsj / dJet;

        hJetDsj->Fill(dJet, dsj, dNorm);
        hJetDsz->Fill(dJet, dsz, dNorm);
      }
    }
//=============================================================================

    delete evt;
    ascii_in >> evt;
  }
//=============================================================================

  TFile *file = TFile::Open(Form("%s.root",sFile.Data()), "NEW");
  list->Write();
  file->Close();
//=============================================================================

  cout << "DONE" << endl;
  return 0;
}
int HFMLTriggerHepMCTrigger::process_event(PHCompositeNode* topNode)
{
  assert(m_Geneventmap);

  PHHepMCGenEvent* genevt = m_Geneventmap->get(_embedding_id);
  if (!genevt)
  {
    std::cout << PHWHERE << " - Fatal error - node PHHepMCGenEventMap missing subevent with embedding ID " << _embedding_id;
    std::cout << ". Print PHHepMCGenEventMap:";
    m_Geneventmap->identify();
    return Fun4AllReturnCodes::ABORTRUN;
  }

  HepMC::GenEvent* theEvent = genevt->getEvent();
  assert(theEvent);
  if (Verbosity() >= VERBOSITY_MORE)
  {
    cout << "HFMLTriggerHepMCTrigger::process_event - process HepMC::GenEvent with signal_process_id = "
         << theEvent->signal_process_id();
    if (theEvent->signal_process_vertex())
    {
      cout << " and signal_process_vertex : ";
      theEvent->signal_process_vertex()->print();
    }
    cout << "  - Event record:" << endl;
    theEvent->print();
  }

  TDatabasePDG* pdg = TDatabasePDG::Instance();

  int targetPID = std::abs(pdg->GetParticle("D0")->PdgCode());
  int daughter1PID = std::abs(pdg->GetParticle("pi+")->PdgCode());
  int daughter2PID = std::abs(pdg->GetParticle("K+")->PdgCode());

  bool acceptEvent = false;

  assert(m_hNorm);
  m_hNorm->Fill("Event", 1);

  unsigned int nD0(0);
  unsigned int nD0PiK(0);

  auto range = theEvent->particle_range();
  for (HepMC::GenEvent::particle_const_iterator piter = range.begin(); piter != range.end(); ++piter)
  {
    const HepMC::GenParticle* p = *piter;
    assert(p);

    if (std::abs(p->pdg_id()) == targetPID)
    {
      if (Verbosity())
      {
        cout << "HFMLTriggerHepMCTrigger::process_event - Accept signal particle : ";
        p->print();
        cout << endl;
      }

      m_hNorm->Fill("D0", 1);
      ++nD0;

      assert(m_DRapidity);
      const double rapidity = 0.5 * log((p->momentum().e() + p->momentum().z()) /
                                        (p->momentum().e() - p->momentum().z()));

      m_DRapidity->Fill(rapidity, 0);

      const HepMC::GenVertex* decayVertex = p->end_vertex();

      int hasDecay1(0);
      int hasDecay2(0);
      int hasDecayOther(0);

      if (decayVertex)
      {
        for (auto diter = decayVertex->particles_out_const_begin();
             diter != decayVertex->particles_out_const_end();
             ++diter)

        {
          const HepMC::GenParticle* pd = *diter;
          assert(pd);

          if (Verbosity())
          {
            cout << "HFMLTriggerHepMCTrigger::process_event - Testing daughter particle: ";
            pd->print();
            cout << endl;
          }

          if (std::abs(pd->pdg_id()) == daughter1PID)
          {
            const double eta = pd->momentum().eta();

            if (eta > _eta_min and eta < _eta_max)
              ++hasDecay1;
          }
          else if (std::abs(pd->pdg_id()) == daughter2PID)
          {
            const double eta = pd->momentum().eta();

            if (eta > _eta_min and eta < _eta_max)
              ++hasDecay2;
          }
          else
            ++hasDecayOther;
        }

        if (hasDecay1 == 1 and hasDecay2 == 1 and hasDecayOther == 0)
        {
          m_hNorm->Fill("D0->PiK", 1);
          ++nD0PiK;

          acceptEvent = true;

          m_DRapidity->Fill(rapidity, 1);
        }

      }  //      if (decayVertex)
      else
      {
        cout << "HFMLTriggerHepMCTrigger::process_event - Warning - target particle did not have decay vertex : ";
        p->print();
        cout << endl;
      }

    }  //    if (std::abs(p-> pdg_id()) == targetPID)
  }    //  for (HepMC::GenEvent::particle_const_iterator piter = range.begin(); piter != range.end(); ++piter)

  if (nD0 >= 2)
  {
    cout <<"HFMLTriggerHepMCTrigger::process_event - D0-Pair with nD0 = "<<nD0<<endl;
    m_hNorm->Fill("D0-Pair", nD0 * (nD0 - 1) / 2);
  }
  if (nD0PiK >= 2)
  {
    m_hNorm->Fill("D0->PiK-Pair", nD0PiK * (nD0PiK - 1) / 2);
  }

  ++_ievent;

  if (Verbosity())
  {
    cout << "HFMLTriggerHepMCTrigger::process_event - acceptEvent = " << acceptEvent;
    cout << endl;

    if (acceptEvent)
    {
      cout << "HFMLTriggerHepMCTrigger::process_event - processed HepMC::GenEvent with signal_process_id = "
           << theEvent->signal_process_id();
      if (theEvent->signal_process_vertex())
      {
        cout << " and signal_process_vertex : ";
        theEvent->signal_process_vertex()->print();
      }
      cout << "  - Event record:" << endl;
      theEvent->print();
    }
  }

  assert(m_Flags);
  m_Flags->set_int_param(Name(), acceptEvent);

  if (acceptEvent)
  {
    m_hNorm->Fill("Accepted", 1);
    return Fun4AllReturnCodes::EVENT_OK;
  }
  else
    return m_RejectReturnCode;
}
int
LeptoquarksReco::AddTrueTauTag( type_map_tcan& tauCandidateMap, PHHepMCGenEventMap *genevtmap )
{
  /* Look for leptoquark and tau particle in the event */
  TruthTrackerHepMC truth;
  truth.set_hepmc_geneventmap( genevtmap );

  int pdg_lq = 39; // leptoquark                                                                                                                                                                          
  int pdg_tau = 15; // tau lepton                                                                                                                                                                         
  int pdg_parton = 0;
  int pdg_electron = 11; // electron

  // Check if electron exists  //                                                                                                                                                                
  HepMC::GenParticle* particle_electron = NULL;
  
  for (PHHepMCGenEventMap::ReverseIter iter = genevtmap->rbegin(); iter != genevtmap->rend(); ++iter)
    {
      PHHepMCGenEvent *genevt = iter->second;
      HepMC::GenEvent *theEvent = genevt->getEvent();
            
      // Loop over all truth particles in event generator collection 
      for ( HepMC::GenEvent::particle_iterator p = theEvent->particles_begin();
	    p != theEvent->particles_end(); ++p ) {
	// If final state electron then tag it //
	if((*p)->pdg_id() == pdg_electron && (*p)->status() == 1) particle_electron = (*p);
      }
    }
            
  /* Search for leptoquark in event */
  HepMC::GenParticle* particle_lq = truth.FindParticle( pdg_lq );

  // Tag event as LQ event or not //
  if (particle_lq) ( _map_event_branches.find( "is_lq_event" ) )->second = 1;
  else ( _map_event_branches.find( "is_lq_event" ) )->second = 0;

  /* Search for lq->tau decay in event */
  HepMC::GenParticle* particle_tau = NULL;

  // Find tau that comes from LQ or just any tau in event //
  if(particle_lq) particle_tau = truth.FindDaughterParticle( pdg_tau, particle_lq );
  else particle_tau = truth.FindParticle(pdg_tau);
  
  /* Search for lq->quark decay in event.
   * Loop over all quark PDG codes until finding a matching quark. */
  HepMC::GenParticle* particle_quark = NULL;
  for ( int pdg_quark = 1; pdg_quark < 7; pdg_quark++ )
    {
      /* try quark */
      particle_quark = truth.FindDaughterParticle( pdg_quark, particle_lq );
      if (particle_quark)
        {
          pdg_parton = pdg_quark;
          break;
        }

      /* try anti-quark */
      particle_quark = truth.FindDaughterParticle( -pdg_quark, particle_lq );
      if (particle_quark)
        {
          pdg_parton = -pdg_quark;
          break;
        }
    }

  /* If TAU in event: Tag the tau candidate (i.e. jet) with smalles delta_R from this tau */
  if( particle_tau )
    {
      PidCandidate* best_match = FindMinDeltaRCandidate( &tauCandidateMap,
                                                         particle_tau->momentum().eta(),
                                                         particle_tau->momentum().phi() );

      
      /* set is_tau = TRUE for PidCandiate with smallest delta_R within reasonable range*/
      if ( best_match )
        {
	  /* Check: If PidCandidate::Evtgen_pid has already been set to a value != 0, exit function. */
	  if( best_match->get_property_int( PidCandidate::evtgen_pid ) != 0 )
	    {
	      cout << "ERROR: Try to set PidCandidate::evtgen_pid for PidCandidate with evtgen_pid != 0" << endl;
	      return -1;
	    }

          /* Update PidCandidate entry */
          best_match->set_property( PidCandidate::evtgen_pid, pdg_tau );
          best_match->set_property( PidCandidate::evtgen_etotal, (float)particle_tau->momentum().e() );
          best_match->set_property( PidCandidate::evtgen_eta, (float)particle_tau->momentum().eta() );
          best_match->set_property( PidCandidate::evtgen_phi, (float)particle_tau->momentum().phi() );
	  
          /* Check particle decay if end-vertex found */
          if ( particle_tau->end_vertex() )
            {
              /* Add information about tau decay */
              uint tau_decay_prong = 0;
              uint tau_decay_hcharged = 0;
              uint tau_decay_lcharged = 0;

	      /* Count how many charged particles (hadrons and leptons) a given particle decays into. */
              truth.FindDecayParticles( particle_tau, tau_decay_prong, tau_decay_hcharged, tau_decay_lcharged );


              /* Update tau candidate entry */
              best_match->set_property( PidCandidate::evtgen_decay_prong, tau_decay_prong );
              best_match->set_property( PidCandidate::evtgen_decay_hcharged, tau_decay_hcharged );
              best_match->set_property( PidCandidate::evtgen_decay_lcharged, tau_decay_lcharged );
            }
        }
    }

  /* If QUARK (->jet) in event: Tag the tau candidate (i.e. jet) with smalles delta_R from this quark */
  if( particle_quark )
    {
      PidCandidate* best_match = FindMinDeltaRCandidate( &tauCandidateMap,
                                                         particle_quark->momentum().eta(),
                                                         particle_quark->momentum().phi() );
      
      /* set is_uds = TRUE for PidCandiate with smallest delta_R if found */
      if ( best_match )
        {
	  /* Check: If PidCandidate::Evtgen_pid has already been set to a value != 0, exit function. */
	  if( best_match->get_property_int( PidCandidate::evtgen_pid ) != 0 )
	    {
	      cout << "ERROR: Try to set PidCandidate::evtgen_pid for PidCandidate with evtgen_pid != 0" << endl;
	      return -1;
	    }
	  /* Set properties of PidCandidate */
          best_match->set_property( PidCandidate::evtgen_pid, pdg_parton );
          best_match->set_property( PidCandidate::evtgen_etotal, (float)particle_quark->momentum().e() );
          best_match->set_property( PidCandidate::evtgen_eta, (float)particle_quark->momentum().eta() );
          best_match->set_property( PidCandidate::evtgen_phi, (float)particle_quark->momentum().phi() );
        }
    }

  if( particle_electron )
    {
      //cout<<"ELECTRON"<<endl;
      PidCandidate* best_match = FindMinDeltaRCandidate( &tauCandidateMap,
                                                         particle_electron->momentum().eta(),
                                                         particle_electron->momentum().phi() );

      /* set electron = TRUE for PidCandiate with smallest delta_R if found */
      if ( best_match )
        {
          /* Check: If PidCandidate::Evtgen_pid has already been set to a value != 0, exit function. */
          if( best_match->get_property_int( PidCandidate::evtgen_pid ) != 0 )
            {
              cout << "ERROR: Try to set PidCandidate::evtgen_pid for PidCandidate with evtgen_pid != 0" << endl;
              return -1;
            }

          /* Set properties of PidCandidate */
          best_match->set_property( PidCandidate::evtgen_pid, pdg_electron );
          best_match->set_property( PidCandidate::evtgen_etotal, (float)particle_electron->momentum().e() );
          best_match->set_property( PidCandidate::evtgen_eta, (float)particle_electron->momentum().eta() );
          best_match->set_property( PidCandidate::evtgen_phi, (float)particle_electron->momentum().phi() );
        }
    }


  return 0;
}
int main(int argc, char* argv[])
{
  TApplication theApp(srcName.Data(), &argc, argv);
//=============================================================================

  if (argc<5) return -1;
  TString sPath = argv[1]; if (sPath.IsNull()) return -1;
  TString sFile = argv[2]; if (sFile.IsNull()) return -1;
  TString sJetR = argv[3]; if (sJetR.IsNull()) return -1;
  TString sSjeR = argv[4]; if (sSjeR.IsNull()) return -1;
//=============================================================================

  sPath.ReplaceAll("#", "/");
//=============================================================================

  double dJetR = -1.;
  if (sJetR=="JetR02") dJetR = 0.2;
  if (sJetR=="JetR03") dJetR = 0.3;
  if (sJetR=="JetR04") dJetR = 0.4;
  if (sJetR=="JetR05") dJetR = 0.5;

  if (dJetR<0.) return -1;
  cout << "Jet R = " << dJetR << endl;
//=============================================================================

  double dSjeR = -1.;
  if (sSjeR=="SjeR01") dSjeR = 0.1;
  if (sSjeR=="SjeR02") dSjeR = 0.2;
  if (sSjeR=="SjeR03") dSjeR = 0.3;
  if (sSjeR=="SjeR04") dSjeR = 0.4;

  if (dSjeR<0.) return -1;
  cout << "Sub-jet R = " << dSjeR << endl;
//=============================================================================

  const int multiLHC = 3000;
  const double dJetsPtMin  = 0.001;
  const double dCutEtaMax  = 1.6;
  const double dJetEtaMax  = 1.;
  const double dJetAreaRef = TMath::Pi() * dJetR * dJetR;

  fastjet::GhostedAreaSpec areaSpc(dCutEtaMax);
  fastjet::JetDefinition   jetsDef(fastjet::antikt_algorithm, dJetR, fastjet::BIpt_scheme, fastjet::Best);

//fastjet::AreaDefinition  areaDef(fastjet::active_area,areaSpc);
  fastjet::AreaDefinition  areaDef(fastjet::active_area_explicit_ghosts,areaSpc);

  fastjet::JetDefinition   bkgsDef(fastjet::kt_algorithm, 0.2, fastjet::BIpt_scheme, fastjet::Best);
  fastjet::AreaDefinition  aBkgDef(fastjet::active_area_explicit_ghosts, areaSpc);

  fastjet::Selector selectJet = fastjet::SelectorAbsEtaMax(dJetEtaMax);
  fastjet::Selector selectRho = fastjet::SelectorAbsEtaMax(dCutEtaMax-0.2);
  fastjet::Selector selecHard = fastjet::SelectorNHardest(2);
  fastjet::Selector selectBkg = selectRho * (!(selecHard));
  fastjet::JetMedianBackgroundEstimator bkgsEstimator(selectBkg, bkgsDef, aBkgDef);
//fastjet::Subtractor                   bkgSubtractor(&bkgsEstimator);

  fastjet::JetDefinition subjDef(fastjet::kt_algorithm, dSjeR, fastjet::BIpt_scheme, fastjet::Best);
//=============================================================================

  TRandom3 *r3 = new TRandom3(0);
  TF1 *fBkg = BackgroundSpec();
//=============================================================================

  std::vector<fastjet::PseudoJet> fjInputVac;
  std::vector<fastjet::PseudoJet> fjInputHyd;
//=============================================================================

  TList *list = new TList();
  TH1D *hWeightSum = new TH1D("hWeightSum", "", 1, 0., 1.); list->Add(hWeightSum);


//=============================================================================

  HepMC::IO_GenEvent ascii_in(Form("%s/%s.hepmc",sPath.Data(),sFile.Data()), std::ios::in);
  HepMC::GenEvent *evt = ascii_in.read_next_event();

  while (evt) {
    fjInputVac.resize(0);
    fjInputHyd.resize(0);

    double dXsect  = evt->cross_section()->cross_section() / 1e9;
    double dWeight = evt->weights().back();
    double dNorm = dWeight * dXsect;
    hWeightSum->Fill(0.5, dWeight);

    int iCount = 0;
    TLorentzVector vPseudo;
    for (HepMC::GenEvent::particle_const_iterator p=evt->particles_begin(); p!=evt->particles_end(); ++p) if ((*p)->status()==1) {
      vPseudo.SetPtEtaPhiM((*p)->momentum().perp(), (*p)->momentum().eta(), (*p)->momentum().phi(), 0.);

      if ((TMath::Abs(vPar.Eta())<dCutEtaMax)) {
        fjInputVac.push_back(fastjet::PseudoJet(vPseudo.Px(), vPseudo.Py(), vPseudo.Pz(), vPseudo.E()));
        fjInputVac.back().set_user_info(new UserInfoTrk(false));
        fjInputVac.back().set_user_index(iCount); iCount+=1;
      }
    }
//=============================================================================

    for (int i=0; i<=multiLHC; i++) {
      double dPt = fBkg->GetRandom(fgkPtBkgMin, fgkPtBkgMax); if (dPt<0.001) continue;

      vPseudo.SetPtEtaPhiM(dPt, r3->Uniform(-1.*dCutEtaMax,dCutEtaMax), r3->Uniform(0.,TMath::TwoPi()), 0.);
      fjInputHyd.push_back(fastjet::PseudoJet(vPseudo.Px(), vPseudo.Py(), vPseudo.Pz(), vPseudo.E()));
      fjInputHyd.back().set_user_info(new UserInfoTrk(true));
      fjInputHyd.back().set_user_index(-10);
    }

    fjInputHyd.insert(fjInputHyd.end(), fjInputVac.begin(),fjInputVac.end());
//=============================================================================

    fastjet::ClusterSequenceArea clustSeq(fjInputVac, jetsDef, areaDef);
    std::vector<fastjet::PseudoJet> includJetsPy = clustSeq.inclusive_jets(dJetsPtMin);
//  std::vector<fastjet::PseudoJet> subtedJetsPy = bkgSubtractor(includJetsPy);
    std::vector<fastjet::PseudoJet> selectJetsPy = selectJet(includJetsPy);
//  std::vector<fastjet::PseudoJet> sortedJetsPy = fastjet::sorted_by_pt(selectJetsPy);

    for (int j=0; j<selectJetsPy.size(); j++) {
      SetJetUserInfo(selectJetsPy[j]);
      selectJetsPy[j].set_user_index(j);
    }
//=============================================================================

    bkgsEstimator.set_particles(fjInputHyd);
    double dBkgRhoHd = bkgsEstimator.rho();
    double dBkgRmsHd = bkgsEstimator.sigma();

    fastjet::ClusterSequenceArea clustSeqHd(fjInputHyd, jetsDef, areaDef);
    std::vector<fastjet::PseudoJet> includJetsHd = clustSeqHd.inclusive_jets(dJetsPtMin);
    std::vector<fastjet::PseudoJet> selectJetsHd = selectJet(includJetsHd);

    for (int j=0; j<selectJetsHd.size(); j++) {
      SetJetUserInfo(selectJetsHd[j]);
      selectJetsHd[j].set_user_index(j);
      if (selectJetsHd[j].user_info<UserInfoJet>().IsBkg()) continue;

      for (int i=0; i<selectJetsPy.size(); i++) {
        if (CalcDeltaR(selectJetsHd[j],selectJetsPy[i])>0.8) continue;
        DoTrkMatch(selectJetsHd[j], selectJetsPy[i]);
      }
    }
//=============================================================================

  








    for (int j=0; j<sortedJets.size(); j++) {
      double dJet = sortedJets[j].pt();

      hJet->Fill(dJet, dNorm);
//=============================================================================

      fastjet::Filter trimmer(subjDef, fastjet::SelectorPtFractionMin(0.));
      fastjet::PseudoJet trimmdJet = trimmer(sortedJets[j]);
      std::vector<fastjet::PseudoJet> trimmdSj = trimmdJet.pieces();

      double nIsj = 0.;
      double d1sj = -1.; int k1sj = -1;
      double d2sj = -1.; int k2sj = -1;
      for (int i=0; i<trimmdSj.size(); i++) {
        double dIsj = trimmdSj[i].pt(); if (dIsj<0.001) continue;

        hJetIsj->Fill(dJet, dIsj, dNorm);
        hJetIsz->Fill(dJet, dIsj/dJet, dNorm);

        if (dIsj>d1sj) {
          d2sj = d1sj; k2sj = k1sj;
          d1sj = dIsj; k1sj = i;
        } else if (dIsj>d2sj) {
          d2sj = dIsj; k2sj = i;
        } nIsj += 1.;
      }

      hJetNsj->Fill(dJet, nIsj, dNorm);
      if (d1sj>0.) { hJet1sj->Fill(dJet, d1sj, dNorm); hJet1sz->Fill(dJet, d1sj/dJet, dNorm); }
      if (d2sj>0.) { hJet2sj->Fill(dJet, d2sj, dNorm); hJet2sz->Fill(dJet, d2sj/dJet, dNorm); }

      if ((d1sj>0.) && (d2sj>0.)) {
        TVector3 v1sj; v1sj.SetPtEtaPhi(d1sj, trimmdSj[k1sj].eta(), trimmdSj[k1sj].phi());
        TVector3 v2sj; v2sj.SetPtEtaPhi(d2sj, trimmdSj[k2sj].eta(), trimmdSj[k2sj].phi());

        double dsj = d1sj - d2sj;
        double dsz = dsj / dJet;
        double dsr = v1sj.DeltaR(v2sj) / 2. / dJetR;

        hJetDsj->Fill(dJet, dsj, dNorm);
        hJetDsz->Fill(dJet, dsz, dNorm);
        hJetDsr->Fill(dJet, dsz, dsr, dNorm);
      }
    }
//=============================================================================

    delete evt;
    ascii_in >> evt;
  }
//=============================================================================

  TFile *file = TFile::Open(Form("%s.root",sFile.Data()), "NEW");
  list->Write();
  file->Close();
//=============================================================================

  cout << "DONE" << endl;
  return 0;
}
int main(int argc, char * argv[]){
	// declaring and initializing some variables. Most of them will be set according to command line options passed to the program after parsing of command line arguments. However, if Boost is not used, the only available command line option is the number of events to generate; other variables will use the values set below
	std::size_t nevents = 0; // number of events to generate
	std::string pythia_cfgfile = "Z2uubar.cmnd"; // name of PYTHIA cofiguration file
	std::string output_filename = "Z2uubar.root"; // name of the output file
	bool verbose = false; // increased verbosity switch

	#ifdef USE_BOOST
		try {
			boost::program_options::options_description desc("Usage");

			// defining command line options. See boost::program_options documentation for more details
			desc.add_options()
							("help", "produce this help message")
							("nevents,n", boost::program_options::value<std::size_t>(&nevents), "number of events to generate")
							("pythiacfg,P", boost::program_options::value<std::string>(&pythia_cfgfile)->default_value("Z2uubar.cmnd"), "PYTHIA config file")
							("outfile,o", boost::program_options::value<std::string>(&output_filename)->default_value("Z2uubar.root"), "Output file")
							("verbose,v", boost::program_options::bool_switch()->default_value(false), "Run with increased verbosity")
			;
			boost::program_options::variables_map vm;
			boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
			boost::program_options::notify(vm);

			if(vm.find("help") != vm.end() || argc < 2) {
				std::cout << "Generator of inclusive events. Version " << Generator_VERSION_MAJOR << '.' << Generator_VERSION_MINOR << std::endl;
				std::cout << desc << std::endl;

				return EXIT_SUCCESS;
			}

			verbose = vm.at("verbose").as<bool>();
		} catch(std::exception const & e) {
			std::cout << e.what() << std::endl;

			return EXIT_FAILURE;
		}
	#else
		if(argc < 2) {
			std::cout << "Generator of inclusive events. Version " << Generator_VERSION_MAJOR << '.' << Generator_VERSION_MINOR << std::endl;
			std::cout << "Usage: " << argv[0] << " n, where \"n\" is a number of events to generate" << std::endl;
			std::cout << "WARNING! This version of the generator does not use program options parser, which means that you are personally responsible for providing correct options to this program." << std::endl;

			return EXIT_SUCCESS;
		} else {
			nevents = std::stoull(argv[1]);
		}
	#endif

	auto start_time = std::chrono::system_clock::now();
	auto last_timestamp = start_time;

	if(verbose) {
			std::cout << "PYTHIA config file: \"" << pythia_cfgfile << "\"" << std::endl << nevents << " events will be generated." << std:: endl;
	}

	if(verbose) {
		std::cout << "Prepairing data store" << std::endl;
	}

	// prepairing event store
	podio::EventStore store;
	podio::ROOTWriter writer(output_filename, &store);

	// registering collections
	auto & evinfocoll = store.create<fcc::EventInfoCollection>("EventInfo");
	auto & pcoll = store.create<fcc::MCParticleCollection>("GenParticle");
	auto & vcoll = store.create<fcc::GenVertexCollection>("GenVertex");

	writer.registerForWrite<fcc::EventInfoCollection>("EventInfo");
	writer.registerForWrite<fcc::MCParticleCollection>("GenParticle");
	writer.registerForWrite<fcc::GenVertexCollection>("GenVertex");

	if(verbose) {
		std::cout << "Initializing PYTHIA" << std::endl;
	}

	// initializing PYTHIA
	Pythia8::Pythia pythia; // creating PYTHIA generator object
	pythia.readFile(pythia_cfgfile); // reading settings from file

	pythia.init(); // initializing PYTHIA generator

	// Interface for conversion from Pythia8::Event to HepMC event.
	HepMC::Pythia8ToHepMC ToHepMC;

	std::size_t counter = 0; // number of "interesting" (that satisfy all the requirements) events generated so far
	std::size_t total = 0; // total number of events generated so far

	if(verbose) {
		std::cout << "Starting to generate events" << std::endl;
	}

	std::map<std::size_t, std::size_t> stable_ptcs_count;

	while(counter < nevents) {
		if(pythia.next()) {
			++total;

			// creating HepMC event storage
			HepMC::GenEvent * hepmcevt = new HepMC::GenEvent(HepMC::Units::GEV, HepMC::Units::MM);

			// converting generated event to HepMC format
			ToHepMC.fill_next_event(pythia, hepmcevt);

			auto nstable = std::count_if(hepmcevt->particles_begin(), hepmcevt->particles_end(), [](HepMC::GenParticle const * const ptc_ptr) {return ptc_ptr->status() == 1;});

			if(nstable <= 7) {
				stable_ptcs_count[nstable]++;
				++counter;

				if(verbose && counter % 100 == 0) {
					std::cout << counter << " events with with 7 or less particles in the final state have been generated (" << total << " total). " << std::chrono::duration<double>(std::chrono::system_clock::now() - last_timestamp).count() / 100 << "events / sec" << std::endl;
					last_timestamp = std::chrono::system_clock::now();
				}

				// filling event info
				auto evinfo = fcc::EventInfo();
				evinfo.Number(counter); // Number takes int as its parameter, so here's a narrowing conversion (std::size_t to int). Should be safe unless we get 2^32 events or more. Then undefined behaviour
				evinfocoll.push_back(evinfo);

				// filling vertices
				std::unordered_map<HepMC::GenVertex *, fcc::GenVertex> vtx_map;
				for(auto iv = hepmcevt->vertices_begin(), endv = hepmcevt->vertices_end(); iv != endv; ++iv) {
					auto vtx = fcc::GenVertex();
					vtx.Position().X = (*iv)->position().x();
					vtx.Position().Y = (*iv)->position().y();
					vtx.Position().Z = (*iv)->position().z();
					vtx.Ctau((*iv)->position().t());
					vtx_map.emplace(*iv, vtx);

					vcoll.push_back(vtx);
				}

				// filling particles
				for(auto ip = hepmcevt->particles_begin(), endp = hepmcevt->particles_end(); ip != endp; ++ip) {
					auto ptc = fcc::MCParticle();
					auto & core = ptc.Core();
					core.Type = (*ip)->pdg_id();
					core.Status = (*ip)->status();

					core.Charge = pythia.particleData.charge(core.Type); // PYTHIA returns charge as a double value (in case it's quark), so here's a narrowing conversion (double to int), but here it's safe
					core.P4.Mass = (*ip)->momentum().m();
					core.P4.Px = (*ip)->momentum().px();
					core.P4.Py = (*ip)->momentum().py();
					core.P4.Pz = (*ip)->momentum().pz();

					auto prodvtx = vtx_map.find((*ip)->production_vertex());
					if(prodvtx != vtx_map.end()) {
						ptc.StartVertex(prodvtx->second);
					}
					auto endvtx = vtx_map.find((*ip)->end_vertex());
					if(endvtx != vtx_map.end()) {
						ptc.EndVertex(endvtx->second);
					}

					pcoll.push_back(ptc);
				}

				writer.writeEvent();
				store.clearCollections();
			}

			// freeing resources
			if(hepmcevt) {
				delete hepmcevt;
				hepmcevt = nullptr;
			}
		}
	}

	writer.finish();

	std::cout << counter << " events with 7 or less particles in the final state have been generated (" << total << " total)." << std::endl;
	for(auto const & nv : stable_ptcs_count) {
		std::cout << std::setw(4) << std::right << nv.first << std::setw(4) << std::right << nv.second << "(" << static_cast<long double>(nv.second) * static_cast<long double>(100) / static_cast<long double>(total) << "%)" << std::endl;
	}
	auto elapsed_seconds = std::chrono::duration<double>(std::chrono::system_clock::now() - start_time).count();
	std::cout << "Elapsed time: " << elapsed_seconds << " s (" << static_cast<long double>(counter) / static_cast<long double>(elapsed_seconds) << " events / s)" << std::endl;

	return EXIT_SUCCESS;
}