Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Calibration/HLDetectorTiming/FitScripts/ExtractTDCADCTiming.C
Go to the documentation of this file.
1 namespace ExtractTDCADCTimingNS {
2 TFile * thisFile;
3 
4 TH1I * Get1DHistogram(const char * plugin, const char * directoryName, const char * name, bool print = true){
5  TH1I * histogram;
6  TString fullName = TString(plugin) + "/" + TString(directoryName) + "/" + TString(name);
7  thisFile->GetObject(fullName, histogram);
8  if (histogram == 0){
9  if (print) cout << "Unable to find histogram " << fullName.Data() << endl;
10  return NULL;
11  }
12  return histogram;
13 }
14 
15 TH2I * Get2DHistogram(const char * plugin, const char * directoryName, const char * name){
16  TH2I * histogram;
17  TString fullName = TString(plugin) + "/" + TString(directoryName) + "/" + TString(name);
18  thisFile->GetObject(fullName, histogram);
19  if (histogram == 0){
20  cout << "Unable to find histogram " << fullName.Data() << endl;
21  return NULL;
22  }
23  return histogram;
24 }
25 };
26 
27 void GetCCDBConstants(TString path, Int_t run, TString variation, vector<double>& container, Int_t column = 1){
28  char command[256];
29  sprintf(command, "ccdb dump %s:%i:%s", path.Data(), run, variation.Data());
30  FILE* inputPipe = gSystem->OpenPipe(command, "r");
31  if(inputPipe == NULL)
32  return;
33  //get the first (comment) line
34  char buff[1024];
35  if(fgets(buff, sizeof(buff), inputPipe) == NULL)
36  return;
37  //get the remaining lines
38  double entry;
39  int counter = 0;
40  while(fgets(buff, sizeof(buff), inputPipe) != NULL){
41  istringstream locConstantsStream(buff);
42  while (locConstantsStream >> entry){
43  counter++;
44  if (counter % column == 0) container.push_back(entry);
45  }
46  }
47  //Close the pipe
48  gSystem->ClosePipe(inputPipe);
49 }
50 //Overload this function to handle the base time offsets
51 void GetCCDBConstants1(TString path, Int_t run, TString variation, double& constant1){
52  char command[256];
53  sprintf(command, "ccdb dump %s:%i:%s", path.Data(), run, variation.Data());
54  FILE* inputPipe = gSystem->OpenPipe(command, "r");
55  if(inputPipe == NULL)
56  return;
57  //get the first (comment) line
58  char buff[1024];
59  if(fgets(buff, sizeof(buff), inputPipe) == NULL)
60  return;
61  //get the line containing the values
62  while(fgets(buff, sizeof(buff), inputPipe) != NULL){
63  istringstream locConstantsStream(buff);
64  locConstantsStream >> constant1;
65  }
66  //Close the pipe
67  gSystem->ClosePipe(inputPipe);
68 }
69 
70 void GetCCDBConstants2(TString path, Int_t run, TString variation, double& constant1, double& constant2){
71  char command[256];
72  sprintf(command, "ccdb dump %s:%i:%s", path.Data(), run, variation.Data());
73  FILE* inputPipe = gSystem->OpenPipe(command, "r");
74  if(inputPipe == NULL)
75  return;
76  //get the first (comment) line
77  char buff[1024];
78  if(fgets(buff, sizeof(buff), inputPipe) == NULL)
79  return;
80  //get the line containing the values
81  while(fgets(buff, sizeof(buff), inputPipe) != NULL){
82  istringstream locConstantsStream(buff);
83  locConstantsStream >> constant1 >> constant2;
84  }
85  //Close the pipe
86  gSystem->ClosePipe(inputPipe);
87 }
88 
89 int GetCCDBIndexTAGM(int column, int row){
90  int CCDBIndex = column + row;
91  if (column > 9) CCDBIndex += 5;
92  if (column > 27) CCDBIndex += 5;
93  if (column > 81) CCDBIndex += 5;
94  if (column > 99) CCDBIndex += 5;
95 
96  return CCDBIndex;
97 }
98 
99 int GetF1TDCslotTAGH(int id) {
100  double N = 32.0; // channels per slot
101  if (id >= 132 && id <= 172) throw("TAGH: unknown id in [132,172]");
102  int HVid = (id <= 131) ? id : (id - 274 + 233);
103  return int((HVid-1)/N) + 1;
104 }
105 
106 Double_t FitFunctionLeft(Double_t *x, Double_t *par)
107 {
108  Float_t xx =x[0];
109  Double_t f = par[0]*TMath::Exp(-0.5 * (TMath::Power((xx - par[1]) / par[2] , 2) ) )+ par[0]*TMath::Exp(-0.5 * (TMath::Power((xx - par[1] - par[3]) / par[2] , 2) ) );
110  return f;
111 }
112 
113 Double_t FitFunctionRight(Double_t *x, Double_t *par)
114 {
115  Float_t xx =x[0];
116  Double_t f = par[0]*TMath::Exp(-0.5 * (TMath::Power((xx - par[1]) / par[2] , 2) ) )+ par[0]*TMath::Exp(-0.5 * (TMath::Power((xx - par[1] + par[3]) / par[2] , 2) ) );
117  return f;
118 }
119 
120 void ExtractTDCADCTiming(TString fileName = "hd_root.root", int runNumber = 10390, TString variation = "default", TString prefix = ""){
121 
122  // set "prefix" in case you want to think about thowing the text files into another directory
123  cout << "Performing TDC/ADC timing fits for File: " << fileName.Data() << " Run: " << runNumber << " Variation: " << variation.Data() << endl;
124 
125  ExtractTDCADCTimingNS::thisFile = TFile::Open( fileName , "UPDATE");
127  cout << "Unable to open file " << fileName.Data() << "...Exiting" << endl;
128  return;
129  }
130  ofstream outFile;
131 
132  // We need to grab the existing values from the CCDB so that we know what was used in the creation of the ROOT file
133  cout << "Grabbing CCDB constants..." << endl;
134 
135  // First are the base times for all of the detectors
136  double cdc_base_time, fcal_base_time;
137  double sc_base_time_tdc, sc_base_time_adc;
138  double fdc_base_time_tdc, fdc_base_time_adc;
139  double bcal_base_time_tdc, bcal_base_time_adc;
140  double tagm_base_time_tdc, tagm_base_time_adc;
141  double tagh_base_time_tdc, tagh_base_time_adc;
142  double tof_base_time_tdc, tof_base_time_adc;
143 
144  double beam_period;
145 
146  GetCCDBConstants1("/CDC/base_time_offset" ,runNumber, variation, cdc_base_time);
147  GetCCDBConstants1("/FCAL/base_time_offset",runNumber, variation, fcal_base_time);
148  GetCCDBConstants1("/PHOTON_BEAM/RF/beam_period",runNumber, variation, beam_period);
149  GetCCDBConstants2("/FDC/base_time_offset" ,runNumber, variation, fdc_base_time_adc, fdc_base_time_tdc);
150  GetCCDBConstants2("/BCAL/base_time_offset" ,runNumber, variation, bcal_base_time_adc, bcal_base_time_tdc);
151  GetCCDBConstants2("/PHOTON_BEAM/microscope/base_time_offset" ,runNumber, variation, tagm_base_time_adc, tagm_base_time_tdc);
152  GetCCDBConstants2("/PHOTON_BEAM/hodoscope/base_time_offset" ,runNumber, variation, tagh_base_time_adc, tagh_base_time_tdc);
153  GetCCDBConstants2("/START_COUNTER/base_time_offset" ,runNumber, variation, sc_base_time_adc, sc_base_time_tdc);
154  GetCCDBConstants2("/TOF/base_time_offset" ,runNumber, variation, tof_base_time_adc, tof_base_time_tdc);
155 
156  cout << "CDC base times = " << cdc_base_time << endl;
157  cout << "FCAL base times = " << fcal_base_time << endl;
158  cout << "FDC base times = " << fdc_base_time_adc << ", " << fdc_base_time_tdc << endl;
159  cout << "BCAL base times = " << bcal_base_time_adc << ", " << bcal_base_time_tdc << endl;
160  cout << "SC base times = " << sc_base_time_adc << ", " << sc_base_time_tdc << endl;
161  cout << "TOF base times = " << tof_base_time_adc << ", " << tof_base_time_tdc << endl;
162  cout << "TAGH base times = " << tagh_base_time_adc << ", " << tagh_base_time_tdc << endl;
163  cout << "TAGM base times = " << tagm_base_time_adc << ", " << tagm_base_time_tdc << endl;
164 
165  cout << "beam_period = " << beam_period << endl;
166 
167  // Then the channel by channel ADC and TDC times for those that need the calibration
168  vector<double> bcal_tdc_offsets;
169  vector<double> fcal_adc_offsets;
170  vector<double> sc_adc_offsets, sc_tdc_offsets;
171  vector<double> tagm_adc_offsets, tagm_tdc_offsets;
172  vector<double> tagh_adc_offsets, tagh_tdc_offsets, tagh_counter_quality;
173  vector<double> tof_adc_offsets, tof_tdc_offsets;
174  GetCCDBConstants("/BCAL/TDC_offsets" ,runNumber, variation, bcal_tdc_offsets);
175  GetCCDBConstants("/FCAL/timing_offsets" ,runNumber, variation, fcal_adc_offsets);
176  GetCCDBConstants("/START_COUNTER/adc_timing_offsets" ,runNumber, variation, sc_adc_offsets);
177  GetCCDBConstants("/START_COUNTER/tdc_timing_offsets" ,runNumber, variation, sc_tdc_offsets);
178  GetCCDBConstants("/PHOTON_BEAM/microscope/fadc_time_offsets" ,runNumber, variation, tagm_adc_offsets,3);// Interested in 3rd column
179  GetCCDBConstants("/PHOTON_BEAM/microscope/tdc_time_offsets" ,runNumber, variation, tagm_tdc_offsets,3);
180  GetCCDBConstants("/PHOTON_BEAM/hodoscope/fadc_time_offsets" ,runNumber, variation, tagh_adc_offsets,2);// Interested in 2nd column
181  GetCCDBConstants("/PHOTON_BEAM/hodoscope/tdc_time_offsets" ,runNumber, variation, tagh_tdc_offsets,2);
182  GetCCDBConstants("/PHOTON_BEAM/hodoscope/counter_quality" ,runNumber, variation, tagh_counter_quality,2);
183  GetCCDBConstants("/TOF/adc_timing_offsets",runNumber, variation, tof_adc_offsets);
184  GetCCDBConstants("/TOF/timing_offsets",runNumber, variation, tof_tdc_offsets);
185 
186  cout << "Done grabbing CCDB constants...Entering fits..." << endl;
187 
188  //Move the base times just for the tracking
189 
190  float CDC_ADC_Offset = 0.0;
191  TH1I * this1DHist = ExtractTDCADCTimingNS::Get1DHistogram("HLDetectorTiming", "CDC", "CDCHit time");
192  if(this1DHist != NULL){
193  Int_t firstBin = this1DHist->FindLastBinAbove( 1 , 1); // Find first bin with content above 1 in the histogram
194  for (int i = 0; i <= 25; i++){
195  if ((firstBin + i) > 0) this1DHist->SetBinContent((firstBin + i), 0);
196  }
197  //Fit a gaussian to the left of the main peak
198  Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
199  TF1 *f = new TF1("f", "gaus");
200  f->SetParameters(100, maximum, 20);
201  f->FixParameter(1 , maximum);
202  TFitResultPtr fr = this1DHist->Fit(f, "S", "", maximum - 20, maximum + 20); // Cant fix value at end of range
203  double mean = fr->Parameter(1);
204  float sigma = fr->Parameter(2);
205  CDC_ADC_Offset = mean - sigma;
206  delete f;
207  }
208 
209  CDC_ADC_Offset *= -1;
210  outFile.open(prefix + "cdc_base_time.txt");
211  outFile << cdc_base_time + CDC_ADC_Offset << endl;
212  outFile.close();
213 
214  float FDC_ADC_Offset = 0.0, FDC_TDC_Offset = 0.0;
215  this1DHist = ExtractTDCADCTimingNS::Get1DHistogram("HLDetectorTiming", "FDC", "FDCHit Cathode time");
216  if(this1DHist != NULL){
217  Int_t firstBin = this1DHist->FindLastBinAbove( 1 , 1); // Find first bin with content above 1 in the histogram
218  for (int i = 0; i <= 25; i++){
219  if ((firstBin + i) > 0) this1DHist->SetBinContent((firstBin + i), 0);
220  }
221  //Fit a gaussian to the left of the main peak
222  Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
223  TF1 *f = new TF1("f", "gaus");
224  f->SetParameters(100, maximum, 20);
225  f->FixParameter(1 , maximum);
226  TFitResultPtr fr = this1DHist->Fit(f, "S", "", maximum - 30, maximum + 20); // Cant fix value at end of range
227  double mean = fr->Parameter(1);
228  float sigma = fr->Parameter(2);
229  FDC_ADC_Offset = mean;
230  delete f;
231  }
232  this1DHist = ExtractTDCADCTimingNS::Get1DHistogram("HLDetectorTiming", "FDC", "FDCHit Wire time");
233  if(this1DHist != NULL){
234  Int_t firstBin = this1DHist->FindLastBinAbove( 1 , 1); // Find first bin with content above 1 in the histogram
235  for (int i = 0; i <= 25; i++){
236  if ((firstBin + i) > 0) this1DHist->SetBinContent((firstBin + i), 0);
237  }
238  //Fit a gaussian to the left of the main peak
239  Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
240  TF1 *f = new TF1("f", "gaus");
241  f->SetParameters(100, maximum, 20);
242  f->FixParameter(1 , maximum);
243  TFitResultPtr fr = this1DHist->Fit(f, "S", "", maximum - 30, maximum + 20); // Cant fix value at end of range
244  double mean = fr->Parameter(1);
245  float sigma = fr->Parameter(2);
246  FDC_TDC_Offset = mean;
247  delete f;
248  }
249 
250  FDC_ADC_Offset *= -1; FDC_TDC_Offset *= -1;
251  outFile.open(prefix + "fdc_base_time.txt");
252  outFile << fdc_base_time_adc + FDC_ADC_Offset << " " << fdc_base_time_tdc + FDC_TDC_Offset << endl;
253  outFile.close();
254 
255  // Now that we have the file open, do all of the fits and write the output
256  // Fit all plots with expected funtional form, output files for CCDB input
257  // Do a finer alignement of the TDC and ADC's in the detectors that have both
258  int minHits = 7;
259 
260  // In order to calibrate the SC in one step, we need to work with the base times and with the TDC/ADC offsets at the same time
261  // Sort of complicates things but saves considerable time.
262 
263  float sc_tdc_base_time = 0.0;
264 
265  this1DHist = ExtractTDCADCTimingNS::Get1DHistogram("HLDetectorTiming", "SC", "SCHit TDC time");
266  if(this1DHist != NULL){
267  //Gaussian
268  Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
269  TFitResultPtr fr = this1DHist->Fit("gaus", "S", "", maximum - 5, maximum + 5);
270  double mean = fr->Parameter(1);
271  sc_tdc_base_time = mean;
272  }
273 
274  TH2I *thisHist = ExtractTDCADCTimingNS::Get2DHistogram("HLDetectorTiming", "SC", "SCHit TDC_ADC Difference");
275  TH1D * selected_SC_TDCADCOffset = NULL;
276  TH1I * SCOffsetDistribution = NULL;
277  if(thisHist != NULL){
278 
279  int nBinsX = thisHist->GetNbinsX();
280  int nBinsY = thisHist->GetNbinsY();
281 
282  selected_SC_TDCADCOffset = new TH1D("selected_SC_TDCADCOffset", "Selected SC TDC/ADC Offset; CCDB Index; Offset [ns]", nBinsX, 0.5, nBinsX + 0.5);
283  SCOffsetDistribution = new TH1I("SCOffsetDistribution", "SC ADC Offset; ADC Offset [ns]; Entries", 1000, -500, 500);
284 
285  for (int i = 1 ; i <= nBinsX; i++){
286  TH1D *projY = thisHist->ProjectionY("temp", i, i);
287  // Scan over the histogram
288  float nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX();
289  float timeWindow = 2; //ns (Full Width)
290  int binWindow = int(timeWindow / nsPerBin);
291  double maxEntries = 0;
292  double maxMean = 0;
293  for (int j = 1 ; j <= projY->GetNbinsX();j++){
294  int minBin = j;
295  int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX();
296  double sum = 0, nEntries = 0;
297  for (int bin = minBin; bin <= maxBin; bin++){
298  sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin);
299  nEntries += projY->GetBinContent(bin);
300  if (bin == maxBin){
301  if (nEntries > maxEntries) {
302  maxMean = sum / nEntries;
303  maxEntries = nEntries;
304  }
305  }
306  }
307  }
308  //outFile.open(prefix + "sc_adc_timing_offsets.txt", ios::out | ios::app);
309  //outFile << -1 * maxMean << endl;
310  //outFile.close();
311  // Some histograms for tracking the magnitude of the shifts
312  selected_SC_TDCADCOffset->SetBinContent(i, -1*maxMean);
313  SCOffsetDistribution->Fill(-1*maxMean);
314  }
315  }
316 
317  // Two Output files to write for the SC
318  float meanDiff = 0.0;
319  if (selected_SC_TDCADCOffset != NULL){
320  meanDiff = SCOffsetDistribution->GetMean();
321  outFile.open(prefix + "sc_adc_timing_offsets.txt", ios::out);
322  for( int iSC = 1; iSC <= 30; iSC++){
323  float SC_ADC_Offset = selected_SC_TDCADCOffset->GetBinContent(iSC);
324  outFile << SC_ADC_Offset + sc_adc_offsets[iSC-1] - meanDiff << endl;
325  }
326  outFile.close();
327  }
328 
329  outFile.open(prefix + "sc_base_time.txt", ios::out);
330  outFile << sc_base_time_adc - (sc_tdc_base_time + meanDiff) << " " << sc_base_time_tdc - sc_tdc_base_time << endl;
331  outFile.close();
332 
333  thisHist = ExtractTDCADCTimingNS::Get2DHistogram("HLDetectorTiming", "TOF", "TOFHit TDC_ADC Difference");
334  if(thisHist != NULL){
335  int nBinsX = thisHist->GetNbinsX();
336  int nBinsY = thisHist->GetNbinsY();
337 
338  TH1D * selected_TOF_TDCADCOffset = new TH1D("selected_TOF_TDCADCOffset", "Selected TOF TDC/ADC Offset; CCDB Index; Offset [ns]", nBinsX, 0.5, nBinsX + 0.5);
339  TH1I * TOFOffsetDistribution = new TH1I("TOFOffsetDistribution", "TOF ADC Offset; ADC Offset [ns]; Entries", 1000, -500, 500);
340 
341  outFile.open(prefix + "tof_adc_timing_offsets.txt");
342  outFile.close(); // Clear Output File
343 
344  for (int i = 1 ; i <= nBinsX; i++){
345  TH1D *projY = thisHist->ProjectionY("temp", i, i);
346  // Scan over the histogram
347  //chose the correct number of bins based on the histogram
348  float nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX();
349  float timeWindow = 0.5; //ns (Full Width) -- Pretty kiler resolution
350  int binWindow = int(timeWindow / nsPerBin);
351  double maxEntries = 0;
352  double maxMean = 0;
353  for (int j = 1 ; j <= projY->GetNbinsX();j++){
354  int minBin = j;
355  int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX();
356  double sum = 0, nEntries = 0;
357  for (int bin = minBin; bin <= maxBin; bin++){
358  sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin);
359  nEntries += projY->GetBinContent(bin);
360  if (bin == maxBin){
361  if (nEntries > maxEntries) {
362  maxMean = sum / nEntries;
363  maxEntries = nEntries;
364  }
365  }
366  }
367  }
368  // Some histograms for tracking the magnitude of the shifts
369  selected_TOF_TDCADCOffset->SetBinContent(i, -1*maxMean);
370  if (maxMean != 0) TOFOffsetDistribution->Fill(-1*maxMean);
371  }
372 
373  double meanOffset = TOFOffsetDistribution->GetMean();
374  outFile.open(prefix + "tof_adc_timing_offsets.txt", ios::out);
375  for (int i = 1 ; i <= nBinsX; i++){
376  double valueToUse = selected_TOF_TDCADCOffset->GetBinContent(i);
377  if (valueToUse == 0) valueToUse = meanOffset;
378  outFile << tof_adc_offsets[i-1] + valueToUse - meanOffset << endl;
379  }
380  outFile.close();
381  outFile.open(prefix + "tof_base_time.txt", ios::out);
382  outFile << tof_base_time_adc - meanOffset << " " << tof_base_time_tdc << endl;
383  outFile.close();
384 
385  }
386 
387  thisHist = ExtractTDCADCTimingNS::Get2DHistogram("HLDetectorTiming", "TAGM", "TAGMHit TDC_ADC Difference");
388  if(thisHist != NULL){
389  float tdcRFOffset[122] = {}; // 122 possible offsets
390  char name[100];
391  //First loop through the TDC RF times to see which ones we can correct
392  TF1 * fitLeft = new TF1("fa",FitFunctionLeft, -1*beam_period / 2, beam_period / 2, 4);
393  TF1 * fitRight = new TF1("fa",FitFunctionRight, -1*beam_period / 2, beam_period / 2, 4);
394  for (unsigned int column = 1; column <= 102; column++){
395  for (unsigned int row = 0; row <= 5; row++){
396  sprintf(name, "Column %.3i Row %.1i", column, row);
397  TH1I *rf_hist = ExtractTDCADCTimingNS::Get1DHistogram("HLDetectorTiming", "TAGM_TDC_RF_Compare", name, false);
398  if (rf_hist != NULL){
399  // do the fit and store the result
400  // Some fancy footwork to fit this periodic function
401  cout << "Fitting TAGM " << name << endl;
402  TF1 *fa;
403  if (rf_hist->GetBinCenter(rf_hist->GetMaximumBin()) < 0.0) fa = fitLeft;
404  else fa = fitRight;
405  fa->SetParLimits(1, -1*beam_period / 2, beam_period / 2);
406  fa->SetParameter(1,rf_hist->GetBinCenter(rf_hist->GetMaximumBin()));
407  fa->SetParLimits(2, 0.175, 1.2);
408  fa->SetParameter(2, 0.4);
409  fa->FixParameter(3, beam_period);
410  TFitResultPtr r = rf_hist->Fit(fa, "S", "", -1*beam_period / 2, beam_period / 2);
411  Int_t status = r;
412  if ( status == 0){ // Fit succeeded
413  Double_t offset = r->Parameter(1);
414  tdcRFOffset[ GetCCDBIndexTAGM(column, row) - 1 ] = offset;
415  }
416  }
417  }
418  }
419 
420  //int nbins = meanHist->GetNbinsX();
421  int nBinsX = thisHist->GetNbinsX();
422  int nBinsY = thisHist->GetNbinsY();
423 
424  TH1D * selectedTAGMOffset = new TH1D("selectedTAGMOffset", "Selected TAGM Offset; Column; Offset [ns]", nBinsX, 0.5, nBinsX + 0.5);
425  TH1I * TAGMOffsetDistribution = new TH1I("TAGMOffsetDistribution", "TAGM ADC Offset; ADC Offset [ns]; Entries", 1000, -500, 500);
426 
427  for (int i = 1 ; i <= nBinsX; i++){
428  TH1D *projY = thisHist->ProjectionY("temp", i, i);
429  // Scan over the histogram
430  //chose the correct number of bins based on the histogram
431  float nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX();
432  float timeWindow = 2; //ns (Full Width)
433  int binWindow = int(timeWindow / nsPerBin);
434  double maxEntries = 0;
435  double maxMean = 0;
436  for (int j = 1 ; j <= projY->GetNbinsX();j++){
437  int minBin = j;
438  int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX();
439  double sum = 0, nEntries = 0;
440  for (int bin = minBin; bin <= maxBin; bin++){
441  sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin);
442  nEntries += projY->GetBinContent(bin);
443  if (bin == maxBin){
444  if (nEntries > maxEntries) {
445  maxMean = sum / nEntries;
446  maxEntries = nEntries;
447  }
448  }
449  }
450  }
451  selectedTAGMOffset->SetBinContent(i, -1 * maxMean);
452  if (maxMean != 0) TAGMOffsetDistribution->Fill(-1 * maxMean);
453  }
454  //Put the average offset in the base times
455  double meanOffset = TAGMOffsetDistribution->GetMean();
456  outFile.open(prefix + "tagm_adc_timing_offsets.txt", ios::out);
457  //for (int i = 1 ; i <= nBinsX; i++){
458  // Loop over rows
459  for (unsigned int column = 1; column <= 102; column++){
460  int index = GetCCDBIndexTAGM(column, 0);
461  double valueToUse = selectedTAGMOffset->GetBinContent(index);
462  if (valueToUse == 0) valueToUse = meanOffset;
463  outFile << "0 " << column << " " << tagm_adc_offsets[index-1] + valueToUse - meanOffset + tdcRFOffset[index-1] << endl;
464  if (column == 9 || column == 27 || column == 81 || column == 99){
465  for (unsigned int row = 1; row <= 5; row++){
466  index = GetCCDBIndexTAGM(column, row);
467  valueToUse = selectedTAGMOffset->GetBinContent(index);
468  double valueToUse = selectedTAGMOffset->GetBinContent(index);
469  if (valueToUse == 0) valueToUse = meanOffset;
470  outFile << row << " " << column << " " << tagm_adc_offsets[index-1] + valueToUse - meanOffset + tdcRFOffset[index-1] << endl;
471  }
472  }
473  }
474  outFile.close();
475 
476  outFile.open(prefix + "tagm_tdc_timing_offsets.txt", ios::out);
477  //for (int i = 1 ; i <= nBinsX; i++){
478  // Loop over rows
479  for (unsigned int column = 1; column <= 102; column++){
480  int index = GetCCDBIndexTAGM(column, 0);
481  outFile << "0 " << column << " " << tagm_tdc_offsets[index-1] + tdcRFOffset[index-1] << endl;
482  if (column == 9 || column == 27 || column == 81 || column == 99){
483  for (unsigned int row = 1; row <= 5; row++){
484  index = GetCCDBIndexTAGM(column, row);
485  outFile << row << " " << column << " " << tagm_tdc_offsets[index-1] + tdcRFOffset[index-1] << endl;
486  }
487  }
488  }
489  outFile.close();
490 
491  outFile.open(prefix + "tagm_base_time.txt", ios::out);
492  outFile << tagm_base_time_adc - meanOffset << " " << tagm_base_time_tdc << endl;
493  outFile.close();
494  }
495 
496  thisHist = ExtractTDCADCTimingNS::Get2DHistogram("HLDetectorTiming", "TAGH", "TAGHHit TDC_ADC Difference");
497  if (thisHist != NULL) {
498 
499  // Setup histograms for determining the most probable change in offset for each F1TDC slot
500  // This is needed to account for the occasional uniform shift in offsets of the 32 counters in a slot
501  const int NtdcSlots = 8;
502  TH1I * tdcDist[NtdcSlots];
503  TH1I * tdcadcDist[NtdcSlots];
504  for (int i = 1; i <= NtdcSlots; i++) {
505  stringstream ss; ss << i;
506  TString s = ss.str();
507  double range = 1000.0; double width = 0.1;
508  int Nbins = range/width;
509  double low = -0.5*range - 0.5*width;
510  double high = 0.5*range - 0.5*width;
511  tdcDist[i-1] = new TH1I("TAGHTDCOffsetDistribution_"+s, "TAGH TDC Offset (slot "+s+"); TDC Offset [ns]; Entries", Nbins, low, high);
512  tdcadcDist[i-1] = new TH1I("TAGHTDCADCOffsetDistribution_"+s, "TAGH TDC/ADC Offset (slot "+s+"); TDC/ADC Offset [ns]; Entries", Nbins, low, high);
513  }
514 
515  // First take a look at the RF offsets
516  double tdcRFOffsetTAGH[274] = {}; // 274 possible offsets
517  char name[100];
518  // Loop through the TDC RF times to see which ones we can correct
519  TF1 * fitLeft = new TF1("fa",FitFunctionLeft, -1*beam_period / 2, beam_period / 2, 4);
520  TF1 * fitRight = new TF1("fa",FitFunctionRight, -1*beam_period / 2, beam_period / 2, 4);
521 
522  for (unsigned int counter_id = 1; counter_id <= 274; counter_id++) {
523  sprintf(name, "Counter ID %.3i", counter_id);
524  cout << "Fitting TAGH " << name << endl;
525  TH1I *rf_hist = ExtractTDCADCTimingNS::Get1DHistogram("HLDetectorTiming", "TAGH_TDC_RF_Compare", name, false);
526  if (rf_hist != NULL) {
527  // do the fit and store the result
528  // Some fancy footwork to fit this periodic function
529  TF1 *fa;
530  if (rf_hist->GetBinCenter(rf_hist->GetMaximumBin()) < 0.0) fa = fitLeft;
531  else fa = fitRight;
532  fa->SetParLimits(1, -1*beam_period / 2, beam_period / 2);
533  fa->SetParameter(1,rf_hist->GetBinCenter(rf_hist->GetMaximumBin()));
534  fa->SetParLimits(2, 0.175, 1.2);
535  fa->SetParameter(2, 0.4);
536  fa->FixParameter(3, beam_period);
537  TFitResultPtr r = rf_hist->Fit(fa, "S", "", -1*beam_period / 2, beam_period / 2);
538  Int_t status = r;
539  if (status == 0) { // Fit succeeded
540  Double_t offset = r->Parameter(1);
541  tdcRFOffsetTAGH[counter_id - 1] = offset;
542  if (tagh_counter_quality[counter_id-1] == 0.0) continue;
543  int tdc_slot = GetF1TDCslotTAGH(counter_id);
544  tdcDist[tdc_slot - 1]->Fill(offset);
545  }
546  }
547  }
548  // Most probable change in TDC/RF offset per F1TDC slot
549  double mpDeltaTDC[NtdcSlots];
550  for (int i = 1; i <= NtdcSlots; i++) {
551  int mpBin = tdcDist[i-1]->GetMaximumBin();
552  mpDeltaTDC[i-1] = (mpBin > 0) ? tdcDist[i-1]->GetBinCenter(mpBin) : 0.0;
553  }
554 
555  outFile.open(prefix + "tagh_adc_timing_offsets.txt", ios::out | ios::trunc);
556  outFile.close(); // clear file
557 
558  int nBinsX = thisHist->GetNbinsX();
559 
560  TH1D * selectedTAGHOffset = new TH1D("selectedTAGHOffset", "Selected TAGH Offset; Column; Offset [ns]", nBinsX, 0.5, nBinsX + 0.5);
561  for (int i = 1 ; i <= nBinsX; i++) {
562  TH1D *projY = thisHist->ProjectionY("temp", i, i);
563  // Scan over histogram to find mean offset in timeWindow with largest integral
564  double nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX();
565  double timeWindow = 2.0; //ns (Full Width)
566  int binWindow = int(timeWindow / nsPerBin);
567  double maxEntries = 0;
568  double maxMean = 0;
569  for (int j = 1 ; j <= projY->GetNbinsX();j++) {
570  int minBin = j;
571  int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX();
572  double sum = 0, nEntries = 0;
573  for (int bin = minBin; bin <= maxBin; bin++) {
574  sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin);
575  nEntries += projY->GetBinContent(bin);
576  if (bin == maxBin) {
577  if (nEntries > maxEntries) {
578  maxMean = sum / nEntries;
579  maxEntries = nEntries;
580  }
581  }
582  }
583  }
584  selectedTAGHOffset->SetBinContent(i, maxMean);
585  if (tagh_counter_quality[i-1] == 0.0) continue;
586  int tdc_slot = GetF1TDCslotTAGH(i);
587  if (maxEntries != 0.0) tdcadcDist[tdc_slot - 1]->Fill(maxMean);
588  }
589  // Most probable change in TDC/ADC offset per F1TDC slot
590  double mpDeltaADC[NtdcSlots];
591  for (int i = 1; i <= NtdcSlots; i++) {
592  int mpBin = tdcadcDist[i-1]->GetMaximumBin();
593  double mpDeltaTDCADC = (mpBin > 0) ? tdcadcDist[i-1]->GetBinCenter(mpBin) : 0.0;
594  mpDeltaADC[i-1] = mpDeltaTDC[i-1] - mpDeltaTDCADC;
595  }
596 
597  outFile.open(prefix + "tagh_adc_timing_offsets.txt");
598  double limit = 2.5; // ns
599  double ccdb_sum = 0.0;
600  for (int i = 1; i <= nBinsX; i++) ccdb_sum += tagh_adc_offsets[i-1];
601  double c1_adcOffset = 0.0;
602  for (int i = 1; i <= nBinsX; i++) {
603  if (tagh_counter_quality[i-1] == 0.0) {
604  outFile << i << " " << 0 << endl;
605  continue;
606  }
607  int tdc_slot = GetF1TDCslotTAGH(i);
608  double ccdb = tagh_adc_offsets[i-1];
609  double delta = tdcRFOffsetTAGH[i-1] - selectedTAGHOffset->GetBinContent(i);
610  if (ccdb_sum > 0.0 && fabs(delta - mpDeltaADC[tdc_slot-1]) > limit) {
611  delta = mpDeltaADC[tdc_slot-1];
612  }
613  double offset = ccdb + delta;
614  if (i == 1) c1_adcOffset = offset;
615  offset -= c1_adcOffset;
616  outFile << i << " " << offset << endl;
617  }
618  outFile.close();
619 
620  outFile.open(prefix + "tagh_tdc_timing_offsets.txt");
621  ccdb_sum = 0.0;
622  for (int i = 1; i <= nBinsX; i++) ccdb_sum += tagh_tdc_offsets[i-1];
623  double c1_tdcOffset = 0.0;
624  for (int i = 1; i <= nBinsX; i++) {
625  if (tagh_counter_quality[i-1] == 0.0) {
626  outFile << i << " " << 0 << endl;
627  continue;
628  }
629  int tdc_slot = GetF1TDCslotTAGH(i);
630  double ccdb = tagh_tdc_offsets[i-1];
631  double delta = tdcRFOffsetTAGH[i-1];
632  if (ccdb_sum > 0.0 && fabs(delta - mpDeltaTDC[tdc_slot-1]) > limit) {
633  delta = mpDeltaTDC[tdc_slot-1];
634  }
635  double offset = ccdb + delta;
636  if (i == 1) c1_tdcOffset = offset;
637  offset -= c1_tdcOffset;
638  outFile << i << " " << offset << endl;
639  }
640  outFile.close();
641 
642  outFile.open(prefix + "tagh_base_time.txt", ios::out);
643  outFile << tagh_base_time_adc - c1_adcOffset << " " << tagh_base_time_tdc - c1_tdcOffset << endl;
644  outFile.close();
645  }
646 
647  // Now for the BCAL. First do the upstream, then the downstream.
648  // The entries in the CCDB are interleaved, so we need to store them temporarily.
649  // A histogram will do.
650  // We will use the averaging method and not FitSlices
651 
652  outFile.open(prefix + "bcal_tdc_timing_offsets.txt", ios::out | ios::trunc);
653  outFile.close(); // clear file
654 
655  TH1D * selectedBCALOffset = new TH1D("selectedBCALOffset", "Selected BCAL TDC Offset; Column; Offset [ns]", 1152, 0.5, 1152 + 0.5);
656  TH1I * BCALOffsetDistribution = new TH1I("BCALOffsetDistribution", "BCAL TDC Offset; TDC Offset [ns]; Entries", 500, -500, 500);
657 
658  thisHist = ExtractTDCADCTimingNS::Get2DHistogram("HLDetectorTiming", "BCAL", "BCALHit Upstream Per Channel TDC-ADC Hit Time");
659  if(thisHist != NULL){
660  int nBinsX = thisHist->GetNbinsX();
661  int nBinsY = thisHist->GetNbinsY();
662  for (int i = 1 ; i <= nBinsX; i++){
663  TH1D *projY = thisHist->ProjectionY("temp", i, i);
664  // Scan over the histogram
665  float nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX();
666  float timeWindow = 2; //ns (Full Width)
667  int binWindow = int(timeWindow / nsPerBin);
668  double maxEntries = 0;
669  double maxMean = 0;
670  for (int j = 1 ; j <= projY->GetNbinsX();j++){
671  int minBin = j;
672  int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX();
673  double sum = 0, nEntries = 0;
674  for (int bin = minBin; bin <= maxBin; bin++){
675  sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin);
676  nEntries += projY->GetBinContent(bin);
677  if (bin == maxBin){
678  if (nEntries > maxEntries) {
679  maxMean = sum / nEntries;
680  maxEntries = nEntries;
681  }
682  }
683  }
684  }
685  selectedBCALOffset->SetBinContent(2*i - 1, maxMean);
686  BCALOffsetDistribution->Fill(maxMean+bcal_tdc_offsets[2*i -2]);
687  }
688  }
689 
690  thisHist = ExtractTDCADCTimingNS::Get2DHistogram("HLDetectorTiming", "BCAL", "BCALHit Downstream Per Channel TDC-ADC Hit Time");
691  if(thisHist != NULL){
692  int nBinsX = thisHist->GetNbinsX();
693  int nBinsY = thisHist->GetNbinsY();
694  for (int i = 1 ; i <= nBinsX; i++){
695  TH1D *projY = thisHist->ProjectionY("temp", i, i);
696  // Scan over the histogram
697  float nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX();
698  float timeWindow = 2; //ns (Full Width)
699  int binWindow = int(timeWindow / nsPerBin);
700  double maxEntries = 0;
701  double maxMean = 0;
702  for (int j = 1 ; j <= projY->GetNbinsX();j++){
703  int minBin = j;
704  int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX(); // Width is about 10ns (1ns per bin)
705  double sum = 0, nEntries = 0;
706  for (int bin = minBin; bin <= maxBin; bin++){
707  sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin);
708  nEntries += projY->GetBinContent(bin);
709  if (bin == maxBin){
710  if (nEntries > maxEntries) {
711  maxMean = sum / nEntries;
712  maxEntries = nEntries;
713  }
714  }
715  }
716  }
717 
718  selectedBCALOffset->SetBinContent(2*i, maxMean);
719  BCALOffsetDistribution->Fill(maxMean+bcal_tdc_offsets[2*i -1]);
720  }
721  }
722 
723  // We want to split things up so the bulk of the offset goes into the base time offset
724  double meanTDCOffset = BCALOffsetDistribution->GetMean();
725 
726  // One is added, the other subtracted @_@
727  outFile.open(prefix + "bcal_base_time.txt", ios::out);
728  outFile << bcal_base_time_adc << " " << bcal_base_time_tdc - meanTDCOffset << endl;
729  outFile.close();
730 
731  for (int i = 1 ; i <= selectedBCALOffset->GetNbinsX(); i++){
732  double valueToUse = selectedBCALOffset->GetBinContent(i);
733  if (valueToUse == 0) valueToUse = meanTDCOffset;
734  outFile.open(prefix + "bcal_tdc_timing_offsets.txt", ios::out | ios::app);
735  outFile << bcal_tdc_offsets[i-1] + valueToUse - meanTDCOffset << endl;
736  outFile.close();
737  }
738 
740  return;
741  }
float fa[100]
Definition: hycal.h:139
TFile * outFile
Definition: FitGains.C:15
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
sprintf(text,"Post KinFit Cut")
Double_t FitFunctionLeft(Double_t *x, Double_t *par)
Double_t FitFunctionRight(Double_t *x, Double_t *par)
static char index(char c)
Definition: base64.cpp:115
TF1 * f
Definition: FitGains.C:21
double counter
Definition: FitGains.C:151
TH1I * Get1DHistogram(const char *plugin, const char *directoryName, const char *name, bool print=true)
void GetCCDBConstants(TString path, Int_t run, TString variation, vector< double > &container, Int_t column=1)
TH2I * Get2DHistogram(const char *plugin, const char *directoryName, const char *name)
Double_t sigma[NCHANNELS]
Definition: st_tw_resols.C:37
void GetCCDBConstants2(TString path, Int_t run, TString variation, double &constant1, double &constant2)
void ExtractTDCADCTiming(TString fileName="hd_root.root", int runNumber=10390, TString variation="default", TString prefix="")
void GetCCDBConstants1(TString path, Int_t run, TString variation, double &constant1)
int GetCCDBIndexTAGM(unsigned int column, unsigned int row)