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