StatusCode CorrectECalBarrelSliWinCluster::execute() { // Get the input collection with clusters const fcc::CaloClusterCollection* inClusters = m_inClusters.get(); fcc::CaloClusterCollection* correctedClusters = m_correctedClusters.createAndPut(); // for single particle events compare with truth particles TVector3 momentum; double phiVertex = 0; double etaVertex = 0; double thetaVertex = 0; double zVertex = 0; const auto particle = m_particle.get(); const auto vertex = m_vertex.get(); if (particle->size() == 1 && vertex->size() == 1) { for(const auto& part : *particle) { momentum = TVector3(part.core().p4.px, part.core().p4.py, part.core().p4.pz); etaVertex = momentum.Eta(); phiVertex = momentum.Phi(); zVertex = vertex->begin()->position().z; thetaVertex = 2 * atan( exp( - etaVertex ) ); verbose() << " vertex eta " << etaVertex << " phi = " << phiVertex << " theta = " << thetaVertex << " z = " << zVertex << endmsg; } } // TODO change that so all systems can be used uint systemId = m_systemId[0]; const dd4hep::DDSegmentation::FCCSWGridPhiEta* segmentation = nullptr; if (m_segmentationPhiEta[systemId] != nullptr) { segmentation = m_segmentationPhiEta[systemId]; } std::vector<TLorentzVector> clustersMassInv; std::vector<TLorentzVector> clustersMassInvScaled; for (const auto& cluster : *inClusters) { double oldEnergy = 0; TVector3 pos(cluster.core().position.x, cluster.core().position.y, cluster.core().position.z); double oldEta = pos.Eta(); double oldPhi = pos.Phi(); for (auto cell = cluster.hits_begin(); cell != cluster.hits_end(); cell++) { oldEnergy += cell->core().energy; } verbose() << " OLD ENERGY = " << oldEnergy << " from " << cluster.hits_size() << " cells" << endmsg; verbose() << " OLD CLUSTER ENERGY = " << cluster.core().energy << endmsg; // Do everything only using the first defined calorimeter (default: Ecal barrel) double oldEtaId = -1; double oldPhiId = -1; if (m_segmentationPhiEta[systemId] != nullptr) { oldEtaId = int(floor((oldEta + 0.5 * segmentation->gridSizeEta() - segmentation->offsetEta()) / segmentation->gridSizeEta())); oldPhiId = int(floor((oldPhi + 0.5 * segmentation->gridSizePhi() - segmentation->offsetPhi()) / segmentation->gridSizePhi())); } // 0. Create new cluster, copy information from input fcc::CaloCluster newCluster = correctedClusters->create(); double energy = 0; newCluster.core().position.x = cluster.core().position.x; newCluster.core().position.y = cluster.core().position.y; newCluster.core().position.z = cluster.core().position.z; for (auto cell = cluster.hits_begin(); cell != cluster.hits_end(); cell++) { if (m_segmentationMulti[systemId] != nullptr) { segmentation = dynamic_cast<const dd4hep::DDSegmentation::FCCSWGridPhiEta*>(&m_segmentationMulti[systemId]->subsegmentation(cell->core().cellId)); oldEtaId = int(floor((oldEta + 0.5 * segmentation->gridSizeEta() - segmentation->offsetEta()) / segmentation->gridSizeEta())); oldPhiId = int(floor((oldPhi + 0.5 * segmentation->gridSizePhi() - segmentation->offsetPhi()) / segmentation->gridSizePhi())); } if (m_decoder[systemId]->get(cell->core().cellId, "system") == systemId) { uint layerId = m_decoder[systemId]->get(cell->core().cellId, "layer"); if(m_nPhiFinal[layerId] > 0 && m_nEtaFinal[layerId] > 0) { uint etaId = m_decoder[systemId]->get(cell->core().cellId, "eta"); uint phiId = m_decoder[systemId]->get(cell->core().cellId, "phi"); if ( etaId >= (oldEtaId - m_halfEtaFin[layerId]) && etaId <= (oldEtaId + m_halfEtaFin[layerId]) && phiId >= phiNeighbour((oldPhiId - m_halfPhiFin[layerId]), segmentation->phiBins()) && phiId <= phiNeighbour((oldPhiId + m_halfPhiFin[layerId]), segmentation->phiBins()) ) { if (m_ellipseFinalCluster) { if ( pow( (etaId - oldEtaId) / (m_nEtaFinal[layerId] / 2.), 2) + pow( (phiId - oldPhiId) / (m_nPhiFinal[layerId] / 2.), 2) < 1) { newCluster.addhits(*cell); energy += cell->core().energy; } } else { newCluster.addhits(*cell); energy += cell->core().energy; } } } } } newCluster.core().energy = energy; // 1. Correct eta position with log-weighting double sumEnFirstLayer = 0; // get current pseudorapidity std::vector<double> sumEnLayer; std::vector<double> sumEnLayerSorted; std::vector<double> sumEtaLayer; std::vector<double> sumWeightLayer; sumEnLayer.assign(m_numLayers, 0); sumEnLayerSorted.assign(m_numLayers, 0); sumEtaLayer.assign(m_numLayers, 0); sumWeightLayer.assign(m_numLayers, 0); // first check the energy deposited in each layer for (auto cell = newCluster.hits_begin(); cell != newCluster.hits_end(); cell++) { dd4hep::DDSegmentation::CellID cID = cell->core().cellId; uint layer = m_decoder[systemId]->get(cID, m_layerFieldName) + m_firstLayerId; sumEnLayer[layer] += cell->core().energy; } // sort energy to check value of 2nd highest, 3rd highest etc for (uint iLayer = 0; iLayer < m_numLayers; iLayer++) { sumEnLayerSorted[iLayer] = sumEnLayer[iLayer]; } std::sort(sumEnLayerSorted.begin(),sumEnLayerSorted.end(),std::greater<double>()); sumEnFirstLayer = sumEnLayer[0]; // repeat but calculating eta barycentre in each layer for (auto cell = newCluster.hits_begin(); cell != newCluster.hits_end(); cell++) { if (m_segmentationMulti[systemId] != nullptr) { segmentation = dynamic_cast<const dd4hep::DDSegmentation::FCCSWGridPhiEta*>(&m_segmentationMulti[systemId]->subsegmentation(cell->core().cellId)); } dd4hep::DDSegmentation::CellID cID = cell->core().cellId; uint layer = m_decoder[systemId]->get(cID, m_layerFieldName) + m_firstLayerId; double weightLog = std::max(0., m_etaRecalcLayerWeights[layer] + log(cell->core().energy / sumEnLayer[layer])); double eta = segmentation->eta(cell->core().cellId); sumEtaLayer[layer] += (weightLog * eta); sumWeightLayer[layer] += weightLog; } // calculate eta position weighting with energy deposited in layer // this energy is a good estimator of 1/sigma^2 of (eta_barycentre-eta_MC) distribution double layerWeight = 0; double sumLayerWeight = 0; double sumLayerWeight2point = 0; double newEta = 0; double newEtaErrorRes = 0; double newEtaErrorRes2point = 0; for (uint iLayer = 0; iLayer < m_numLayers; iLayer++) { if (sumWeightLayer[iLayer] > 1e-10) { sumEtaLayer[iLayer] /= sumWeightLayer[iLayer]; newEta += sumEtaLayer[iLayer] * sumEnLayer[iLayer]; layerWeight = 1. / (pow(m_etaLayerResolutionSampling[iLayer], 2) / energy + pow(m_etaLayerResolutionConst[iLayer], 2)); sumLayerWeight += layerWeight; newEtaErrorRes += sumEtaLayer[iLayer] * layerWeight; if (iLayer == 1 || iLayer == 2) { newEtaErrorRes2point += sumEtaLayer[iLayer] * layerWeight; sumLayerWeight2point += layerWeight; } } } newEta /= energy; newEtaErrorRes /= sumLayerWeight; newEtaErrorRes2point /= sumLayerWeight2point; // alter Cartesian position of a cluster using new eta position double radius = pos.Perp(); double phi = pos.Phi(); newCluster.core().position.x = radius * cos(phi); newCluster.core().position.y = radius * sin(phi); newCluster.core().position.z = radius * sinh(newEta); // 2. Correct energy for pileup noise uint numCells = newCluster.hits_size(); double noise = 0; if (m_constPileupNoise == 0) { noise = getNoiseConstantPerCluster(newEta, numCells) * m_gauss.shoot() * std::sqrt(static_cast<int>(m_mu)); verbose() << " NUM CELLS = " << numCells << " cluster noise const = " << getNoiseConstantPerCluster(newEta, numCells) << " scaled to PU " << m_mu<< " = " << getNoiseConstantPerCluster(newEta, numCells)* std::sqrt(static_cast<int>(m_mu)) << endmsg; } else { noise = m_constPileupNoise * m_gauss.shoot() * std::sqrt(static_cast<int>(m_mu)); } newCluster.core().energy += noise; m_hPileupEnergy->Fill(noise); // 3. Correct for energy upstream // correct for presampler based on energy in the first layer layer: // check eta of the cluster and get correction parameters: double P00 = 0, P01 = 0, P10 = 0, P11 = 0; for (uint iEta = 0; iEta < m_etaBorders.size(); iEta++) { if (fabs(newEta) < m_etaBorders[iEta]) { P00 = m_presamplerShiftP0[iEta]; P01 = m_presamplerShiftP1[iEta]; P10 = m_presamplerScaleP0[iEta]; P11 = m_presamplerScaleP1[iEta]; break; } } // if eta is larger than the last available eta values, take the last known parameters if (fabs(newEta) > m_etaBorders.back()) { warning() << "cluster eta = " << newEta << " is larger than last defined eta values." << endmsg; //return StatusCode::FAILURE; } double presamplerShift = P00 + P01 * cluster.core().energy; double presamplerScale = P10 + P11 * sqrt(cluster.core().energy); double energyFront = presamplerShift + presamplerScale * sumEnFirstLayer * m_samplingFraction[0]; m_hUpstreamEnergy->Fill(energyFront); newCluster.core().energy += energyFront; // Fill histograms m_hEnergyPreAnyCorrections->Fill(oldEnergy); m_hEnergyPostAllCorrections->Fill(newCluster.core().energy); m_hEnergyPostAllCorrectionsAndScaling->Fill(newCluster.core().energy / m_response); // Position resolution m_hEta->Fill(newEta); m_hPhi->Fill(phi); verbose() << " energy " << energy << " numCells = " << numCells << " old energy = " << oldEnergy << " newEta " << newEta << " phi = " << phi << " theta = " << 2 * atan( exp( - newEta ) ) << endmsg; m_hNumCells->Fill(numCells); // Fill histograms for single particle events if (particle->size() == 1) { m_hDiffEta->Fill(newEta - etaVertex); m_hDiffEtaResWeight->Fill(newEtaErrorRes - etaVertex); m_hDiffEtaResWeight2point->Fill(newEtaErrorRes2point - etaVertex); for(uint iLayer = 0; iLayer < m_numLayers; iLayer++) { m_hDiffEtaLayer[iLayer]->Fill(sumEtaLayer[iLayer] - etaVertex); if (energy > 0) m_hEnergyFractionInLayers->Fill(iLayer+1, sumEnLayer[iLayer] / energy); } m_hDiffPhi->Fill(phi - phiVertex); } } return StatusCode::SUCCESS; }
int xAna::HggTreeWriteLoop(const char* filename, int ijob, bool correctVertex, bool correctEnergy, bool setRho0 ) { //bool invDRtoTrk = false; if( _config == 0 ) { cout << " config file was not set properly... bail out" << endl; return -1; } if (fChain == 0) return -1; Long64_t nentries = fChain->GetEntriesFast(); // nentries = 10000; cout << "nentries: " << nentries << endl; Long64_t entry_start = ijob *_config->nEvtsPerJob(); Long64_t entry_stop = (ijob+1)*_config->nEvtsPerJob(); if( _config->nEvtsPerJob() < 0 ) { entry_stop = nentries; } if( entry_stop > nentries ) entry_stop = nentries; cout << " *** doing entries from: " << entry_start << " -> " << entry_stop << endl; if( entry_start > entry_stop ) return -1; EnergyScaleReader enScaleSkimEOS; /// skim EOS bugged so need to undo the energy scale in the skim EnergyScaleReader enScale; // enScaleSkimEOS.setup( "ecalCalibFiles/EnergyScale2012_Lisbon_9fb.txt" ); enScale.setup( _config->energyScaleFile() ); Float_t HiggsMCMass = _weight_manager->getCrossSection()->getHiggsMass(); Float_t HiggsMCPt = -1; bool isHiggsSignal = false; if( HiggsMCMass > 0 ) isHiggsSignal = true; mode_ = _weight_manager->getCrossSection()->mode(); isData = false; if(mode_==-1) isData = true; // mode_ = ijob; // DoCorrectVertex_ = correctVertex; DoCorrectEnergy_ = correctEnergy; DoSetRho0_ = setRho0; doJetRegression = _config->getDoJetRegression(); doControlSample = _config->getDoControlSample(); phoID_2011[0] = new TMVA::Reader("!Color:Silent"); phoID_2011[1] = new TMVA::Reader("!Color:Silent"); phoID_2012[0] = new TMVA::Reader("!Color:Silent"); phoID_2012[1] = new TMVA::Reader("!Color:Silent"); DiscriDiPho_2011 = new TMVA::Reader("!Color:Silent"); DiscriDiPho_2012 = new TMVA::Reader("!Color:Silent"); if(doJetRegression!=0) jetRegres = new TMVA::Reader("!Color:Silent"); Setup_MVA(); if( _config->setup() == "ReReco2011" ) for( int i = 0 ; i < 2; i++ ) phoID_mva[i] = phoID_2011[i]; else for( int i = 0 ; i < 2; i++ ) phoID_mva[i] = phoID_2012[i]; MassResolution massResoCalc; massResoCalc.addSmearingTerm(); if( _config->setup() == "ReReco2011" ) Ddipho_mva = DiscriDiPho_2011; else Ddipho_mva = DiscriDiPho_2012; float Ddipho_cat[5]; Ddipho_cat[4] = -1; if( _config->setup() == "ReReco2011" ) { Ddipho_cat[0] = 0.89; Ddipho_cat[1] = 0.72; Ddipho_cat[2] = 0.55; Ddipho_cat[3] = +0.05; } else { Ddipho_cat[0] = 0.91; Ddipho_cat[1] = 0.79; Ddipho_cat[2] = 0.49; Ddipho_cat[3] = -0.05; } // else { Ddipho_cat[0] = 0.88; Ddipho_cat[1] = 0.71; Ddipho_cat[2] = 0.50; Ddipho_cat[3] = -0.05; } DiscriVBF_UseDiPhoPt = true; DiscriVBF_UsePhoPt = true; DiscriVBF_cat.resize(2); DiscriVBF_cat[0] = 0.985; DiscriVBF_cat[1] = 0.93; DiscriVBF_useMvaSel = _config->doVBFmvaCat(); /// depending on the selection veto or not on electrons (can do muele, elemu,eleele) bool vetoElec[2] = {true,true}; if( _config->invertElectronVeto() ) { vetoElec[0] = false; vetoElec[1] = false; } if( _config->isEleGamma() ) { vetoElec[0] = false; vetoElec[1] = true ; } if( _config->isGammaEle() ) { vetoElec[0] = true ; vetoElec[1] = false; } cout << " --------- veto electron config -----------" << endl; cout << " Leading Pho VetoElec: " << vetoElec[0] << endl; cout << " Trailing Pho VetoElec: " << vetoElec[1] << endl; DoDebugEvent = true; bool DoPreselection = true; // bool DoPrint = true; TString VertexFileNamePrefix; TRandom3 *rnd = new TRandom3(); rnd->SetSeed(0); /// output tree and cross check file _xcheckTextFile.open(TString(filename)+".xcheck.txt"); // _xcheckTextFile = cout; _minitree = new MiniTree( filename ); TTree * tSkim = 0; if( _config->doSkimming() ) tSkim = (TTree*) fChain->CloneTree(0); InitHists(); _minitree->mc_wXsec = _weight_manager->xSecW(); _minitree->mc_wNgen = 100000./_weight_manager->getNevts(); if( isData ) { _minitree->mc_wXsec = 1; _minitree->mc_wNgen = 1; } Int_t isprompt0 = -1; Int_t isprompt1 = -1; set<Long64_t> syncEvt; cout <<" ================ mode " << mode_ <<" =============================== "<<endl; /// setupType has to be passed via config file // photonOverSmearing overSmearICHEP("Test52_ichep"); photonOverSmearing overSmearHCP( "oversmear_hcp2012" ); photonOverSmearing overSmear( _config->setup() ); int overSmearSyst = _config->getEnergyOverSmearingSyst(); Long64_t nbytes = 0, nb = 0; //////////////////////////////////////////////////////////////////////////// //////////////////////////// Start the loop //////////////////////////////// //////////////////////////////////////////////////////////////////////////// vector<int> nEvts; vector<string> nCutName; nCutName.push_back("TOTAL :"); nEvts.push_back(0); nCutName.push_back("2 gammas :"); nEvts.push_back(0); nCutName.push_back("triggers :"); nEvts.push_back(0); nCutName.push_back("nan weight :"); nEvts.push_back(0); nCutName.push_back("presel kin cuts:"); nEvts.push_back(0); nCutName.push_back("pass 2 gam incl:"); nEvts.push_back(0); nCutName.push_back("pass all :"); nEvts.push_back(0); nCutName.push_back(" --> pass 2 gam lep: "); nEvts.push_back(0); nCutName.push_back(" --> pass 2 gam vbf: "); nEvts.push_back(0); vector<int> selVtxSumPt2(3); selVtxSumPt2[0] = 0; selVtxSumPt2[1] = -1; selVtxSumPt2[2] = -1; for (Long64_t jentry=entry_start; jentry< entry_stop ; ++jentry) { Long64_t ientry = LoadTree(jentry); if (ientry < -9999) break; if( jentry % 10000 == 0) cout<<"processing event "<<jentry<<endl; nb = fChain->GetEntry(jentry); nbytes += nb; /// reset minitree variables _minitree->initEvent(); // study mc truth block if( !isData ) { fillMCtruthInfo_HiggsSignal(); _minitree->fillMCtrueOnly(); } /// reco analysis unsigned icutlevel = 0; nEvts[icutlevel++]++; if( nPho < 2 ) continue; nEvts[icutlevel++]++; /// set synchronisation flag if( syncEvt.find(event) != syncEvt.end() ) DoDebugEvent = true; else DoDebugEvent = false; if( DoDebugEvent ) _xcheckTextFile << "==========================================================" << endl; if( DoDebugEvent ) _xcheckTextFile << "================= debugging event: " << event << endl; /// PU & BSz reweightings if( !isData ) { int itpu = 1; /// 0 without OOT PU - 1 with OOT PU _minitree->mc_wPU = _weight_manager->puW( nPU[itpu] ); // PUwei = _weight_manager->puWTrue( puTrue[itpu] ); } hTotEvents->Fill(1,_minitree->mc_wPU); bool sigWH = false ; bool sigZH = false ; int mc_whzh_type = 0; _minitree->mc_wHQT = 1; if( isHiggsSignal ) { if ( _weight_manager->getCrossSection()->getMCType() == "vh" ) for( Int_t i=0; i < nMC && i <= 1; ++i ) { if( abs(mcPID[i]) == 24 ) sigWH=true; if( abs(mcPID[i]) == 23 ) sigZH=true; } if( sigWH ) mc_whzh_type = 1; if( sigZH ) mc_whzh_type = 2; for( Int_t i=0; i<nMC; ++i) if ( abs(mcPID[i]) == 25 ) HiggsMCPt = mcPt[i]; if( _weight_manager->getCrossSection()->getMCType() == "ggh" && _config->setup().find( "ReReco2011" ) != string::npos ) _minitree->mc_wHQT = getHqTWeight(HiggsMCMass, HiggsMCPt); } if ((mode_ == 2 || mode_ ==1 || mode_ == 18 || mode_ == 19) && processID==18) continue; // Remove double counting in gamma+jets and QCDjets Int_t mcIFSR_pho = 0; Int_t mcPartonic_pho = 0; if (mode_ == 1 || mode_ == 2 || mode_ == 3 || mode_ == 18 || mode_ == 19 ) { for (Int_t i=0; i<nMC; ++i) { if (mcPID[i] == 22 && (fabs(mcMomPID[i]) < 6 || mcMomPID[i] == 21)) mcIFSR_pho++; if (mcPID[i] == 22 && mcMomPID[i] == 22) mcPartonic_pho++; } } // if pythia is used for diphoton.. no IFSR removing from QCD and Gjets!!!!!! if ((mode_==1 || mode_ == 2 || mode_ == 18 ) && mcIFSR_pho >= 1 && mcPartonic_pho >=1) continue; if ((mode_ == 3 || mode_ == 19 )&& mcIFSR_pho == 2) continue; bool prompt2= false; bool prompt1= false; bool prompt0= false; vertProb = -1; if (mode_ == 2 || mode_ == 1 || mode_ == 18 ){ if ( mcPartonic_pho >= 1 && mcIFSR_pho >= 1 ) prompt2 = true; else if ( mcPartonic_pho >= 1 && mcIFSR_pho == 0 ) prompt1 = true; else if ( mcPartonic_pho == 0 && mcIFSR_pho == 0 ) prompt0 = true; } else if(mode_ == 3 || mode_ == 19 ){ if ( mcIFSR_pho >= 2 ) prompt2 = true; else if ( mcIFSR_pho == 1 ) prompt1 = true; else if ( mcIFSR_pho == 0 ) prompt0 = true; if( prompt1 ) _minitree->mc_wXsec = 1.3*_weight_manager->xSecW(); } if(mode_==1 || mode_==2 || mode_==3 || mode_==18 || mode_==19){ if(prompt0)isprompt0=1; else isprompt0=0; if(prompt1)isprompt1=1; else isprompt1=0; } if( mode_ == 20 && isZgamma() ) continue; /// wei weight is just temporary and may not contain all info. float wei = _minitree->mc_wXsec * _minitree->mc_wPU * _minitree->mc_wNgen * _minitree->mc_wHQT; if( isData && !PassTriggerSelection() ) continue; nEvts[icutlevel++]++; if( std::isinf( wei ) || std::isnan( wei ) )continue; nEvts[icutlevel++]++; //// ********************* define S4 variable **********************//// for( int i=0; i<nPho; ++i){ if( _config->setup() == "ReReco2011" ) phoS4ratio[i] = 1; else phoS4ratio[i] = phoE2x2[i] / phoE5x5[i]; } //// ************************************************************* //// if( !isData ) { //// ************** MC corrections (mostly MC) ******************* //// // 1. energy shifting / smearing for( int i=0; i<nPho; ++i) if( fabs(phoSCEta[i]) <= 2.5 ) { float smearing = overSmear.randOverSmearing(phoSCEta[i],phoR9[i],isInGAP_EB(i),overSmearSyst); phoRegrE[i] *= (1 + smearing); phoE[i] *= (1 + smearing); /// from MassFactorized in gglobe: energyCorrectedError[ipho] *=(l.pho_isEB[ipho]) ? 1.07 : 1.045 ; float smearFactor = 1; if( _config->setup() == "ReReco2011" ) smearFactor = fabs(phoSCEta[i]) < 1.45 ? 1.07: 1.045; phoRegrErr[i] *= smearFactor; } // 2. reweighting of photon id variables (R9...) for (int i=0; i<nPho; ++i) ReweightMC_phoIdVar(i); //// ************************************************************* //// } //// ********** Apply regression energy ************* //// float phoStdE[500]; for( int i=0; i<nPho; ++i) if( fabs(phoSCEta[i]) <= 2.5 ) { if( isData ){ float enCorrSkim = 1;//enScaleSkimEOS.energyScale( phoR9[i], phoSCEta[i], run); float phoEnScale = enScale.energyScale( phoR9[i], phoSCEta[i], run)/enCorrSkim; phoRegrE[i] *= phoEnScale; phoE[i] *= phoEnScale; } phoStdE[i] = phoE[i]; phoE[i] = phoRegrE[i]; /// transform calo position abd etaVtx, phiVtx with SC position for( int x = 0 ; x < 3; x++ ) phoCaloPos[i][x] = phoSCPos[i][x]; for( int ivtx = 0 ; ivtx < nVtxBS; ivtx++ ) { TVector3 xxi = getCorPhotonTVector3(i,ivtx); phoEtaVtx[i][ivtx] = xxi.Eta(); phoPhiVtx[i][ivtx] = xxi.Phi(); } /// additionnal smearing to go to data energy resolution phoRegrSmear[i] = phoE[i]*overSmearHCP.meanOverSmearing(phoSCEta[i],phoR9[i],isInGAP_EB(i),0); phoEt[i] = phoE[i] / cosh(phoEta[i]); } //// ************************************************* //// /// lepton selection int iElecVtx(-1), iMuonVtx(-1); vector<int> elecIndex = selectElectronsHCP2012( wei, iElecVtx ); vector<int> muonIndex = selectMuonsHCP2012( wei, iMuonVtx ); vector<int> event_vtx; vector<int> event_ilead ; vector<int> event_itrail; vector<TLorentzVector> event_plead ; vector<TLorentzVector> event_ptrail; TLorentzVector leptag; int lepCat = -1; bool exitLoop = false; for( int ii = 0 ; ii < nPho ; ++ii ) { for( int jj = (ii+1); jj < nPho ; ++jj ) { // Preselection 2nd leg if (DoPreselection && !preselectPhoton(ii,phoEt[ii])) continue; if (DoPreselection && !preselectPhoton(jj,phoEt[jj])) continue; /// define i, j locally, so when they are inverted this does not mess up the loop int i = ii; int j = jj; if(phoEt[j] > phoEt[i]){ i = jj; j = ii; } // Select vertex int selVtx = 0; TLorentzVector gi,gj; double mij(-1); vector<int> selVtxIncl; if(_config->vtxSelType()==0) selVtxIncl = getSelectedVertex(i,j,true,true ); else //use sumpt2 ranking selVtxIncl = selVtxSumPt2; selVtx = selVtxIncl[0]; if( selVtx < 0 ) continue; /// check lepton tag if( muonIndex.size() > 0 ) { //selVtx = iMuonVtx; leptag.SetPtEtaPhiM( muPt[muonIndex[0]], muEta[muonIndex[0]], muPhi[muonIndex[0]],0); if( selectTwoPhotons(i,j,selVtx,gi,gj,vetoElec) ) { lepCat = 0; } } /// check electron tag only if muon tag failed if( elecIndex.size() > 0 && lepCat == -1 ) { //selVtx = iElecVtx; leptag.SetPtEtaPhiM( elePt[elecIndex[0]], eleEta[elecIndex[0]], elePhi[elecIndex[0]],0); if( selectTwoPhotons(i,j,selVtx,gi,gj,vetoElec) ) { lepCat = 1; if( fabs( (leptag+gi).M() - 91.19 ) < 10 || fabs( (leptag+gj).M() - 91.19 ) < 10 ) lepCat = -1; /// this is not actually the cut, but it should be but ok (dR(pho,eleTrk) > 1 no dR(pho,anyTrk) > 1 ) if(phoCiCdRtoTrk[i] < 1 || phoCiCdRtoTrk[j] <1 ) lepCat = -1; } } if( lepCat >= 0 ) { mij = (gi+gj).M(); if( _config->analysisType() == "MVA" ) if( gi.Pt() / mij < 45./120. || gj.Pt() / mij < 30./120. ) lepCat = -1; if( _config->analysisType() == "baselineCiC4PF" ) if( gi.Pt() / mij < 45./120. || gj.Pt() < 25. ) lepCat = -1; if( leptag.DeltaR(gi) < 1.0 || leptag.DeltaR(gj) < 1.0 ) lepCat = -1; } if( lepCat >= 0 ) { cout << " ****** keep leptag event pts[photons] i: " << i << " j: " << j << " -> event: " << ientry << endl; cout << " leptonCat: " << lepCat << endl; /// if one pair passes lepton tag then no need to go further /// fill in variables event_vtx.resize( 1); event_vtx[0] = selVtx; event_ilead.resize( 1); event_ilead[0] = i; event_itrail.resize(1); event_itrail[0] = j; event_plead.resize( 1); event_plead[0] = gi; event_ptrail.resize(1); event_ptrail[0] = gj; exitLoop = true; break; } else { /// inclusive + VBF + MetTag preselection /// apply kinematic cuts if( !selectTwoPhotons(i,j,selVtx,gi,gj,vetoElec) ) continue; /// drop photon pt cuts from inclusive cuts (add them in categorisation only) mij = (gi+gj).M(); if( ! _config->doSkimming() && ( gi.Pt() < _config->pt1Cut() || gi.Pt() < _config->pt2Cut() || gi.Pt()/mij < _config->loosePt1MCut() || gj.Pt()/mij < _config->loosePt2MCut() ) ) continue; } /// here i = lead; j = trail (selectTwoPhotons does that) /// fill in variables event_vtx.push_back( selVtx ); event_ilead.push_back( i ); event_itrail.push_back( j ); event_plead.push_back( gi ); event_ptrail.push_back( gj ); } if( exitLoop ) break; } if(event_ilead.size()==0 || event_itrail.size()==0)continue; if(event_vtx.size() == 0 ) continue; // no pairs selected nEvts[icutlevel++]++; // Now decide which photon-photon pair in the event to select // for lepton tag (size of arrays is 1, so dummy selection) unsigned int selectedPair = 0; float sumEt = -1; for (unsigned int p=0; p < event_vtx.size(); p++) { float tempSumEt = event_plead[p].Pt() + event_ptrail[p].Pt(); if( tempSumEt > sumEt) { sumEt = tempSumEt; selectedPair = p; } } int ilead = event_ilead[ selectedPair ]; int itrail = event_itrail[ selectedPair ]; int selVtx = event_vtx[ selectedPair ]; TLorentzVector glead = event_plead[selectedPair]; TLorentzVector gtrail = event_ptrail[selectedPair]; TLorentzVector hcand = glead + gtrail; int CAT4 = cat4(phoR9[ilead], phoR9[itrail], phoSCEta[ilead], phoSCEta[itrail]); if( glead.Pt() < _config->pt1Cut() ) continue; if( gtrail.Pt() < _config->pt2Cut() ) continue; if( hcand.M() < _config->mggCut() ) continue; nEvts[icutlevel++]++; _minitree->mtree_runNum = run; _minitree->mtree_evtNum = event; _minitree->mtree_lumiSec = lumis; // TLorentzVector g1,g2; // g1.SetPtEtaPhiM(phoE[ilead ]/cosh(phoEta[ilead]),phoEta[ilead ], phoPhi[ilead ], 0); // g2.SetPtEtaPhiM(phoE[itrail]/cosh(phoEta[ilead]),phoEta[itrail], phoPhi[itrail], 0); // TLorentzVector lgg = g1 + g2; //_minitree->mtree_massDefVtx = lgg.M(); _minitree->mtree_massDefVtx = hcand.M()/sqrt(phoE[ilead]*phoE[itrail])*sqrt(phoStdE[ilead]*phoStdE[itrail]); // calc again vertex to get correct vertex probability (can be different from last one in loop) vector<int> sortedVertex; if(_config->vtxSelType()==0) sortedVertex = getSelectedVertex( ilead, itrail, true, true ); else //use sumpt2 ranking sortedVertex = selVtxSumPt2; if( sortedVertex.size() < 2 ) sortedVertex.push_back(-1); if( sortedVertex.size() < 3 ) sortedVertex.push_back(-1); if( lepCat >= 0 ) { /// lepton tag sortedVertex[0] = selVtx; sortedVertex[1] = -1; sortedVertex[2] = -1; // vertProb = 1; } _minitree->mtree_rho = rho2012; _minitree->mtree_rho25 = rho25; _minitree->mtree_zVtx = vtxbs[selVtx][2]; _minitree->mtree_nVtx = nVtxBS; _minitree->mtree_ivtx1 = selVtx; _minitree->mtree_ivtx2 = sortedVertex[1]; _minitree->mtree_ivtx3 = sortedVertex[2]; _minitree->mtree_vtxProb = vertProb; _minitree->mtree_vtxMva = vertMVA; _minitree->mtree_mass = hcand.M(); _minitree->mtree_pt = hcand.Pt(); _minitree->mtree_piT = hcand.Pt()/hcand.M(); _minitree->mtree_y = hcand.Rapidity(); /// spin variables TLorentzVector gtmp1 = glead; gtmp1.Boost( -hcand.BoostVector() ); TLorentzVector gtmp2 = gtrail; gtmp2.Boost( -hcand.BoostVector() ); _minitree->mtree_cThetaLead_heli = cos( gtmp1.Angle(hcand.BoostVector()) ); _minitree->mtree_cThetaTrail_heli = cos( gtmp2.Angle(hcand.BoostVector()) ); _minitree->mtree_cThetaStar_CS = 2*(glead.E()*gtrail.Pz() - gtrail.E()*glead.Pz())/(hcand.M()*sqrt(hcand.M2()+hcand.Pt()*hcand.Pt())); /// fill photon id variables in main tree _minitree->mtree_minR9 = +999; _minitree->mtree_minPhoIdEB = +999; _minitree->mtree_minPhoIdEE = +999; _minitree->mtree_maxSCEta = -1; _minitree->mtree_minSCEta = +999; for( int i = 0 ; i < 2; i++ ) { int ipho = -1; if( i == 0 ) ipho = ilead; if( i == 1 ) ipho = itrail; fillPhotonVariablesToMiniTree( ipho, selVtx, i ); if( _minitree->mtree_r9[i] < _minitree->mtree_minR9 ) _minitree->mtree_minR9 = _minitree->mtree_r9[i]; if( fabs( _minitree->mtree_sceta[i] ) < 1.5 && _minitree->mtree_mvaid[i] < _minitree->mtree_minPhoIdEB ) _minitree->mtree_minPhoIdEB = _minitree->mtree_mvaid[i]; if( fabs( _minitree->mtree_sceta[i] ) >= 1.5 && _minitree->mtree_mvaid[i] < _minitree->mtree_minPhoIdEE ) _minitree->mtree_minPhoIdEE = _minitree->mtree_mvaid[i]; if( fabs( _minitree->mtree_sceta[i] ) > _minitree->mtree_maxSCEta ) _minitree->mtree_maxSCEta = fabs(_minitree->mtree_sceta[i]); if( fabs( _minitree->mtree_sceta[i] ) < _minitree->mtree_minSCEta ) _minitree->mtree_minSCEta = fabs(_minitree->mtree_sceta[i]); } //------------ compute diphoton mva (add var to minitree inside function) ----------------// massResoCalc.setP4CalPosVtxResoSmear( glead,gtrail, TVector3(phoCaloPos[ilead ][0], phoCaloPos[ilead ][1],phoCaloPos[ilead ][2]), TVector3(phoCaloPos[itrail][0], phoCaloPos[itrail][1],phoCaloPos[itrail][2]), TVector3(vtxbs[selVtx][0], vtxbs[selVtx][1], vtxbs[selVtx][2]), _minitree->mtree_relResOverE, _minitree->mtree_relSmearing ); _minitree->mtree_massResoTot = massResoCalc.relativeMassResolutionFab_total( vertProb ); _minitree->mtree_massResoEng = massResoCalc.relativeMassResolutionFab_energy( ); _minitree->mtree_massResoAng = massResoCalc.relativeMassResolutionFab_angular(); float diphotonmva = DiPhoID_MVA( glead, gtrail, hcand, massResoCalc, vertProb, _minitree->mtree_mvaid[0],_minitree->mtree_mvaid[1] ); // ---- Start categorisation ---- // _minitree->mtree_lepTag = 0; _minitree->mtree_metTag = 0; _minitree->mtree_vbfTag = 0; _minitree->mtree_hvjjTag = 0; // 1. lepton tag if( lepCat >= 0 ) { _minitree->mtree_lepTag = 1; _minitree->mtree_lepCat = lepCat; _minitree->mtree_fillLepTree = true; // if( lepCat == 0 ) fillMuonTagVariables(lepTag,glead,gtrail,elecIndex[0],selVtx); // if( lepCat == 1 ) fillElecTagVariables(lepTag,glead,gtrail,muonIndex[0],selVtx); } // 3. met tag (For the jet energy regression, MET needs to be corrected first.) _minitree->mtree_rawMet = recoPfMET; _minitree->mtree_rawMetPhi = recoPfMETPhi; // if( !isData ) { /// bug in data skim, met correction already applied //3.1 Soft Jet correction (FC?) applyJEC4SoftJets(); //3.2 smearing if( !isData ) METSmearCorrection(ilead, itrail); //3.3 shifting (even in data? but different in data and MC) METPhiShiftCorrection(); //3.4 scaling if( isData) METScaleCorrection(ilead, itrail); // } _minitree->mtree_corMet = recoPfMET; _minitree->mtree_corMetPhi = recoPfMETPhi; // 2. dijet tag Int_t nVtxJetID = -1; if( _config->doPUJetID() ) nVtxJetID = nVtxBS; //vector<int> goodJetsIndex = selectJets( ilead, itrail, nVtxJetID, wei, selVtx ); vector<int> goodJetsIndex = selectJetsJEC( ilead, itrail, nVtxJetID, wei, selVtx ); int vbftag(-1),hstratag(-1),catjet(-1); dijetSelection( glead, gtrail, goodJetsIndex, wei, selVtx, vbftag, hstratag, catjet); _minitree->mtree_vbfTag = vbftag; _minitree->mtree_hvjjTag = hstratag; _minitree->mtree_vbfCat = catjet; // 2x. radion analysis // take the very same photon candidates as in the H->GG analysis above _minitree->radion_evtNum = event; *(_minitree->radion_gamma1) = glead; *(_minitree->radion_gamma2) = gtrail; vector<int> goodJetsIndexRadion = selectJetsRadion(nVtxJetID, selVtx); _minitree->radion_bJetTags->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_genJetPt ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_eta ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_cef ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_nef ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_mef ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_nconstituents ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_chf ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_JECUnc ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_ptLeadTrack ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_vtxPt ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_vtx3dL ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_SoftLeptPtCut ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_dPhiMETJet ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_nch ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_vtx3deL ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_vtxMass ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_ptRaw ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_EnRaw ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_SoftLeptptRelCut->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_SoftLeptdRCut ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_partonID ->Set(goodJetsIndexRadion.size()); _minitree->radion_jet_dRJetGenJet ->Set(goodJetsIndexRadion.size()); _minitree->radion_MET = recoPfMET; _minitree->radion_rho25 = rho25; for (unsigned i = 0; i < goodJetsIndexRadion.size(); i++) { int iJet = goodJetsIndexRadion[i]; //_minitree->radion_bJetTags->AddAt(jetCombinedSecondaryVtxMVABJetTags[iJet], i); _minitree->radion_bJetTags->AddAt(jetCombinedSecondaryVtxBJetTags[iJet], i); _minitree->radion_jet_genJetPt ->AddAt(jetGenJetPt[iJet], i); _minitree->radion_jet_eta ->AddAt(jetEta[iJet], i); _minitree->radion_jet_cef ->AddAt(jetCEF[iJet], i); _minitree->radion_jet_nef ->AddAt(jetNEF[iJet], i); _minitree->radion_jet_mef ->AddAt(jetMEF[iJet], i); _minitree->radion_jet_nconstituents ->AddAt(jetNConstituents[iJet], i); _minitree->radion_jet_chf ->AddAt(jetCHF[iJet], i); _minitree->radion_jet_JECUnc ->AddAt(jetJECUnc[iJet], i); _minitree->radion_jet_ptLeadTrack ->AddAt(jetLeadTrackPt[iJet], i); _minitree->radion_jet_vtxPt ->AddAt(jetVtxPt[iJet], i); _minitree->radion_jet_vtx3dL ->AddAt(jetVtx3dL[iJet], i); _minitree->radion_jet_SoftLeptPtCut ->AddAt(jetSoftLeptPt[iJet], i); _minitree->radion_jet_nch ->AddAt(jetNCH[iJet], i); _minitree->radion_jet_vtx3deL ->AddAt(jetVtx3deL[iJet], i); _minitree->radion_jet_vtxMass ->AddAt(jetVtxMass[iJet], i); _minitree->radion_jet_ptRaw ->AddAt(jetRawPt[iJet], i); _minitree->radion_jet_EnRaw ->AddAt(jetRawEn[iJet], i); _minitree->radion_jet_SoftLeptptRelCut ->AddAt(jetSoftLeptPtRel[iJet], i); _minitree->radion_jet_SoftLeptdRCut ->AddAt(jetSoftLeptdR[iJet], i); _minitree->radion_jet_partonID ->AddAt(jetPartonID[iJet], i); _minitree->radion_jet_dRJetGenJet ->AddAt(sqrt(pow(jetEta[iJet]-jetGenEta[iJet],2)+pow(jetPhi[iJet]-jetGenPhi[iJet],2)), i); float tmpPi = 3.1415927, tmpDPhi=fabs(jetPhi[iJet]-recoPfMETPhi); if(tmpDPhi>tmpPi) tmpDPhi=2*tmpPi-tmpDPhi; _minitree->radion_jet_dPhiMETJet ->AddAt(tmpDPhi, i); TLorentzVector* jet = new((*(_minitree->radion_jets))[_minitree->radion_jets->GetEntriesFast()]) TLorentzVector(); jet->SetPtEtaPhiE(jetPt[iJet], jetEta[iJet], jetPhi[iJet], jetEn[iJet]); } // Continue step 3. if ( MetTagSelection(glead,gtrail,goodJetsIndex) && _minitree->mtree_vbfTag == 0 && _minitree->mtree_lepTag == 0 && _minitree->mtree_corMet > 70. && fabs( phoSCEta[ilead] ) < 1.45 && fabs( phoSCEta[itrail]) < 1.45 ) _minitree->mtree_metTag = 1; //----------- categorisation (for now incl + vbf + lep + met) -----------// _minitree->mtree_catBase = CAT4; _minitree->mtree_catMva = -1; for( int icat_mva = 0 ; icat_mva < 4; icat_mva++ ) if( diphotonmva >= Ddipho_cat[icat_mva] ) { _minitree->mtree_catMva = icat_mva; break; } if ( _minitree->mtree_lepTag == 1 ) { _minitree->mtree_catBase = _minitree->mtree_lepCat + 6; _minitree->mtree_catMva = _minitree->mtree_lepCat + 6; } else if( _minitree->mtree_vbfTag == 1 ) { _minitree->mtree_catBase = _minitree->mtree_vbfCat + 4; _minitree->mtree_catMva = _minitree->mtree_vbfCat + 4; } else if( _minitree->mtree_metTag == 1 ) { _minitree->mtree_catBase = 8; _minitree->mtree_catMva = 8; } if( diphotonmva < Ddipho_cat[3] ) _minitree->mtree_catMva = -1; /// photon pt cut was dropped from the inclusive cuts if( _minitree->mtree_catMva < 4 && (glead.Pt()/hcand.M() < 1./3. || gtrail.Pt()/hcand.M() < 1./4.) ) _minitree->mtree_catMva = -1; if( _minitree->mtree_catBase < 4 && (glead.Pt()/hcand.M() < 1./3. || gtrail.Pt()/hcand.M() < 1./4.) ) _minitree->mtree_catBase = -1; //------------ MC weighting factors and corrections if( !isData ) { /// needs to be recomputed for each event (because reinit var for each event) _minitree->mc_wNgen = 100000./_weight_manager->getNevts(); _minitree->mc_wXsec = _weight_manager->xSecW(mc_whzh_type); if( ( mode_ == 3 || mode_ == 19 ) && isprompt1 == 1 ) _minitree->mc_wXsec *= 1.3; _minitree->mc_wBSz = _weight_manager->bszW(vtxbs[selVtx][2]-mcVtx[0][2]); _minitree->mc_wVtxId = _weight_manager->vtxPtCorrW( hcand.Pt() ); /// photon identification float wPhoId[] = { 1., 1.}; for( int i = 0 ; i < 2; i++ ) { wPhoId[i] = 1; int index = -1; if( i == 0 ) index = ilead; if( i == 1 ) index = itrail; wPhoId[i] *= _weight_manager->phoIdPresel(phoR9[index],phoSCEta[index]); if( _config->analysisType() == "baselineCiC4PF" ) wPhoId[i] *= _weight_manager->phoIdCiC(phoR9[index],phoSCEta[index]); if( _config->analysisType() == "MVA" ) wPhoId[i] *= _weight_manager->phoIdMVA(phoR9[index],phoSCEta[index]); if( vetoElec[i] ) wPhoId[i] *= _weight_manager->phoIdEleVeto(phoR9[index],phoSCEta[index]); } _minitree->mc_wPhoEffi = wPhoId[0]*wPhoId[1]; /// trigger efficiency _minitree->mc_wTrigEffi = 0.9968; /// FIX ME /// cross section volontary not included in total weight _minitree->mc_wei = _minitree->mc_wPU * _minitree->mc_wBSz * _minitree->mc_wHQT * /// = 1 but in 2011 _minitree->mc_wVtxId * _minitree->mc_wPhoEffi * _minitree->mc_wTrigEffi * _minitree->mc_wNgen; wei = _minitree->mc_wei; } nEvts[icutlevel++]++; if( _minitree->mtree_lepTag ) nEvts[icutlevel+0]++; if( _minitree->mtree_vbfTag ) nEvts[icutlevel+1]++; //// following crap can be removed when the synchornization will be successfull. if( DoDebugEvent ) { _minitree->setSynchVariables(); _xcheckTextFile << " pho1 pos: " << phoPos[ilead] << endl; _xcheckTextFile << " ieta1 : " << phoSeedDetId1[ilead] << " iphi1: " << phoSeedDetId2[ilead] << endl; _xcheckTextFile << " pho2 pos: " << phoPos[itrail] << endl; _xcheckTextFile << " ieta1 : " << phoSeedDetId1[itrail] << " iphi1: " << phoSeedDetId2[itrail] << endl; _xcheckTextFile << " oversmear 1: " << overSmear.meanOverSmearing(phoSCEta[ilead],phoR9[ilead] ,isInGAP_EB(ilead),0) << endl; _xcheckTextFile << " oversmear 2: " << overSmear.meanOverSmearing(phoSCEta[itrail],phoR9[itrail],isInGAP_EB(itrail),0) << endl; _xcheckTextFile << " mass reso (eng only): " << _minitree->mtree_massResoEng << endl; _xcheckTextFile << " mass reso (ang only): " << _minitree->mtree_massResoAng << endl; for( unsigned i = 0 ; i < _minitree->sync_iName.size(); i++ ) cout << _minitree->sync_iName[i] << ":" << *_minitree->sync_iVal[i] << " "; for( unsigned i = 0 ; i < _minitree->sync_lName.size(); i++ ) cout << _minitree->sync_lName[i] << ":" << *_minitree->sync_lVal[i] << " "; for( unsigned i = 0 ; i < _minitree->sync_fName.size(); i++ ) cout << _minitree->sync_fName[i] << ":" << *_minitree->sync_fVal[i] << " "; cout << endl; cout << " myVtx = " << selVtx << "; 1=" << sortedVertex[1] << " 2= " << sortedVertex[2] << endl; for( int ivtx = 0; ivtx < nVtxBS; ivtx++ ) { cout << " etas[ ivtx = " << ivtx << "] = " << phoEtaVtx[ilead][ivtx] << " - " << phoEtaVtx[itrail][ivtx] << " - zVtx = " << vtxbs[ivtx][2] << endl; } } _minitree->fill(); if( _config->doSkimming() && tSkim ) { /// undo all modifs before filling the skim fChain->GetEntry(jentry); tSkim->Fill(); } //--------------- // } }// end for entry if( _config->doSkimming() ) { _minitree->mtree_file->cd(); TH1F *hEvents = new TH1F("hEvents","hEvents",2,0,2); hEvents->SetBinContent(1,_weight_manager->getNevts()); hEvents->SetBinContent(2,nEvts[nEvts.size()-1]); hEvents->Write(); tSkim->Write(); _minitree->mtree_file->Close(); } else _minitree->end(); for( unsigned icut = 0 ; icut < nEvts.size(); icut++ ) cout << nCutName[icut] << nEvts[icut] << endl; delete rnd; return nEvts[nEvts.size()-1]; }
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; }