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