rivet is hosted by Hepforge, IPPP Durham
ATLAS_2012_I1094061.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/Projections/ChargedFinalState.hh"
00004 
00005 namespace Rivet {
00006 
00007 
00008   class ATLAS_2012_I1094061 : public Analysis {
00009 
00010     ////////////////////////////////////////////////////////////////////////////
00011     /**
00012      * Little container to hold a pair of foreground and background histos and then
00013      * divide them at the end of the analysis
00014      */
00015     struct HistoPair{
00016       enum HistoType { FOREGROUND, BACKGROUND };
00017 
00018       HistoPair(): _analysis(0),
00019                    _h_foreground(0), _h_background(0), _d_final(0)
00020       {  }
00021 
00022       void init(int ds, int xaxis, int yaxis, ATLAS_2012_I1094061* analysis){
00023         _ds = ds;
00024         _xaxis = xaxis;
00025         _yaxis = yaxis;
00026         _analysis = analysis;
00027         ++HistoPair::_s_counter;
00028         const BinEdges& edges = _analysis->binEdges(_ds, _xaxis, _yaxis);
00029         string sCount = boost::lexical_cast<string>(HistoPair::_s_counter);
00030         _h_foreground = analysis->bookHistogram1D("tmpForeground" + sCount, edges);
00031         _h_background = analysis->bookHistogram1D("tmpBackground" + sCount, edges);
00032       }
00033 
00034       void fillForeground(double value, double weight){
00035         _h_foreground->fill(value, weight);
00036         _h_foreground->fill(-value, weight);
00037       }
00038 
00039       void fillBackground(double value, double weight){
00040         _h_background->fill(value, weight);
00041         _h_background->fill(-value, weight);
00042       }
00043 
00044       void fill(double value, double weight, HistoType type){
00045 
00046         switch(type){
00047           case FOREGROUND:
00048             fillForeground(value, weight);
00049             break;
00050           case BACKGROUND:
00051             fillBackground(value, weight);
00052             break;
00053         }
00054       }
00055 
00056       void finalize(double wgtSum, double bgWeight, double avNTracks){
00057 
00058         _h_foreground->scale(1. / wgtSum);
00059         _h_background->scale(1. / bgWeight);
00060 
00061         string histoPath = _analysis->histoPath(_ds, _xaxis, _yaxis);
00062 
00063         AIDA::IDataPointSet *final = _analysis->histogramFactory().divide(histoPath, *_h_foreground, *_h_background);
00064 
00065         for (int ii=0; ii!= final->size(); ++ii) {
00066           AIDA::IDataPoint* pt = final->point(ii);
00067           double y = pt->coordinate(1)->value();
00068           pt->coordinate(1)->setValue(y-(avNTracks - 1));
00069         }
00070 
00071         _analysis->histogramFactory().destroy(_h_foreground);
00072         _analysis->histogramFactory().destroy(_h_background);
00073       }
00074 
00075     private:
00076 
00077       int _ds, _xaxis, _yaxis;
00078 
00079       ATLAS_2012_I1094061 *_analysis;
00080 
00081       AIDA::IHistogram1D* _h_foreground;
00082       AIDA::IHistogram1D* _h_background;
00083       AIDA::IDataPointSet* _d_final;
00084 
00085       static short _s_counter;
00086 
00087     };
00088 
00089 
00090     ////////////////////////////////////////////////////////////////////////////
00091 
00092   public:
00093 
00094     ATLAS_2012_I1094061(): Analysis("ATLAS_2012_I1094061"),
00095     _minpT(100.*MeV), _etaMax(2.5), _nVersions(5), _version(0),
00096     _etaCut(2.), _phiCut(0.5*M_PI),
00097     _historyInclusive(_nVersions, ParticleVector()), _historyN20(_nVersions, ParticleVector()),
00098     _historyInclusiveWgts(_nVersions, 0.), _historyN20Wgts(_nVersions, 0.),
00099     _particleCountInclusive(0.), _particleCountN20(0.),
00100     _weightInclusive(0.), _weightN20(0.),
00101     _bgWeightInclusive(0.), _bgWeightN20(0.){
00102 
00103     }
00104 
00105     ////////////////////////////////////////////////////////////////////////////
00106     void init(){
00107 
00108       const ChargedFinalState cfs(-2.5, 2.5, _minpT);
00109       addProjection(cfs, "ChargedParticles");
00110 
00111       // Only do the multiplicity > 20 plots for 7 TeV collisions
00112       _doN20 = (fabs(sqrtS() - 7000.*GeV) < 0.1*GeV);
00113 
00114       int yaxis = (_doN20)? 2: 1;
00115 
00116       _hp_DEta_0_pi.init(1, 1, yaxis, this);
00117       _hp_DEta_0_pi2.init(2, 1, yaxis, this);
00118       _hp_DEta_pi2_pi.init(3, 1, yaxis, this);
00119 
00120       _hp_DPhi_0_2.init(4, 1, yaxis, this);
00121       _hp_DPhi_2_5.init(5, 1, yaxis, this);
00122 
00123       if(_doN20){
00124 
00125         yaxis = 3;
00126 
00127         _hp_N20_DEta_0_pi.init(1, 1, yaxis, this);
00128         _hp_N20_DEta_0_pi2.init(2, 1, yaxis, this);
00129         _hp_N20_DEta_pi2_pi.init(3, 1, yaxis, this);
00130 
00131         _hp_N20_DPhi_0_2.init(4, 1, yaxis, this);
00132         _hp_N20_DPhi_2_5.init(5, 1, yaxis, this);
00133 
00134       }
00135       return;
00136     }
00137 
00138     ////////////////////////////////////////////////////////////////////////////
00139     void analyze(const Event &evt){
00140 
00141       const ChargedFinalState &cfsProj = applyProjection<ChargedFinalState>(evt, "ChargedParticles");
00142 
00143       ParticleVector chargedParticles = cfsProj.particles();
00144 
00145       if(chargedParticles.size() < 2) vetoEvent;
00146 
00147       bool hasN20 = (_doN20 && chargedParticles.size() >= 20);
00148 
00149       double dMultiplicity = (double)chargedParticles.size();
00150 
00151       double multiplicityWeightIncr = dMultiplicity * evt.weight();
00152 
00153       _weightInclusive += evt.weight();
00154       _particleCountInclusive += multiplicityWeightIncr;
00155 
00156       if(hasN20){
00157         _weightN20 += evt.weight();
00158         _particleCountN20 += multiplicityWeightIncr;
00159       }
00160 
00161       double fgWeight = 2.*evt.weight() / dMultiplicity;
00162 
00163       for(ParticleVector::const_iterator p1 = chargedParticles.begin();
00164           p1 != chargedParticles.end(); ++p1){
00165 
00166         ParticleVector::const_iterator p2 = p1;
00167         ++p2;
00168 
00169         // fill the foreground distributions
00170         while(p2 != chargedParticles.end()){
00171           fillHistosInclusive(*p1, *p2, fgWeight, HistoPair::FOREGROUND);
00172           if(hasN20) fillHistosN20(*p1, *p2, fgWeight, HistoPair::FOREGROUND);
00173           ++p2;
00174         }// end filling the foreground distributions
00175 
00176         // loop over the history of particles from previous events and fill the background
00177         // by correlating those particles with the current event
00178 
00179         for(size_t version = 0; version != _nVersions; ++version){
00180 
00181           const ParticleVector &bgParticles = _historyInclusive[version];
00182           double bgWeight = evt.weight() * _historyInclusiveWgts[version];
00183 
00184           for(ParticleVector::const_iterator p2 = bgParticles.begin();
00185               p2 != bgParticles.end(); ++p2){
00186             fillHistosInclusive(*p1, *p2, bgWeight, HistoPair::BACKGROUND);
00187             _bgWeightInclusive += bgWeight;
00188           }
00189 
00190           if(!hasN20) continue;
00191 
00192           const ParticleVector &bgParticlesN20 = _historyN20[version];
00193           bgWeight = evt.weight() * _historyN20Wgts[version];
00194 
00195           for(ParticleVector::const_iterator p2 = bgParticlesN20.begin();
00196               p2 != bgParticlesN20.end(); ++p2){
00197             fillHistosN20(*p1, *p2, bgWeight, HistoPair::BACKGROUND);
00198             _bgWeightN20 += bgWeight;
00199           }
00200 
00201         }//end loop over particle history for background fill
00202 
00203       }// end particle loop
00204 
00205       // Overwrite the history for the version count number
00206       _historyInclusive[_version] = chargedParticles;
00207       _historyInclusiveWgts[_version] = evt.weight();
00208 
00209       if(hasN20){
00210         _historyN20[_version] = chargedParticles;
00211         _historyN20Wgts[_version] = evt.weight();
00212       }
00213 
00214       ++_version;
00215       if(_version == _nVersions) _version = 0;
00216 
00217       return;
00218     }
00219 
00220     ////////////////////////////////////////////////////////////////////////////
00221     void finalize(){
00222 
00223       double avMultiplicity = _particleCountInclusive / _weightInclusive;
00224 
00225       _hp_DEta_0_pi.finalize(_weightInclusive,  _bgWeightInclusive, avMultiplicity);
00226       _hp_DEta_0_pi2.finalize(_weightInclusive, _bgWeightInclusive, avMultiplicity);
00227       _hp_DEta_pi2_pi.finalize(_weightInclusive,_bgWeightInclusive, avMultiplicity);
00228 
00229       _hp_DPhi_0_2.finalize(_weightInclusive, _bgWeightInclusive, avMultiplicity);
00230       _hp_DPhi_2_5.finalize(_weightInclusive, _bgWeightInclusive, avMultiplicity);
00231 
00232       if(_doN20){
00233         avMultiplicity = _particleCountN20 / _weightN20;
00234         _hp_N20_DEta_0_pi.finalize(_weightN20,   _bgWeightN20, avMultiplicity);
00235         _hp_N20_DEta_0_pi2.finalize(_weightN20,  _bgWeightN20, avMultiplicity);
00236         _hp_N20_DEta_pi2_pi.finalize(_weightN20, _bgWeightN20, avMultiplicity);
00237 
00238         _hp_N20_DPhi_0_2.finalize(_weightN20, _bgWeightN20, avMultiplicity);
00239         _hp_N20_DPhi_2_5.finalize(_weightN20, _bgWeightN20, avMultiplicity);
00240       }
00241 
00242       return;
00243     }
00244 
00245     ////////////////////////////////////////////////////////////////////////////
00246 
00247     void fillHistos(const Particle &p1, const Particle &p2, double weight,
00248                     HistoPair::HistoType type, bool inclusive){
00249 
00250       double dEta = fabs(p1.eta() - p2.eta());
00251       double dPhi = mapAngle0ToPi(p1.phi() - p2.phi());
00252       double dPhiShift = TWOPI - dPhi;
00253 
00254       HistoPair &dEta_0_pi   = (inclusive)? _hp_DEta_0_pi   :_hp_N20_DEta_0_pi;
00255       HistoPair &dPhi_0_2    = (inclusive)? _hp_DPhi_0_2    :_hp_N20_DPhi_0_2;
00256       HistoPair &dPhi_2_5    = (inclusive)? _hp_DPhi_2_5    :_hp_N20_DPhi_2_5;
00257       HistoPair &dEta_0_pi2  = (inclusive)? _hp_DEta_0_pi2  :_hp_N20_DEta_0_pi2;
00258       HistoPair &dEta_pi2_pi = (inclusive)? _hp_DEta_pi2_pi :_hp_N20_DEta_pi2_pi;
00259 
00260       dEta_0_pi.fill(dEta, weight, type);
00261 
00262       if(dEta < _etaCut){
00263         dPhi_0_2.fill(dPhi, weight, type);
00264         dPhi_0_2.fill(dPhiShift, weight, type);
00265       }else{
00266         dPhi_2_5.fill(dPhi, weight, type);
00267         dPhi_2_5.fill(dPhiShift, weight, type);
00268       }
00269 
00270       if(dPhi < _phiCut){
00271         dEta_0_pi2.fill(dEta, weight, type);
00272       }else{
00273         dEta_pi2_pi.fill(dEta, weight, type);
00274       }
00275 
00276       return;
00277 
00278     }
00279     ////////////////////////////////////////////////////////////////////////////
00280 
00281     void fillHistosInclusive(const Particle &p1, const Particle &p2, double weight,
00282                              HistoPair::HistoType type){
00283 
00284       fillHistos(p1, p2, weight, type, true);
00285       return;
00286     }
00287 
00288     void fillHistosN20(const Particle &p1, const Particle &p2, double weight,
00289                        HistoPair::HistoType type){
00290 
00291       fillHistos(p1, p2, weight, type, false);
00292       return;
00293     }
00294     ////////////////////////////////////////////////////////////////////////////
00295 
00296 
00297     double _minpT;
00298     double _etaMax;
00299 
00300     size_t _nVersions;
00301     size_t _version;
00302 
00303     double _etaCut;
00304     double _phiCut;
00305 
00306     /// The "history" vectors contain the history of particles from _nVersions previous events
00307     /// These are used to construct the background correlation.
00308     vector<ParticleVector> _historyInclusive;
00309     vector<ParticleVector> _historyN20;
00310 
00311     vector<double>         _historyInclusiveWgts;
00312     vector<double>         _historyN20Wgts;
00313 
00314     double _particleCountInclusive;
00315     double _particleCountN20;
00316     double _weightInclusive;
00317     double _weightN20;
00318 
00319     double _bgWeightInclusive;
00320     double _bgWeightN20;
00321 
00322     bool _doN20;
00323 
00324     HistoPair _hp_DEta_0_pi;
00325     HistoPair _hp_DEta_0_pi2;
00326     HistoPair _hp_DEta_pi2_pi;
00327 
00328     HistoPair _hp_DPhi_0_2;
00329     HistoPair _hp_DPhi_2_5;
00330 
00331     HistoPair _hp_N20_DEta_0_pi;
00332     HistoPair _hp_N20_DEta_0_pi2;
00333     HistoPair _hp_N20_DEta_pi2_pi;
00334 
00335     HistoPair _hp_N20_DPhi_0_2;
00336     HistoPair _hp_N20_DPhi_2_5;
00337 
00338   };
00339 
00340 
00341   short ATLAS_2012_I1094061::HistoPair::_s_counter = 0;
00342 
00343 
00344   DECLARE_RIVET_PLUGIN(ATLAS_2012_I1094061);
00345 
00346 }