diff --git a/Analysis/TotalInvMass/CMakeLists.txt b/Analysis/TotalInvMass/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..f51ee995440c5b76114495421ba3bc2fd26b8528 --- /dev/null +++ b/Analysis/TotalInvMass/CMakeLists.txt @@ -0,0 +1,18 @@ +gaudi_subdir(TotalInvMass v0r0) + +find_package(CLHEP REQUIRED;CONFIG) +find_package(DD4hep COMPONENTS DDG4 REQUIRED) +find_package(EDM4HEP REQUIRED) +find_package(GEAR REQUIRED) +find_package(GSL REQUIRED ) +find_package(LCIO REQUIRED ) +find_package(podio REQUIRED ) +find_package(k4FWCore REQUIRED) + +set(TotalInvMass_srcs src/TotalInvMass.cc) + +gaudi_add_module(TotalInvMass ${TotalInvMass_srcs} + INCLUDE_DIRS k4FWCore GaudiKernel GaudiAlgLib ${CLHEP_INCLUDE_DIR} DD4hep gear ${GSL_INCLUDE_DIRS} ${LCIO_INCLUDE_DIRS} + LINK_LIBRARIES k4FWCore GaudiKernel GaudiAlgLib ${CLHEP_LIBRARIES} DD4hep ${GEAR_LIBRARIES} ${GSL_LIBRARIES} ${LCIO_LIBRARIES} + EDM4HEP::edm4hep EDM4HEP::edm4hepDict +) diff --git a/Analysis/TotalInvMass/src/TotalInvMass.cc b/Analysis/TotalInvMass/src/TotalInvMass.cc new file mode 100644 index 0000000000000000000000000000000000000000..536739b25b1939bb841dbb54216c21671c78a28c --- /dev/null +++ b/Analysis/TotalInvMass/src/TotalInvMass.cc @@ -0,0 +1,718 @@ +#include "TotalInvMass.hh" +#include <EVENT/LCCollection.h> +#include <IMPL/LCCollectionVec.h> +#include <EVENT/LCFloatVec.h> +#include <EVENT/MCParticle.h> +#include <EVENT/ReconstructedParticle.h> +#include <IMPL/MCParticleImpl.h> +#include <values.h> +#include <string> +#include <iostream> +#include <EVENT/LCFloatVec.h> +#include <EVENT/LCParameters.h> +#include <stdexcept> +#include <TFile.h> +#include <TTree.h> +#include <TH1F.h> +#include <TVector3.h> +#include <TRandom.h> +#include <Rtypes.h> +#include <sstream> +#include <cmath> +#include <vector> +#include <TMath.h> +#include "TLorentzVector.h" +#include <UTIL/CellIDDecoder.h> + +using namespace std; + +DECLARE_COMPONENT(TotalInvMass) + + +const float sqrts = 250.0; //GeV + +const string ECALCellIDDecoder = "M:3,S-1:3,I:9,J:9,K-1:6"; +//TH1F *h_hit; + +TotalInvMass::TotalInvMass(const std::string& name, ISvcLocator* svcLoc) + : GaudiAlgorithm(name, svcLoc), + _output(0) +{ + // _description = "Print MC Truth" ; + + /* + _colName="MCParticle"; + registerProcessorParameter( "MCObjects" , + "The name of the PFOs" , + _colName , + _colName); + */ + + /* + _leptonID = 13; + registerProcessorParameter( "LeptonIDTag" , + "Lepton ID that will be used in this analysis." , + _leptonID , + _leptonID); + */ + +} + +StatusCode TotalInvMass::initialize() { + info() << "TotalInvMass::initializing..." << endmsg; + // printParameters(); + + TFile *tree_file=new TFile(_treeFileName.value().c_str(),(_overwrite ? "RECREATE" : "UPDATE")); + + if (!tree_file->IsOpen()) { + delete tree_file; + tree_file=new TFile(_treeFileName.value().c_str(),"NEW"); + } + + //h_hit=new TH1F("hit","hit",80,0,80); + _outputTree = new TTree(_treeName.value().c_str(),_treeName.value().c_str()); + _outputTree->SetAutoSave(32*1024*1024); // autosave every 32MB + _outputTree->Branch("EventNr", &_eventNr, "EventNr/I"); + _outputTree->Branch("Num", &_Num, "Num/I"); + + _outputTree->Branch("OriQuarkID", &_OriQuarkID, "OriQuarkID/I"); + + _outputTree->Branch("ISREn", &_ISREn, "ISREn/F"); + _outputTree->Branch("ISRP", _ISRP, "ISRP[3]/F"); + _outputTree->Branch("ISRPt", &_ISRPt, "ISRPt/F"); + + + _outputTree->Branch("NEn", &_NEn, "NEn/F"); + _outputTree->Branch("NPt", &_NPt, "NPt/F"); + + _outputTree->Branch("N3En", &_N3En, "N3En/F"); + _outputTree->Branch("N3Pt", &_N3Pt, "N3Pt/F"); + + + _outputTree->Branch("OriJ1CosTheta", &_OriJ1CosTheta, "OriJ1CosTheta/F"); + _outputTree->Branch("OriJ2CosTheta", &_OriJ2CosTheta, "OriJ2CosTheta/F"); + _outputTree->Branch("MaxOriJetCosTheta", &_MaxOriJetCosTheta, "MaxOriJetCosTheta/F"); + + _outputTree->Branch("J1CosTheta", &_J1CosTheta, "J1CosTheta/F"); + _outputTree->Branch("J2CosTheta", &_J2CosTheta, "J2CosTheta/F"); + _outputTree->Branch("MaxJetCosTheta", &_MaxJetCosTheta, "MaxJetCosTheta/F"); + + _outputTree->Branch("OQDir", &_OQDir, "OQDir/F"); + _outputTree->Branch("HDPID", &_HDPID, "HDPID/I"); //Higgs Daughter Type, Direction?? + _outputTree->Branch("visE", &_visE, "visE/F"); //Higgs Daughter Type, Direction?? + _outputTree->Branch("HDir", &_HDir, "HDir/F"); + _outputTree->Branch("Mass_a", &_Mass_a, "Mass_a/F"); + _outputTree->Branch("Mass_p", &_Mass_p, "Mass_p/F"); + _outputTree->Branch("Mass_p_Pisr", &_Mass_p_Pisr, "Mass_p_Pisr"); + _outputTree->Branch("Mass_a_Pisr", &_Mass_a_Pisr, "Mass_a_Pisr"); + _outputTree->Branch("Mass_a_Plcal",&_Mass_a_Plcal, "Mass_a_Plcal"); + + _outputTree->Branch("TotalP_a", TotalP_a, "TotalP_a[4]/F"); + _outputTree->Branch("ChP", ChP, "ChP[4]/F"); + _outputTree->Branch("PhP", PhP, "PhP[4]/F"); //Gamma + _outputTree->Branch("NeP", NeP, "NeP[4]/F"); + _outputTree->Branch("FrP", FrP, "FrP[4]/F"); + + _outputTree->Branch("FrPh", FrPh, "FrPh[4]/F"); + _outputTree->Branch("FrNe", FrNe, "FrNe[4]/F"); + + _outputTree->Branch("KPF", KPF, "KPF[4]/F"); + + _outputTree->Branch("UdP", UdP, "UdP[4]/F"); + + _outputTree->Branch("TotalP_p", TotalP_p, "TotalP_p[4]/F"); + _outputTree->Branch("nCHPFO_a", &nCHPFO_a, "nCHPFO_a/I"); + _outputTree->Branch("nCHPFO_p", &nCHPFO_p, "nCHPFO_p/I"); + _outputTree->Branch("nNEPFO_a", &nNEPFO_a, "nNEPFO_a/I"); + _outputTree->Branch("nNEPFO_p", &nNEPFO_p, "nNEPFO_p/I"); + _outputTree->Branch("NeCaloE_a", NeCaloE_a, "NeCaloE_a[2]/F"); + _outputTree->Branch("NeCaloE_p", NeCaloE_p, "NeCaloE_p[2]/F"); + _outputTree->Branch("ElargeP", &ElargeP, "ElargeP[2]/F"); + _outputTree->Branch("TrkSumEn", &TrkSumEn, "TrkSumEn/F"); + _outputTree->Branch("EequP", &EequP, "EequP[2]/F"); + _outputTree->Branch("EsmallP", &EsmallP, "EsmallP[2]/F"); + + _outputTree->Branch("EcalTotalE", &_EcalTotalE, "EcalTotalE/F"); + _outputTree->Branch("EcalEn1", &_EcalEn1, "EcalEn1/F"); + _outputTree->Branch("EcalEn2", &_EcalEn2, "EcalEn2/F"); + _outputTree->Branch("EcalEn3", &_EcalEn3, "EcalEn3/F"); + _outputTree->Branch("EcalEn4", &_EcalEn4, "EcalEn4/F"); + _outputTree->Branch("EcalEn5", &_EcalEn5, "EcalEn5/F"); + _outputTree->Branch("HcalTotalE", &_HcalTotalE, "HcalTotalE/F"); + _outputTree->Branch("HcalEn1", &_HcalEn1, "HcalEn1/F"); + _outputTree->Branch("HcalEn2", &_HcalEn2, "HcalEn2/F"); + _outputTree->Branch("HcalEn3", &_HcalEn3, "HcalEn3/F"); + _outputTree->Branch("HcalEn4", &_HcalEn4, "HcalEn4/F"); + _outputTree->Branch("HcalEn5", &_HcalEn5, "HcalEn5/F"); + _outputTree->Branch("EcalCluE", &_EcalCluE, "EcalCluE/F"); + _outputTree->Branch("HcalCluE", &_HcalCluE, "HcalCluE/F"); + + _outputTree->Branch("EcalCluE_p", &_EcalCluE_p, "EcalCluE_p/F"); + _outputTree->Branch("HcalCluE_p", &_HcalCluE_p, "HcalCluE_p/F"); + + _outputPFO = new TTree("PFO","PFO"); + _outputPFO->Branch("EventNr", &_eventNr, "EventNr/I"); + _outputPFO->Branch("Num", &_Num, "Num/I"); + _outputPFO->Branch("Type", &Type, "Type/I"); // 0 == Arbor & 1 == Pandora + _outputPFO->Branch("Charge", &Charge, "Charge/I"); + _outputPFO->Branch("Energy", &Energy, "Energy/F"); + _outputPFO->Branch("P", P, "P[3]/F"); + _outputPFO->Branch("CluEn", &CluEn, "CluEn/F"); + _outputPFO->Branch("CluEnCom", CluEnCom, "CluEnCom[2]/F"); + + _outputPFO->Branch("TrackHit", &TrackHit, "TrackHit/I"); + _outputPFO->Branch("StartPos", StartPos, "StartPos[3]/F"); + _outputPFO->Branch("EndPos", EndPos, "EndPos[3]/F"); + + _Num = 0; + + info() << "TotalInvMass::initializd" << endmsg; + + return GaudiAlgorithm::initialize(); + +} + +StatusCode TotalInvMass::execute() +{ + info() << "TotalInvMass::executing..." << endmsg; + + EVENT::LCEvent* evtP = nullptr; + + // if (evtP) { + + TLorentzVector ArborTotalP(0, 0, 0, 0); + TLorentzVector ArborChP(0, 0, 0, 0); + TLorentzVector ArborPhP(0, 0, 0, 0); + TLorentzVector ArborNeP(0, 0, 0, 0); + TLorentzVector ArborFrP(0, 0, 0, 0); + TLorentzVector ArborUdP(0, 0, 0, 0); + TLorentzVector ArborFrPh(0, 0, 0, 0); + TLorentzVector ArborFrNe(0, 0, 0, 0); + TLorentzVector ArborKPF(0, 0, 0, 0); + TLorentzVector PandoraTotalP(0, 0, 0, 0); + TLorentzVector ArborLCAL(0, 0, 0, 0); + TLorentzVector ArborISR(0, 0, 0, 0); + TLorentzVector PandoraISR(0, 0, 0, 0); + + // TODO: using the event header + // _eventNr = evtP->getEventNumber(); + + for(int i0 = 0; i0 < 4; i0++) { + TotalP_a[i0] = 0; + TotalP_p[i0] = 0; + ChP[i0] = 0; + PhP[i0] = 0; + NeP[i0] = 0; + FrP[i0] = 0; + UdP[i0] = 0; + FrPh[i0] = 0; + FrNe[i0] = 0; + KPF[i0] = 0; + if(i0 < 2) { + NeCaloE_a[i0] = 0; + NeCaloE_p[i0] = 0; + CluEnCom[i0] = 0; + ElargeP[i0] = 0; + EequP[i0] = 0; + EsmallP[i0] = 0; + } + if(i0 < 3) { + P[i0] = 0; + } + } + + nCHPFO_a = 0; + nCHPFO_p = 0; + nNEPFO_a = 0; + nNEPFO_p = 0; + Type = -100; + Charge = -100; + Energy = 0; + CluEn = 0; + TrkSumEn = 0; + + _EcalTotalE = 0; _HcalTotalE = 0; _EcalCluE = 0; _HcalCluE = 0; + _EcalCluE_p = 0; _HcalCluE_p = 0; + _HcalEn1=0;_HcalEn2=0;_HcalEn3=0;_HcalEn4=0;_HcalEn5=0; + _EcalEn1=0;_EcalEn2=0;_EcalEn3=0;_EcalEn4=0;_EcalEn5=0; + + _HDPID = -1; + _OriQuarkID = 0; + _OQDir = -10; + _HDir = -10; + _visE=0; + + _J1CosTheta = -2; + _J2CosTheta = -2; + + std::vector<CaloHitColHandler*> hdl_EcalHitColl{ + &m_ecalbarrelhitcol, + &m_ecalendcaphitcol + }; + std::vector<CaloHitColHandler*> hdl_HcalHitColl{ + &m_hcalbarrelhitcol, + &m_hcalendcaphitcol, + &m_hcalotherhitcol + }; + + std::vector<std::string> EcalHitColl; + std::vector<std::string> HcalHitColl; + EcalHitColl.push_back("ECALBarrel"); + EcalHitColl.push_back("ECALEndcap"); + //EcalHitColl.push_back("ECALOther"); + //EcalHitColl.push_back("LCAL"); + //EcalHitColl.push_back("LHCAL"); + HcalHitColl.push_back("HCALBarrel"); + HcalHitColl.push_back("HCALEndcap"); + HcalHitColl.push_back("HCALOther"); + + try{ + + for(int t = 0; t< int(hdl_EcalHitColl.size()); t++) { + const edm4hep::CalorimeterHitCollection* ecalcoll = hdl_EcalHitColl[t]->get(); + for(auto hit: *ecalcoll) { + // TODO + int NLayer = 0; + _EcalTotalE += hit.getEnergy(); + + // UTIL::CellIDDecoder<EVENT::CalorimeterHit> idDecoder(ECALCellIDDecoder); + // int NLayer = idDecoder(a_hit)["K-1"]; + //h_hit->Fill(NLayer,a_hit->getEnergy()); + if(NLayer < 6) { + _EcalEn1 += hit.getEnergy(); + } else if(NLayer < 12) { + _EcalEn2 += hit.getEnergy(); + } else if(NLayer < 18) { + _EcalEn3 += hit.getEnergy(); + } else if(NLayer < 24) { + _EcalEn4 += hit.getEnergy(); + } else{ + _EcalEn5 += hit.getEnergy(); + } + } + } + + for(int t2 = 0; t2< int(hdl_HcalHitColl.size()); t2++) { + const edm4hep::CalorimeterHitCollection* hcalcoll = hdl_HcalHitColl[t2]->get(); + for (auto hit: *hcalcoll) { + // TODO + int NLayer = 0; + int HLayer = NLayer+30; + // UTIL::CellIDDecoder<EVENT::CalorimeterHit> idDecoder(ECALCellIDDecoder); + // int NLayer = idDecoder(a_hit)["K-1"]; + + //h_hit->Fill(HLayer,a_hit->getEnergy()); + _HcalTotalE += hit.getEnergy(); + if(NLayer < 10) { + _HcalEn1 += hit.getEnergy(); + } else if(NLayer < 20) { + _HcalEn2 += hit.getEnergy(); + } else if(NLayer < 30) { + _HcalEn3 += hit.getEnergy(); + } else if(NLayer < 40) { + _HcalEn4 += hit.getEnergy(); + } else { + _HcalEn5 += hit.getEnergy(); + } + } + } + + + }catch(lcio::DataNotAvailableException err) { } + + try{ + auto MCPCol = m_mcParticle.get(); + + TVector3 tmpP; + TVector3 ISRP(0, 0, 0); + _N3En = 0; + _N3Pt = 0; + + int NNeutrinoCount = 0; + + for (int s0 = 0; s0 < MCPCol->size(); ++s0) { + auto MCP = (*MCPCol)[s0]; + int tmpPID = MCP.getPDG(); + int NParent = MCP.parents_size(); + int NDaughter = MCP.daughters_size(); + auto VTX0 = MCP.getVertex(); + auto EndP0 = MCP.getEndpoint(); + TVector3 VTX(VTX0.x, VTX0.y, VTX0.z); + TVector3 EndP(EndP0.x, EndP0.y, EndP0.z); + + if(tmpPID == 22 && NParent == 0 && s0 < 4) { + auto tmpP0 = MCP.getMomentum(); + tmpP = TVector3(tmpP0.x, tmpP0.y, tmpP0.z); + ISRP += tmpP; + } + + if( (abs(tmpPID) == 12 || abs(tmpPID) == 14 || abs(tmpPID) == 16) && NParent != 0 && NDaughter == 0 && VTX.Mag() < 100 && EndP.Mag() > 100) { + _NEn += tmpP.Mag(); + _NPt += tmpP.Perp(); + NNeutrinoCount++; + if(NNeutrinoCount > 2) { + auto tmpP0 = MCP.getMomentum(); + tmpP = TVector3(tmpP0.x, tmpP0.y, tmpP0.z); + _N3En += tmpP.Mag(); + _N3Pt += tmpP.Perp(); + cout<<"Found Neutrino: "<<NNeutrinoCount<<" En "<<_N3En<<" Pt "<<_N3Pt<<endl; + } + } + + if(tmpPID == 25 && NDaughter > 1 && NParent !=0 ) { //Higgs + // cout<<"tmpPID:HDPID"<<tmpPID<<" "<<NDaughter<<" "<<NParent<<endl; + _HDPID = abs(MCP.getDaughters(0).getPDG()); + _HDir = MCP.getMomentum()[2]/MCP.getEnergy(); + + if(NDaughter == 2) { + auto D1 = MCP.getDaughters(0); + _J1CosTheta = D1.getMomentum()[2]/D1.getEnergy(); + auto D2 = MCP.getDaughters(1); + _J2CosTheta = D2.getMomentum()[2]/D2.getEnergy(); + } + } + if(abs(tmpPID)<7 && NParent == 0) { + if(tmpPID>0) + _OriJ1CosTheta =MCP.getMomentum()[2]/MCP.getEnergy(); + else + _OriJ2CosTheta = MCP.getMomentum()[2]/MCP.getEnergy(); + } + + if(abs(tmpPID)<7 && NParent == 0) { + _OriQuarkID = abs(tmpPID); + _OQDir = MCP.getMomentum()[2]/MCP.getEnergy(); + } + + + if(abs(_J1CosTheta) > abs(_J2CosTheta)) + _MaxJetCosTheta = _J1CosTheta; + else + _MaxJetCosTheta = _J2CosTheta; + + if(abs(_OriJ1CosTheta) > abs(_OriJ2CosTheta)) + _MaxOriJetCosTheta = _OriJ1CosTheta; + else + _MaxOriJetCosTheta = _OriJ2CosTheta; + + if( (fabs(VTX.Z()) < 1000 && fabs(VTX.Perp()) < 1600 ) && ( fabs(EndP.Z()) > 2000 || fabs(EndP.Perp()) > 1600 )&&abs(tmpPID)!=12&&abs(tmpPID)!=14&&abs(tmpPID)!=16 ){ + _visE+=MCP.getEnergy(); + } + } + + _ISRPt = ISRP.Perp(); + _ISREn = ISRP.Mag(); + _ISRP[0] = ISRP.X(); + _ISRP[1] = ISRP.Y(); + _ISRP[2] = ISRP.Z(); + + }catch(lcio::DataNotAvailableException err) { } + + try{ + auto col_RecoNeP = m_reconep.get(); + for(int i0 = 0; i0 < col_RecoNeP->size(); i0++) { + auto a_RecoP = (*col_RecoNeP)[i0]; + TLorentzVector currP( a_RecoP.getMomentum()[0], a_RecoP.getMomentum()[1], a_RecoP.getMomentum()[2], a_RecoP.getEnergy()); + ArborTotalP += currP; + auto currMom0 = a_RecoP.getMomentum(); + TVector3 currMom(currMom0.x, currMom0.y, currMom0.z); + // if(a_RecoP->getType() == 22 && a_RecoP->getEnergy() > 2) //Compensate... + // ArborTotalP += 0.98*currP; + // else + // ArborTotalP += currP; + + if(a_RecoP.getCharge() != 0) { + ArborChP += currP; + } else if(a_RecoP.getType() == 310) { + ArborKPF += currP; + } else if(a_RecoP.getType() == 22) { + if(a_RecoP.getEnergy() < 3.0) + ArborFrPh += currP; + else + ArborPhP += currP; + } else if(a_RecoP.getType() == 2112) { + if(a_RecoP.getEnergy() < 3.0) + ArborFrNe += currP; + else + ArborNeP += currP; + } else if(a_RecoP.getEnergy() < 3.0) { + ArborFrP += currP; + cout<<"Undef "<<a_RecoP.getType()<<endl; + } else { + ArborUdP += currP; + cout<<"Undef "<<a_RecoP.getType() << "En "<<a_RecoP.getEnergy()<<endl; + } + + if(a_RecoP.clusters_size() > 0) { + auto a_clu = a_RecoP.getClusters(0); + auto CluPos0 = a_clu.getPosition(); + TVector3 CluPos(CluPos0.x, CluPos0.y, CluPos0.z); + if( CluPos.Perp() < 300 && abs(CluPos.Z()) < 1300 && a_RecoP.getCharge() == 0 ) // 1150-1300 + ArborLCAL += currP; + + float MinAngleToCH = 1.0E6; + float MinAngleToNE = 1.0E6; + + if(a_RecoP.getEnergy() > 5 && a_RecoP.getCharge() == 0) { + for(int i1 = 0; i1 < col_RecoNeP->size(); i1++) { + if(i1 != i0) { + auto b_RecoP = (*col_RecoNeP)[i1]; + auto tmpMom0 = b_RecoP.getMomentum(); + TVector3 tmpMom(tmpMom0.x, tmpMom0.y, tmpMom0.z); + float tmpAngle = currMom.Angle(tmpMom); + if( b_RecoP.getEnergy() > 3.0 ) { + if(b_RecoP.getCharge() != 0) { + if(tmpAngle < MinAngleToCH) { + MinAngleToCH = tmpAngle; + } + } else { + if(tmpAngle < MinAngleToNE) { + MinAngleToNE = tmpAngle; + } + } + } + } + } + + if( MinAngleToNE > 0.5 || MinAngleToCH > 0.5 ) { + ArborISR += currP; + } + } + } + + TrackHit = 0; + for(int k = 0; k < 3; k++) { + StartPos[k] = 0; + EndPos[k] = 0; + } + + Charge = int(a_RecoP.getCharge()); + CluEn = 0; + CluEnCom[0] = 0; + CluEnCom[1] = 0; + + if(Charge) { + Type = 1; + nCHPFO_a ++; + } else { + Type = 0; + nNEPFO_a ++; + } + + Energy = a_RecoP.getEnergy(); + P[0] = a_RecoP.getMomentum()[0]; + P[1] = a_RecoP.getMomentum()[1]; + P[2] = a_RecoP.getMomentum()[2]; + + if(a_RecoP.clusters_size() > 0) { + + auto currClu = a_RecoP.getClusters(0); + CluEn = currClu.getEnergy(); + + if((!Charge) and (currClu.subdetectorEnergies_size() > 2)) { + CluEnCom[0] = currClu.getSubdetectorEnergies(0); + CluEnCom[1] = currClu.getSubdetectorEnergies(1); + NeCaloE_a[0] += currClu.getSubdetectorEnergies(0); + NeCaloE_a[1] += currClu.getSubdetectorEnergies(1); + } + + if (currClu.subdetectorEnergies_size() > 2) { + _EcalCluE += currClu.getSubdetectorEnergies(0); + _HcalCluE += currClu.getSubdetectorEnergies(1); + } + + + if(Charge) { + TrkSumEn += Energy; + + if (a_RecoP.tracks_size()>0) { + auto a_Trk = a_RecoP.getTracks(0); + TrackHit = a_Trk.trackerHits_size(); + + if (TrackHit>2) { + StartPos[0] = (a_Trk.getTrackerHits(0)).getPosition()[0]; + StartPos[1] = (a_Trk.getTrackerHits(0)).getPosition()[1]; + StartPos[2] = (a_Trk.getTrackerHits(0)).getPosition()[2]; + + EndPos[0] = (a_Trk.getTrackerHits(TrackHit - 1)).getPosition()[0]; + EndPos[1] = (a_Trk.getTrackerHits(TrackHit - 1)).getPosition()[1]; + EndPos[2] = (a_Trk.getTrackerHits(TrackHit - 1)).getPosition()[2]; + } + } + + if( Energy > CluEn + sqrt(Energy)) { + ElargeP[0] += Energy; + ElargeP[1] += CluEn; + } else if( fabs(Energy - CluEn) < sqrt(Energy) ) { + EequP[0] += Energy; + EequP[1] += CluEn; + } else { + EsmallP[0] += Energy; + EsmallP[1] += CluEn; + } + + } + } + + _outputPFO->Fill(); + + } + }catch (lcio::DataNotAvailableException err) { } + + try{ + //LCCollection* col_RecoPandora = evtP->getCollection( "PandoraPFOs" ); + //for(int i2 = 0; i2 < col_RecoPandora->getNumberOfElements(); i2++) + for(int s = 0; s < 1; s++) { + auto col_PFO_iter = m_arbopfo.get(); + /* + if(s==0) + col_PFO_iter = evtP->getCollection( "ArborChargedCore" ); + else + col_PFO_iter = evtP->getCollection( "ArborNeutralCore" ); + */ + + for(int i2 = 0; i2 < col_PFO_iter->size(); i2++) { + auto a_RecoP = (*col_PFO_iter)[i2]; + TLorentzVector currP( a_RecoP.getMomentum()[0], a_RecoP.getMomentum()[1], a_RecoP.getMomentum()[2], a_RecoP.getEnergy()); + PandoraTotalP += currP; + + if(a_RecoP.getCharge()) { + nCHPFO_p++; + } else { + nNEPFO_p++; + } + + auto currMom0 = a_RecoP.getMomentum(); + TVector3 currMom(currMom0.x, currMom0.y, currMom0.z); + + if(a_RecoP.clusters_size() > 0) { + + float MinAngleToCH = 1.0E6; + float MinAngleToNE = 1.0E6; + + auto currClu = a_RecoP.getClusters(0); + CluEn = currClu.getEnergy(); + + _EcalCluE_p += CluEn; + _HcalCluE_p += currClu.getSubdetectorEnergies(1); + + if(a_RecoP.getEnergy() > 5 && a_RecoP.getCharge() == 0) { + for(int i3 = 0; i3 < col_PFO_iter->size(); i3++) { + if(i3 != i2) { + auto b_RecoP = (*col_PFO_iter)[i3]; + auto tmpMom0 = b_RecoP.getMomentum(); + TVector3 tmpMom(tmpMom0.x, tmpMom0.y, tmpMom0.z); + float tmpAngle = currMom.Angle(tmpMom); + if( b_RecoP.getEnergy() > 3.0 ) { + if(b_RecoP.getCharge() != 0) { + if(tmpAngle < MinAngleToCH) { + MinAngleToCH = tmpAngle; + } + } else { + if(tmpAngle < MinAngleToNE) { + MinAngleToNE = tmpAngle; + } + } + } + } + } + + if( MinAngleToNE > 0.5 || MinAngleToCH > 0.5 ) { + PandoraISR += currP; + } + } + } + } + } + }catch (lcio::DataNotAvailableException err) { } + + _Mass_a = 0; + _Mass_p = 0; + _Mass_a_Pisr = 0; + _Mass_a_Plcal = 0; + _Mass_p_Pisr = 0; + + _Mass_a = ArborTotalP.M(); + _Mass_p = PandoraTotalP.M(); + + _Mass_a_Pisr = (ArborTotalP - ArborISR).M(); + _Mass_a_Plcal = (ArborTotalP - ArborLCAL).M(); + _Mass_p_Pisr = (PandoraTotalP - PandoraISR).M(); + + TotalP_a[0] = ArborTotalP.X(); + TotalP_a[1] = ArborTotalP.Y(); + TotalP_a[2] = ArborTotalP.Z(); + TotalP_a[3] = ArborTotalP.T(); + + TotalP_p[0] = PandoraTotalP.X(); + TotalP_p[1] = PandoraTotalP.Y(); + TotalP_p[2] = PandoraTotalP.Z(); + TotalP_p[3] = PandoraTotalP.T(); + + ChP[0] = ArborChP.X(); + ChP[1] = ArborChP.Y(); + ChP[2] = ArborChP.Z(); + ChP[3] = ArborChP.T(); + + PhP[0] = ArborPhP.X(); + PhP[1] = ArborPhP.Y(); + PhP[2] = ArborPhP.Z(); + PhP[3] = ArborPhP.T(); + + NeP[0] = ArborNeP.X(); + NeP[1] = ArborNeP.Y(); + NeP[2] = ArborNeP.Z(); + NeP[3] = ArborNeP.T(); + + FrP[0] = ArborFrP.X(); + FrP[1] = ArborFrP.Y(); + FrP[2] = ArborFrP.Z(); + FrP[3] = ArborFrP.T(); + + UdP[0] = ArborUdP.X(); + UdP[1] = ArborUdP.Y(); + UdP[2] = ArborUdP.Z(); + UdP[3] = ArborUdP.T(); + + FrPh[0] = ArborFrPh.X(); + FrPh[1] = ArborFrPh.Y(); + FrPh[2] = ArborFrPh.Z(); + FrPh[3] = ArborFrPh.T(); + + FrNe[0] = ArborFrNe.X(); + FrNe[1] = ArborFrNe.Y(); + FrNe[2] = ArborFrNe.Z(); + FrNe[3] = ArborFrNe.T(); + + KPF[0] = ArborKPF.X(); + KPF[1] = ArborKPF.Y(); + KPF[2] = ArborKPF.Z(); + KPF[3] = ArborKPF.T(); + + cout<<_Mass_a<<" : "<<_Mass_p<<endl; + + _outputTree->Fill(); + _Num++; + // } + + + info() << "TotalInvMass::execute done" << endmsg; + + return StatusCode::SUCCESS; + +} + +StatusCode TotalInvMass::finalize() +{ + + if (_outputTree) { + + TFile *tree_file = _outputTree->GetCurrentFile(); //just in case we switched to a new file + tree_file->Write(); + delete tree_file; + } + + return GaudiAlgorithm::finalize(); +} + + + diff --git a/Analysis/TotalInvMass/src/TotalInvMass.hh b/Analysis/TotalInvMass/src/TotalInvMass.hh new file mode 100644 index 0000000000000000000000000000000000000000..98a36eeacf870e3728475947e7fb3811ed037cc4 --- /dev/null +++ b/Analysis/TotalInvMass/src/TotalInvMass.hh @@ -0,0 +1,125 @@ +#ifndef _TotalInvMass_hh_ +#define _TotalInvMass_hh_ + +#include "GaudiAlg/GaudiAlgorithm.h" +#include "GaudiKernel/Property.h" + +#include "k4FWCore/DataHandle.h" + +#include <string> +#include <iostream> +#include <fstream> +#include <TNtuple.h> +#include <TObject.h> +#include <TTree.h> +#include <TFile.h> + +#include "edm4hep/MCParticleCollection.h" +#include "edm4hep/CalorimeterHitCollection.h" +#include "edm4hep/ReconstructedParticleCollection.h" + +class TotalInvMass : public GaudiAlgorithm +{ +public: + + TotalInvMass(const std::string& name, ISvcLocator* svcLoc); + + ~TotalInvMass() {}; + + StatusCode initialize() override; + + StatusCode execute() override; + + StatusCode finalize() override; + +protected: + typedef DataHandle<edm4hep::MCParticleCollection> MCParticleColHandler; + MCParticleColHandler m_mcParticle{"MCParticle", Gaudi::DataHandle::Reader, this}; + + typedef DataHandle<edm4hep::CalorimeterHitCollection> CaloHitColHandler; + CaloHitColHandler m_ecalbarrelhitcol{"ECALBarrel", Gaudi::DataHandle::Reader, this}; + CaloHitColHandler m_ecalendcaphitcol{"ECALEndcap", Gaudi::DataHandle::Reader, this}; + + CaloHitColHandler m_hcalbarrelhitcol{"HCALBarrel", Gaudi::DataHandle::Reader, this}; + CaloHitColHandler m_hcalendcaphitcol{"HCALEndcap", Gaudi::DataHandle::Reader, this}; + CaloHitColHandler m_hcalotherhitcol {"HCALOther", Gaudi::DataHandle::Reader, this}; + + typedef DataHandle<edm4hep::ReconstructedParticleCollection> RecParticleColHandler; + RecParticleColHandler m_reconep{"AncientPFOs", Gaudi::DataHandle::Reader, this}; + RecParticleColHandler m_arbopfo{"ArborLICHPFOs", Gaudi::DataHandle::Reader, this}; + + Gaudi::Property<std::string> _treeFileName{this, + "TreeOutputFile", "MCTruth.root", + "The name of the file to which the ROOT tree will be written"}; + Gaudi::Property<std::string> _treeName{this, + "TreeName", "MCPart", + "The name of the ROOT tree"}; + std::string _colName; + std::string _colAdcVals; + + Gaudi::Property<int> _overwrite{this, + "OverwriteFile", 0, + "If zero an already existing file will not be overwritten."}; + int _leptonID; + float _cmsE; + TTree *_outputTree, *_outputPFO; + float _ISRP[3]; + float _ISREn, _ISRPt; + float _N3En, _N3Pt; + float _NEn, _NPt; + + int _HDPID, _OriQuarkID; + float _OQDir, _HDir; + int _NMuP, _NMuM, _NChP, _NChM; + float _P_MuP[4], _P_MuM[4], _P_DL[4]; + int _EventType; + float _InvMass, _RecoilMass; + float _J1CosTheta, _J2CosTheta, _MaxJetCosTheta; + float _OriJ1CosTheta, _OriJ2CosTheta, _MaxOriJetCosTheta; + float _Mass_a, _Mass_p; + + int _PID1, _PID2; + float _PL1[4], _PL2[4], _RPL1[4], _RPL2[4], _SM[4], _P_allCharged[4], _P_allNeutral[4], _P_Higgs[4], _P_allReco[4]; + float _Hmass; + int _Num; + int _NHDaug; + int _HdaughterPID; + int _ZdaughterPID; + float _Pz[4], _Ph[4], _PzD1[4], _PzD2[4], _PhD1[4], _PhD2[4], _RPzD1[4], _RPzD2[4], _RPhD1[4], _RPhD2[4]; + float _P[4], _SumP[4], _VisP[4], _MissP[4]; + int _PID, _NFMCP, _MotherFlag, _NNeutrino; + float _ENeutrino, _DiPhMass, _DiPhMassCorr; + // float _CosTheta, _Phi, _Charge; + float _Mz, _Mrecoil, _MzReco, _MhReco, _MrecoilReco; + float KthEn[7][9]; + unsigned int _eventNr; + + float _Mass_p_Pisr, _Mass_a_Pisr, _Mass_a_Plcal; + + float TotalP_a[4], TotalP_p[4]; + int nCHPFO_a, nCHPFO_p, nNEPFO_a, nNEPFO_p; + float NeCaloE_a[2], NeCaloE_p[2]; + float ElargeP[2], EequP[2], EsmallP[2]; + + float ChP[4], FrP[4], PhP[4], NeP[4], UdP[4], FrPh[4], FrNe[4], KPF[4]; + float _EcalTotalE, _HcalTotalE, _EcalCluE, _HcalCluE, _EcalCluE_p, _HcalCluE_p; + float _HcalEn1, _HcalEn2,_HcalEn3,_HcalEn4,_HcalEn5; + float _EcalEn1, _EcalEn2,_EcalEn3,_EcalEn4,_EcalEn5; + + int Type, Charge; + float Energy, TrkSumEn; + float P[3], CluEnCom[2]; + float CluEn; + + int TrackHit; + float StartPos[3], EndPos[3]; + float _visE; + + std::string _fileName; + std::ostream *_output; + std::string _histFileName; +}; + +#endif + + diff --git a/Examples/options/tut_analysis_TotalInvMass.py b/Examples/options/tut_analysis_TotalInvMass.py new file mode 100644 index 0000000000000000000000000000000000000000..eb7faebb30a6907790371ff4677735c2ece03b11 --- /dev/null +++ b/Examples/options/tut_analysis_TotalInvMass.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +from Gaudi.Configuration import * + +from Configurables import k4DataSvc +dsvc = k4DataSvc("EventDataSvc") + +# read LCIO files +from Configurables import k4LCIOInput +lcioinput = k4LCIOInput("k4LCIOInput") + +import glob + +# inputlists = ["/cefs/higgs/yudan/CEPC240/Reco_tpc_1800/qqh/Reco_qqh__00001.slcio"] +inputlists = ["/cefs/higgs/yudan/CEPC240/Reco_tpc_1800/qqh/Reco_qqh__00003.slcio"] +# inputlists = glob.glob("/cefs/higgs/yudan/CEPC240/Reco_tpc_1800/qqh/Reco_qqh__*.slcio") + +lcioinput.inputs = inputlists +lcioinput.collections = [ + "MCParticle:MCParticle", + "CalorimeterHit:ECALBarrel", + "CalorimeterHit:ECALEndcap", + "CalorimeterHit:HCALBarrel", + "CalorimeterHit:HCALEndcap", + "CalorimeterHit:HCALOther", + "ReconstructedParticle:AncientPFOs", + "ReconstructedParticle:ArborLICHPFOs" +] + +from Configurables import TotalInvMass +total_inv_mass = TotalInvMass("TotalInvMass") + +# # write PODIO file +# from Configurables import PodioOutput +# write = PodioOutput("write") +# write.filename = "test.root" +# write.outputCommands = ["keep *"] + +# ApplicationMgr +from Configurables import ApplicationMgr +ApplicationMgr( + TopAlg = [lcioinput, total_inv_mass], + EvtSel = 'NONE', + EvtMax = -1, + ExtSvc = [dsvc], + OutputLevel=INFO #DEBUG +) +