|
[Rivet] New CMS plugin: strangeness in UE (CMS-PAS-QCD-11-010) and UE at forward eta (CMS-PAS-FWD-11-003)Hendrik Hoeth hendrik.hoeth at cern.chWed Dec 12 17:00:47 GMT 2012
Hi Albert, I've now checked the two analyses, and while the strangeness analysis was straight forward, I spent several hours and lots of cursing cleaning up the forward UE analysis. In the future I will simply send such code back, because we do expect some minimum quality control from you. You find my code in the attachment -- it is about half as long as the original code and, unlike yours, doesn't crash after ~1300 Pythia events. Some "highlights" of the original code: - A self-written selection sort algorithm to sort particle by rapidity, instead using the provided tools. Takes up 17 lines of code and scales as O(n^2). - This could be a "ParticleVector myTempParticles = sfsv.particles();". Note also the cast from Particle to Particle. ------------------------------------ ParticleVector myTempParticles; foreach (const Particle& p, sfsv.particles()) { myTempParticles.push_back(Particle(p)); } ------------------------------------ - I *love* the following one. The whole purpose of the loop is to find the hardest jet (i.e. jets[0]). And the "if (index_1 != -1)" is naturally fulfilled, because we require at least one jet: ------------------------------------ const FastJets& jetpro = applyProjection<FastJets>(event, "Jets"); const Jets& jets = jetpro.jetsByPt(1.0*GeV); if (jets.size()>0) { int index_1 = -1; // for the jet with the 1.highest pT double tempmax_1 = -100; // jet with the 1.highest pt for (size_t ijets = 0; ijets<jets.size(); ++ijets) { if (tempmax_1 == -100 || tempmax_1 < jets[ijets].momentum().pT()/GeV) { tempmax_1 = jets[ijets].momentum().pT()/GeV; index_1 = ijets; } } if (index_1 != -1) { // do something, fill a histogram } } ------------------------------------ So this code boils down to: ------------------------------------ const FastJets& jetpro = applyProjection<FastJets>(event, "Jets"); const Jets& jets = jetpro.jetsByPt(1.0*GeV); if (jets.size()<1) vetoEvent; // do something, fill a histogram, using jets[0]. ------------------------------------ - In your code all the analysis code had three identical copies: One for each energy. - I wonder what invisible particles the jet finder is supposed to use, after being given only charged particles: ------------------------------------ const ChargedFinalState fsj(-2.5,2.5,0.3*GeV); addProjection(fsj, "FSJ"); FastJets jetpro (fsj, FastJets::ANTIKT, 0.5); jetpro.useInvisibles(); addProjection(jetpro, "Jets"); ------------------------------------ - Casting a FourMomentum to a FourMomentum doesn't do much, except for rendering the code unreadable. And why the author does a manual mass-square just one line below using the mass2() method is beyond my mental capabilities. ------------------------------------ FourMomentum Xfourmom; for (int ipart=0; ipart <= deltaymax_pos; ++ipart) { Xfourmom += myRapiditySortedParticles[ipart].momentum(); } if(FourMomentum(Xfourmom).mass2() <0 ) vetoEvent; long double Mx2 = FourMomentum(Xfourmom).mass()*FourMomentum(Xfourmom).mass(); ------------------------------------ This list goes on and on. Global variables that could be local. Strange types ("signed int", "long double", ...). PLEASE have a look at the code next time before dumping it on us, because we will have to maintain it in the future -- together with several hundred other analyses. Thanks. Cheers, Hendrik -- If your dreams don't scare you, then you are not dreaming big enough. -------------- next part -------------- // Samantha Dooling DESY // February 2012 // // -*- C++ -*- // ============================= // // Ratio of the energy deposited in the pseudorapditiy range // -6.6 < eta < -5.2 for events with a charged particle jet // // ============================= #include "Rivet/Analysis.hh" #include "Rivet/RivetAIDA.hh" #include "Rivet/Tools/Logging.hh" #include "Rivet/Projections/FinalState.hh" #include "Rivet/Projections/ChargedFinalState.hh" #include "Rivet/Projections/FastJets.hh" #include "Rivet/Projections/Beam.hh" #include "Rivet/Projections/VetoedFinalState.hh" #include "LWH/Histogram1D.h" namespace Rivet { class CMS_2012_PAS_FWD_11_003 : public Analysis { public: /// Constructor CMS_2012_PAS_FWD_11_003() : Analysis("CMS_2012_PAS_FWD_11_003") { } void init() { // gives the range of eta and min pT for the final state from which I get the jets FastJets jetpro (ChargedFinalState(-2.5, 2.5, 0.3*GeV), FastJets::ANTIKT, 0.5); addProjection(jetpro, "Jets"); // skip Neutrinos and Muons VetoedFinalState fsv(FinalState(-7.0, -4.0, 0.*GeV)); fsv.vetoNeutrinos(); fsv.addVetoPairId(MUON); addProjection(fsv, "fsv"); // for the hadron level selection VetoedFinalState sfsv(FinalState(-MAXRAPIDITY, MAXRAPIDITY, 0.*GeV)); sfsv.vetoNeutrinos(); sfsv.addVetoPairId(MUON); addProjection(sfsv, "sfsv"); //counters passedSumOfWeights = 0.; inclEflow = 0.; // Temporary histograms to fill the energy flow for leading jet events. // Ratios are calculated in finalyze(). int id = 0; if (fuzzyEquals(sqrtS()/GeV, 900, 1e-3)) id=1; if (fuzzyEquals(sqrtS()/GeV, 2760, 1e-3)) id=2; if (fuzzyEquals(sqrtS()/GeV, 7000, 1e-3)) id=3; _tmp_jet = bookHistogram1D("eflow_jet", binEdges(id, 1, 1)); // Leading jet energy flow in pt _tmp_njet = bookHistogram1D("number_jet", binEdges(id, 1, 1)); // Number of events in pt } /// Perform the per-event analysis void analyze(const Event& event) { const double weight = event.weight(); // Skip if the event is empty const FinalState& fsv = applyProjection<FinalState>(event, "fsv"); if (fsv.empty()) vetoEvent; // ====================== Minimum Bias selection const FinalState& sfsv = applyProjection<FinalState>(event, "sfsv"); ParticleVector parts = sfsv.particlesByRapidity(); if (parts.empty()) vetoEvent; // find dymax double dymax = 0; int gap_pos = -1; for (size_t i=0; i < parts.size()-1; ++i) { double dy = parts[i+1].momentum().rapidity() - parts[i].momentum().rapidity(); if (dy > dymax) { dymax = dy; gap_pos = i; } } // calculate mx2 and my2 FourMomentum xmom; for (int i=0; i<=gap_pos; ++i) { xmom += parts[i].momentum(); } double mx2 = xmom.mass2(); if (mx2<0) vetoEvent; FourMomentum ymom; for (size_t i=gap_pos+1; i<parts.size(); ++i) { ymom += parts[i].momentum(); } double my2 = ymom.mass2(); if (my2<0) vetoEvent; // calculate xix and xiy and xidd double xix = mx2 / sqr(sqrtS()); double xiy = my2 / sqr(sqrtS()); double xidd = mx2*my2 / sqr(sqrtS()*0.938*GeV); // combine the selection: xi cuts bool passedHadronCuts = false; if (fuzzyEquals(sqrtS()/GeV, 900, 1e-3) && (xix > 0.1 || xiy > 0.4 || xidd > 0.5)) passedHadronCuts = true; if (fuzzyEquals(sqrtS()/GeV, 2760, 1e-3) && (xix > 0.07 || xiy > 0.2 || xidd > 0.5)) passedHadronCuts = true; if (fuzzyEquals(sqrtS()/GeV, 7000, 1e-3) && (xix > 0.04 || xiy > 0.1 || xidd > 0.5)) passedHadronCuts = true; if (!passedHadronCuts) vetoEvent; // ============================== MINIMUM BIAS EVENTS // loop over particles to calculate the energy passedSumOfWeights += weight; foreach (const Particle& p, fsv.particles()) { if (-5.2 > p.momentum().eta() && p.momentum().eta() > -6.6) inclEflow += weight*p.momentum().E()/GeV; } // ============================== JET EVENTS const FastJets& jetpro = applyProjection<FastJets>(event, "Jets"); const Jets& jets = jetpro.jetsByPt(1.0*GeV); if (jets.size()<1) vetoEvent; if (fabs(jets[0].momentum().eta()) < 2.0) { _tmp_njet->fill(jets[0].momentum().pT()/GeV, weight); // energy flow foreach (const Particle& p, fsv.particles()) { if (p.momentum().eta() > -6.6 && p.momentum().eta() < -5.2) { // ask for the CASTOR region _tmp_jet->fill(jets[0].momentum().pT()/GeV, weight * p.momentum().E()/GeV); } } } }// analysis void finalize() { _tmp_jet->scale(passedSumOfWeights/inclEflow); AIDA::IHistogramFactory& hf = histogramFactory(); if (fuzzyEquals(sqrtS()/GeV, 900, 1e-3)) hf.divide(histoDir() + "/d01-x01-y01", *_tmp_jet, *_tmp_njet); if (fuzzyEquals(sqrtS()/GeV, 2760, 1e-3)) hf.divide(histoDir() + "/d02-x01-y01", *_tmp_jet, *_tmp_njet); if (fuzzyEquals(sqrtS()/GeV, 7000, 1e-3)) hf.divide(histoDir() + "/d03-x01-y01", *_tmp_jet, *_tmp_njet); hf.destroy(_tmp_jet); hf.destroy(_tmp_njet); } private: // counters double passedSumOfWeights; double inclEflow; // histograms AIDA::IHistogram1D* _tmp_jet; AIDA::IHistogram1D* _tmp_njet; }; // The hook for the plugin system DECLARE_RIVET_PLUGIN(CMS_2012_PAS_FWD_11_003); }
More information about the Rivet mailing list |