75 #include "StBTofCollection.h"
76 #include "StBTofHit.h"
77 #include "StBTofHeader.h"
78 #include "StEventTypes.h"
80 #include "StMessMgr.h"
81 #include "StThreeVectorD.hh"
82 #include "StEventUtilities/StuRefMult.hh"
83 #include "PhysicalConstants.h"
84 #include "phys_constants.h"
85 #include "tables/St_vpdTotCorr_Table.h"
87 #include "StBTofUtil/StBTofHitCollection.h"
88 #include "StMuDSTMaker/COMMON/StMuDstMaker.h"
89 #include "StMuDSTMaker/COMMON/StMuDst.h"
90 #include "StMuDSTMaker/COMMON/StMuBTofHit.h"
92 #include "StVpdCalibMaker.h"
94 #include "StMessMgr.h"
95 #include "StMemoryInfo.hh"
103 const Double_t StVpdCalibMaker::VHRBIN2PS = 24.4140625;
105 const Double_t StVpdCalibMaker::HRBIN2PS = 97.65625;
107 const Double_t StVpdCalibMaker::TMAX = 51200.;
109 const Double_t StVpdCalibMaker::VZDIFFCUT=6.;
111 const Double_t StVpdCalibMaker::TDIFFCUT=0.8;
113 const Double_t StVpdCalibMaker::FracTruncated=0.2;
124 mTruncation = kFALSE;
128 mValidCalibPar = kFALSE;
134 mInitFromFile = kFALSE;
136 setCalibFilePvpd(
"/star/institutions/rice/calib/default/pvpdCali_4DB.dat");
138 mUseVpdStart = kTRUE;
139 mForceTofStart = kFALSE;
141 mCutVpdOutliers = kTRUE;
149 void StVpdCalibMaker::resetPars()
151 memset(mVPDTotEdge, 0,
sizeof(mVPDTotEdge));
152 memset(mVPDTotCorr, 0,
sizeof(mVPDTotCorr));
156 void StVpdCalibMaker::resetVpd()
158 memset(mVPDLeTime, 0,
sizeof(mVPDLeTime));
159 memset(mVPDTot, 0,
sizeof(mVPDTot));
160 memset(mFlag, 0,
sizeof(mFlag));
161 mVPD_qaTruth = vector<Int_t>(2*NVPD,0);
163 for(
int i=0;i<MaxVpdVz;i++) {
164 mVPDVtxZ[i] = -9999.;
167 mVPDHitPatternEast = 0;
168 mVPDHitPatternWest = 0;
172 Int_t StVpdCalibMaker::Init()
177 if (IAttr(
"pppAMode")) {
178 mUseVpdStart = kFALSE;
179 mForceTofStart = kTRUE;
180 mCutVpdOutliers = kFALSE;
181 LOG_INFO <<
"pppAMode is on." << endm;
193 LOG_INFO <<
"Histograms are booked" << endm;
194 if (mHistoFileName!=
"") {
195 LOG_INFO <<
"Histograms will be stored in " << mHistoFileName.c_str() << endm;
200 return StMaker::Init();
204 Int_t StVpdCalibMaker::InitRun(Int_t runnumber)
209 val = initParameters(runnumber);
211 mValidCalibPar = kTRUE;
213 return StMaker::InitRun(runnumber);
215 mValidCalibPar = kFALSE;
216 LOG_WARN <<
" !!! No valid calibration parameters for VPD! " << endm;
223 Int_t StVpdCalibMaker::initParameters(Int_t runnumber)
228 LOG_INFO <<
"Initializing VPD calibration parameters from file"
229 <<
"(" << mCalibFilePvpd <<
")" << endm;
231 inData.open(mCalibFilePvpd.c_str());
233 for(
int i=0;i<NVPD*2;i++) {
237 LOG_ERROR <<
"number of bins (" << nbin <<
") out of range ("
238 << NBinMax <<
") for vpd channel " << i << endm;
241 for(
int j=0;j<=nbin;j++) inData>>mVPDTotEdge[i][j];
242 for(
int j=0;j<=nbin;j++) inData>>mVPDTotCorr[i][j];
248 LOG_INFO <<
"Initializing VPD calibration parameters from database" << endm;
251 TDataSet *dbDataSet = GetDataBase(
"Calibrations/tof/vpdTotCorr");
253 St_vpdTotCorr* vpdTotCorr =
static_cast<St_vpdTotCorr*
>(dbDataSet->
Find(
"vpdTotCorr"));
255 LOG_ERROR <<
"unable to get vpdTotCorr table parameters" << endm;
259 vpdTotCorr_st* totCorr =
static_cast<vpdTotCorr_st*
>(vpdTotCorr->GetArray());
260 Int_t numRows = vpdTotCorr->GetNRows();
262 if(numRows!=NVPD*2) {
263 LOG_WARN <<
" Mis-matched number of rows in vpdTotCorr table: " << numRows
264 <<
" (exp:" << NVPD*2 <<
")" << endm;
267 LOG_DEBUG <<
" Number of rows read in: " << numRows <<
" for Vpd ToT correction" << endm;
269 for (Int_t i=0;i<numRows;i++) {
270 if (!mForceTofStart){
272 short flag = totCorr[i].corralgo;
275 LOG_INFO <<
"Selected VPD for TOF start-timing (corralgo=0)" << endm;
279 LOG_INFO <<
"VPD NOT used for TOF start-timing (corralgo=1)" << endm;
282 LOG_WARN <<
"Unknown calibration option " << flag << endm;
286 if (totCorr[0].corralgo==0 && (totCorr[i].corralgo!=0))
287 {LOG_WARN <<
"corralgo dbase inconsistency: " << totCorr[i].corralgo << endm;}
288 if (totCorr[0].corralgo==1 && (totCorr[i].corralgo!=1))
289 {LOG_WARN <<
"corralgo dbase inconsistency: " << totCorr[i].corralgo << endm;}
293 short tubeId = totCorr[i].tubeId;
296 LOG_ERROR <<
"tubeId (" << tubeId <<
") out of range ("
297 << 2*NVPD <<
")" << endm;
301 for(Int_t j=0;j<NBinMax;j++) {
302 mVPDTotEdge[tubeId-1][j] = totCorr[i].tot[j];
303 mVPDTotCorr[tubeId-1][j] = totCorr[i].corr[j];
304 LOG_DEBUG <<
" east/west: " << (tubeId-1)/NVPD <<
" tubeId: " << tubeId << endm;
309 if (mForceTofStart) { LOG_INFO <<
"Detected user override in Start Timing selection ::setUseVpdStart()." << endm;}
311 LOG_INFO <<
"Selected VPD for TOF start-timing" << endm;
314 LOG_INFO <<
"VPD NOT used for TOF start-timing" << endm;
321 LOG_ERROR <<
"unable to get vpdTotCorr dataset ... reset all to zero values (NOT GOOD!) and disable use for TOF-start" << endm;
324 LOG_INFO <<
"VPD NOT used for TOF start-timing" << endm;
336 if (mHistoFileName!=
"") writeHistograms();
344 LOG_DEBUG <<
" StVpdCalibMaker::Make: starting ..." << endm;
345 if(mHisto&&mhEventCounter) mhEventCounter->Fill(0);
346 if(!mValidCalibPar) {
347 LOG_WARN <<
" No valid calibration parameters. Skip ... " << endm;
351 if(mHisto&&mhEventCounter) mhEventCounter->Fill(1);
353 bool loadOK = loadVpdData();
356 if(mHisto&&mhEventCounter) mhEventCounter->Fill(2);
358 tsum(mVPDTot, mVPDLeTime, mVPD_qaTruth);
361 if(mHisto) fillHistograms();
362 if(mHisto&&mhEventCounter) mhEventCounter->Fill(3);
363 bool writeOK = writeVpdData();
365 if(writeOK&&mHisto) mhEventCounter->Fill(4);
372 Bool_t StVpdCalibMaker::writeVpdData()
const
377 LOG_WARN <<
" No MuDst to write ... " << endm;
383 LOG_WARN <<
" No StEvent/btofCollection to write ... " << endm;
389 if(!tofHeader)
return kFALSE;
391 for(
int i=0;i<NVPD;i++) {
392 tofHeader->setVpdTime(west, i+1, mVPDLeTime[i]);
393 tofHeader->setVpdTime(east, i+1, mVPDLeTime[i+NVPD]);
395 tofHeader->setVpdHitPattern(east, mVPDHitPatternEast);
396 tofHeader->setVpdHitPattern(west, mVPDHitPatternWest);
397 for(
int i=0;i<mNVzVpd;i++) {
398 tofHeader->setVpdVz(mVPDVtxZ[i],i);
401 LOG_INFO <<
"BTofHeader: NWest = " << tofHeader->numberOfVpdHits(west)
402 <<
" NEast = " << tofHeader->numberOfVpdHits(east) << endm;
403 if(tofHeader->numberOfVpdHits(west)!=mNWest ||
404 tofHeader->numberOfVpdHits(east)!=mNEast) {
405 LOG_WARN <<
"BTofHeader inconsistency: Local nWest = " << mNWest <<
" nEast = " << mNEast << endm;
407 LOG_INFO <<
"summary: VPD-VtxZ = " << mVPDVtxZ[0]
408 <<
"; TSum West = " << mTSumWest <<
" East = " << mTSumEast << endm;
415 Bool_t StVpdCalibMaker::loadVpdData()
420 LOG_WARN <<
"No MuDstMaker ... bye-bye" << endm;
423 mMuDst = mMuDstMaker->
muDst();
425 LOG_WARN <<
"No MuDst ... bye-bye" << endm;
437 Int_t nhits = mMuDst->numberOfBTofHit();
439 for(
int i=0;i<nhits;i++) {
442 int trayId = aHit->tray();
443 if(trayId==WestVpdTrayId || trayId==EastVpdTrayId) {
444 int tubeId = aHit->cell();
445 int indx = (trayId-NTray-1)*NVPD+(tubeId-1);
447 LOG_ERROR <<
"vpd index (" << indx <<
") out of range ("
448 << 2*NVPD <<
") for trayId-tubeId " << trayId
449 <<
"-" << tubeId << endm;
452 mVPDLeTime[indx] = aHit->leadingEdgeTime();
453 mVPDTot[indx] = aHit->tot();
454 mVPD_qaTruth[indx] = aHit->qaTruth();
465 LOG_WARN <<
"No StEvent present" << endl;
468 if (!thisEvent->btofCollection() ) {
469 LOG_WARN <<
"No BTOFCollection present" << endm;
472 if (!thisEvent->btofCollection()->hitsPresent() ) {
473 LOG_WARN <<
"No hits present" << endm;
483 mBTofColl = thisEvent->btofCollection();
484 StSPtrVecBTofHit &tofHits = mBTofColl->tofHits();
485 Int_t nhits = tofHits.size();
486 LOG_INFO <<
"Total number of TOF cells + VPD tubes : " << nhits << endm;
488 for(
int i=0;i<nhits;i++) {
491 int trayId = aHit->tray();
492 if(trayId==WestVpdTrayId || trayId==EastVpdTrayId) {
493 int tubeId = aHit->cell();
494 int indx = (trayId-NTray-1)*NVPD+(tubeId-1);
496 LOG_ERROR <<
"vpd index (" << indx <<
") out of range ("
497 << 2*NVPD <<
") for trayId-tubeId " << trayId
498 <<
"-" << tubeId << endm;
501 mVPDLeTime[indx] = aHit->leadingEdgeTime();
502 mVPDTot[indx] = aHit->tot();
503 mVPD_qaTruth[indx] = aHit->qaTruth();
513 void StVpdCalibMaker::tsum(
const Double_t *tot,
const Double_t *time, std::vector<Int_t> qaTruth)
520 mVPDHitPatternWest = 0;
521 mVPDHitPatternEast = 0;
524 for(
int i=0;i<2*NVPD;i++) {
525 if (i>=NVPD) vpdEast=
true;
528 if ( qaTruth[i] > 0 && time[i] != 0.) {
529 LOG_DEBUG <<
"Simulation" << endm;
533 mVPDLeTime[i] = time[i];
534 mTSumEast += mVPDLeTime[i];
535 mVPDHitPatternEast |= 1<<(i-NVPD);
540 mVPDLeTime[i] = time[i];
541 mTSumWest += mVPDLeTime[i];
542 mVPDHitPatternWest |= 1<<i;
548 else if( time[i]>0. && tot[i]>0. ) {
551 for(
int j=0;j<NBinMax-1;j++) {
552 if(tot[i]>=mVPDTotEdge[i][j] && tot[i]<mVPDTotEdge[i][j+1]) {
557 if(ibin>=0&&ibin<NBinMax) {
558 Double_t x1 = mVPDTotEdge[i][ibin];
559 Double_t x2 = mVPDTotEdge[i][ibin+1];
560 Double_t y1 = mVPDTotCorr[i][ibin];
561 Double_t y2 = mVPDTotCorr[i][ibin+1];
562 Double_t dcorr = y1 + (tot[i]-x1)*(y2-y1)/(x2-x1);
566 mVPDLeTime[i] = time[i] - dcorr;
567 mTSumEast += mVPDLeTime[i];
568 mVPDHitPatternEast |= 1<<(i-NVPD);
573 mVPDLeTime[i] = time[i] - dcorr;
574 mTSumWest += mVPDLeTime[i];
575 mVPDHitPatternWest |= 1<<i;
581 LOG_WARN <<
" Vpd East tube " << i+1-NVPD <<
" TOT ("<< ibin
582 <<
") out of range (0-"<<NBinMax<<
") !" << endm;
585 LOG_WARN <<
" Vpd West tube " << i+1 <<
" TOT ("<< ibin
586 <<
") out of range (0-"<<NBinMax<<
") !" << endm;
592 else LOG_DEBUG <<
"No hit." << endm;
599 void StVpdCalibMaker::vzVpdFinder()
601 for(
int i=0;i<2*NVPD;i++){
603 if (mVPD_qaTruth[i] > 0 && mVPDLeTime[i]!=0 && mFlag[i]) {
604 mTruncation = kFALSE;
606 else if(mVPDLeTime[i]<1.e-4 || !mFlag[i])
continue;
609 if(i<NVPD&&mNWest>1) {
610 vpdtime = (mVPDLeTime[i]*mNWest-mTSumWest)/(mNWest-1);
611 if(fabs(vpdtime)>TDIFFCUT && mCutVpdOutliers) {
612 mTSumWest -= mVPDLeTime[i];
615 mVPDHitPatternWest &= ( 0x7ffff - (1<<i) );
619 if(i>=NVPD&&mNEast>1) {
620 vpdtime = (mVPDLeTime[i]*mNEast-mTSumEast)/(mNEast-1);
621 if(fabs(vpdtime)>TDIFFCUT && mCutVpdOutliers) {
622 mTSumEast -= mVPDLeTime[i];
625 mVPDHitPatternEast &= ( 0x7ffff - (1<<(i-NVPD)) );
632 if(mTruncation && mCutVpdOutliers) {
633 LOG_DEBUG <<
"Uh-oh, stepped into the truncation block!" << endm;
634 Int_t hitIndex[2*NVPD];
636 TMath::Sort(nTube, &mVPDLeTime[0], &hitIndex[0]);
637 int nRejectedWest = (int)(FracTruncated*mNWest+0.5);
638 LOG_DEBUG <<
" NWest before = " << mNWest <<
" rejected = " << nRejectedWest << endm;
639 for(
int i=0;i<nRejectedWest;i++) {
640 int index = hitIndex[i];
641 mTSumWest -= mVPDLeTime[index];
642 mVPDLeTime[index] = 0.;
644 mVPDHitPatternWest &= ( 0x7ffff - (1<<index) );
648 TMath::Sort(nTube, &mVPDLeTime[NVPD], &hitIndex[NVPD]);
649 int nRejectedEast = (int)(FracTruncated*mNEast+0.5);
650 LOG_DEBUG <<
" NEast before = " << mNEast <<
" rejected = " << nRejectedEast << endm;
651 for(
int i=0;i<nRejectedEast;i++) {
652 int index = hitIndex[i+NVPD] + NVPD;
653 mTSumEast -= mVPDLeTime[index];
654 mVPDLeTime[index] = 0.;
656 mVPDHitPatternEast &= ( 0x7ffff - (1<<(index-NVPD)) );
662 if ( mNEast>=mVPDEastHitsCut && mNWest>=mVPDWestHitsCut ) {
663 mVPDVtxZ[0] = (mTSumEast/mNEast - mTSumWest/mNWest)/2.*(C_C_LIGHT/1.e9);
664 LOG_DEBUG <<
"Vertex is at: " << mVPDVtxZ[0] << endm;
671 void StVpdCalibMaker::bookHistograms()
673 mhEventCounter =
new TH1D(
"eventCounter",
"eventCounter",20,0,20);
674 mhNVpdHits =
new TH2D(
"vpdHits",
" west vs east ",20,0.,20.,20,0.,20.);
675 mmVpdVertexHist =
new TH1D(
"mVpdVertexHist",
"Calculated Vpd Vertices; Position (cm); Counts", 300, -50, 50);
676 for(
int i=0;i<2*NVPD;i++) {
681 buf.Form(
"res_W_%d",i+1);
684 buf.Form(
"res_E_%d",i-NVPD+1);
686 mhVpd[i] =
new TH1D(buf, buf, 3000, -3., 3.);
688 mhVpdAll =
new TH1D(
"res_All",
"res_All", 3000, -3., 3.);
692 void StVpdCalibMaker::fillHistograms()
695 if (mhNVpdHits) mhNVpdHits->Fill(mNEast, mNWest);
696 if (mmVpdVertexHist) mmVpdVertexHist->Fill(mVPDVtxZ[0]);
698 for(
int i=0;i<NVPD;i++) {
699 if(mVPDLeTime[i]>0.) {
700 Double_t tdiff = (mNWest*mVPDLeTime[i] - mTSumWest)/(mNWest - 1);
701 if (mhVpd[i]) mhVpd[i]->Fill(tdiff);
702 if (mhVpdAll) mhVpdAll->Fill(tdiff);
707 for(
int j=0;j<NVPD;j++) {
709 if(mVPDLeTime[i]>0.) {
710 Double_t tdiff = (mNEast*mVPDLeTime[i] - mTSumEast)/(mNEast - 1);
711 if (mhVpd[i]) mhVpd[i]->Fill(tdiff);
712 if (mhVpdAll) mhVpdAll->Fill(tdiff);
720 void StVpdCalibMaker::writeHistograms()
const
723 TFile *theHistoFile =
new TFile(mHistoFileName.c_str(),
"RECREATE");
724 LOG_INFO <<
"StVpdCalibMaker::writeHistograms()"
725 <<
" histogram file " << mHistoFileName << endm;
727 if (theHistoFile&&theHistoFile->IsOpen()){
731 mhEventCounter->Write();
734 mmVpdVertexHist->Write();
735 for(
int i=0;i<2*NVPD;i++) {
740 theHistoFile->Close();
744 LOG_ERROR <<
"unable to open histogram file" << endm;
static StMuBTofHit * btofHit(int i)
returns pointer to the i-th muBTofHit
void setVPDHitsCut(const Int_t eastVpdCut, const Int_t westVpdCut)
set the VPD # of hits cut
void setCreateHistoFlag(const Bool_t histos=kTRUE)
enable QA histogram filling
virtual ~StVpdCalibMaker()
Destructor.
void setHistoFileName(const Char_t *filename)
set histogram output file name
StVpdCalibMaker(const Char_t *name="vpdCalib")
Default constructor.
static StBTofHeader * btofHeader()
returns pointer to the btofHeader - dongx
virtual TDataSet * Find(const char *path) const