rivet is hosted by Hepforge, IPPP Durham
ATLAS_2011_S9108483.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/Tools/BinnedHistogram.hh"
00004 #include "Rivet/Math/Constants.hh"
00005 #include "Rivet/Projections/ChargedFinalState.hh"
00006 #include "Rivet/Projections/NonHadronicFinalState.hh"
00007 #include "Rivet/Projections/VetoedFinalState.hh"
00008 
00009 namespace Rivet {
00010 
00011 
00012   class ATLAS_2011_S9108483 : public Analysis {
00013   public:
00014 
00015     /// @name Constructors etc.
00016     //@{
00017 
00018     /// Constructor
00019     ATLAS_2011_S9108483()
00020       : Analysis("ATLAS_2011_S9108483")
00021     {
00022     }
00023 
00024     //@}
00025 
00026 
00027   public:
00028 
00029     /// @name Analysis methods
00030     //@{
00031 
00032     /// Book histograms and initialise projections before the run
00033     void init() {
00034 
00035       // get the non-hadronic final-state particles
00036       double etaMax = 2.5;
00037       const NonHadronicFinalState nhfs(-etaMax,etaMax,13.*GeV);
00038       addProjection(nhfs,"NHFS");
00039       // select the charged ones
00040       const ChargedFinalState cfs(nhfs);
00041       addProjection(cfs,"CFS");
00042       // and then veto electrons, and taus to be safe
00043       VetoedFinalState vfs(cfs);
00044       vfs.addVetoPairId(PID::ELECTRON);
00045 
00046       addProjection(vfs,"VFS");
00047 
00048       /// Book histograms
00049       _count_trigger   = bookHisto1D("count_trigger"  , 1, 0., 1.);
00050       _count_event     = bookHisto1D("count_selection", 1, 0., 1.);
00051       _count_quality   = bookHisto1D("count_quality"  , 1, 0., 1.);
00052       _count_beta      = bookHisto1D("count_beta"     , 1, 0., 1.);
00053       _count_90  = bookHisto1D("count_90" , 1, 0., 1.);
00054       _count_110 = bookHisto1D("count_110", 1, 0., 1.);
00055       _count_120 = bookHisto1D("count_120", 1, 0., 1.);
00056       _count_130 = bookHisto1D("count_130", 1, 0., 1.);
00057 
00058       _hist_beta = bookHisto1D("beta",1000, 0.,   2.);
00059       _hist_time = bookHisto1D("time",1000, -50,  50.);
00060       _hist_mass = bookHisto1D("mass",  60, 5., 305.);
00061     }
00062 
00063 
00064     double rndGauss(double sigma, double mean) {
00065       double r = sqrt(-2.0*log(rand()/static_cast<double>(RAND_MAX)));
00066       double phi = rand()/static_cast<double>(RAND_MAX)*2.0*pi;
00067       return mean+sigma*r*sin(phi);
00068     }
00069 
00070     /// Perform the per-event analysis
00071     void analyze(const Event& event) {
00072       // smearing parameters
00073       // time measurement (in ns)
00074 //       const double tsmear=5.*0.7;
00075       const double tsmear=0.7;
00076       // sagita error
00077       const double csag  =1.1E-4;
00078       // multiple scattering
00079       const double cms   =2.0E-2;
00080       // muon chamber radius (in metres)
00081       const double radius = 10.e3;
00082       // convert to ns
00083       const double tr = radius/c_light;
00084       // event weight
00085       const double weight = event.weight();
00086       // get the charged final-state particles
00087       Particles charged =
00088         applyProjection<VetoedFinalState>(event,"VFS").particles();
00089       // need at least two candidates
00090       if(charged.size()<2) vetoEvent;
00091       // number passing trigger
00092       _count_trigger->fill(0.5,weight);
00093       // Z mass veto
00094       foreach ( const Particle & mu1,charged ) {
00095         foreach ( const Particle & mu2,charged ) {
00096           double mass = (mu1.momentum()+mu2.momentum()).mass();
00097           double diff = abs(mass-91.18);
00098           if(diff<10.) vetoEvent;
00099         }
00100       }
00101       // number passing first event selection
00102       _count_event->fill(0.5,weight);
00103       // now find the candidates
00104       // loop over the particles and find muons and heavy charged particles
00105       map<double,Particle> muonCandidates;
00106       foreach ( const Particle & mu,charged ) {
00107         // calculate the smeared momentum
00108         double pT     = mu.momentum().perp2();
00109         double pmag   = sqrt(pT+sqr(mu.momentum().z()));
00110         double deltap = sqrt( sqr(csag*sqr(pmag)) +
00111                               sqr(cms*mu.momentum().t()/GeV));
00112         double psmear = rndGauss(deltap,pmag);
00113         // keep particles with pT>40
00114         if(psmear/pmag*mu.momentum().perp()<40.*GeV||
00115            psmear/pmag*mu.momentum().perp()>1000.*GeV) continue;
00116         muonCandidates.insert(make_pair(psmear,mu));
00117       }
00118       // require two candidates
00119       if(muonCandidates.size()<2) vetoEvent;
00120       // number passing "quality" cut
00121       _count_quality->fill(0.5,weight);
00122       // now do the time of flight
00123       bool filled = false;
00124       for(map<double,Particle>::const_iterator it=muonCandidates.begin();
00125           it!=muonCandidates.end();++it) {
00126         // true magnitude and pT of momentum
00127         double pT     = it->second.momentum().perp2();
00128         double pmag   = sqrt(pT+sqr(it->second.momentum().z()));
00129         pT = sqrt(pT);
00130         // true time difference in ns
00131         double deltaT  =tr *(it->second.momentum().t()-pmag)/pT;
00132         // smear it
00133         deltaT = rndGauss(tsmear,deltaT);
00134         // beta
00135         double beta = 1./(1.+deltaT/tr*pT/pmag);
00136         _hist_beta->fill(beta, weight);
00137         _hist_time->fill(deltaT, weight);
00138         // beta cut
00139         if(beta<0.95) continue;
00140         // mass
00141         double mass = 2.*pT*it->first*deltaT/tr*(1.+0.5*deltaT/tr*pT/pmag);
00142         if(mass<0.) continue;
00143         mass = sqrt(mass);
00144         filled = true;
00145         _hist_mass->fill(mass,weight);
00146         if(mass>90. ) {
00147           _count_90 ->fill(0.5,weight);
00148           if(mass>110.) {
00149             _count_110->fill(0.5,weight);
00150             if(mass>120.) {
00151               _count_120->fill(0.5,weight);
00152               if(mass>130.) {
00153                 _count_130->fill(0.5,weight);
00154               }
00155             }
00156           }
00157         }
00158       }
00159       if(!filled) vetoEvent;
00160       // number passing beta cut
00161       _count_beta->fill(0.5,weight);
00162     }
00163 
00164     //@}
00165 
00166     void finalize() {
00167       double fact = crossSection()/sumOfWeights()*37;
00168       MSG_WARNING("testing " << crossSection() << " " << sumOfWeights() << " " << fact);
00169       scale(_hist_beta,fact);
00170       scale(_hist_time,fact);
00171       scale(_hist_mass,fact);
00172       scale( _count_trigger, fact);
00173       scale( _count_event, fact);
00174       scale( _count_quality, fact);
00175       scale( _count_beta, fact);
00176       scale( _count_90, fact);
00177       scale( _count_110, fact);
00178       scale( _count_120, fact);
00179       scale( _count_130, fact);
00180     }
00181 
00182   private:
00183 
00184     /// @name Histograms
00185     //@{
00186     Histo1DPtr _hist_beta;
00187     Histo1DPtr _hist_time;
00188     Histo1DPtr _hist_mass;
00189     Histo1DPtr _count_trigger;
00190     Histo1DPtr _count_event;
00191     Histo1DPtr _count_quality;
00192     Histo1DPtr _count_beta;
00193     Histo1DPtr _count_90;
00194     Histo1DPtr _count_110;
00195     Histo1DPtr _count_120;
00196     Histo1DPtr _count_130;
00197     //@}
00198 
00199   };
00200 
00201   // The hook for the plugin system
00202   DECLARE_RIVET_PLUGIN(ATLAS_2011_S9108483);
00203 
00204 
00205 }