Rivet Analyses Reference

ATLAS_2011_S9108483

Long-lived heavy charged particle search
Experiment: ATLAS (LHC)
Inspire ID: 914491
Status: UNVALIDATED
Authors:
  • Peter Richardson
References:Beams: p+ p+
Beam energies: (3500.0, 3500.0) GeV
Run details:
  • BSM signal events at 7000 GeV.

ATLAS search for long-lived heavy charged particles for four different mass cuts. Currently only the slepton search is implemented.

Source code: ATLAS_2011_S9108483.cc
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// -*- C++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Math/Constants.hh"
#include "Rivet/Projections/ChargedFinalState.hh"
#include "Rivet/Projections/NonHadronicFinalState.hh"
#include "Rivet/Projections/VetoedFinalState.hh"

namespace Rivet {


  class ATLAS_2011_S9108483 : public Analysis {
  public:

    /// Constructor
    RIVET_DEFAULT_ANALYSIS_CTOR(ATLAS_2011_S9108483);


    /// @name Analysis methods
    //@{

    /// Book histograms and initialise projections before the run
    void init() {

      // get the non-hadronic final-state particles
      double etaMax = 2.5;
      const NonHadronicFinalState nhfs((Cuts::etaIn(-etaMax,etaMax) && Cuts::pT >= 13.*GeV));
      declare(nhfs,"NHFS");
      // select the charged ones
      const ChargedFinalState cfs(nhfs);
      declare(cfs,"CFS");
      // and then veto electrons, and taus to be safe
      VetoedFinalState vfs(cfs);
      vfs.addVetoPairId(PID::ELECTRON);

      declare(vfs,"VFS");

      /// Book histograms
      book(_count_trigger   ,"count_trigger"  , 1, 0., 1.);
      book(_count_event     ,"count_selection", 1, 0., 1.);
      book(_count_quality   ,"count_quality"  , 1, 0., 1.);
      book(_count_beta      ,"count_beta"     , 1, 0., 1.);
      book(_count_90  ,"count_90" , 1, 0., 1.);
      book(_count_110 ,"count_110", 1, 0., 1.);
      book(_count_120 ,"count_120", 1, 0., 1.);
      book(_count_130 ,"count_130", 1, 0., 1.);

      book(_hist_beta ,"beta",1000, 0.,   2.);
      book(_hist_time ,"time",1000, -50,  50.);
      book(_hist_mass ,"mass",  60, 5., 305.);
    }


    double rndGauss(double sigma, double mean) {
      double r = sqrt(-2.0*log(rand()/static_cast<double>(RAND_MAX)));
      double phi = rand()/static_cast<double>(RAND_MAX)*2.0*pi;
      return mean+sigma*r*sin(phi);
    }

    /// Perform the per-event analysis
    void analyze(const Event& event) {
      // smearing parameters
      // time measurement (in ns)
//       const double tsmear=5.*0.7;
      const double tsmear=0.7;
      // sagita error
      const double csag  =1.1E-4;
      // multiple scattering
      const double cms   =2.0E-2;
      // muon chamber radius (in metres)
      const double radius = 10.e3;
      // convert to ns
      const double tr = radius/c_light;
      // get the charged final-state particles
      Particles charged =
        apply<VetoedFinalState>(event,"VFS").particles();
      // need at least two candidates
      if(charged.size()<2) vetoEvent;
      // number passing trigger
      _count_trigger->fill(0.5);
      // Z mass veto
      for ( const Particle & mu1 : charged ) {
        for ( const Particle & mu2 : charged ) {
          double mass = (mu1.momentum()+mu2.momentum()).mass();
          double diff = abs(mass-91.18);
          if(diff<10.) vetoEvent;
        }
      }
      // number passing first event selection
      _count_event->fill(0.5);
      // now find the candidates
      // loop over the particles and find muons and heavy charged particles
      map<double,Particle> muonCandidates;
      for (const Particle& mu : charged) {
        // calculate the smeared momentum
        double pT     = mu.pT2();
        double pmag   = sqrt(pT+sqr(mu.pz()));
        double deltap = sqrt( sqr(csag*sqr(pmag)) + sqr(cms*mu.E()/GeV));
        double psmear = rndGauss(deltap,pmag);
        // keep particles with pT>40
        if(psmear/pmag*mu.perp()<40.*GeV||
           psmear/pmag*mu.perp()>1000.*GeV) continue;
        muonCandidates.insert(make_pair(psmear,mu));
      }
      // require two candidates
      if(muonCandidates.size()<2) vetoEvent;
      // number passing "quality" cut
      _count_quality->fill(0.5);
      // now do the time of flight
      bool filled = false;
      for(map<double,Particle>::const_iterator it=muonCandidates.begin();
          it!=muonCandidates.end();++it) {
        // true magnitude and pT of momentum
        double pT     = it->second.pT2();
        double pmag   = sqrt(pT+sqr(it->second.pz()));
        pT = sqrt(pT);
        // true time difference in ns
        double deltaT  =tr *(it->second.E()-pmag)/pT;
        // smear it
        deltaT = rndGauss(tsmear,deltaT);
        // beta
        double beta = 1./(1.+deltaT/tr*pT/pmag);
        _hist_beta->fill(beta);
        _hist_time->fill(deltaT);
        // beta cut
        if(beta<0.95) continue;
        // mass
        double mass = 2.*pT*it->first*deltaT/tr*(1.+0.5*deltaT/tr*pT/pmag);
        if(mass<0.) continue;
        mass = sqrt(mass);
        filled = true;
        _hist_mass->fill(mass);
        if(mass>90. ) {
          _count_90 ->fill(0.5);
          if(mass>110.) {
            _count_110->fill(0.5);
            if(mass>120.) {
              _count_120->fill(0.5);
              if(mass>130.) {
                _count_130->fill(0.5);
              }
            }
          }
        }
      }
      if(!filled) vetoEvent;
      // number passing beta cut
      _count_beta->fill(0.5);
    }

    //@}

    void finalize() {
      double fact = crossSection()/sumOfWeights()*37;
      MSG_WARNING("testing " << crossSection() << " " << sumOfWeights() << " " << fact);
      scale(_hist_beta,fact);
      scale(_hist_time,fact);
      scale(_hist_mass,fact);
      scale( _count_trigger, fact);
      scale( _count_event, fact);
      scale( _count_quality, fact);
      scale( _count_beta, fact);
      scale( _count_90, fact);
      scale( _count_110, fact);
      scale( _count_120, fact);
      scale( _count_130, fact);
    }

  private:

    /// @name Histograms
    //@{
    Histo1DPtr _hist_beta;
    Histo1DPtr _hist_time;
    Histo1DPtr _hist_mass;
    Histo1DPtr _count_trigger;
    Histo1DPtr _count_event;
    Histo1DPtr _count_quality;
    Histo1DPtr _count_beta;
    Histo1DPtr _count_90;
    Histo1DPtr _count_110;
    Histo1DPtr _count_120;
    Histo1DPtr _count_130;
    //@}

  };


  RIVET_DECLARE_ALIASED_PLUGIN(ATLAS_2011_S9108483, ATLAS_2011_I914491);

}