10 #include "PhysicalConstants.h"
11 #include "StMessMgr.h"
14 #include "StTriggerData.h"
16 #include "StMtdCollection.h"
19 #include "StMuDSTMaker/COMMON/StMuDstMaker.h"
20 #include "StMuDSTMaker/COMMON/StMuDst.h"
21 #include "StMuDSTMaker/COMMON/StMuEvent.h"
22 #include "StMuDSTMaker/COMMON/StMuMtdHit.h"
24 #include "tables/St_mtdModuleToQTmap_Table.h"
25 #include "tables/St_mtdQTSlewingCorr_Table.h"
26 #include "tables/St_trgOfflineFilter_Table.h"
27 #include "StMtdTrackingMaskMaker.h"
33 mStEvent(NULL), mMuDst(NULL), mIsDiMuon(kFALSE), mTrigData(NULL),
34 mTpcSectorsForTracking(0)
44 mhNTrigMtdHits = NULL;
45 mhNTpcSectorForTracking = NULL;
49 StMtdTrackingMaskMaker::~StMtdTrackingMaskMaker()
55 Int_t StMtdTrackingMaskMaker::Init()
64 Int_t StMtdTrackingMaskMaker::InitRun(
const Int_t runNumber)
67 LOG_INFO <<
"Retrieving trigger ID from database ..." << endm;
68 St_trgOfflineFilter* flaggedTrgs =
69 (St_trgOfflineFilter *) GetDataBase(
"Calibrations/trg/trgOfflineFilter");
72 LOG_ERROR <<
"Could not find Calibrations/trg/trgOfflineFilter in database" << endm;
76 trgOfflineFilter_st* flaggedTrg = flaggedTrgs->GetTable();
77 for (
long j = 0;j < flaggedTrgs->GetNRows(); j++, flaggedTrg++)
79 int trigid = flaggedTrg->trigid;
80 if (0<trigid && trigid<1e9) mTriggerIDs.push_back(trigid);
84 memset(mModuleToQT,-1,
sizeof(mModuleToQT));
85 memset(mModuleToQTPos,-1,
sizeof(mModuleToQTPos));
86 memset(mQTtoModule,-1,
sizeof(mQTtoModule));
89 LOG_INFO <<
"Retrieving mtdModuleToQTmap table from database ..." << endm;
90 TDataSet *dataset = GetDataBase(
"Geometry/mtd/mtdModuleToQTmap");
91 St_mtdModuleToQTmap *mtdModuleToQTmap =
static_cast<St_mtdModuleToQTmap*
>(dataset->
Find(
"mtdModuleToQTmap"));
94 LOG_ERROR <<
"No mtdModuleToQTmap table found in database" << endm;
97 mtdModuleToQTmap_st *mtdModuleToQTtable =
static_cast<mtdModuleToQTmap_st*
>(mtdModuleToQTmap->GetTable());
99 for(
int i=0; i<gMtdNBacklegs; i++)
101 for(
int j=0; j<gMtdNModules; j++)
104 int qt = mtdModuleToQTtable->qtBoardId[index];
105 int channel = mtdModuleToQTtable->qtChannelId[index];
106 mModuleToQT[i][j] = qt;
109 mModuleToQTPos[i][j] = channel;
113 if(channel%8==1) mModuleToQTPos[i][j] = 1 + channel/8 * 2;
114 else mModuleToQTPos[i][j] = 2 + channel/8 * 2;
117 if(mModuleToQT[i][j]>0 && mModuleToQTPos[i][j]>0)
118 mQTtoModule[mModuleToQT[i][j]-1][mModuleToQTPos[i][j]-1] = j + 1;
123 memset(mQTSlewBinEdge,-1,
sizeof(mQTSlewBinEdge));
124 memset(mQTSlewCorr,-1,
sizeof(mQTSlewCorr));
125 LOG_INFO <<
"Retrieving mtdQTSlewingCorr table from database ..." << endm;
126 dataset = GetDataBase(
"Calibrations/mtd/mtdQTSlewingCorr");
127 St_mtdQTSlewingCorr *mtdQTSlewingCorr =
static_cast<St_mtdQTSlewingCorr*
>(dataset->
Find(
"mtdQTSlewingCorr"));
128 if(!mtdQTSlewingCorr)
130 LOG_ERROR <<
"No mtdQTSlewingCorr table found in database" << endm;
133 mtdQTSlewingCorr_st *mtdQTSlewingCorrtable =
static_cast<mtdQTSlewingCorr_st*
>(mtdQTSlewingCorr->GetTable());
134 for(
int j=0; j<4; j++)
136 for(
int i=0; i<16; i++)
138 for(Int_t k=0; k<8; k++)
140 Int_t index = j*16*8 + i*8 + k;
141 mQTSlewBinEdge[j][i][k] = (int) mtdQTSlewingCorrtable->slewingBinEdge[index];
142 mQTSlewCorr[j][i][k] = (
int) mtdQTSlewingCorrtable->slewingCorr[index];
154 mTpcSectorsForTracking = 0;
155 mFiredSectors.clear();
157 memset(mTrigQTpos,-1,
sizeof(mTrigQTpos));
160 SetAttr(
"TpcSectorsByMtd",mTpcSectorsForTracking);
169 mStEvent = (
StEvent*) GetInputDS(
"StEvent");
172 LOG_DEBUG <<
"Running on StEvent ..." << endm;
173 iret = processStEvent();
180 mMuDst = muDstMaker->
muDst();
181 iret = processMuDst();
185 LOG_ERROR <<
"No muDST is available ... "<< endm;
190 SetAttr(
"TpcSectorsByMtd",mTpcSectorsForTracking);
195 LOG_INFO <<
"Is di-muon event: " << mIsDiMuon << endm;
196 LOG_INFO <<
"Tracking mask by MTD: " << (bitset<24>)mTpcSectorsForTracking << endm;
203 Int_t StMtdTrackingMaskMaker::processStEvent()
205 mhEventStat->Fill(0.5);
208 for(
unsigned int j=0; j<mTriggerIDs.size(); j++)
210 if(mStEvent->triggerIdCollection()->nominal()->isTrigger(mTriggerIDs[j]))
216 if(!mIsDiMuon)
return kStOK;
217 mhEventStat->Fill(1.5);
228 LOG_WARN <<
"No mtd collection available in StEvent ... " << endm;
231 StSPtrVecMtdHit& mtdHits = mtdCollection->mtdHits();
232 int nMtdHits = mtdHits.size();
233 mhNMtdHits->Fill(nMtdHits);
234 int nTrigMtdHits = 0;
236 for(
int i=0; i<nMtdHits; i++)
245 int backleg = hit->backleg();
246 int module = hit->module();
247 int cell = hit->cell();
248 double hit_phi = getMtdHitGlobalPhi(backleg, module, cell);
251 determineTpcTrackingMask();
252 mhNTrigMtdHits->Fill(nTrigMtdHits);
258 Int_t StMtdTrackingMaskMaker::processMuDst()
260 mhEventStat->Fill(0.5);
263 for(
unsigned int j=0; j<mTriggerIDs.size(); j++)
265 if(mMuDst->
event()->triggerIdCollection().nominal().isTrigger(mTriggerIDs[j]))
271 if(!mIsDiMuon)
return kStOK;
272 mhEventStat->Fill(1.5);
280 int nMtdHits = mMuDst->numberOfMTDHit();
281 mhNMtdHits->Fill(nMtdHits);
282 int nTrigMtdHits = 0;
284 for(
int i=0; i<nMtdHits; i++)
293 int backleg = hit->backleg();
294 int module = hit->module();
295 int cell = hit->cell();
296 double hit_phi = getMtdHitGlobalPhi(backleg, module, cell);
299 determineTpcTrackingMask();
300 mhNTrigMtdHits->Fill(nTrigMtdHits);
313 unsigned short decision = mTrigData->dsmTF201Ch(0);
316 int mix_tacsum[4][2];
319 for(
int i = 0; i < 4; i++)
321 mix_tacsum[i][0] = (mTrigData->mtdDsmAtCh(3*i,0)) + ((mTrigData->mtdDsmAtCh(3*i+1,0)&0x3)<<8);
322 mix_id[i][0] = (mTrigData->mtdDsmAtCh(3*i+1,0)&0xc)>>2;
323 mix_tacsum[i][1] = (mTrigData->mtdDsmAtCh(3*i+1,0)>>4) + ((mTrigData->mtdDsmAtCh(3*i+2,0)&0x3f)<<4);
324 mix_id[i][1] = (mTrigData->mtdDsmAtCh(3*i+2,0)&0xc0)>>6;
326 for(
int j=0; j<2; j++)
328 if(mix_tacsum[i][j]>0) nMixSignal ++;
331 mhNMIXsignals->Fill(nMixSignal);
334 int mxq_tacsum[4][2];
335 int mxq_tacsum_pos[4][2];
336 for(
int i=0; i<4; i++)
338 for(
int j=0; j<2; j++)
340 mxq_tacsum[i][j] = 0;
341 mxq_tacsum_pos[i][j] = -1;
348 for(
int i=0; i<32; i++)
353 mtdQTtac[0][i-i/4*2-2] = mTrigData->mtdAtAddress(i,0);
354 mtdQTtac[1][i-i/4*2-2] = mTrigData->mtdgemAtAddress(i,0);
355 mtdQTtac[2][i-i/4*2-2] = mTrigData->mtd3AtAddress(i,0);
356 mtdQTtac[3][i-i/4*2-2] = mTrigData->mtd4AtAddress(i,0);
360 mtdQTadc[0][i-i/4*2] = mTrigData->mtdAtAddress(i,0);
361 mtdQTadc[1][i-i/4*2] = mTrigData->mtdgemAtAddress(i,0);
362 mtdQTadc[2][i-i/4*2] = mTrigData->mtd3AtAddress(i,0);
363 mtdQTadc[3][i-i/4*2] = mTrigData->mtd4AtAddress(i,0);
371 for(
int im=0; im<4; im++)
373 for(
int i=0; i<8; i++)
376 for(
int k=0; k<2; k++)
378 j[k] = mtdQTtac[im][i*2+k];
379 a[k] = mtdQTadc[im][i*2+k];
382 if(a[k]>=0 && a[k]<=mQTSlewBinEdge[im][i*2+k][0]) slew_bin = 0;
385 for(
int l=1; l<8; l++)
387 if(a[k]>mQTSlewBinEdge[im][i*2+k][l-1] && a[k]<=mQTSlewBinEdge[im][i*2+k][l])
395 j[k] += mQTSlewCorr[im][i*2+k][slew_bin];
398 if(j[0]<100 || j[1]<100)
continue;
399 if(abs(j[0]-j[1])>600)
continue;
403 int module = mQTtoModule[im][i];
404 int sumTac = int( j[0] + j[1] + abs(module-3)*1./8 * (j[0]-j[1]) );
406 if(mxq_tacsum[im][0] < sumTac)
408 mxq_tacsum[im][1] = mxq_tacsum[im][0];
409 mxq_tacsum[im][0] = sumTac;
411 mxq_tacsum_pos[im][1] = mxq_tacsum_pos[im][0];
412 mxq_tacsum_pos[im][0] = i+1;
414 else if (mxq_tacsum[im][1] < sumTac)
416 mxq_tacsum[im][1] = sumTac;
417 mxq_tacsum_pos[im][1] = i+1;
421 mhNQTsignals->Fill(nQtSignal);
424 for(
int i = 0; i < 4; i++)
426 for(
int j=0; j<2; j++)
428 if((decision>>(i*2+j+4))&0x1)
431 mTrigQTpos[i][j] = mxq_tacsum_pos[i][j];
435 mhNMuons->Fill(nMuon);
437 LOG_DEBUG <<
"# of muon candidates = " << nMuon << endm;
449 return isQTFiredTrigger( mModuleToQT[hit->backleg()-1][hit->module()-1], mModuleToQTPos[hit->backleg()-1][hit->module()-1]);
461 return isQTFiredTrigger( mModuleToQT[hit->backleg()-1][hit->module()-1], mModuleToQTPos[hit->backleg()-1][hit->module()-1]);
471 return (pos==mTrigQTpos[qt-1][0] || pos==mTrigQTpos[qt-1][1]);
475 void StMtdTrackingMaskMaker::determineTpcTrackingMask()
478 sort(mFiredSectors.begin(),mFiredSectors.end());
479 mFiredSectors.erase(unique(mFiredSectors.begin(),mFiredSectors.end()),mFiredSectors.end());
481 mhNTpcSectorForTracking->Fill(mFiredSectors.size());
484 for(
unsigned int i=0; i<mFiredSectors.size(); i++)
486 int bit = mFiredSectors[i] - 1;
487 mTpcSectorsForTracking |= (1U << bit);
489 LOG_DEBUG <<
"Output TPC mask = " << (bitset<24>) mTpcSectorsForTracking << endm;
502 IntVec westTpc, eastTpc;
509 for(
unsigned int i=0; i<eastTpc.size(); i++)
510 mFiredSectors.push_back(eastTpc[i]);
512 for(
unsigned int i=0; i<westTpc.size(); i++)
513 mFiredSectors.push_back(westTpc[i]);
527 double tpc_sector_width = pi/6.;
529 int tpc_sector_1 = 3 - int(floor(hit_phi/tpc_sector_width));
530 if(tpc_sector_1<1) tpc_sector_1 += 12;
532 int tpc_sector_2 = tpc_sector_1 - 1;
533 if(tpc_sector_2<1) tpc_sector_2 += 12;
535 sectors.push_back(tpc_sector_1);
536 sectors.push_back(tpc_sector_2);
538 LOG_DEBUG <<
"For hit at phi = " << hit_phi/pi*180 <<
", west TPC sectors are "
539 << tpc_sector_1 <<
" and " << tpc_sector_2 << endm;
554 double tpc_sector_width = pi/6.;
556 int tpc_sector_1 = int(floor(hit_phi/tpc_sector_width))+21;
557 if(tpc_sector_1>24) tpc_sector_1 -= 12;
559 int tpc_sector_2 = tpc_sector_1 + 1;
560 if(tpc_sector_2>24) tpc_sector_2 -= 12;
562 sectors.push_back(tpc_sector_1);
563 sectors.push_back(tpc_sector_2);
565 LOG_DEBUG <<
"For hit at phi = " << hit_phi/pi*180 <<
", east TPC sectors are "
566 << tpc_sector_1 <<
" and " << tpc_sector_2 << endm;
572 double StMtdTrackingMaskMaker::getMtdHitGlobalPhi(
const int backleg,
const int module,
const int cell)
578 double backlegPhiCen = gMtdFirstBacklegPhiCenter + (backleg-1) * (gMtdBacklegPhiWidth+gMtdBacklegPhiGap);
579 if(backlegPhiCen>2*pi) backlegPhiCen -= 2*pi;
580 double stripPhiCen = 0;
581 if(module>0 && module<4)
583 stripPhiCen = backlegPhiCen - (gMtdNChannels/4.-0.5-cell)*(gMtdCellWidth+gMtdCellGap)/gMtdMinRadius;
587 stripPhiCen = backlegPhiCen + (gMtdNChannels/4.-0.5-cell)*(gMtdCellWidth+gMtdCellGap)/gMtdMinRadius;
589 return rotatePhi(stripPhiCen);
593 double StMtdTrackingMaskMaker::rotatePhi(
const double phi)
596 while(outPhi<0) outPhi += 2*pi;
597 while(outPhi>2*pi) outPhi -= 2*pi;
603 void StMtdTrackingMaskMaker::bookHistos()
606 mhEventStat =
new TH1F(
"hEventStat",
"Event statistics",5,0,5);
607 mhEventStat->GetXaxis()->SetBinLabel(1,
"All events");
608 mhEventStat->GetXaxis()->SetBinLabel(2,
"Good trigger");
610 mhNQTsignals =
new TH1F(
"hNQTsignals",
"Number of QT signals per event;N",10,0,10);
612 mhNMIXsignals =
new TH1F(
"hNMIXsignals",
"Number of MT101 signals per event;N",10,0,10);
614 mhNMuons =
new TH1F(
"hNMuons",
"Number of TF201 signals per event;N",10,0,10);
616 mhNMtdHits =
new TH1F(
"hNMtdHits",
"Number of MTD hits per event;N",50,0,50);
618 mhNTrigMtdHits =
new TH1F(
"hNTrigMtdHits",
"Number of triggering MTD hits per event;N",10,0,10);
620 mhNTpcSectorForTracking =
new TH1F(
"hNTpcSectorForTracking",
"Number of TPC sectors for tracking per event;N",20,0,20);
624 AddHist(mhEventStat);
625 AddHist(mhNQTsignals);
626 AddHist(mhNMIXsignals);
629 AddHist(mhNTrigMtdHits);
630 AddHist(mhNTpcSectorForTracking);
IntVec findEastTpcSectors(const double hit_phi)
This class finds the MTD hits that actually fire the trigger, and mask the correponding TPC sectors f...
void findTpcSectorsForTracking(const double hit_phi, const int hit_module)
bool isMtdHitFiredTrigger(const StMtdHit *hit)
bool isQTFiredTrigger(const int qt, const int pos)
IntVec findWestTpcSectors(const double hit_phi)
static StMuEvent * event()
returns pointer to current StMuEvent (class holding the event wise information, e.g. event number, run number)
void processTriggerData()
void Clear(Option_t *option="")
User defined functions.
virtual TDataSet * Find(const char *path) const