StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StVpdCalibMaker.cxx
1 /*******************************************************************
2  *
3  * $Id: StVpdCalibMaker.cxx,v 1.16 2021/05/29 23:57:19 geurts Exp $
4  *
5  * Author: Xin Dong
6  *****************************************************************
7  *
8  * Description: - VPD Calibration Maker to do the calibration for upVPD
9  * - store into StBTofHeader
10  *
11  *****************************************************************
12  *
13  * $Log: StVpdCalibMaker.cxx,v $
14  * Revision 1.16 2021/05/29 23:57:19 geurts
15  * Updates to improve pp and pA handling - by Bassam Aboona (TAMU)
16  *
17  * Revision 1.15 2020/07/03 21:54:50 geurts
18  * Removed an old typo in the log messages regarding the corralgo version that the VPD will be using.
19  *
20  * Revision 1.14 2018/04/30 23:18:00 smirnovd
21  * Reduce excessive output
22  *
23  * Revision 1.13 2017/03/02 18:26:50 jeromel
24  * Updates to StVpdCalibMaker after review - changes by jdb, nl
25  *
26  *
27  * Revision 1.13 2016/11/14 luttrell
28  * Simulated vpd hits no longer undergo electronics corrections
29  *
30  * Revision 1.12 2012/12/14 06:36:05 geurts
31  * Changed global database calls to direct table access and/or removed deprecated database access code.
32  *
33  * Revision 1.11 2011/02/23 20:00:52 geurts
34  * Change MaxBin for ToT arrays from 60 to 128 (in agreement with the IDL definition of vpdTotCorr)
35  * Move the log message that informs the user about the start-timing mode outside the tube loop ... no need to see the same message 38 times.
36  *
37  * Revision 1.10 2011/01/07 21:28:51 geurts
38  * Allow user to "force" VPD-start or startless mode, regardless of dbase setting
39  *
40  * Revision 1.9 2010/12/18 01:10:27 geurts
41  * bugfix: apply VPD outlier correction in StEvent mode, too.
42  *
43  * Revision 1.8 2010/12/10 21:38:06 geurts
44  * RT#1996: default initialization of database table in case dataset is not found
45  *
46  * Revision 1.7 2010/10/31 05:43:57 geurts
47  * apply outlier truncation to all energies, keep at 20% (previously only enabled for low beam energies)
48  *
49  * Revision 1.6 2010/05/25 22:09:48 geurts
50  * improved database handling and reduced log output
51  *
52  * Revision 1.5 2010/05/12 22:46:51 geurts
53  * Startless BTOF self-calibration method (Xin)
54  *
55  * Revision 1.4 2010/05/06 22:37:41 geurts
56  * Remove slower hits (outliers) in VPD timing calculations (Xin Dong)
57  *
58  * Revision 1.3 2010/01/29 19:51:08 geurts
59  * Fixed a bug in vzVpdFinder outlier bookkeeping (Xin Dong)
60  *
61  * Revision 1.2 2009/12/04 22:22:17 geurts
62  * two updates (Xin):
63  * - use the new calibration table vpdTotCorr
64  * - update on the vzVpdFinder(), a cut on timing diff is used to remove outliers.
65  *
66  * Revision 1.1 2009/11/09 20:55:54 geurts
67  * first release
68  *
69  *
70  *******************************************************************/
71 #include <iostream>
72 #include "TFile.h"
73 
74 #include "StEvent.h"
75 #include "StBTofCollection.h"
76 #include "StBTofHit.h"
77 #include "StBTofHeader.h"
78 #include "StEventTypes.h"
79 #include "Stypes.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"
86 
87 #include "StBTofUtil/StBTofHitCollection.h"
88 #include "StMuDSTMaker/COMMON/StMuDstMaker.h"
89 #include "StMuDSTMaker/COMMON/StMuDst.h"
90 #include "StMuDSTMaker/COMMON/StMuBTofHit.h"
91 
92 #include "StVpdCalibMaker.h"
93 
94 #include "StMessMgr.h"
95 #include "StMemoryInfo.hh"
96 #include "StTimer.hh"
97 
98 #ifdef __ROOT__
99 ClassImp(StVpdCalibMaker)
100 #endif
101 
103  const Double_t StVpdCalibMaker::VHRBIN2PS = 24.4140625; // 1000*25/1024 (ps/chn)
105  const Double_t StVpdCalibMaker::HRBIN2PS = 97.65625; // 97.65625= 1000*100/1024 (ps/chn)
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;
114 
115 //_____________________________________________________________________________
116 StVpdCalibMaker::StVpdCalibMaker(const Char_t *name) : StMaker(name)
117 {
121  setVPDHitsCut(1,1);
122 
123  //mEvent = 0;
124  mTruncation = kFALSE;
125  mMuDst = 0;
126  mMuDstIn = kFALSE;
127  mBTofColl = 0;
128  mValidCalibPar = kFALSE;
129 
130  setCreateHistoFlag(kFALSE);
131  setHistoFileName("vpdana.root");
132 
133  // default initialization from database
134  mInitFromFile = kFALSE;
135  // assign default locations and names to the calibration files
136  setCalibFilePvpd("/star/institutions/rice/calib/default/pvpdCali_4DB.dat");
137  // use vpd as start by default;
138  mUseVpdStart = kTRUE;
139  mForceTofStart = kFALSE; // flag indicates user-override for TOF Start time calculation
140 
141  mCutVpdOutliers = kTRUE;
142 }
143 
144 //_____________________________________________________________________________
146 { /* noop */ }
147 
148 //_____________________________________________________________________________
149 void StVpdCalibMaker::resetPars()
150 {
151  memset(mVPDTotEdge, 0, sizeof(mVPDTotEdge));
152  memset(mVPDTotCorr, 0, sizeof(mVPDTotCorr));
153 }
154 
155 //_____________________________________________________________________________
156 void StVpdCalibMaker::resetVpd()
157 {
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);
162 
163  for(int i=0;i<MaxVpdVz;i++) {
164  mVPDVtxZ[i] = -9999.;
165  }
166  mNVzVpd = 0;
167  mVPDHitPatternEast = 0;
168  mVPDHitPatternWest = 0;
169 }
170 
171 //____________________________________________________________________________
172 Int_t StVpdCalibMaker::Init()
173 {
174  resetPars();
175  resetVpd();
176 
177  if (IAttr("pppAMode")) {
178  mUseVpdStart = kFALSE;
179  mForceTofStart = kTRUE;
180  mCutVpdOutliers = kFALSE;
181  LOG_INFO << "pppAMode is on." << endm;
182  }
183 
184  // m_Mode can be set by SetMode() method
185 // if(m_Mode) {
186 // // setHistoFileName("vpdana.root");
187 // } else {
188 // setHistoFileName("");
189 // }
190 
191  if (mHisto){
192  bookHistograms();
193  LOG_INFO << "Histograms are booked" << endm;
194  if (mHistoFileName!="") {
195  LOG_INFO << "Histograms will be stored in " << mHistoFileName.c_str() << endm;
196  }
197  }
198 
199  //return kStOK;
200  return StMaker::Init();
201 }
202 
203 //____________________________________________________________________________
204 Int_t StVpdCalibMaker::InitRun(Int_t runnumber)
205 {
206  // tof run configurations
207 
208  Int_t val = kStOK;
209  val = initParameters(runnumber);
210  if(val==kStOK) {
211  mValidCalibPar = kTRUE;
212  //return kStOK;
213  return StMaker::InitRun(runnumber);
214  } else {
215  mValidCalibPar = kFALSE;
216  LOG_WARN << " !!! No valid calibration parameters for VPD! " << endm;
217  return kStWarn;
218  }
219 
220 }
221 
222 //_____________________________________________________________________________
223 Int_t StVpdCalibMaker::initParameters(Int_t runnumber)
224 {
227  if (mInitFromFile){
228  LOG_INFO << "Initializing VPD calibration parameters from file"
229  << "(" << mCalibFilePvpd << ")" << endm;
230  ifstream inData;
231  inData.open(mCalibFilePvpd.c_str());
232  int nchl, nbin;
233  for(int i=0;i<NVPD*2;i++) {
234  inData>>nchl;
235  inData>>nbin;
236  if (nbin>NBinMax) {
237  LOG_ERROR << "number of bins (" << nbin << ") out of range ("
238  << NBinMax << ") for vpd channel " << i << endm;
239  return kStErr;
240  }
241  for(int j=0;j<=nbin;j++) inData>>mVPDTotEdge[i][j];
242  for(int j=0;j<=nbin;j++) inData>>mVPDTotCorr[i][j];
243  }
244  inData.close();
245  }
246  else {
248  LOG_INFO << "Initializing VPD calibration parameters from database" << endm;
249 
250  // read vpdTotCorr table
251  TDataSet *dbDataSet = GetDataBase("Calibrations/tof/vpdTotCorr");
252  if (dbDataSet){
253  St_vpdTotCorr* vpdTotCorr = static_cast<St_vpdTotCorr*>(dbDataSet->Find("vpdTotCorr"));
254  if(!vpdTotCorr) {
255  LOG_ERROR << "unable to get vpdTotCorr table parameters" << endm;
256  // assert(vpdTotCorr);
257  return kStErr;
258  }
259  vpdTotCorr_st* totCorr = static_cast<vpdTotCorr_st*>(vpdTotCorr->GetArray());
260  Int_t numRows = vpdTotCorr->GetNRows();
261 
262  if(numRows!=NVPD*2) {
263  LOG_WARN << " Mis-matched number of rows in vpdTotCorr table: " << numRows
264  << " (exp:" << NVPD*2 << ")" << endm;
265  }
266 
267  LOG_DEBUG << " Number of rows read in: " << numRows << " for Vpd ToT correction" << endm;
268 
269  for (Int_t i=0;i<numRows;i++) {
270  if (!mForceTofStart){
271  if(i==0) { // identify once only, for the first tube
272  short flag = totCorr[i].corralgo;
273  if(flag==0) {
274  mUseVpdStart=kTRUE;
275  LOG_INFO << "Selected VPD for TOF start-timing (corralgo=0)" << endm;
276  }
277  else if(flag==1) {
278  mUseVpdStart=kFALSE;
279  LOG_INFO << "VPD NOT used for TOF start-timing (corralgo=1)" << endm;
280  }
281  else {
282  LOG_WARN << "Unknown calibration option " << flag << endm;
283  }
284  }
285  else { // verify that all other entries agree
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;}
290  }
291  }
292 
293  short tubeId = totCorr[i].tubeId;
294  // check index range
295  if (tubeId>2*NVPD) {
296  LOG_ERROR << "tubeId (" << tubeId << ") out of range ("
297  << 2*NVPD << ")" << endm;
298  return kStErr;
299  }
300 
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;
305  } // end j 0->NBinMax
306  } // end i 0->numRows
307 
308  // Let the user know what is used for calculating TOF Start (and how we got there)
309  if (mForceTofStart) { LOG_INFO << "Detected user override in Start Timing selection ::setUseVpdStart()." << endm;}
310  if (mUseVpdStart) {
311  LOG_INFO << "Selected VPD for TOF start-timing" << endm;
312  }
313  else {
314  LOG_INFO << "VPD NOT used for TOF start-timing" << endm;
315  }
316  }
317  else {
318  // Note: this construction addresses RT#1996 and allows backward compatibility with older database
319  // timestamps at which these database structures did not exist. All values will be zero (hence the ERROR)
320  // and the VPD will be disabled for TOF start timing, i.e. the TOF could still operate in start-less mode
321  LOG_ERROR << "unable to get vpdTotCorr dataset ... reset all to zero values (NOT GOOD!) and disable use for TOF-start" << endm;
322  resetPars();
323  mUseVpdStart=kFALSE;
324  LOG_INFO << "VPD NOT used for TOF start-timing" << endm;
325  return kStErr;
326  }
327  }
328 
329  return kStOK;
330 }
331 
332 
333 //_____________________________________________________________________________
335 {
336  if (mHistoFileName!="") writeHistograms();
337  return StMaker::Finish();//kStOK;
338 }
339 
340 
341 //_____________________________________________________________________________
343 {
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;
348  return kStWarn;
349  }
350 
351  if(mHisto&&mhEventCounter) mhEventCounter->Fill(1);
352  resetVpd();
353  bool loadOK = loadVpdData();
354 
355  if(!loadOK) return kStWarn;
356  if(mHisto&&mhEventCounter) mhEventCounter->Fill(2);
357 
358  tsum(mVPDTot, mVPDLeTime, mVPD_qaTruth);
359  vzVpdFinder();
360 
361  if(mHisto) fillHistograms();
362  if(mHisto&&mhEventCounter) mhEventCounter->Fill(3);
363  bool writeOK = writeVpdData();
364  if (!writeOK) return kStWarn;
365  if(writeOK&&mHisto) mhEventCounter->Fill(4);
366 
367  return StMaker::Make(); //kStOK;
368 }
369 
370 
371 //_____________________________________________________________________________
372 Bool_t StVpdCalibMaker::writeVpdData() const
373 {
374  StBTofHeader *tofHeader = 0;
375  if(mMuDstIn) {
376  if(!mMuDst) {
377  LOG_WARN << " No MuDst to write ... " << endm;
378  return kFALSE;
379  }
380  tofHeader = (StBTofHeader *) mMuDst->btofHeader();
381  } else {
382  if(!mBTofColl) {
383  LOG_WARN << " No StEvent/btofCollection to write ... " << endm;
384  return kFALSE;
385  }
386  tofHeader = (StBTofHeader *) mBTofColl->tofHeader();
387  }
388 
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]);
394  }
395  tofHeader->setVpdHitPattern(east, mVPDHitPatternEast);
396  tofHeader->setVpdHitPattern(west, mVPDHitPatternWest);
397  for(int i=0;i<mNVzVpd;i++) {
398  tofHeader->setVpdVz(mVPDVtxZ[i],i);
399  }
400 
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;
406  }
407  LOG_INFO <<"summary: VPD-VtxZ = " << mVPDVtxZ[0]
408  << "; TSum West = " << mTSumWest << " East = " << mTSumEast << endm;
409 
410  return kTRUE;
411 }
412 
413 
414 //____________________________________________________________________________
415 Bool_t StVpdCalibMaker::loadVpdData()
416 {
417  if(mMuDstIn) {
418  StMuDstMaker *mMuDstMaker = (StMuDstMaker *)GetMaker("MuDst");
419  if(!mMuDstMaker) {
420  LOG_WARN << "No MuDstMaker ... bye-bye" << endm;
421  return kFALSE;
422  }
423  mMuDst = mMuDstMaker->muDst();
424  if(!mMuDst) {
425  LOG_WARN << "No MuDst ... bye-bye" << endm;
426  return kFALSE;
427  }
428 
429  // Apply truncation to all energies and collision systems
430 // if(mMuDst->event() && mMuDst->event()->runInfo().centerOfMassEnergy()<40.) {
431  mTruncation = kTRUE;
432 // } else {
433 // mTruncation = kFALSE;
434 // }
435 
436 
437  Int_t nhits = mMuDst->numberOfBTofHit();
438 // Int_t nhits = mMuDst->btofArray(muBTofHit)->GetEntries();
439  for(int i=0;i<nhits;i++) {
440  StMuBTofHit *aHit = (StMuBTofHit *)mMuDst->btofHit(i);
441  if(!aHit) continue;
442  int trayId = aHit->tray();
443  if(trayId==WestVpdTrayId || trayId==EastVpdTrayId) { // VPD this time
444  int tubeId = aHit->cell();
445  int indx = (trayId-NTray-1)*NVPD+(tubeId-1);
446  if (indx>=2*NVPD){
447  LOG_ERROR << "vpd index (" << indx << ") out of range ("
448  << 2*NVPD << ") for trayId-tubeId " << trayId
449  << "-" << tubeId << endm;
450  return kStErr;
451  }
452  mVPDLeTime[indx] = aHit->leadingEdgeTime();
453  mVPDTot[indx] = aHit->tot();
454  mVPD_qaTruth[indx] = aHit->qaTruth();
455  }
456  }
457 
458  }
459 
460  else {
461  StEvent *thisEvent = (StEvent *) GetInputDS("StEvent");
462 
463  // event selection // no primary vertex required
464  if( !thisEvent ) {
465  LOG_WARN << "No StEvent present" << endl;
466  return kFALSE;
467  }
468  if (!thisEvent->btofCollection() ) {
469  LOG_WARN << "No BTOFCollection present" << endm;
470  return kFALSE;
471  }
472  if (!thisEvent->btofCollection()->hitsPresent() ) {
473  LOG_WARN << "No hits present" << endm;
474  return kFALSE;
475  }
476 
477 // if(thisEvent->runInfo() && thisEvent->runInfo()->centerOfMassEnergy()<40.) { // 40 GeV or less
478  mTruncation = kTRUE;
479 // } else {
480 // mTruncation = kFALSE;
481 // }
482 
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;
487 
488  for(int i=0;i<nhits;i++) {
489  StBTofHit *aHit = dynamic_cast<StBTofHit*>(tofHits[i]);
490  if(!aHit) continue;
491  int trayId = aHit->tray();
492  if(trayId==WestVpdTrayId || trayId==EastVpdTrayId) { // VPD this time
493  int tubeId = aHit->cell();
494  int indx = (trayId-NTray-1)*NVPD+(tubeId-1);
495  if (indx>=2*NVPD){
496  LOG_ERROR << "vpd index (" << indx << ") out of range ("
497  << 2*NVPD << ") for trayId-tubeId " << trayId
498  << "-" << tubeId << endm;
499  return kStErr;
500  }
501  mVPDLeTime[indx] = aHit->leadingEdgeTime();
502  mVPDTot[indx] = aHit->tot();
503  mVPD_qaTruth[indx] = aHit->qaTruth();
504  }
505  } // end loop hits
506  }
507 
508  return kTRUE;
509 }
510 
511 
512 //_____________________________________________________________________________
513 void StVpdCalibMaker::tsum(const Double_t *tot, const Double_t *time, std::vector<Int_t> qaTruth)
514 {
516  mTSumEast = 0.;
517  mTSumWest = 0.;
518  mNEast = 0;
519  mNWest = 0;
520  mVPDHitPatternWest = 0;
521  mVPDHitPatternEast = 0;
522 
523  bool vpdEast=false;
524  for(int i=0;i<2*NVPD;i++) {
525  if (i>=NVPD) vpdEast=true;
526 
527  //**************BEGIN SIMULATION CODE BLOCK***************
528  if ( qaTruth[i] > 0 && time[i] != 0.) {
529  LOG_DEBUG << "Simulation" << endm;
530 
531  if (vpdEast){
532  mNEast++;
533  mVPDLeTime[i] = time[i];
534  mTSumEast += mVPDLeTime[i];
535  mVPDHitPatternEast |= 1<<(i-NVPD);
536  mFlag[i] = 1;
537  }
538  else {
539  mNWest++;
540  mVPDLeTime[i] = time[i];
541  mTSumWest += mVPDLeTime[i];
542  mVPDHitPatternWest |= 1<<i;
543  mFlag[i] = 1;
544  }
545  }
546  //**************END SIMULATION CODE BLOCK*****************
547 
548  else if( time[i]>0. && tot[i]>0. ) {
549 
550  int ibin = -1;
551  for(int j=0;j<NBinMax-1;j++) {
552  if(tot[i]>=mVPDTotEdge[i][j] && tot[i]<mVPDTotEdge[i][j+1]) {
553  ibin = j;
554  break;
555  }
556  }
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);
563 
564  if (vpdEast){
565  mNEast++;
566  mVPDLeTime[i] = time[i] - dcorr;
567  mTSumEast += mVPDLeTime[i];
568  mVPDHitPatternEast |= 1<<(i-NVPD);
569  mFlag[i] = 1;
570  }
571  else {
572  mNWest++;
573  mVPDLeTime[i] = time[i] - dcorr;
574  mTSumWest += mVPDLeTime[i];
575  mVPDHitPatternWest |= 1<<i;
576  mFlag[i] = 1;
577  }
578  }
579  else {
580  if (vpdEast){
581  LOG_WARN << " Vpd East tube " << i+1-NVPD << " TOT ("<< ibin
582  << ") out of range (0-"<<NBinMax<<") !" << endm;
583  }
584  else{
585  LOG_WARN << " Vpd West tube " << i+1 << " TOT ("<< ibin
586  << ") out of range (0-"<<NBinMax<<") !" << endm;
587  }
588  mVPDLeTime[i] = 0.; // out of range, remove this hit
589  }
590  }
591 
592  else LOG_DEBUG << "No hit." << endm;
593  }
594 
595 }
596 
597 //_____________________________________________________________________________
599 void StVpdCalibMaker::vzVpdFinder()
600 {
601  for(int i=0;i<2*NVPD;i++){
602  // check
603  if (mVPD_qaTruth[i] > 0 && mVPDLeTime[i]!=0 && mFlag[i]) { // Check for simulation
604  mTruncation = kFALSE;
605  }
606  else if(mVPDLeTime[i]<1.e-4 || !mFlag[i]) continue;
607 
608  double vpdtime;
609  if(i<NVPD&&mNWest>1) { // west VPD
610  vpdtime = (mVPDLeTime[i]*mNWest-mTSumWest)/(mNWest-1); // Cuts on times with a significant deviation from the average.
611  if(fabs(vpdtime)>TDIFFCUT && mCutVpdOutliers) {
612  mTSumWest -= mVPDLeTime[i];
613  mVPDLeTime[i] = 0.;
614  mNWest--;
615  mVPDHitPatternWest &= ( 0x7ffff - (1<<i) );
616  mFlag[i] = 0;
617  }
618  }
619  if(i>=NVPD&&mNEast>1) { // east VPD
620  vpdtime = (mVPDLeTime[i]*mNEast-mTSumEast)/(mNEast-1); // Cuts on times with a significant deviation from the average.
621  if(fabs(vpdtime)>TDIFFCUT && mCutVpdOutliers) {
622  mTSumEast -= mVPDLeTime[i];
623  mVPDLeTime[i] = 0.;
624  mNEast--;
625  mVPDHitPatternEast &= ( 0x7ffff - (1<<(i-NVPD)) );
626  mFlag[i] = 0;
627  }
628  }
629  }
630 
631  // remove slower hit in low energy runs.
632  if(mTruncation && mCutVpdOutliers) {
633  LOG_DEBUG << "Uh-oh, stepped into the truncation block!" << endm;
634  Int_t hitIndex[2*NVPD];
635  Int_t nTube = 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.;
643  mNWest--;
644  mVPDHitPatternWest &= ( 0x7ffff - (1<<index) );
645  mFlag[index] = 0;
646  }
647 
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.;
655  mNEast--;
656  mVPDHitPatternEast &= ( 0x7ffff - (1<<(index-NVPD)) );
657  mFlag[index] = 0;
658  }
659  }
660 
661  // calculate the vertex z from vpd
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;
665  mNVzVpd++;
666  }
667 }
668 
669 
670 //_____________________________________________________________________________
671 void StVpdCalibMaker::bookHistograms()
672 {
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++) {
677  //char buf[100];
678  TString buf;
679  if(i<NVPD) {
680  //sprintf(buf,"res_W_%d",i+1);
681  buf.Form("res_W_%d",i+1);
682  } else {
683  //sprintf(buf,"res_E_%d",i-mNVPD+1);
684  buf.Form("res_E_%d",i-NVPD+1);
685  }
686  mhVpd[i] = new TH1D(buf, buf, 3000, -3., 3.);
687  }
688  mhVpdAll = new TH1D("res_All","res_All", 3000, -3., 3.);
689 }
690 
691 //_____________________________________________________________________________
692 void StVpdCalibMaker::fillHistograms()
693 {
694  if(!mHisto) return;
695  if (mhNVpdHits) mhNVpdHits->Fill(mNEast, mNWest);
696  if (mmVpdVertexHist) mmVpdVertexHist->Fill(mVPDVtxZ[0]);
697  if(mNWest>=2) {
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);
703  }
704  }
705  }
706  if(mNEast>=2) {
707  for(int j=0;j<NVPD;j++) {
708  int i = j + NVPD;
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);
713  }
714  }
715  }
716 }
717 
718 
719 //_____________________________________________________________________________
720 void StVpdCalibMaker::writeHistograms() const
721 {
722  // Output file
723  TFile *theHistoFile = new TFile(mHistoFileName.c_str(), "RECREATE");
724  LOG_INFO << "StVpdCalibMaker::writeHistograms()"
725  << " histogram file " << mHistoFileName << endm;
726 
727  if (theHistoFile&&theHistoFile->IsOpen()){
728  theHistoFile->cd();
729 
730  if(mHisto) {
731  mhEventCounter->Write();
732  mhNVpdHits->Write();
733  mhVpdAll->Write();
734  mmVpdVertexHist->Write();
735  for(int i=0;i<2*NVPD;i++) {
736  mhVpd[i]->Write();
737  }
738  }
739 
740  theHistoFile->Close();
741  delete theHistoFile;
742  }
743  else
744  LOG_ERROR << "unable to open histogram file" << endm;
745 
746  return;
747 }
static StMuBTofHit * btofHit(int i)
returns pointer to the i-th muBTofHit
Definition: StMuDst.h:419
void setVPDHitsCut(const Int_t eastVpdCut, const Int_t westVpdCut)
set the VPD # of hits cut
StMuDst * muDst()
Definition: StMuDstMaker.h:425
void setCreateHistoFlag(const Bool_t histos=kTRUE)
enable QA histogram filling
virtual Int_t Make()
Definition: StMaker.cxx:898
virtual ~StVpdCalibMaker()
Destructor.
void setHistoFileName(const Char_t *filename)
set histogram output file name
virtual Int_t Make()
Definition: Stypes.h:42
Definition: Stypes.h:40
StVpdCalibMaker(const Char_t *name="vpdCalib")
Default constructor.
static StBTofHeader * btofHeader()
returns pointer to the btofHeader - dongx
Definition: StMuDst.h:423
virtual Int_t Finish()
Definition: StMaker.cxx:776
Definition: Stypes.h:44
virtual TDataSet * Find(const char *path) const
Definition: TDataSet.cxx:362
virtual Int_t Finish()