StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StEemcGammaFilter.cxx
1 // $Id: StEemcGammaFilter.cxx,v 1.2 2010/08/09 21:52:21 seluzhen Exp $
2 
3 #include <cstdlib>
4 #include <cmath>
5 #include <iostream>
6 #include <vector>
7 #include <map>
8 #include <algorithm>
9 
10 using namespace std;
11 
12 #include "StMCFilter/StGenParticle.h"
13 #include "StMCFilter/StEemcGammaFilter.h"
14 
15 #include "TLorentzVector.h"
16 
17 // IMPORTANT IMPORTANT IMPORTANT
18 // Defining the static instance of user filter provides creating this
19 // class during the loading of library. Afterward GEANT could select
20 // the needed filter by name.
21 
22 static StEemcGammaFilter eemcGammaFilter;
23 
24 
26 //Defining the constants for endcap filtering/
28 //the radius of cone in eta-phi space for clustering
29 const double StEemcGammaFilter::mConeRadius = 0.22;
30 
31 //minimum energy of a gamma candidate seed track
32 const double StEemcGammaFilter::mSeedThreshold = 3.8; //2.4; //2.6;
33 
34 //minimum energy of a gamma candidate cluster
35 const double StEemcGammaFilter::mClusterThreshold = 5.0; //3.3; //3.6;
36 
37 //minimum eta of a gamma candidate
38 const double StEemcGammaFilter::mEtaLow = 0.95;
39 
40 //maximum eta of a gamma candidate
41 const double StEemcGammaFilter::mEtaHigh =2.1;
42 
43 //maximum vertex of gamma candidate
44 const double StEemcGammaFilter::mMaxVertex = 120.0;
45 
46 //depth of the EEMC SMD
47 const double StEemcGammaFilter:: mCalDepth = 279.5;
48 
49 //factor that hadronic energy is decreased to model
50 //response of EEMC to hardons
51 // const double StEemcGammaFilter:: mHadronScale = 0.4;
52 const double StEemcGammaFilter:: mHadronScale = 1.0;
53 
54 //minimum energy of event tracks that are kept
55 //for clustering
56 const double StEemcGammaFilter:: mMinPartEnergy = 0.00001;
57 
58 
59 bool operator>(const TLorentzVector& v1, const TLorentzVector& v2)
60 {
61  return v1.E() > v2.E();
62 }
63 
64 
66 // Constructor //
68 
69 StEemcGammaFilter::StEemcGammaFilter(): StMCFilter("eemcGammaFilter.1.00")
70 {
71 
72  //some options for testing
73  //sets a printout level. 0 = min, 1=medium and 2=max
74  mPrintLevel = 0;
75  //Fliter mode
76  //0 - test mode (accept all events)
77  //1 - reject events at Pythia level
78 // mFilterMode = 1;
79  mFilterMode = 1;
80 
81  if (!mFilterMode)
82  cout<<"StEemcGammaFilter:: running the TEST mode (accepting all events). Set mFilterMode=1 to actually reject events"<< endl;
83 
84  cout<<"StEemcGammaFilter::"
85  <<" mConeRadius "<<mConeRadius
86  <<" mSeedThreshold "<< mSeedThreshold
87  <<" mClusterThreshold "<< mClusterThreshold
88  <<" mEtaLow "<<mEtaLow
89  <<" mEtaHigh "<<mEtaHigh
90  <<" mMaxVertex "<<mMaxVertex
91  <<endl;
92  cout<<"StEemcGammaFilter::"
93  <<" mCalDepth " << mCalDepth
94  <<" mMinPartEnergy " <<mMinPartEnergy
95  <<" mHadronScale " <<mHadronScale
96  <<" mFilterMode " <<mFilterMode
97  <<" mPrintLevel "<<mPrintLevel
98  <<endl;
99 
100 
101 }
102 
103 
105 // Filter events immediately after vertex //
107 
109 {
110 
111  //vectors of vectors to hold tracks
112  //tracks in detector coordinates
113  vector<TLorentzVector> seedTracksDet;
114  vector<TLorentzVector> eventTracksDet;
115 
116  //particle coordinates
117 // vector<TLorentzVector> eventTracks;
118 
119  float zVertex = 0;
120  int acceptFlag= 0;
121 
122  const StGenParticle* track = 0;
123  // Loop over particles
124  for(int i = 0; i < ptl.Size(); ++i)
125  {
126 
127  track = ptl(i);
128  if(!track) continue;
129 
130  // Skip any intermediate particles
131  if(track->GetStatusCode() != 1) continue;
132 
133  int id = track->GetPdgCode();
134 
135  //get momentum 4-vector and vertex
136  double p[4] = {0, 0, 0, 0};
137  double v[3] = {0, 0, 0};
138 
139  track->Momentum(p);
140  track->Vertex(v);
141  zVertex = v[2];
142  //can reject for vertex now
143  if(fabs(v[2])>mMaxVertex)
144  {
145  if(mPrintLevel>=1) cout<<"Rejecting event with extreme vertex of "<<v[2]<<endl;
146  if (mFilterMode==0 || mPrintLevel>=1)
147  if (acceptFlag==0) { cout<<"StEemcGammaFilter::RejectGT() - Reject!"<<endl; acceptFlag = -1;}
148  if (mFilterMode) return mFilterMode;
149  }
150 
151 
152  //fill a lorentz vector with particle kinematics
153  TLorentzVector particleV(p[0],p[1],p[2],p[3]);;
154 
155  if(mPrintLevel>=2)
156  {
157  cout<<"Particle vector px py pz E Et:\n";
158  cout<<particleV.Px()<<" "<<particleV.Py()<<" "<<particleV.Pz()
159  <<" "<<particleV.E()<<" "<<particleV.Et()<<endl;
160  }
161 
162  //When moving to detector coordinates we want
163  //the r of detector vector normalized to the smd
164  //and we add on the vertex
165  double scale = (mCalDepth-v[2]) / fabs(p[2]);
166  for(unsigned int j = 0; j < 3; ++j) p[j] = p[j] * scale + v[j];
167 
168  TVector3 positionV(p[0],p[1],p[2]);
169  //Let's re-normalize this to the momentum
170  positionV.SetMag(particleV.P());
171 
172  TLorentzVector detectorV(positionV,p[3]);
173 
174 
175  if(mPrintLevel>=2)
176  {
177  cout<<"Detector vector px py pz E Et:\n";
178  cout<<detectorV.Px()<<" "<<detectorV.Py()<<" "<<detectorV.Pz()
179  <<" "<<detectorV.E()<<" "<<detectorV.Et()<<endl;
180  }
181 
182  // To mimic the response of the calorimeters to hadrons,
183  // decrease energy deposited by some factor
184  // for all particles except for
185  // photons (22), neutral pions (111), eta (221), electrons (11)
186  // antiprotons (-2212), and antineutrons (-2112)
187  // note: charged pions are 211
188 
189  bool hadronFlag = abs(id) != 22 && abs(id) != 111 && abs(id) != 221 && abs(id) != 11;
190  //we keep anti-baryons at full energy with guess that they
191  //annhilated and deposit all their energy
192  hadronFlag &= id != -2212 && id != -2112;
193 
194 
195  if(hadronFlag){
196  particleV*=mHadronScale;
197  detectorV*=mHadronScale;
198  if(mPrintLevel>=2)
199  cout<<"Particle with id "<< id<<" is a hadron - E was "<<track->Energy()<<" and is now "<<detectorV.Energy()<<endl;
200  }
201 
202 
203  /*
204  If we had a track that's low in energy let's throw it out
205  */
206 
207  if(particleV.E()<mMinPartEnergy){
208  if(mPrintLevel>=1)
209  cout<<"Throwing out track with energy "<<particleV.E()
210  <<" from particle with id "<<id<<endl;
211  continue;
212  }
213 
214 
215 
216  // Ignore tracks outside of the fiducial volume
217  if(detectorV.Eta() < mEtaLow || detectorV.Eta() > mEtaHigh) continue;
218 
219  //store seed tracks with energy above threshold
220  //Gamma maker uses particle tracks (corrected for vertex) to measure momentum
221  //but we want detector eta and phi for clustering so save both
222  if(particleV.Energy() > mSeedThreshold)
223  {
224  seedTracksDet.push_back(detectorV);
225  if(mPrintLevel>=1)
226  {
227  cout<<"Seed track stored with E "<<particleV.Energy()
228  <<" et "<<particleV.Et()
229  <<" detector eta "<<detectorV.Eta()
230  <<" and detector phi "<<detectorV.Phi()<<endl;
231  cout<<"StStRoot/StMCFilter/StGenParticle Print :"<<endl;
232  track->Print();
233  }
234  }
235 
236  // Store all tracks
237  eventTracksDet.push_back(detectorV);
238 // eventTracks.push_back(particleV);
239 
240  }
241 
242  // Search for clusters around each seed
243 
244 
245 
246 
247  if(seedTracksDet.empty()){
248  if(mPrintLevel>=1)
249  cout<<"Did not find any fiducial seed tracks passing the energy threshold.\n";
250  if (mFilterMode==0 || mPrintLevel>=1)
251  if(mPrintLevel>=1) {if (acceptFlag==0) cout<<"StEemcGammaFilter::RejectGT() - Reject!"<<endl;}
252  acceptFlag += -10;
253  if(mPrintLevel>=1)
254  {
255  cout << "StEemcGammaFilter:: max clusters: seed: " << acceptFlag << " " << zVertex << " "
256  << 0.0 <<" "<< 0.0<<" "<<0.0<<" "<<0.0<<" "<<0.0
257  << " :Et: "
258  << 0.0 <<" "<< 0.0<<" "<<0.0<<" "<<0.0<<" "<<0.0<< endl;
259  }
260  return mFilterMode;
261  }
262 
263 // if(eventTracksDet.size()!=eventTracks.size())
264 // cout<<"Did not save detector and particle variables for all event tracks!\n";
265 
266 
267  /*
268  This is a very simple way to cluster.
269  I loop over the seed tracks and include tracks in
270  eta and phi (detector Eta and Phi) space with R<R_max.
271  Using a vector sum to add tracks, then get transverse
272  energy at the end when all tracks are added.
273 
274  */
275 
276  //sorting the seed tracks in terms of energy makes it
277  //more likely to find cluster in first few loops
278  sort(seedTracksDet.begin(),seedTracksDet.end(),greater<TLorentzVector>());
279 
280  TLorentzVector maxSeedCluster(0.,0.,0.,0.);
281  TLorentzVector maxEtCluster(0.,0.,0.,0.);
282  float maxEtClusterValue = 0;
283  float maxSeedClusterSeedEnergy = 0;
284  float maxEtClusterSeedEnergy = 0;
285 
286  for(unsigned int iseed = 0; iseed<seedTracksDet.size(); iseed++)
287  {
288  if(mPrintLevel>=1)
289  {
290  cout<<"Begin looping seed track with energy "<<seedTracksDet[iseed].Energy()
291  <<" detector eta "<<seedTracksDet[iseed].Eta()
292  <<" and detector phi "<<seedTracksDet[iseed].Phi()<<endl;
293  }
294 
295  TLorentzVector clusterV(0.,0.,0.,0.);
296 
297 // if(eventTracksDet.empty())continue;
298 
299  for(unsigned int ievent = 0; ievent<eventTracksDet.size(); ievent++)
300  {
301 
302  //use detector variables for clustering in eta-phi space
303  double dEta = seedTracksDet[iseed].Eta()-eventTracksDet[ievent].Eta();
304  double dPhi = acos( cos( seedTracksDet[iseed].Phi() - eventTracksDet[ievent].Phi()) );
305  double R = sqrt( dEta * dEta + dPhi * dPhi );
306 
307 
308  //use particle variables for momentum
309  TLorentzVector &trackV = eventTracksDet[ievent];
310 
311 
312  if(R <= mConeRadius) {
313  clusterV+=trackV;
314  if(mPrintLevel>=1)
315  {
316  cout<<"Track accepted with energy "<<trackV.Energy()
317  <<" et "<<trackV.Et()
318  <<" dEta "<<dEta
319  <<" dPhi "<<dPhi
320  <<" R "<<R<<endl;
321  cout<<"EtSum now "<<clusterV.Et()<<endl;
322  }
323  }//within our maximum radius
324  }//all event tracks looped
325  if (clusterV.Et() > maxEtClusterValue ) // cluster with maximum Et
326  {
327  maxEtClusterValue = clusterV.Et();
328  maxEtCluster = clusterV;
329  maxEtClusterSeedEnergy = seedTracksDet[iseed].Energy();
330  }
331  if (iseed==0) // cluster with maximum seed particle
332  {
333  maxSeedCluster = clusterV;
334  maxSeedClusterSeedEnergy = seedTracksDet[iseed].Energy();
335  }
336 
337 
338  // If a cluster was found above threshold,
339  // let the event through the filter
340  if(clusterV.Et() > mClusterThreshold)
341  {
342  if(mPrintLevel>=1)
343  cout<<"Cluster accepted with et "<<clusterV.Et()
344  <<" eta "<<clusterV.Eta()<< " and phi "<<clusterV.Phi()<<endl;
345 // if(mPrintLevel>=1)
346  if (mFilterMode==0 || mPrintLevel>=1)
347  if (acceptFlag==0)
348  {
349  if(mPrintLevel>=1) cout << "StEemcGammaFilter::RejectGT() - Accept!" << endl;
350  acceptFlag= 1;
351  }
352  if (mFilterMode) return 0;
353  }
354 
355  }
356 
357  // If no clusters were found, abort the event
358 // if(mPrintLevel>=1)
359  if (mFilterMode==0 || mPrintLevel>=1)
360  {if (acceptFlag==0) if(mPrintLevel>=1) cout << "StEemcGammaFilter::RejectGT() - Reject!" << endl;}
361  if (acceptFlag==0) acceptFlag = -100;
362  if(mPrintLevel>=1)
363  {
364  cout << "StEemcGammaFilter:: max clusters: seed: " << acceptFlag << " " << zVertex << " "
365  << maxSeedClusterSeedEnergy<<" "<< maxSeedCluster.E()<<" "<<maxSeedCluster.Et()<<" "<<maxSeedCluster.Eta()<<" "<<maxSeedCluster.Phi()
366  << " :Et: "
367  << maxEtClusterSeedEnergy<<" "<<maxEtCluster.E()<<" "<<maxEtCluster.Et()<<" "<<maxEtCluster.Eta()<<" "<<maxEtCluster.Phi()
368  << endl;
369  }
370 
371  return mFilterMode;
372 }
373 
374 // $Log: StEemcGammaFilter.cxx,v $
375 // Revision 1.2 2010/08/09 21:52:21 seluzhen
376 // updated comment field
377 //
378 
int RejectGT(const StGenParticleMaster &ptl) const
Rejection of GEANT Tracking.
Pythia level Endcap EMC gamma filter.
Abstract base class for particles related to common /HEPEVT/.