StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StFgtPedStatQA.cxx
1 /***************************************************************************
2  *
3  * $Id: StFgtPedStatQA.cxx,v 1.4 2014/07/25 18:46:00 xuanli Exp $
4  * Author: S. Gliske, Jan 2012
5  *
6  ***************************************************************************
7  *
8  * Description: See header
9  *
10  ***************************************************************************
11  *
12  * $Log: StFgtPedStatQA.cxx,v $
13  * Revision 1.4 2014/07/25 18:46:00 xuanli
14  * c++ 11 test
15  *
16  * Revision 1.3 2012/01/31 16:48:34 wwitzke
17  * Changed for cosmic test stand.
18  *
19  * Revision 1.2 2012/01/31 09:31:37 sgliske
20  * includes updated for things moved to StFgtPooll
21  *
22  * Revision 1.1 2012/01/31 09:26:16 sgliske
23  * StFgtQaMakers moved to StFgtPool
24  *
25  * Revision 1.14 2012/01/28 20:10:12 avossen
26  * addec cluster uncertainty
27  *
28  * Revision 1.13 2012/01/28 13:06:31 sgliske
29  * fixed some indexing issues in StFgtStatusMaker and StFgtPedStatQA
30  *
31  * Revision 1.12 2012/01/26 13:04:28 sgliske
32  * Updated to use StFgtConsts and
33  * bug fix in apv numbering
34  *
35  * Revision 1.11 2012/01/26 11:39:39 sgliske
36  * bin indexing matches new convention
37  *
38  * Revision 1.10 2012/01/24 09:23:56 sgliske
39  * bug fix, again
40  *
41  * Revision 1.9 2012/01/24 08:42:22 sgliske
42  * bug fix
43  *
44  * Revision 1.8 2012/01/24 08:22:43 sgliske
45  * Fixed title of 1D histos
46  *
47  * Revision 1.6 2012/01/24 08:11:12 sgliske
48  * Bug fixes
49  *
50  * Revision 1.5 2012/01/18 19:00:52 sgliske
51  * minor bug fix
52  *
53  * Revision 1.4 2012/01/18 18:53:01 sgliske
54  * minor bug fix
55  *
56  * Revision 1.3 2012/01/18 18:20:26 sgliske
57  * directly use elec coord domian as fundamental domain
58  *
59  * Revision 1.2 2012/01/17 22:25:07 sgliske
60  * removed hack for DB and
61  * fixed bug in writing status to txt file
62  *
63  * Revision 1.1 2012/01/17 20:10:02 sgliske
64  * creation
65  *
66  *
67  *
68  **************************************************************************/
69 
70 #include <string>
71 #include "StFgtPedStatQA.h"
72 #include "StRoot/StFgtUtil/geometry/StFgtGeom.h"
73 #include "StRoot/StFgtPool/StFgtCosmicTestStandGeom/StFgtCosmicTestStandGeom.h"
74 #include "StRoot/StFgtPool/StFgtPedMaker/StFgtPedMaker.h"
75 #include "StRoot/StFgtPool/StFgtPedMaker/StFgtPedMaker.h"
76 #include "StRoot/StFgtPool/StFgtStatusMaker/StFgtStatusMaker.h"
77 #include "StRoot/StFgtPool/StFgtStatusMaker/StFgtStatusMaker.h"
78 #include "StRoot/StFgtDbMaker/StFgtDb.h"
79 #include "StRoot/StFgtDbMaker/StFgtDbMaker.h"
80 #include "StRoot/StFgtUtil/StFgtConsts.h"
81 
82 #include <TCanvas.h>
83 #include <TLine.h>
84 #include <TPave.h>
85 #include <TPaveText.h>
86 #include <TPaveStats.h>
87 #include <TROOT.h>
88 #include <TStyle.h>
89 #include <TH1.h>
90 #include <TH2.h>
91 #include <TFile.h>
92 
93 
94 // constructor
95 StFgtPedStatQA::StFgtPedStatQA( const Char_t* name,
96  const Char_t* pedMkrName,
97  const Char_t* statMkrName ) :
98  StMaker( name ), mPedMkrName( pedMkrName ), mPedMkr(0), mStatMkrName( statMkrName ), mStatMkr(0), mTimeBin(2),
99  maxAdcPed( 27.5 ), maxAdcRMS( 47.5 ), maxAdcFrac( 47.5 ) {
100 
101  mFilenameArr[0] = &mFilenameTxt;
102  mFilenameArr[1] = &mFilenameRoot;
103  mFilenameArr[2] = &mFilenamePdf;
104 };
105 
106 // deconstructor
107 StFgtPedStatQA::~StFgtPedStatQA(){
108  // nothing
109 };
110 
111 // initialize
112 Int_t StFgtPedStatQA::Init(){
113  Int_t ierr = kStOk;
114 
115  // make sure the file can be opened
116 
117  for( Int_t i=0; i<3 && !ierr; ++i ){
118  if( !mFilenameArr[i]->empty() ){
119  std::ofstream fout( mFilenameArr[i]->data() );
120  if( !fout ){
121  LOG_FATAL << "Error opening file '" << mFilenameArr[i] << "'" << endm;
122  ierr = kStFatal;
123  };
124  };
125  };
126 
127  // make sure there's a pedmaker
128  mPedMkr = static_cast< StFgtPedMaker* >( GetMaker( mPedMkrName.data() ) );
129  if( !mPedMkr ){
130  LOG_FATAL << "Cannot find StFgtPedMaker" << endm;
131  ierr = kStFatal;
132  };
133 
134  // make sure it will compute the peds for this timebine
135  if( !ierr ){
136  if( !mPedMkr->mTimeBinMask & (1<<mTimeBin) ){
137  LOG_WARN << "StFgtPedMaker is not set to compute the time bin needed for StFgtPedStatQA" << endm;
138  mPedMkr->mTimeBinMask |= (1<<mTimeBin);
139  LOG_WARN << "StFgtPedMaker::mTimeBinMask set to 0x" << std::hex << mPedMkr->mTimeBinMask << std::dec << endm;
140  };
141  };
142 
143  // make sure there's a status maker
144  mStatMkr = static_cast< StFgtStatusMaker* >( GetMaker( mStatMkrName.data() ) );
145  if( !mStatMkr ){
146  LOG_FATAL << "Cannot find StFgtStatusMaker" << endm;
147  ierr = kStFatal;
148  };
149 
150  return ierr;
151 };
152 
153 // here is the real computation of the maker
155  Int_t ierr = kStOk;
156 
157  if( !mStatMkr->mHasFinished )
158  ierr = mStatMkr->Finish();
159 
160  cout << "StFgtPedStatQA::Finish()" << endl;
161 
162  // need to program this better in the future, so these values can
163  // be changed by users at runtime
164  enum { kNumApv = kFgtApvsPerQuad*kFgtNumDiscs*kFgtNumQuads,
165  kNumUsedApv = kNumApv, kMaxADC = 1500, kMaxRMS = 205, kBins = 100, kMaxAliveYaxis = 132 };
166 
167  Bool_t doMakeHists = !mFilenamePdf.empty() || !mFilenameRoot.empty();
168  Bool_t doMakeTxt = !mFilenameTxt.empty();
169 
170  std::ofstream *foutPtr;
171 
172  if( doMakeTxt ){
173  foutPtr = new std::ofstream( mFilenameTxt.data(), std::ios_base::out & std::ios_base::trunc );
174  if( !(*foutPtr) ){
175  LOG_FATAL << "Error opening file '" << mFilenameTxt.data() << "'" << endm;
176  ierr = kStFatal;
177  };
178  };
179 
180 
181  TFile *tfilePtr = 0;
182 
183  TH1F *hPed[kNumApv], *hRMS[kNumApv], *hFrac[kNumApv];
184  TH2F *hPed2D = 0;
185  TH2F *hRMS2D = 0;
186  TH2F *hFrac2D = 0;
187  TH1F *hAlive = 0;
188 
189  Int_t canWidth = 850, canHeight = 1100;
190  std::stringstream ss;
191 
192  if( !ierr && doMakeHists ){
193  gROOT->SetStyle( "Plain" );
194  gStyle->SetPalette(1);
195  gStyle->SetOptStat(111110);
196  gStyle->SetPaperSize(TStyle::kUSLetter);
197 
198  if( !mFilenameRoot.empty() )
199  tfilePtr = new TFile ( mFilenameRoot.data(), "RECREATE", "FGT Ped QA" );
200 
201  for( Int_t i=0; i<kNumApv; ++i ){
202  ss.str("");
203  ss.clear();
204  ss << i;
205 
206  hPed[i] = new TH1F( (std::string("hPed_") + ss.str() ).data(), "", kBins/3, 0, kMaxADC );
207  hRMS[i] = new TH1F( (std::string("hRMS_") + ss.str() ).data(), "", kBins/3, 0, kMaxRMS );
208  hFrac[i] = new TH1F( (std::string("hFrac_") + ss.str() ).data(), "", kBins/3, 0, 1 );
209  };
210 
211  hPed2D = new TH2F( "hPed2D", "", kNumUsedApv, 0, kNumUsedApv, kBins, 0, kMaxADC );
212  hRMS2D = new TH2F( "hRMS2D", "", kNumUsedApv, 0, kNumUsedApv, kBins, 0, kMaxRMS );
213  hFrac2D = new TH2F( "hFrac2D", "", kNumUsedApv, 0, kNumUsedApv, kBins, 0, 1 );
214  hAlive = new TH1F( "hAlive", "", kNumUsedApv, 0, kNumUsedApv );
215  };
216 
217  StFgtPedMaker::pedDataVec_t& pedVec = mPedMkr->mDataVec;
218  StFgtPedMaker::pedDataVec_t::iterator pedVecIter;
219 
220  StFgtDb *fgtTables = 0;
221  if( !mPedMkr->mDbMkrName.empty() ){
222  if( !mPedMkr->mFgtDbMkr ){
223  LOG_FATAL << "Pointer to Fgt DB Maker is null" << endm;
224  ierr = kStFatal;
225  };
226  if( !ierr ){
227  fgtTables = mPedMkr->mFgtDbMkr->getDbTables();
228 
229  if( !fgtTables ){
230  LOG_FATAL << "Pointer to Fgt DB Tables is null" << endm;
231  ierr = kStFatal;
232  };
233  };
234  };
235 
236  Int_t numnonzero = 0;
237  if( !ierr ){
238  Int_t pedIdx = 0;
239  for( pedVecIter = pedVec.begin(); pedVecIter != pedVec.end() && !ierr; ++pedVecIter, ++pedIdx ){
240  if( pedVecIter->n ){
241  ++numnonzero;
242 
243  Int_t timebin = pedIdx % kFgtNumTimeBins;
244 
245  Int_t elecId = pedIdx / kFgtNumTimeBins;
246  UChar_t status = mStatMkr->mStatus[ elecId ];
247 
248  UChar_t invalidID = (1<<mStatMkr->INVALID_ID);
249  if( status != invalidID ){
250  Int_t rdo, arm, apv, channel;
251  StFgtGeom::getElecCoordFromElectId( elecId, rdo, arm, apv, channel );
252  assert( apv < 22 );
253  assert( rdo < 3 );
254  assert( arm < 6 );
255 
256  // DEBUG
257  if( fgtTables ){
258  Int_t rdo2, arm2, apv2, channel2;
259 
260  Int_t geoId = fgtTables->getGeoIdFromElecCoord( rdo, arm, apv, channel );
261 
262  fgtTables->getElecCoordFromGeoId(geoId, rdo2, arm2, apv2, channel2 );
263  Int_t elecId2 = StFgtGeom::getElectIdFromElecCoord( rdo2, arm2, apv2, channel2 );
264 
265  if( elecId2 != elecId && geoId > -1 ){
266  cout << "ERROR: " << elecId << " -> " << rdo << ' ' << arm << ' ' << apv << ' ' << channel;
267  cout << " -> " << geoId << " -> " << rdo2 << ' ' << arm2 << ' ' << apv2 << ' ' << channel2;
268  cout << " -> " << elecId2 << endl;
269  };
270  };
271 
272  Int_t geoId = 0;
273  if( fgtTables ){
274  geoId = fgtTables->getGeoIdFromElecCoord( rdo, arm, apv, channel );
275  } else {
276  ierr = kStFatal;
277  LOG_ERROR << "Error: not supported for use without the DB" << endm;
278  };
279  Short_t disc, quad, strip;
280  Char_t layer;
281  StFgtGeom::decodeGeoId( geoId, disc, quad, layer, strip );
282 
283  // bin index
284 // if( apv > 9 )
285 // apv -= 2;
286 // Int_t histIdx = apv+20*(rdo-1+2*arm); // on a scale of 0-239
287  Int_t histIdx = (apv%12) + 10*( quad + 4*disc );
288 
289  if( doMakeTxt ){
290  (*foutPtr) << elecId << ' ' << rdo << ' ' << arm << ' ' << apv << ' ' << channel << " | ";
291  (*foutPtr) << geoId << ' ' << disc << ' ' << quad << ' ' << layer << ' ' << strip << " | ";
292  (*foutPtr) << timebin << ' ' << pedVecIter ->ped << ' ' << pedVecIter->RMS << ' ' << pedVecIter->fracClose << " | ";
293  (*foutPtr) << "0x" << std::hex << (UInt_t)(status) << std::dec << " | " << histIdx << endl;
294  };
295 
296  if( timebin == mTimeBin && doMakeHists ){
297  hPed[histIdx]->Fill( pedVecIter->ped );
298  hRMS[histIdx]->Fill( pedVecIter->RMS );
299  hFrac[histIdx]->Fill( pedVecIter->fracClose );
300 
301  hPed2D->Fill( histIdx, pedVecIter->ped );
302  hRMS2D->Fill( histIdx, pedVecIter->RMS );
303  hFrac2D->Fill( histIdx, pedVecIter->fracClose );
304 
305  if( hAlive->GetBinContent( histIdx+1 ) < 1 ){
306  StFgtStatusMaker::apvData_t &data = mStatMkr->mApvData[ elecId / kFgtNumChannels ];
307  hAlive->SetBinContent( histIdx+1, kFgtNumChannels-data.numDead );
308  if( ( apv >= kFgtApvsPerAssembly ? apv-kFgtApvGap : apv ) % kFgtApvsPerOct == kFgtApvsPerOct/2 ){
309  ss.str("");
310  ss.clear();
311  ss << disc+1 << (Char_t)(quad+'A') << StFgtGeom::getOctant( apv );
312 
313  hAlive->GetXaxis()->SetBinLabel( histIdx+1, ss.str().data() );
314  hPed2D->GetXaxis()->SetBinLabel( histIdx+1, ss.str().data() );
315  hRMS2D->GetXaxis()->SetBinLabel( histIdx+1, ss.str().data() );
316  hFrac2D->GetXaxis()->SetBinLabel( histIdx+1, ss.str().data() );
317  };
318  };
319  };
320  };
321  };
322  };
323  };
324 
325  LOG_INFO << "---> PedVec has " << numnonzero << " of " << pedVec.size() << " nonzero entries" << endm;
326 
327  if( doMakeTxt ){
328  delete foutPtr;
329  foutPtr = 0;
330  };
331 
332  if( !ierr && doMakeHists ){
333  for( Int_t histIdx = 0; histIdx < kNumApv; ++histIdx ){
334  Bool_t used = 1;
335 
336  // histIdx = (apv%12) + 10*( quad + 4*disc );
337 
338  Int_t i = histIdx;
339  Int_t apvMod = i % 12;
340  i /= 10;
341  Int_t quad = i % 4;
342  i /= 4;
343  Int_t disc = i;
344 
345  Bool_t octIsShort = ( StFgtGeom::getOctant( apvMod ) == 'S' );
346  Int_t geoId = StFgtGeom::encodeGeoId( disc, quad, 'P', octIsShort*700 );
347  if( geoId > -1 ){
348  assert( fgtTables );
349  Int_t rdo, arm, apv, channel;
350 
351  // note: the rdo/arm will be correct, but not the apv or channel
352  fgtTables->getElecCoordFromGeoId( geoId, rdo, arm, apv, channel );
353 
354  ss.str("");
355  ss.clear();
356  ss << "Rdo. " << rdo << ", Arm " << arm << ", APV%12 " << apvMod << ", Octant ";
357  ss << disc+1 << (Char_t)(quad+'A') << (octIsShort ? 'S' : 'L');
358  } else {
359  used = 0;
360  };
361 
362  if( used ){
363  hPed[histIdx]->SetTitle( ( ss.str() + "; Ped Value [ADC]; Counts" ).data() );
364  hRMS[histIdx]->SetTitle( ( ss.str() + "; Ped St. Dev. [ADC]; Counts" ).data() );
365  hFrac[histIdx]->SetTitle( ( ss.str() + "; Frac. of Integral Near Ped.; Counts" ).data() );
366  } else {
367  hPed[histIdx]->SetTitle( "" );
368  hRMS[histIdx]->SetTitle( "" );
369  hFrac[histIdx]->SetTitle( "" );
370  };
371  };
372  hPed2D->SetTitle("Pedestals per APV; ; ADC");
373  hRMS2D->SetTitle("Pedestal RMS per APV; ; ADC");
374  hFrac2D->SetTitle("Fraction of Integral Near Pedestal per APV; ; Fraction");
375  hAlive->SetTitle("Number Good Strips per APV; ; Number");
376 
377  if( !mFilenameRoot.empty() ){
378  hPed2D->Write();
379  hRMS2D->Write();
380  hFrac2D->Write();
381  hAlive->Write();
382  for( Int_t i=0; i<kNumApv; ++i ){
383  if( !std::string(hPed[i]->GetTitle()).empty() ){
384  hPed[i]->Write();
385  hRMS[i]->Write();
386  hFrac[i]->Write();
387  };
388  };
389  };
390 
391  hAlive->SetFillColor(kYellow-9);
392  hAlive->SetLineColor(kBlue);
393 
394  if( !mFilenamePdf.empty() ){
395  // draw
396  TCanvas *can1 = new TCanvas( "fgtCan1", "fgt Ped QA", canWidth, canHeight );
397  TCanvas *can2 = new TCanvas( "fgtCan2", "fgt Ped QA", canWidth, canHeight );
398 
399  hPed2D->SetMaximum( maxAdcPed );
400  hRMS2D->SetMaximum( maxAdcRMS );
401  hFrac2D->SetMaximum( maxAdcFrac );
402  hAlive->SetMaximum( kMaxAliveYaxis );
403 
404  can1->Divide( 1, 4 );
405 
406  TH1 *h2D[] = { hAlive, hPed2D, hRMS2D, hFrac2D };
407  Float_t highCut[]={ kFgtNumChannels, mStatMkr->mMaxPed, mStatMkr->mMaxRMS, mStatMkr->mMaxFrac };
408  Float_t fMaxDead = kFgtNumChannels-mStatMkr->mMaxDead;
409  Float_t lowCut[] ={ fMaxDead, mStatMkr->mMinPed, mStatMkr->mMinRMS, mStatMkr->mMinFrac };
410 
411  for( Int_t i=0; i<4; ++i ){
412  can1->cd(i+1);
413  gPad->SetLeftMargin( 0.06 );
414  gPad->SetRightMargin( 0.05 );
415  gPad->SetBottomMargin( 0.11 );
416  gPad->SetGridx(1);
417  gPad->SetGridy(0);
418 
419  h2D[i]->SetStats(0);
420  //h2D[i]->LabelsOption( "a", "X" ); // order bins by label
421  h2D[i]->Draw( i ? "COLZ" : "" );
422  h2D[i]->GetXaxis()->SetTitleOffset(0.9);
423  h2D[i]->GetXaxis()->SetTitleSize(0.06);
424  h2D[i]->GetXaxis()->SetLabelSize(0.06);
425  h2D[i]->GetYaxis()->SetTitleOffset(1.2);
426  h2D[i]->GetYaxis()->SetTitleSize(0.06);
427  h2D[i]->GetYaxis()->SetLabelSize(0.06);
428 
429  TLine *lineA = new TLine ( 0, highCut[i], kNumUsedApv, highCut[i] );
430  lineA->SetLineColor(kRed);
431  lineA->Draw();
432 
433  TLine *lineB = new TLine ( 0, lowCut[i], kNumUsedApv, lowCut[i] );
434  lineB->SetLineColor(kRed);
435  lineB->Draw();
436 
437  gPad->Update();
438  gPad->Modified();
439 
440  TPaveText *title = (TPaveText*)(gPad->GetPrimitive("title"));
441  if( title ){
442  title->SetX1NDC( 0.045 );
443  title->SetX2NDC( 0.55 );
444  title->SetY1NDC( 0.91 ) ;
445  title->SetY2NDC( 0.999 );
446  title->SetBorderSize(0);
447  title->SetTextAlign( 12 );
448  title->SetTextColor(kBlue);
449  title->Draw();
450  };
451 
452  TPave *palette = (TPave*)(gPad->GetPrimitive("palette"));
453  if( palette ){
454  palette->SetX1NDC( 0.955 );
455  palette->SetX2NDC( 0.985 );
456  palette->Draw();
457  };
458  };
459 
460  can1->Print( (mFilenamePdf + "[").data() ); // open the file
461  can1->Print( mFilenamePdf.data() );
462 
463  can2->Divide( 3, 5 );
464  for( Int_t i=0; i<kNumApv; ++i ){
465  for( Int_t j=0; j<3; ++j ){
466  can2->cd( (i%5)*3+1+j );
467 
468  TH1F *hist = 0;
469  Float_t max = 0;
470  if( j == 0 ){
471  hist = hPed[i];
472  max = maxAdcPed;
473  } else if( j ==1 ){
474  hist = hRMS[i];
475  max = maxAdcRMS;
476  } else {
477  hist = hFrac[i];
478  max = maxAdcFrac;
479  };
480  hist->SetMaximum( max );
481 
482  gPad->SetBottomMargin(0.15);
483  hist->GetXaxis()->SetTitleSize(0.06);
484  hist->GetXaxis()->SetLabelSize(0.06);
485  hist->GetYaxis()->SetTitleOffset(0.85);
486  hist->GetYaxis()->SetTitleSize(0.06);
487  hist->GetYaxis()->SetLabelSize(0.06);
488  hist->SetLineColor(kBlue);
489 
490  hist->Draw();
491  gPad->Update();
492  gPad->Modified();
493  TPaveText *title = (TPaveText*)(gPad->GetPrimitive("title"));
494  if( title ){
495  title->SetX1NDC( 0 );
496  title->SetX2NDC( 0.55 );
497  title->SetY1NDC( 0.91 ) ;
498  title->SetY2NDC( 0.999 );
499  title->SetBorderSize(0);
500  title->SetTextAlign( 12 );
501  title->SetTextColor(kRed);
502  title->Draw();
503  };
504 
505  TPaveStats *stats = (TPaveStats*)(gPad->GetPrimitive("stats"));
506  if( stats ){
507  stats->SetX1NDC( 0.68 );
508  stats->SetX2NDC( 0.99 );
509  stats->SetY1NDC( 0.68 ) ;
510  stats->SetY2NDC( 0.99 );
511  stats->Draw();
512  };
513  };
514 
515  if( (i+1) % 5 == 0 && !std::string(hPed[i]->GetTitle()).empty() ){
516  can2->Print( mFilenamePdf.data() );
517  };
518  };
519 
520  can2->Print( ( mFilenamePdf + "]").data() ); // close the file
521  };
522 
523  if( !mFilenameRoot.empty() )
524  tfilePtr->Close();
525  };
526 
527  return ierr;
528 };
529 
530 ClassImp( StFgtPedStatQA );
Definition: Stypes.h:41