StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StBemcGammaFilter.cxx
1 #include "stdlib.h"
2 #include "math.h"
3 #include <iostream>
4 #include <vector>
5 #include <map>
6 
7 #include "StMCFilter/StGenParticle.h"
8 #include "StMCFilter/StBemcGammaFilter.h"
9 
10 
11 // IMPORTANT IMPORTANT IMPORTANT
12 // Defining the static instance of user filter provides creating this
13 // class during the loading of library. Afterward GEANT could select
14 // the needed filter by name.
15 
16 static StBemcGammaFilter bemcGammaFilter;
17 
18 using namespace std;
19 
21 bool comparePhi(kinematics A, kinematics B) { return A.phi < B.phi ? true : false; }
22 
24 
26 {
27 
28  // 2009 Defaults
29  mConeRadius = 0.12; // Circumscribe a 3x3 BEMC tower cluster
30  mSeedThreshold = 5.0;
31  mClusterThreshold = 6.55;
32  mEtaLow = -1.05;
33  mEtaHigh = 1.05;
34  mMaxVertex = 80;
35 
36 }
37 
41 
42 void StBemcGammaFilter::parseConfig(string attr, float val)
43 {
44 
45  if(attr == "ConeRadius")
46  {
47  cout << "StBemcGammaFilter::parseConfig() - Setting mConeRadius to " << val << endl;
48  mConeRadius = val;
49  }
50  else if(attr == "SeedThreshold")
51  {
52  cout << "StBemcGammaFilter::parseConfig() - Setting mSeedThreshold to " << val << endl;
53  mSeedThreshold = val;
54  }
55  else if(attr == "ClusterThreshold")
56  {
57  cout << "StBemcGammaFilter::parseConfig() - Setting mClusterThreshold to " << val << endl;
58  mClusterThreshold = val;
59  }
60  else if(attr == "EtaLow")
61  {
62  cout << "StBemcGammaFilter::parseConfig() - Setting mEtaLow to " << val << endl;
63  mEtaLow = val;
64  }
65  else if(attr == "EtaHigh")
66  {
67  cout << "StBemcGammaFilter::parseConfig() - Setting mEtaHigh to " << val << endl;
68  mEtaHigh = val;
69  }
70  else if(attr == "MaxVertex")
71  {
72  cout << "StBemcGammaFilter::parseConfig() - Setting mMaxVertex to " << val << endl;
73  mMaxVertex = val;
74  }
75  else
76  {
77  cout << "StBemcGammaFilter::parseConfig() - " << attr << " is not an existing parameter!" << endl;
78  }
79 
80  return;
81 
82 }
83 
87 
89 {
90 
91  // Instantiate variables
92  const StGenParticle* track = 0;
93 
94  double p[4] = {0, 0, 0, 0};
95  double v[3] = {0, 0, 0};
96 
97  // Immediately abort events with extreme vertices
98  track = ptl(0);
99  track->Vertex(v);
100  if(fabs(v[2]) > mMaxVertex) return 1;
101 
102  // Resume instantiations
103  double E = 0;
104  double particleEt = 0;
105  double detectorEt = 0;
106  double detectorEta = 0;
107  double detectorPhi = 0;
108 
109  int id = 0;
110  bool hadronFlag = 0;
111 
112  double rSmd = 230.705;
113  double rSmd2 = rSmd * rSmd;
114 
115  double pT2 = 0;
116  double pdotv = 0;
117  double pcrossv = 0;
118  double N = 0;
119  double rho2 = 0;
120 
121  double pi = 3.141592653589793;
122 
123  map<double, kinematics> seedTracks;
124  map<double, kinematics> eventTracks;
125 
126  // Loop over particles
127  for(int i = 0; i < ptl.Size(); ++i)
128  {
129 
130  track = ptl(i);
131  if(!track) continue;
132 
133  // Skip any intermediate particles
134  if(track->GetStatusCode() != 1) continue;
135 
136  id = track->GetPdgCode();
137  E = track->Energy();
138 
139  // To mimic the response of the calorimeters to hadrons,
140  // reduce the energy of all particles except for
141  // photons (22), neutral pions (111), eta (221), electrons (11)
142  // antiprotons (-2212), and antineutrons (-2112)
143 
144  hadronFlag = abs(id) != 22 && abs(id) != 111 && abs(id) != 221 && abs(id) != 11;
145  hadronFlag &= id != -2212 && id != -2112;
146 
147  if(hadronFlag) E *= 0.85;
148 
149  // Compute track kinematics from the vertex
150  track->Vertex(v);
151  track->Momentum(p);
152 
153  pT2 = p[0] * p[0] + p[1] * p[1];
154  particleEt = E * sqrt( pT2 / (pT2 + p[2] * p[2]) );
155 
156  // Compute track kinematics corrected for vertex
157  pdotv = p[0] * v[0] + p[1] + v[1];
158  pcrossv = p[0] * v[1] - p[1] * v[0];
159  N = ( - pdotv + sqrt( pT2 * rSmd2 - pcrossv ) ) / pT2;
160 
161  for(unsigned int j = 0; j < 3; ++j) p[j] = N * p[j] + v[j];
162 
163  rho2 = p[0] * p[0] + p[1] * p[1];
164 
165  detectorEt = E * sqrt( rho2 / (rho2 + p[2] * p[2] ) );
166  detectorEta = - log( sqrt(rho2) / ( sqrt( rho2 + p[2] * p[2] ) + p[2] ) );
167  detectorPhi = atan2(p[1], p[0]);
168 
169  // Ignore tracks outside of the fiducial volume
170  if(detectorEta < mEtaLow) continue;
171  if(detectorEta > mEtaHigh) continue;
172 
173  // Store seed tracks
174  if(E > mSeedThreshold) seedTracks[detectorPhi] = kinematics(E, detectorEta, detectorPhi);
175 
176  // Store all tracks
177  eventTracks[detectorPhi] = kinematics(particleEt, detectorEta, detectorPhi);
178 
179  }
180 
181  // Search for clusters around each seed,
182  // being careful with the discontinuity in phi
183 
184  map<double, kinematics>::iterator itSeed;
185  map<double, kinematics>::iterator itEvent;
186 
187  double phiLeft = 0;
188  double phiRight = 0;
189 
190  double dEta = 0;
191  double dPhi = 0;
192  double R = 0;
193 
194  double EtSum = 0;
195 
196  itEvent = eventTracks.begin();
197 
198  for(itSeed = seedTracks.begin(); itSeed != seedTracks.end(); ++itSeed)
199  {
200 
201  EtSum = 0;
202  dPhi = 0;
203 
204  // Calculate phi boundaries of seed cone
205  phiLeft = (itSeed->first) - mConeRadius;
206  phiRight = (itSeed->first) + mConeRadius;
207 
208  // Slide back in the list if the previous cone overlaps with current cone
209  while(itEvent != eventTracks.begin())
210  {
211  if(itEvent->first > phiLeft) --itEvent;
212  else break;
213  }
214 
215  // Slide to the end of the list if the cone crosses the discontinuity in phi
216  if(phiLeft < - pi)
217  {
218 
219  // Reset the track iterator only if at least one track is within the cone overflow
220  map<double, kinematics>::reverse_iterator rit = eventTracks.rbegin();
221  if(rit->first > phiLeft + 2 * pi)
222  {
223 
224  // Remap phi domain
225  phiLeft = phiLeft + 2 * pi;
226  phiRight = phiRight + 2 * pi;
227 
228  // Reverse iterate to the first track that falls outside the cone
229  while(rit->first > phiLeft) ++rit;
230 
231  // Set event track iterator to this last track
232  // Note the increment operator to take into account the decrement
233  // implicit in reverse_iterator::base()
234  itEvent = (++rit).base();
235 
236  }
237 
238  }
239 
240  // Loop past tracks before the cone
241  while(itEvent->first < phiLeft) ++itEvent;
242 
243  // Loop over tracks in the cone
244  dPhi = 0;
245 
246  while(itEvent->first < phiRight)
247  {
248 
249  dEta = itSeed->second.eta - itEvent->second.eta;
250  dPhi = acos( cos( itSeed->first - itEvent->first) );
251  R = sqrt( dEta * dEta + dPhi * dPhi );
252 
253  if(R < mConeRadius) EtSum += itEvent->second.Et;
254 
255  // Increment event track,
256  ++itEvent;
257 
258  // Slide to the front of the list if the cone crosses the discontinuity in phi
259  if(itEvent == eventTracks.end())
260  {
261 
262  // Remap phi
263  phiLeft = phiLeft - 2 * pi;
264  phiRight = phiRight - 2 * pi;
265 
266  itEvent = eventTracks.begin();
267 
268  }
269 
270  }
271 
272  // If a cluster was found above threshold,
273  // let the event through the filter
274  if(EtSum > mClusterThreshold) return 0; // 0 FOR BOTH TESTS
275 
276  }
277 
278  // If no clusters were found, abort the event
279  return 1;
280 
281 }
double mEtaHigh
Maximum detector eta.
double mConeRadius
Cone radius of cluster.
double mClusterThreshold
Cluster E_{T} threshold for clustering finding.
Abstract base class for particles related to common /HEPEVT/.
void parseConfig(std::string, float)
int RejectGT(const StGenParticleMaster &ptl) const
double mSeedThreshold
Seed energy threshold for cluster finding.
double mMaxVertex
Maximum vertex magnitude in cm.
double mEtaLow
Minimum detector eta.
StBemcGammaFilter()
Constructor.
Sparse class to hold track kinematics.