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
| // -*- C++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/ChargedFinalState.hh"
namespace Rivet {
class ALICE_2012_I1181770 : public Analysis {
public:
ALICE_2012_I1181770()
: Analysis("ALICE_2012_I1181770")
{ }
void init() {
// Projection setup
declare(ChargedFinalState(), "CFS");
// Book (energy-specific) histograms
int isqrts = -1;
if (isCompatibleWithSqrtS(900)) isqrts = 1;
else if (isCompatibleWithSqrtS(2760)) isqrts = 2;
else if (isCompatibleWithSqrtS(7000)) isqrts = 3;
assert(isqrts > 0);
book(_h_frac_sd_inel, 1, 1, isqrts);
book(_h_frac_dd_inel, 2, 1, isqrts);
book(_h_xsec_sd , 3, 1, isqrts);
book(_h_xsec_dd , 4, 1, isqrts);
book(_h_xsec_inel , 5, 1, isqrts);
}
void analyze(const Event& event) {
const ChargedFinalState& cfs = apply<ChargedFinalState>(event, "CFS");
if (cfs.size() < 2) vetoEvent; // need at least two particles to calculate gaps
// Fill INEL plots for each event
_h_xsec_inel->fill(sqrtS()/GeV);
// Identify particles with most positive/most negative rapidities
const Particles particlesByRap = cfs.particles(cmpMomByRap);
const Particle pslowest = particlesByRap.front();
const Particle pfastest = particlesByRap.back();
// Find gap sizes
const Particles particlesByEta = cfs.particles(cmpMomByEta); // sorted from minus to plus
const size_t num_particles = particlesByEta.size();
vector<double> gaps;
for (size_t ip = 1; ip < num_particles; ++ip) {
const Particle& p1 = particlesByEta[ip-1];
const Particle& p2 = particlesByEta[ip];
const double gap = p2.eta() - p1.eta();
assert(gap >= 0);
gaps.push_back(gap);
}
// First, last, and largest gaps
const double gapmax = *max_element(gaps.begin(), gaps.end());
const double gapbwd = gaps.front();
const double gapfwd = gaps.back();
// Mx calculation
FourMomentum p4lead;
if (pslowest.pid() == PID::PROTON && pfastest.pid() == PID::PROTON) {
p4lead = (fabs(pslowest.rapidity()) > fabs(pfastest.rapidity())) ? pslowest.momentum() : pfastest.momentum();
} else if (pslowest.pid() == PID::PROTON) {
p4lead = pslowest.momentum();
} else if (pfastest.pid() == PID::PROTON) {
p4lead = pfastest.momentum();
}
const double Mx = sqrt( (sqrtS()-p4lead.E()-p4lead.p3().mod()) * (sqrtS()-p4lead.E()+p4lead.p3().mod()) );
// Fill SD (and escape) if Mx is sufficiently low
if (Mx < 200*GeV) {
_h_xsec_sd->fill(sqrtS()/GeV);
return;
}
// Also remove SD-like events in NSD events
if (fuzzyEquals(gapbwd, gapmax) || fuzzyEquals(gapfwd, gapmax)) vetoEvent;
// Fill DD plots
if (gapmax > 3) _h_xsec_dd->fill(sqrtS()/GeV);
}
void finalize() {
// get the ratio plots: SD/inel, DD/inel
divide(_h_xsec_sd , _h_xsec_inel, _h_frac_sd_inel);
divide(_h_xsec_sd , _h_xsec_inel, _h_frac_dd_inel);
const double scaling = crossSection()/millibarn/sumOfWeights();
scale(_h_xsec_sd, scaling);
scale(_h_xsec_dd, scaling);
scale(_h_xsec_inel, scaling);
}
private:
Scatter2DPtr _h_frac_sd_inel;
Scatter2DPtr _h_frac_dd_inel;
Histo1DPtr _h_xsec_sd;
Histo1DPtr _h_xsec_dd;
Histo1DPtr _h_xsec_inel;
};
// Hook for the plugin system
RIVET_DECLARE_PLUGIN(ALICE_2012_I1181770);
}
|