StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StMtdEvtFilterMaker.cxx
1 #include <iostream>
2 #include <math.h>
3 #include <vector>
4 #include <stdlib.h>
5 #include <bitset>
6 
7 #include "TH1F.h"
8 
9 #include "StMessMgr.h"
10 
11 #include "StEventTypes.h"
12 #include "StThreeVectorF.hh"
13 #include "StEvent.h"
14 #include "StTrack.h"
15 #include "StTrackGeometry.h"
16 #include "StDcaGeometry.h"
17 #include "StTpcDedxPidAlgorithm.h"
18 #include "StDedxPidTraits.h"
19 #include "StTrackPidTraits.h"
20 
21 #include "StMuDSTMaker/COMMON/StMuDstMaker.h"
22 #include "StMuDSTMaker/COMMON/StMuDst.h"
23 #include "StMuDSTMaker/COMMON/StMuEvent.h"
24 #include "StMuDSTMaker/COMMON/StMuTrack.h"
25 #include "StMuDSTMaker/COMMON/StMuMtdHit.h"
26 #include "StMuDSTMaker/COMMON/StMuMtdPidTraits.h"
27 
28 
29 #include "StMtdEvtFilterMaker.h"
30 #include "tables/St_trgOfflineFilter_Table.h"
31 #include "tables/St_mtdEventFilterCuts_Table.h"
32 #include "tables/St_MtdTrackFilterTag_Table.h"
33 
34 #include "tables/St_HighPtTag_Table.h"
35 
36 ClassImp(StMtdEvtFilterMaker)
37 
38 //_____________________________________________________________________________
39 StMtdEvtFilterMaker::StMtdEvtFilterMaker(const Char_t *name) : StMaker(name)
40 {
41  // default constructor
42 
43  mStEvent = NULL;
44  mMuDst = NULL;
45  mIsJpsiEvent = kFALSE;
46  mIsDiMuon = kFALSE;
47  mIsDiMuonOnly = kFALSE;
48 
49 
50  mMinTrkPtAll = 1.0;
51  mMinTrkPtLead = 0;
52  mMinNHitsFit = 15;
53  mMinNHitsDedx = 10;
54  mMinFitHitsFraction = 0.52;
55  mMaxDca = 1e4;
56  mMinNsigmaPi = -1e4;
57  mMaxNsigmaPi = 1e4;
58  mMaxDeltaZ = 1e4;
59  nMinMuonCandidates = 2;
60 
61  mSaveHistos = false;
62  mhEventStat = NULL;
63  mhNMuonCandidates = NULL;
64 }
65 
66 //_____________________________________________________________________________
67 StMtdEvtFilterMaker::~StMtdEvtFilterMaker()
68 {
69  // default destructor
70 }
71 
72 //_____________________________________________________________________________
73 Int_t StMtdEvtFilterMaker::Init()
74 {
75  SetFlavor("MtdEvtFilter","trgOfflineFilter");
76 
77  // book histograms
78  bookHistos();
79 
80  return kStOK;
81 }
82 
83 //_____________________________________________________________________________
84 Int_t StMtdEvtFilterMaker::InitRun(const Int_t runNumber)
85 {
86  LOG_INFO << "Retrieving trigger ID from database ..." << endm;
87  mTriggerIDs.clear();
88  mOtherTrigIDs.clear();
89 
90  St_trgOfflineFilter* flaggedTrgs =
91  static_cast<St_trgOfflineFilter *>(GetDataBase("Calibrations/trg/trgOfflineFilter"));
92  if (!flaggedTrgs)
93  {
94  LOG_ERROR << "Could not find Calibrations/trg/trgOfflineFilter in database" << endm;
95  return kStErr;
96  }
97 
98  trgOfflineFilter_st* flaggedTrg = flaggedTrgs->GetTable();
99  for (long j = 0; j < flaggedTrgs->GetNRows(); j++, flaggedTrg++)
100  {
101  int trigid = flaggedTrg->trigid;
102  if(trigid==0) continue;
103  else if (trigid<1e9) mTriggerIDs.push_back(trigid);
104  else mOtherTrigIDs.push_back(trigid-1e9);
105  }
106 
107  if(Debug())
108  {
109  for(unsigned int i=0; i<mTriggerIDs.size(); i++){
110  LOG_INFO << "Di-muon trigger ID: " << mTriggerIDs[i] << endm; }
111 
112  for(unsigned int i=0; i<mOtherTrigIDs.size(); i++){
113  LOG_INFO << "Other MTD trigger ID: " << mOtherTrigIDs[i] << endm; }
114  }
115 
116  LOG_INFO << "Retrieving event filtering cuts from database ..." << endm;
117 
118  St_mtdEventFilterCuts *mtdEventFilterCuts =
119  static_cast<St_mtdEventFilterCuts*>(GetDataBase("Calibrations/mtd/mtdEventFilterCuts"));
120  if(!mtdEventFilterCuts)
121  {
122  LOG_ERROR << "No mtdEventFilterCuts table found in database" << endm;
123  return kStErr;
124  }
125  mtdEventFilterCuts_st *table = static_cast<mtdEventFilterCuts_st*>(mtdEventFilterCuts->GetTable());
126 
127  mMinTrkPtAll = table->minTrkPtAll;
128  mMinTrkPtLead = table->minTrkPtLead;
129  mMinNHitsFit = (int)table->minNHitsFit;
130  mMinNHitsDedx = (int)table->minNHitsDedx;
131  mMinFitHitsFraction = table->minFitHitsFrac;
132  mMaxDca = table->maxDca;
133  mMinNsigmaPi = table->minNsigmaPi;
134  mMaxNsigmaPi = table->maxNsigmaPi;
135  mMaxDeltaZ = table->maxDeltaZ;
136  nMinMuonCandidates = (int)table->minNMuons;
137  if(Debug())
138  {
139  LOG_INFO << "minTrkPtAll = " << mMinTrkPtAll << endm;
140  LOG_INFO << "minTrkPtLead = " << mMinTrkPtLead << endm;
141  LOG_INFO << "minNHitsFit = " << mMinNHitsFit << endm;
142  LOG_INFO << "minNHitsDedx = " << mMinNHitsDedx << endm;
143  LOG_INFO << "minFitHitsFrac = " << mMinFitHitsFraction << endm;
144  LOG_INFO << "maxDca = " << mMaxDca << endm;
145  LOG_INFO << "minNsigmaPi = " << mMinNsigmaPi << endm;
146  LOG_INFO << "maxNsigmaPi = " << mMaxNsigmaPi << endm;
147  LOG_INFO << "maxDeltaZ = " << mMaxDeltaZ << endm;
148  LOG_INFO << "minNMuons = " << nMinMuonCandidates << endm;
149  }
150 
151 
152  return kStOK;
153 }
154 
155 //_____________________________________________________________________________
157 {
158 
159  mIsJpsiEvent = kFALSE;
160  mIsDiMuon = kFALSE;
161  mIsDiMuonOnly = kFALSE;
162 
163 
164  // Check the availability of input data
165  Int_t iret = -1;
166 
167  mStEvent = (StEvent*) GetInputDS("StEvent");
168  if(mStEvent)
169  {
170  LOG_DEBUG << "Running on StEvent ..." << endm;
171  iret = processStEvent();
172  }
173  else
174  {
175  StMuDstMaker *muDstMaker = (StMuDstMaker*) GetMaker("MuDst");
176  if(muDstMaker)
177  {
178  mMuDst = muDstMaker->muDst();
179  iret = processMuDst();
180  }
181  else
182  {
183  LOG_ERROR << "No muDST is available ... "<< endm;
184  iret = kStErr;
185  }
186  }
187 
188  MtdTrackFilterTag_st tagTable;
189  StMaker* maskMk = GetMakerInheritsFrom("StMtdTrackingMaskMaker");
190  tagTable.tpcSectors = (maskMk ? maskMk->UAttr("TpcSectorsByMtd") : ~0U);
191  tagTable.isRejectEvent = (isRejectEvent() ? 1 : 0);
192  tagTable.shouldHaveRejectEvent = shouldHaveRejectEvent();
193  St_MtdTrackFilterTag* MtdTrackFilterTag = new St_MtdTrackFilterTag("MtdTrackFilterTag",1);
194  MtdTrackFilterTag->AddAt(&tagTable,0);
195  AddData(MtdTrackFilterTag);
196 
197  if(mStEvent)
198  {
199  LOG_INFO << "Is event rejected: " << tagTable.isRejectEvent << endm;
200  LOG_INFO << "Should event be rejected: " << tagTable.shouldHaveRejectEvent << endm;
201  }
202 
203  return iret;
204 }
205 
206 //_____________________________________________________________________________
208 {
213 
214  return (mIsDiMuonOnly && !mIsJpsiEvent);
215 }
216 
217 //_____________________________________________________________________________
219 {
224 
225  if(mIsDiMuon)
226  {
227  if(!mIsDiMuonOnly && !mIsJpsiEvent) return 1;
228  else return 2;
229  }
230  else return 0;
231 }
232 
233 //_____________________________________________________________________________
234 void StMtdEvtFilterMaker::checkTriggerIDs(const vector<unsigned int> triggers)
235 {
240 
241  for(unsigned int i=0; !mIsDiMuon && i<triggers.size(); i++)
242  {
243  for(unsigned int j=0; !mIsDiMuon && j<mTriggerIDs.size(); j++)
244  {
245  mIsDiMuon = ((int)triggers[i]==mTriggerIDs[j]);
246  }
247  }
248 
249  mIsDiMuonOnly = mIsDiMuon;
250  for(unsigned int i=0; mIsDiMuonOnly && i<triggers.size(); i++)
251  {
252  for(unsigned int j=0; mIsDiMuonOnly && j<mOtherTrigIDs.size(); j++)
253  {
254  mIsDiMuonOnly = !((int)triggers[i]==mOtherTrigIDs[j]);
255  }
256  }
257 }
258 
259 //_____________________________________________________________________________
260 Int_t StMtdEvtFilterMaker::processMuDst()
261 {
262  mhEventStat->Fill(0.5);
263 
264  // check trigger id
265  vector<unsigned int> triggers = mMuDst->event()->triggerIdCollection().nominal().triggerIds();
266  checkTriggerIDs(triggers);
267  if(!mIsDiMuon) return kStOK;
268  mhEventStat->Fill(1.5);
269 
270  // Global tracks
271  int nNodes = mMuDst->numberOfGlobalTracks();
272  LOG_DEBUG << "# of global tracks " << nNodes << endm;
273 
274  int nMuonCandidates = 0;
275  double pt_max = 0;
276 
277  for(int i=0; i<nNodes; i++)
278  {
279  StMuTrack *gTrack = mMuDst->globalTracks(i);
280  if(!isValidTrack(gTrack)) continue;
281  if(!isMuonCandidate(gTrack)) continue;
282 
283  nMuonCandidates ++;
284  double pt = gTrack->pt();
285  if(pt_max<pt) pt_max = pt;
286  }
287 
288  mhNMuonCandidates->Fill(nMuonCandidates);
289  if(nMuonCandidates>=nMinMuonCandidates && pt_max>mMinTrkPtLead)
290  {
291  mIsJpsiEvent = kTRUE;
292  mhEventStat->Fill(2.5);
293  }
294 
295  return kStOK;
296 }
297 
298 //_____________________________________________________________________________
299 Int_t StMtdEvtFilterMaker::processStEvent()
300 {
301  mhEventStat->Fill(0.5);
302 
303  // check trigger id
304  vector<unsigned int> triggers = mStEvent->triggerIdCollection()->nominal()->triggerIds();
305  checkTriggerIDs(triggers);
306  if(!mIsDiMuon) return kStOK;
307  mhEventStat->Fill(1.5);
308 
309  // Global tracks
310  StSPtrVecTrackNode& nodes = mStEvent->trackNodes();
311  int nNodes = nodes.size();
312  LOG_DEBUG << "# of global tracks " << nNodes << endm;
313 
314  int nMuonCandidates = 0;
315  double pt_max = 0;
316  for(int i=0; i<nNodes; i++)
317  {
318  StTrack *gTrack = nodes[i]->track(global);
319 
320  if(!isValidTrack(gTrack)) continue;
321  if(!isMuonCandidate(gTrack)) continue;
322 
323  nMuonCandidates ++;
324  double pt = gTrack->geometry()->momentum().perp();
325  if(pt_max<pt) pt_max = pt;
326  }
327 
328  mhNMuonCandidates->Fill(nMuonCandidates);
329  if(nMuonCandidates>=nMinMuonCandidates && pt_max>mMinTrkPtLead)
330  {
331  mIsJpsiEvent = kTRUE;
332  mhEventStat->Fill(2.5);
333  }
334 
335  return kStOK;
336 }
337 
338 //_____________________________________________________________________________
339 bool StMtdEvtFilterMaker::isValidTrack(StTrack *track)
340 {
344  if(!track) return kFALSE;
345  StThreeVectorF mom = track->geometry()->momentum();
346  Float_t pt = mom.perp();
347  int nHitsFit = track->fitTraits().numberOfFitPoints(kTpcId);
348  int nHitsPoss = track->numberOfPossiblePoints(kTpcId);
349  int nHitsDedx = 0;
350  StTpcDedxPidAlgorithm pidAlgorithm;
351  const StParticleDefinition *pd = track->pidTraits(pidAlgorithm);
352  if(pd && pidAlgorithm.traits())
353  nHitsDedx = pidAlgorithm.traits()->numberOfPoints();
354 
355  if(pt < mMinTrkPtAll) return kFALSE;
356  if(nHitsFit<mMinNHitsFit) return kFALSE;
357  if(nHitsDedx<mMinNHitsDedx) return kFALSE;
358  if(nHitsFit/(1.0*nHitsPoss)<mMinFitHitsFraction) return kFALSE;
359  if(mMaxDca<1e4)
360  {
361  // Only check track DCA when the cut is reset
362  // by the user
363 
364  StPrimaryVertex* pvtx = mStEvent->primaryVertex();
365  if(!pvtx) return kFALSE;
366  StThreeVectorD vtxPos = pvtx->position();
367  StDcaGeometry* trDcaGeom = ((StGlobalTrack*) track)->dcaGeometry();
368  if(!trDcaGeom) return kFALSE;
369  StPhysicalHelixD dcahh = trDcaGeom->helix();
370  double dca = dcahh.distance(vtxPos,kFALSE);
371  if(dca>mMaxDca) return kFALSE;
372  }
373 
374  return kTRUE;
375 }
376 
377 //_____________________________________________________________________________
378 bool StMtdEvtFilterMaker::isValidTrack(StMuTrack *track)
379 {
383 
384  if(!track) return kFALSE;
385  StThreeVectorF mom = track->momentum();
386  double pt = mom.perp();
387  int nHitsFit = track->nHitsFit(kTpcId);
388  int nHitDedx = track->nHitsDedx();
389  int nHitPoss = track->nHitsPoss(kTpcId);
390  double dca = track->dcaGlobal().mag();
391 
392  if(pt < mMinTrkPtAll) return kFALSE;
393  if(nHitsFit<mMinNHitsFit) return kFALSE;
394  if(nHitDedx<mMinNHitsDedx) return kFALSE;
395  if(dca>mMaxDca) return kFALSE;
396  if(nHitsFit/(1.0*nHitPoss)<mMinFitHitsFraction) return kFALSE;
397  return kTRUE;
398 }
399 
400 //_____________________________________________________________________________
402 {
406 
407  if(!track) return kFALSE;
408 
409  if(mMaxNsigmaPi<1e4)
410  {
411  // nSigmaPi cut
412  double nSigmaPi = -999.;
413  StTpcDedxPidAlgorithm pidAlgorithm;
414  const StParticleDefinition *pd = track->pidTraits(pidAlgorithm);
415  if(pd && pidAlgorithm.traits())
416  {
417  static StPionPlus* Pion = StPionPlus::instance();
418  nSigmaPi = pidAlgorithm.numberOfSigma(Pion);
419  }
420  if(nSigmaPi<mMinNsigmaPi || nSigmaPi>mMaxNsigmaPi) return kFALSE;
421  }
422 
423  // dz cut
424  StMtdPidTraits* mtdpid = 0;
425  StSPtrVecTrackPidTraits& traits = track->pidTraits();
426  for(unsigned int it=0; it<traits.size(); it++)
427  {
428  if (traits[it]->detector() == kMtdId)
429  {
430  mtdpid = dynamic_cast<StMtdPidTraits*>(traits[it]);
431  break;
432  }
433  }
434  if(!mtdpid) return kFALSE;
435  if(mMaxDeltaZ<1e4)
436  {
437  double dz = mtdpid->deltaZ();
438  if(dz > mMaxDeltaZ) return kFALSE;
439  }
440 
441  return kTRUE;
442  }
443 
444 //_____________________________________________________________________________
446 {
450 
451  if(!track) return kFALSE;
452 
453  if(mMaxNsigmaPi<1e4)
454  {
455  // nSigmaPi cut
456  double nSigmaPi = track->nSigmaPion();
457  if(nSigmaPi<mMinNsigmaPi || nSigmaPi>mMaxNsigmaPi) return kFALSE;
458  }
459 
460  // dz cut
461  const StMuMtdHit *hit = track->mtdHit();
462  if(!hit) return kFALSE;
463  if(mMaxDeltaZ<1e4)
464  {
465  const StMuMtdPidTraits mtdPid = track->mtdPidTraits();
466  double dz = mtdPid.deltaZ();
467  if(dz > mMaxDeltaZ) return kFALSE;
468  }
469 
470  return kTRUE;
471  }
472 
473 //_____________________________________________________________________________
474 void StMtdEvtFilterMaker::bookHistos()
475 {
476  mhEventStat = new TH1F("hEventStat","Event statistics",5,0,5);
477  mhEventStat->GetXaxis()->SetBinLabel(1,"All events");
478  mhEventStat->GetXaxis()->SetBinLabel(2,"Good trigger");
479  mhEventStat->GetXaxis()->SetBinLabel(3,"Accepted");
480 
481  mhNMuonCandidates = new TH1F("hNMuonCandidates","Number of muon candidates per event;N",10,0,10);
482 
483  if(mSaveHistos)
484  {
485  AddHist(mhEventStat);
486  AddHist(mhNMuonCandidates);
487  }
488 
489 }
490 
491 // $Id: StMtdEvtFilterMaker.cxx,v 1.3 2016/07/27 15:24:30 marr Exp $
492 // $Log: StMtdEvtFilterMaker.cxx,v $
493 // Revision 1.3 2016/07/27 15:24:30 marr
494 // Fix coverity check: initialization of data members
495 //
496 // Revision 1.2 2015/04/23 21:10:19 marr
497 // 1. remove dz and pTlead cuts in the filtering by default
498 // 2. change the number scheme for shouldHaveRejectEvent()
499 //
500 // Revision 1.1 2015/04/07 14:10:37 jeromel
501 // First version of StMtdEvtFilterMaker - R.Ma - review closed 2015/04/06
502 //
503 //
static TObjArray * globalTracks()
returns pointer to the global tracks list
Definition: StMuDst.h:303
StMuDst * muDst()
Definition: StMuDstMaker.h:425
virtual void AddData(TDataSet *data, const char *dir=".data")
User methods.
Definition: StMaker.cxx:332
Double_t pt() const
Returns pT at point of dca to primary vertex.
Definition: StMuTrack.h:256
UShort_t nHitsDedx() const
Return number of hits used for dEdx.
Definition: StMuTrack.h:238
This class is used to check number of muon candidates in each event. It runs both on StEvent and MuDs...
double distance(const StThreeVector< double > &p, bool scanPeriods=true) const
minimal distance between point and helix
Definition: StHelix.cc:240
bool isMuonCandidate(StTrack *track)
UShort_t nHitsFit() const
Return total number of hits used in fit.
Definition: StMuTrack.h:239
Double_t nSigmaPion() const
Returns Craig&#39;s distance to the calculated dE/dx band for pions in units of sigma.
Definition: StMuTrack.h:245
UShort_t nHitsPoss() const
Return number of possible hits on track.
Definition: StMuTrack.cxx:242
static StMuEvent * event()
returns pointer to current StMuEvent (class holding the event wise information, e.g. event number, run number)
Definition: StMuDst.h:320
const StThreeVectorF & momentum() const
Returns 3-momentum at dca to primary vertex.
Definition: StMuTrack.h:260
Definition: Stypes.h:40
StThreeVectorF dcaGlobal(Int_t vtx_id=-1) const
Returns 3D distance of closest approach to primary vertex of associated global track.
Definition: StMuTrack.cxx:371
Definition: Stypes.h:44