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