00001 #include <iostream>
00002 #include <math.h>
00003 #include <vector>
00004 #include <stdlib.h>
00005 #include <iterator>
00006 #include <bitset>
00007
00008 #include "TH1F.h"
00009
00010 #include "PhysicalConstants.h"
00011 #include "StMessMgr.h"
00012
00013 #include "StEvent.h"
00014 #include "StTriggerData.h"
00015 #include "StTrack.h"
00016 #include "StMtdCollection.h"
00017 #include "StMtdHit.h"
00018
00019 #include "StMuDSTMaker/COMMON/StMuDstMaker.h"
00020 #include "StMuDSTMaker/COMMON/StMuDst.h"
00021 #include "StMuDSTMaker/COMMON/StMuEvent.h"
00022 #include "StMuDSTMaker/COMMON/StMuMtdHit.h"
00023
00024 #include "tables/St_mtdModuleToQTmap_Table.h"
00025 #include "tables/St_trgOfflineFilter_Table.h"
00026 #include "StMtdTrackingMaskMaker.h"
00027
00028 ClassImp(StMtdTrackingMaskMaker)
00029
00030
00031 StMtdTrackingMaskMaker::StMtdTrackingMaskMaker(const Char_t *name) : StMaker(name),
00032 mStEvent(NULL), mMuDst(NULL), mIsDiMuon(kFALSE), mTrigData(NULL),
00033 mTpcSectorsForTracking(0)
00034 {
00035
00036 }
00037
00038
00039 StMtdTrackingMaskMaker::~StMtdTrackingMaskMaker()
00040 {
00041
00042 }
00043
00044
00045 Int_t StMtdTrackingMaskMaker::Init()
00046 {
00047
00048 bookHistos();
00049
00050 return kStOK;
00051 }
00052
00053
00054 Int_t StMtdTrackingMaskMaker::InitRun(const Int_t runNumber)
00055 {
00056
00057 LOG_INFO << "Retrieving trigger ID from database ..." << endm;
00058 St_trgOfflineFilter* flaggedTrgs =
00059 (St_trgOfflineFilter *) GetDataBase("Calibrations/trg/trgOfflineFilter");
00060 if (!flaggedTrgs)
00061 {
00062 LOG_ERROR << "Could not find Calibrations/trg/trgOfflineFilter in database" << endm;
00063 return kStErr;
00064 }
00065
00066 trgOfflineFilter_st* flaggedTrg = flaggedTrgs->GetTable();
00067 for (long j = 0;j < flaggedTrgs->GetNRows(); j++, flaggedTrg++)
00068 {
00069 int trigid = flaggedTrg->trigid;
00070 if (0<trigid && trigid<1e9) mTriggerIDs.push_back(trigid);
00071 }
00072
00073
00074 memset(mModuleToQT,-1,sizeof(mModuleToQT));
00075 memset(mModuleToQTPos,-1,sizeof(mModuleToQTPos));
00076
00077
00078 LOG_INFO << "Retrieving mtdModuleToQTmap table from database ..." << endm;
00079 TDataSet *dataset = GetDataBase("Geometry/mtd/mtdModuleToQTmap");
00080 St_mtdModuleToQTmap *mtdModuleToQTmap = static_cast<St_mtdModuleToQTmap*>(dataset->Find("mtdModuleToQTmap"));
00081 if(!mtdModuleToQTmap)
00082 {
00083 LOG_ERROR << "No mtdModuleToQTmap table found in database" << endm;
00084 return kStErr;
00085 }
00086 mtdModuleToQTmap_st *mtdModuleToQTtable = static_cast<mtdModuleToQTmap_st*>(mtdModuleToQTmap->GetTable());
00087
00088 for(int i=0; i<gMtdNBacklegs; i++)
00089 {
00090 for(int j=0; j<gMtdNModules; j++)
00091 {
00092 int index = i*5 + j;
00093 int qt = mtdModuleToQTtable->qtBoardId[index];
00094 int channel = mtdModuleToQTtable->qtChannelId[index];
00095 mModuleToQT[i][j] = qt;
00096 if(channel<0)
00097 {
00098 mModuleToQTPos[i][j] = channel;
00099 }
00100 else
00101 {
00102 if(channel%8==1) mModuleToQTPos[i][j] = 1 + channel/8 * 2;
00103 else mModuleToQTPos[i][j] = 2 + channel/8 * 2;
00104 }
00105 }
00106 }
00107 return kStOK;
00108 }
00109
00110
00111 void StMtdTrackingMaskMaker::Clear(Option_t *option)
00112 {
00113
00114 mTpcSectorsForTracking = 0;
00115 mFiredSectors.clear();
00116
00117 memset(mTrigQTpos,-1, sizeof(mTrigQTpos));
00118 mIsDiMuon = kFALSE;
00119
00120 SetAttr("TpcSectorsByMtd",mTpcSectorsForTracking);
00121 }
00122
00123
00124 Int_t StMtdTrackingMaskMaker::Make()
00125 {
00126
00127
00128 Int_t iret = -1;
00129 mStEvent = (StEvent*) GetInputDS("StEvent");
00130 if(mStEvent)
00131 {
00132 LOG_DEBUG << "Running on StEvent ..." << endm;
00133 iret = processStEvent();
00134 }
00135 else
00136 {
00137 StMuDstMaker *muDstMaker = (StMuDstMaker*) GetMaker("MuDst");
00138 if(muDstMaker)
00139 {
00140 mMuDst = muDstMaker->muDst();
00141 iret = processMuDst();
00142 }
00143 else
00144 {
00145 LOG_ERROR << "No muDST is available ... "<< endm;
00146 iret = kStErr;
00147 }
00148 }
00149
00150 SetAttr("TpcSectorsByMtd",mTpcSectorsForTracking);
00151
00152
00153 if(mStEvent)
00154 {
00155 LOG_INFO << "Is di-muon event: " << mIsDiMuon << endm;
00156 LOG_INFO << "Tracking mask by MTD: " << (bitset<24>)mTpcSectorsForTracking << endm;
00157 }
00158
00159 return iret;
00160 }
00161
00162
00163 Int_t StMtdTrackingMaskMaker::processStEvent()
00164 {
00165 mhEventStat->Fill(0.5);
00166
00167
00168 for(unsigned int j=0; j<mTriggerIDs.size(); j++)
00169 {
00170 if(mStEvent->triggerIdCollection()->nominal()->isTrigger(mTriggerIDs[j]))
00171 {
00172 mIsDiMuon = kTRUE;
00173 break;
00174 }
00175 }
00176 if(!mIsDiMuon) return kStOK;
00177 mhEventStat->Fill(1.5);
00178
00179
00180 mTrigData = (StTriggerData*)mStEvent->triggerData();
00181 if(!mTrigData) return kStWarn;
00182 processTriggerData();
00183
00184
00185 StMtdCollection *mtdCollection = mStEvent->mtdCollection();
00186 if(!mtdCollection)
00187 {
00188 LOG_WARN << "No mtd collection available in StEvent ... " << endm;
00189 return kStWarn;
00190 }
00191 StSPtrVecMtdHit& mtdHits = mtdCollection->mtdHits();
00192 int nMtdHits = mtdHits.size();
00193 mhNMtdHits->Fill(nMtdHits);
00194 int nTrigMtdHits = 0;
00195
00196 for(int i=0; i<nMtdHits; i++)
00197 {
00198 StMtdHit *hit = mtdHits[i];
00199 if(!hit) continue;
00200 if(!isMtdHitFiredTrigger(hit)) continue;
00201 nTrigMtdHits++;
00202
00203
00204
00205 int backleg = hit->backleg();
00206 int module = hit->module();
00207 int cell = hit->cell();
00208 double hit_phi = getMtdHitGlobalPhi(backleg, module, cell);
00209 findTpcSectorsForTracking(hit_phi, module);
00210 }
00211 determineTpcTrackingMask();
00212 mhNTrigMtdHits->Fill(nTrigMtdHits);
00213 return kStOK;
00214 }
00215
00216
00217
00218 Int_t StMtdTrackingMaskMaker::processMuDst()
00219 {
00220 mhEventStat->Fill(0.5);
00221
00222
00223 for(unsigned int j=0; j<mTriggerIDs.size(); j++)
00224 {
00225 if(mMuDst->event()->triggerIdCollection().nominal().isTrigger(mTriggerIDs[j]))
00226 {
00227 mIsDiMuon = kTRUE;
00228 break;
00229 }
00230 }
00231 if(!mIsDiMuon) return kStOK;
00232 mhEventStat->Fill(1.5);
00233
00234
00235 mTrigData = const_cast<StTriggerData*>(mMuDst->event()->triggerData());
00236 if(!mTrigData) return kStWarn;
00237 processTriggerData();
00238
00239
00240 int nMtdHits = mMuDst->numberOfMTDHit();
00241 mhNMtdHits->Fill(nMtdHits);
00242 int nTrigMtdHits = 0;
00243
00244 for(int i=0; i<nMtdHits; i++)
00245 {
00246 StMuMtdHit *hit = mMuDst->mtdHit(i);
00247 if(!hit) continue;
00248 if(!isMtdHitFiredTrigger(hit)) continue;
00249 nTrigMtdHits++;
00250
00251
00252
00253 int backleg = hit->backleg();
00254 int module = hit->module();
00255 int cell = hit->cell();
00256 double hit_phi = getMtdHitGlobalPhi(backleg, module, cell);
00257 findTpcSectorsForTracking(hit_phi, module);
00258 }
00259 determineTpcTrackingMask();
00260 mhNTrigMtdHits->Fill(nTrigMtdHits);
00261 return kStOK;
00262 }
00263
00264
00265 void StMtdTrackingMaskMaker::processTriggerData()
00266 {
00271
00272
00273 unsigned short decision = mTrigData->dsmTF201Ch(0);
00274
00275
00276 int mix_tacsum[4][2];
00277 int mix_id[4][2];
00278 int nMixSignal = 0;
00279 for(int i = 0; i < 4; i++)
00280 {
00281 mix_tacsum[i][0] = (mTrigData->mtdDsmAtCh(3*i,0)) + ((mTrigData->mtdDsmAtCh(3*i+1,0)&0x3)<<8);
00282 mix_id[i][0] = (mTrigData->mtdDsmAtCh(3*i+1,0)&0xc)>>2;
00283 mix_tacsum[i][1] = (mTrigData->mtdDsmAtCh(3*i+1,0)>>4) + ((mTrigData->mtdDsmAtCh(3*i+2,0)&0x3f)<<4);
00284 mix_id[i][1] = (mTrigData->mtdDsmAtCh(3*i+2,0)&0xc0)>>6;
00285
00286 for(int j=0; j<2; j++)
00287 {
00288 if(mix_tacsum[i][j]>0) nMixSignal ++;
00289 }
00290 }
00291 mhNMIXsignals->Fill(nMixSignal);
00292
00293
00294 unsigned short mxq_tacsum[4][2];
00295 int mxq_tacsum_pos[4][2];
00296 for(int i=0; i<4; i++)
00297 {
00298 for(int j=0; j<2; j++)
00299 {
00300 mxq_tacsum[i][j] = 0;
00301 mxq_tacsum_pos[i][j] = -1;
00302 }
00303 }
00304
00305
00306 int mtdQTtac[4][16];
00307 for(int i=0; i<32; i++)
00308 {
00309 int type = (i/4)%2;
00310 if(type==1)
00311 {
00312 mtdQTtac[0][i-i/4*2-2] = mTrigData->mtdAtAddress(i,0);
00313 mtdQTtac[1][i-i/4*2-2] = mTrigData->mtdgemAtAddress(i,0);
00314 mtdQTtac[2][i-i/4*2-2] = mTrigData->mtd3AtAddress(i,0);
00315 mtdQTtac[3][i-i/4*2-2] = mTrigData->mtd4AtAddress(i,0);
00316 }
00317 }
00318
00319
00320
00321 int nQtSignal = 0;
00322 for(int im=0; im<4; im++)
00323 {
00324 for(int i=0; i<16; i++)
00325 {
00326 if(i%2==1) continue;
00327 int j2 = mtdQTtac[im][i];
00328 int j3 = mtdQTtac[im][i+1];
00329
00330 if(j2<100 || j3<100) continue;
00331 nQtSignal++;
00332
00333 int sumTac = j2+j3;
00334
00335 if(mxq_tacsum[im][0] < sumTac)
00336 {
00337 mxq_tacsum[im][1] = mxq_tacsum[im][0];
00338 mxq_tacsum[im][0] = sumTac;
00339
00340 mxq_tacsum_pos[im][1] = mxq_tacsum_pos[im][0];
00341 mxq_tacsum_pos[im][0] = i/2+1;
00342 }
00343 else if (mxq_tacsum[im][1] < sumTac)
00344 {
00345 mxq_tacsum[im][1] = sumTac;
00346 mxq_tacsum_pos[im][1] = i/2+1;
00347 }
00348 }
00349 }
00350 mhNQTsignals->Fill(nQtSignal);
00351
00352 int nMuon = 0;
00353 for(int i = 0; i < 4; i++)
00354 {
00355 for(int j=0; j<2; j++)
00356 {
00357 if((decision>>(i*2+j+4))&0x1)
00358 {
00359 nMuon ++;
00360 mTrigQTpos[i][j] = mxq_tacsum_pos[i][j];
00361 }
00362 }
00363 }
00364 mhNMuons->Fill(nMuon);
00365
00366 LOG_DEBUG << "# of muon candidates = " << nMuon << endm;
00367 }
00368
00369
00370 bool StMtdTrackingMaskMaker::isMtdHitFiredTrigger(const StMtdHit *hit)
00371 {
00377
00378 return isQTFiredTrigger( mModuleToQT[hit->backleg()-1][hit->module()-1], mModuleToQTPos[hit->backleg()-1][hit->module()-1]);
00379 }
00380
00381
00382 bool StMtdTrackingMaskMaker::isMtdHitFiredTrigger(const StMuMtdHit *hit)
00383 {
00389
00390 return isQTFiredTrigger( mModuleToQT[hit->backleg()-1][hit->module()-1], mModuleToQTPos[hit->backleg()-1][hit->module()-1]);
00391 }
00392
00393
00394 bool StMtdTrackingMaskMaker::isQTFiredTrigger(const int qt, const int pos)
00395 {
00399
00400 return (pos==mTrigQTpos[qt-1][0] || pos==mTrigQTpos[qt-1][1]);
00401 }
00402
00403
00404 void StMtdTrackingMaskMaker::determineTpcTrackingMask()
00405 {
00406
00407 sort(mFiredSectors.begin(),mFiredSectors.end());
00408 mFiredSectors.erase(unique(mFiredSectors.begin(),mFiredSectors.end()),mFiredSectors.end());
00409
00410 mhNTpcSectorForTracking->Fill(mFiredSectors.size());
00411
00412
00413 for(unsigned int i=0; i<mFiredSectors.size(); i++)
00414 {
00415 int bit = mFiredSectors[i] - 1;
00416 mTpcSectorsForTracking |= (1U << bit);
00417 }
00418 LOG_DEBUG << "Output TPC mask = " << (bitset<24>) mTpcSectorsForTracking << endm;
00419 }
00420
00421
00422 void StMtdTrackingMaskMaker::findTpcSectorsForTracking(const double hit_phi, const int hit_module)
00423 {
00430
00431 IntVec westTpc, eastTpc;
00432 westTpc.clear();
00433 eastTpc.clear();
00434
00435 if(hit_module<5) eastTpc = findEastTpcSectors(hit_phi);
00436 if(hit_module>1) westTpc = findWestTpcSectors(hit_phi);
00437
00438 for(unsigned int i=0; i<eastTpc.size(); i++)
00439 mFiredSectors.push_back(eastTpc[i]);
00440
00441 for(unsigned int i=0; i<westTpc.size(); i++)
00442 mFiredSectors.push_back(westTpc[i]);
00443 }
00444
00445
00446 vector<int> StMtdTrackingMaskMaker::findWestTpcSectors(const double hit_phi)
00447 {
00452
00453 IntVec sectors;
00454 sectors.clear();
00455
00456 double tpc_sector_width = pi/6.;
00457
00458 int tpc_sector_1 = 3 - int(floor(hit_phi/tpc_sector_width));
00459 if(tpc_sector_1<1) tpc_sector_1 += 12;
00460
00461 int tpc_sector_2 = tpc_sector_1 - 1;
00462 if(tpc_sector_2<1) tpc_sector_2 += 12;
00463
00464 sectors.push_back(tpc_sector_1);
00465 sectors.push_back(tpc_sector_2);
00466
00467 LOG_DEBUG << "For hit at phi = " << hit_phi/pi*180 << ", west TPC sectors are "
00468 << tpc_sector_1 << " and " << tpc_sector_2 << endm;
00469 return sectors;
00470 }
00471
00472
00473 vector<int> StMtdTrackingMaskMaker::findEastTpcSectors(const double hit_phi)
00474 {
00479
00480 IntVec sectors;
00481 sectors.clear();
00482
00483 double tpc_sector_width = pi/6.;
00484
00485 int tpc_sector_1 = int(floor(hit_phi/tpc_sector_width))+21;
00486 if(tpc_sector_1>24) tpc_sector_1 -= 12;
00487
00488 int tpc_sector_2 = tpc_sector_1 + 1;
00489 if(tpc_sector_2>24) tpc_sector_2 -= 12;
00490
00491 sectors.push_back(tpc_sector_1);
00492 sectors.push_back(tpc_sector_2);
00493
00494 LOG_DEBUG << "For hit at phi = " << hit_phi/pi*180 << ", east TPC sectors are "
00495 << tpc_sector_1 << " and " << tpc_sector_2 << endm;
00496
00497 return sectors;
00498 }
00499
00500
00501 double StMtdTrackingMaskMaker::getMtdHitGlobalPhi(const int backleg, const int module, const int cell)
00502 {
00506
00507 double backlegPhiCen = gMtdFirstBacklegPhiCenter + (backleg-1) * (gMtdBacklegPhiWidth+gMtdBacklegPhiGap);
00508 if(backlegPhiCen>2*pi) backlegPhiCen -= 2*pi;
00509 double stripPhiCen = 0;
00510 if(module>0 && module<4)
00511 {
00512 stripPhiCen = backlegPhiCen - (gMtdNChannels/4.-0.5-cell)*(gMtdCellWidth+gMtdCellGap)/gMtdMinRadius;
00513 }
00514 else
00515 {
00516 stripPhiCen = backlegPhiCen + (gMtdNChannels/4.-0.5-cell)*(gMtdCellWidth+gMtdCellGap)/gMtdMinRadius;
00517 }
00518 return rotatePhi(stripPhiCen);
00519 }
00520
00521
00522 double StMtdTrackingMaskMaker::rotatePhi(const double phi)
00523 {
00524 double outPhi = phi;
00525 while(outPhi<0) outPhi += 2*pi;
00526 while(outPhi>2*pi) outPhi -= 2*pi;
00527 return outPhi;
00528 }
00529
00530
00531
00532 void StMtdTrackingMaskMaker::bookHistos()
00533 {
00534
00535 mhEventStat = new TH1F("hEventStat","Event statistics",5,0,5);
00536 mhEventStat->GetXaxis()->SetBinLabel(1,"All events");
00537 mhEventStat->GetXaxis()->SetBinLabel(2,"Good trigger");
00538
00539 mhNQTsignals = new TH1F("hNQTsignals","Number of QT signals per event;N",10,0,10);
00540
00541 mhNMIXsignals = new TH1F("hNMIXsignals","Number of MT101 signals per event;N",10,0,10);
00542
00543 mhNMuons = new TH1F("hNMuons","Number of TF201 signals per event;N",10,0,10);
00544
00545 mhNMtdHits = new TH1F("hNMtdHits","Number of MTD hits per event;N",50,0,50);
00546
00547 mhNTrigMtdHits = new TH1F("hNTrigMtdHits","Number of triggering MTD hits per event;N",10,0,10);
00548
00549 mhNTpcSectorForTracking = new TH1F("hNTpcSectorForTracking","Number of TPC sectors for tracking per event;N",20,0,20);
00550
00551 if(mSaveHistos)
00552 {
00553 AddHist(mhEventStat);
00554 AddHist(mhNQTsignals);
00555 AddHist(mhNMIXsignals);
00556 AddHist(mhNMuons);
00557 AddHist(mhNMtdHits);
00558 AddHist(mhNTrigMtdHits);
00559 AddHist(mhNTpcSectorForTracking);
00560 }
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572