ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
S800Calibration.cxx
Go to the documentation of this file.
1 #include "S800Calibration.h"
2 
3 #include <TEnv.h>
4 #include <TError.h>
5 #include <TMath.h>
6 #include <TString.h>
7 
8 #include "S800.h"
9 #include "S800Settings.h"
10 #include "S800defs.h"
11 #include "lmcurve.h"
12 #include "lmfit.h"
13 #include "lmmin.h"
14 
15 #include <cmath>
16 #include <iostream>
17 
18 using namespace std;
19 
21 {
22  // S800
23  fped.resize(2);
24  fslope.resize(2);
25  foffset.resize(2);
26  fbad.resize(2);
27  for (int i = 0; i < 2; i++) {
28  // Initialize the CRDC vectors to 0s and 1s
29  fped[i].resize(S800_FP_CRDC_CHANNELS, 0);
30  fslope[i].resize(S800_FP_CRDC_CHANNELS, 1);
31  foffset[i].resize(S800_FP_CRDC_CHANNELS, 0);
32  }
33 }
34 
36 {
37  // S800
38  fped.resize(2);
39  fslope.resize(2);
40  foffset.resize(2);
41  fbad.resize(2);
42  for (int i = 0; i < 2; i++) {
43  // Initialize the CRDC vectors to 0s and 1s
44  fped[i].resize(S800_FP_CRDC_CHANNELS, 0);
45  fslope[i].resize(S800_FP_CRDC_CHANNELS, 1);
46  foffset[i].resize(S800_FP_CRDC_CHANNELS, 0);
47  }
48 
49  fcrdccal.resize(S800_FP_CRDC_CHANNELS);
50  ReadCrdcCalibration(fSett->CalFile(), fSett->PedestalFile());
51  ReadCrdcBadPads(fSett->BadFile());
52 
53  fICoffset.resize(S800_FP_IC_CHANNELS);
54  fICslope.resize(S800_FP_IC_CHANNELS);
55  ReadICCalibration(fSett->CalFileIC());
56 }
57 
59 {
60  fped.clear();
61  fslope.clear();
62  foffset.clear();
63  fbad.clear();
64  fcrdccal.clear();
65  fICoffset.clear();
66  fICslope.clear();
67  // std::cout << "destructor" << std::endl;
68 }
69 
70 // S800
71 // CRDC cathode pedestal/gain
72 void S800Calibration::ReadCrdcCalibration(const char *filename, const char *pedfile)
73 {
74  TEnv crdcpedestals; //
75  Int_t status = crdcpedestals.ReadFile(pedfile, kEnvLocal);
76  if (status == -1) {
77  Warning(__FUNCTION__, "Could not read CrdcPedFile %s", pedfile);
78  } else {
79  Info(__FUNCTION__, "Reading CrdcPedFile %s", pedfile);
80  }
81 
82  TEnv crdccal;
83  status = crdccal.ReadFile(filename, kEnvLocal);
84  if (status == -1) {
85  Warning(__FUNCTION__, "Could not read CrdcCalFile %s", filename);
86  } else {
87  Info(__FUNCTION__, "Reading CrdcCalFile %s", filename);
88  }
89 
90  for (int c = 0; c < 2; c++) {
91  for (int p = 0; p < S800_FP_CRDC_CHANNELS; p++) {
92  fped[c][p] = crdcpedestals.GetValue(Form("Crdc.%d.Ped.%03d", c, p), 0.0);
93  fslope[c][p] = crdccal.GetValue(Form("Crdc.%d.Slope.%03d", c, p), 1.0);
94  foffset[c][p] = crdccal.GetValue(Form("Crdc.%d.Offset.%03d", c, p), 0.0);
95  }
96  }
97 
98  // for (int p=0;p<S800_FP_CRDC_CHANNELS;p++){
99  // std::cout<<fped[0][p]<<" "<<fslope[0][p]<<" "<<foffset[0][p]<<std::endl;
100  // }
101 }
102 
103 // CRDC cathode bad pad
104 void S800Calibration::ReadCrdcBadPads(const char *filename)
105 {
106  TEnv bad; // = new TEnv(filename);
107  Int_t status = bad.ReadFile(filename, kEnvLocal);
108  if (status == -1) {
109  Warning(__FUNCTION__, "Could not read bad pad file %s", filename);
110  } else {
111  Info(__FUNCTION__, "Reading bad pad file %s", filename);
112  }
113 
114  for (UShort_t i = 0; i < 2; i++) {
115  fbad[i].resize(bad.GetValue(Form("Crdc.%d.Nofbadpads", i), 0));
116  for (UShort_t k = 0; k < fbad[i].size(); k++) {
117  fbad[i][k] = bad.GetValue(Form("Crdc.%d.badpad.%d", i, k), 0);
118  // std::cout << i << " " << k << " " << fbad[i][k] << std::endl;
119  }
120  }
121 }
122 
123 // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv will be removed vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
124 void S800Calibration::CrdcCal(std::vector<Short_t> channel, std::vector<Short_t> data, Int_t id)
125 {
126  Short_t index;
127  std::vector<Float_t> sum;
128  std::vector<Short_t> samples;
129  sum.clear();
130  sum.resize(S800_FP_CRDC_CHANNELS);
131  samples.clear();
132  samples.resize(S800_FP_CRDC_CHANNELS);
133  fcrdccal.clear();
134  fcrdccal.resize(S800_FP_CRDC_CHANNELS);
135  if (channel.size() != data.size()) {
136  std::cerr << " channel (" << channel.size() << ") and data (" << data.size() << ") have different sizes "
137  << std::endl;
138  return;
139  }
140 
141  for (UShort_t f = 0; f < channel.size(); f++) {
142  index = channel[f];
143  sum[index] += data[f] - fped[id][index];
144  samples[index]++;
145  }
146  for (UShort_t ch = 0; ch < S800_FP_CRDC_CHANNELS; ch++) {
147  if (samples[ch] > 0) {
148  fcrdccal[ch] = sum[ch]; // / fSett->SampleWidth();
149  fcrdccal[ch] *= fslope[id][ch];
150  fcrdccal[ch] += foffset[id][ch];
151  } else {
152  fcrdccal[ch] = sqrt(-1.0);
153  }
154  }
155 
156  return;
157 }
158 
159 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Will be removed^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
160 
161 std::vector<Float_t> S800Calibration::GetCalibratedCrdcPads(std::vector<Short_t> channels, std::vector<Short_t> data,
162  Int_t id, vector<Float_t> &PedSubtractedPads)
163 {
164  // Channels should be a vector holding which pads fired in this event
165  // data should be the read values in the same order as the channels
166  // NOTE each pad will always have several (3-4) reads in each event
167  // these have to be summed together in order to get the actual read
168 
169  Short_t index;
170  // std::vector<Float_t> sum;
171  std::vector<Float_t> samples;
172 
173  // sum.resize(S800_FP_CRDC_CHANNELS);
174  samples.resize(S800_FP_CRDC_CHANNELS, 0);
175 
176  std::vector<Float_t> calibratedPadValues;
177  calibratedPadValues.resize(S800_FP_CRDC_CHANNELS, 0);
178  PedSubtractedPads.resize(S800_FP_CRDC_CHANNELS, 0);
179 
180  if (channels.size() != data.size()) {
181  // the length of the channels vector and the data vector should be the same.
182  std::cerr << " channel (" << channels.size() << ") and data (" << data.size() << ") have different sizes "
183  << std::endl;
184  throw 1;
185  }
186 
187  // First loop over the data that was given and add up all the reads for each pad
188  // With the pedistal subtracted
189  for (UShort_t f = 0; f < channels.size(); f++) {
190  index = channels[f];
191 
192  calibratedPadValues[index] += (data[f] - fped[id][index]);
193  PedSubtractedPads[index] += (data[f] - fped[id][index]);
194  samples[index]++;
195  }
196 
197  // Now for all the channels that had at least 1 read in it
198  // apply gain calibrations
199  for (UShort_t ch = 0; ch < S800_FP_CRDC_CHANNELS; ch++) {
200 
201  if (samples[ch] > 0) {
202  // calibratedPadValues[ch] = calibratedPadValues[ch] / samples[ch]; // / fSett->SampleWidth();
203  // PedSubtractedPads[ch] = PedSubtractedPads[ch] / samples[ch]; // / fSett->SampleWidth();
204 
205  calibratedPadValues[ch] *= fslope[id][ch];
206  calibratedPadValues[ch] += foffset[id][ch];
207  } else {
208  calibratedPadValues[ch] = sqrt(-1.0);
209  }
210  }
211 
212  return calibratedPadValues;
213 }
214 
215 // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv will be removed vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
216 void S800Calibration::SetCrdc(std::vector<Short_t> channel, std::vector<Short_t> data, Float_t tac, Float_t anode,
217  Int_t id)
218 {
219  fcrdc.Clear();
220  fcrdc.SetID(id);
221  this->CrdcCal(channel, data, id);
222  fcrdc.SetCal(fcrdccal);
223 
224  // cout<<"ID IS "<<id<<endl;
225  // for (int i=0;i<fcrdccal.size();i++){
226  // cout<<fcrdccal[i]<<" ";
227  // }cout<<endl;
228  // cin.get();
229 
230  // debug
231  // std::cout << "\n" << id << std::endl;
232  // for (int i = 0; i < channel.size(); i++) {
233  // std::cout << channel[i] << " " << data[i] << std::endl;
234  // }
235  double x = fSett->XOffset(id) + fSett->XSlope(id) * this->CalcX();
236  double y = fSett->YOffset(id) + fSett->YSlope(id) * tac;
237  fcrdc.SetX(x);
238  fcrdc.SetY(y);
239  fcrdc.SetTAC(tac);
240  fcrdc.SetAnode(anode);
241 }
242 
244 {
245 
246  // Cluster search
247  Bool_t flg_clstr = kFALSE;
248  Int_t iclstr = -1;
249  const Int_t maxclstr = S800_FP_CRDC_CHANNELS;
250  // maximum number of clusters (I know this is too many...)
251  Int_t clstr[maxclstr][3]; // clstr[][0] is left edge clstr[][1] right edge clstr[][2] is width
252  Float_t maxchg[maxclstr]; //
253  Float_t maxpad[maxclstr];
254  const Float_t qmax = 25.; // MINUMUM value of max charge
255  // to be considered to form a cluster
256  const Float_t qthr = 8.; // MINUMUM value of charge to be considered to be hit
257  Float_t tmp_qmax = 0.0;
258  Int_t gclstr = 0;
259 
260  for (UShort_t i = 0; i < S800_FP_CRDC_CHANNELS; i++) {
261  if (IsBad(i, fcrdc.GetID()))
262  continue;
263  if ((flg_clstr == kFALSE) && (!std::isnan(fcrdccal[i]))) {
264  flg_clstr = kTRUE;
265  iclstr = iclstr + 1;
266  clstr[iclstr][0] = i; // leading edge
267  clstr[iclstr][1] = -1; // trailing edge (tentative)
268  maxchg[iclstr] = fcrdccal[i];
269  maxpad[iclstr] = i; // Added by sam 3/19/2015 maybe is a good thing
270  } else if ((flg_clstr == kTRUE) && (!std::isnan(fcrdccal[i]))) {
271  if (fcrdccal[i] > maxchg[iclstr]) {
272  maxchg[iclstr] = fcrdccal[i];
273  maxpad[iclstr] = i;
274  }
275  } else if ((flg_clstr == kTRUE) && (std::isnan(fcrdccal[i]))) {
276  flg_clstr = kFALSE;
277  clstr[iclstr][1] = i - 1;
278  clstr[iclstr][2] = i - clstr[iclstr][0];
279  // if (maxpad[iclstr] < qmax) {
280  if (maxchg[iclstr] < qmax) { // As pointed out by Sasano-san 2015/3/9
281  iclstr = iclstr - 1;
282  }
283  }
284  }
285 
286  // if a cluster is located at the end of the cathode
287  if (flg_clstr == kTRUE) {
288  clstr[iclstr][1] = S800_FP_CRDC_CHANNELS - 1;
289  clstr[iclstr][2] = S800_FP_CRDC_CHANNELS - clstr[iclstr][0];
290  }
291 
292  if (iclstr == 0) {
293  // There is only one possible good cluster. Use that one
294  gclstr = 0;
295  } else if (iclstr > 0) {
296  // There is more than one possible good cluster.
297 
298  /*********************************************************************
299  NOTE: MAY HAVE TO THROW ALWAY EVENTS WITH MORE THAN ONE CLUSTER
300  **********************************************************************/
301 
302  // Will use the largest one
303 
304  tmp_qmax = maxchg[0];
305  // look for the GOOD cluster (gclstr) to be used to the analysis
306  // (the cluster with the max charge is used)
307  for (Int_t i = 0; i < iclstr + 1; i++) {
308  if (maxchg[i] > tmp_qmax) {
309  tmp_qmax = maxchg[i];
310  gclstr = i;
311  }
312  }
313  } else {
314  // NO Clusters have been found return NAN
315  return sqrt(-1.0);
316  }
317 
318  fcrdc.SetMaxChg((Float_t)maxchg[gclstr]);
319  fcrdc.SetMaxPad((Float_t)maxpad[gclstr]);
320  fcrdc.SetNumClusters(iclstr + 1); // iclstr is 0 when there is 1 cluster
321  fcrdc.SetMaxClusterWidth(clstr[gclstr][2]);
322 
323  Int_t j = 0;
324  Double_t xpad[S800_FP_CRDC_CHANNELS], qcal[S800_FP_CRDC_CHANNELS]; // (I know this is too many...)
325  Float_t sum_q = 0.0, sum_qx = 0.0, sum_qxx = 0.0;
326 
327  for (UShort_t i = clstr[gclstr][0]; i <= clstr[gclstr][1]; i++) {
328  if (IsBad(i, fcrdc.GetID()))
329  continue;
330  if (fcrdccal[i] < qthr)
331  continue;
332  sum_q += fcrdccal[i];
333  sum_qx += fcrdccal[i] * i;
334  sum_qxx += fcrdccal[i] * i * i;
335  // for fit
336  xpad[j] = (Double_t)i;
337  qcal[j] = (Double_t)fcrdccal[i];
338  // debug
339  // std::cout << j << " " << xpad[j] << " " << qcal[j] << std::endl;
340  j++;
341  }
342 
343  fcrdc.SetXpad(xpad, j);
344  fcrdc.SetYpad(qcal, j);
345 
346  Double_t xcog = (Double_t)sum_qx / sum_q;
347  auto sigma = (Double_t)TMath::Sqrt(sum_qxx / sum_q - (sum_qx / sum_q) * (sum_qx / sum_q));
348  if (xcog < 0 || xcog > S800_FP_CRDC_CHANNELS) { // no gravity center found
349  xcog = sqrt(-1.0);
350  std::cout << "Something strange happens with the CRDC data." << std::endl;
351  }
352  fcrdc.SetXcog((Float_t)xcog);
353  fcrdc.SetCathode((Float_t)sum_q);
354 
355  if (fSett->XFit()) {
356 
357  // Do fit
358  Double_t xfit;
359  Double_t par[3];
360  Int_t n_par = 3; // number of parameters in model function f
361 
362  lm_status_struct status;
364  control.printflags = 0; // monitor status (+1) and parameters (+2)
365 
366  // Initial guess
367  par[0] = (Double_t)maxchg[gclstr];
368  par[1] = xcog;
369  par[2] = sigma;
370 
371  if (fSett->XFitFunc() == 1) {
372  // Secant Hyperbolic Squared
373  lmcurve_fit(n_par, par, j, xpad, qcal, sechs, &control, &status);
374  } else if (fSett->XFitFunc() == 2) {
375  // gaussian
376  // lmcurve_fit( n_par, par, j, xpad, qcal, gauss, &control, &status );
377  }
378 
379  xfit = par[1];
380  fcrdc.SetXfit((Float_t)xfit);
381  fcrdc.SetFitPrm(0, (Float_t)par[0]);
382  fcrdc.SetFitPrm(1, (Float_t)par[1]);
383  fcrdc.SetFitPrm(2, (Float_t)par[2]);
384  fcrdc.SetFnorm(status.fnorm);
385  return (Float_t)xfit;
386  }
387 
388  // If we do not do fit, return xcog
389  return (Float_t)xcog;
390 }
391 
392 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^will be removed^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
393 
394 Float_t S800Calibration::CalcX2(CRDC *theCRDC)
395 {
396 
397  vector<Float_t> theCalibratedPads = theCRDC->GetCal();
398  vector<Float_t> thePedSubtractedPads = theCRDC->GetPedSubtractedPads();
399  // Cluster search
400  Bool_t flg_clstr = kFALSE;
401  Int_t iclstr = -1; // Counter keeping track of the clusters. Used as the first index in clstr[][]
402  const Int_t maxclstr = S800_FP_CRDC_CHANNELS;
403  // maximum number of clusters (I know this is too many...)
404  Int_t clstr[maxclstr][3]; // clstr[][0] is left edge clstr[][1] right edge clstr[][2] is width
405  Float_t maxchg[maxclstr]; // Array holding the max charge of each cluster
406  Float_t maxpad[maxclstr]; // Array holding the pad of the max charge of each cluster
407  const Float_t qmax = 25.; // MINUMUM value of max charge
408  // to be considered to form a cluster
409  const Float_t qthr = 8.; // MINUMUM value of charge to be considered to be hit
410 
411  Int_t gclstr = 0;
412 
413  for (UShort_t i = 0; i < S800_FP_CRDC_CHANNELS; i++) {
414  if (IsBad(i, theCRDC->GetID()))
415  continue;
416 
417  if ((flg_clstr == kFALSE) && (!std::isnan(theCalibratedPads[i]))) {
418  flg_clstr = kTRUE;
419  iclstr = iclstr + 1; // iclstr starts at -1
420  clstr[iclstr][0] = i; // leading edge
421  clstr[iclstr][1] = -1; // trailing edge (tentative)
422  maxchg[iclstr] = theCalibratedPads[i];
423  maxpad[iclstr] = i; // Added by sam 3/19/2015 maybe is a good thing
424  } else if ((flg_clstr == kTRUE) && (!std::isnan(theCalibratedPads[i]))) {
425  if (theCalibratedPads[i] > maxchg[iclstr]) {
426  maxchg[iclstr] = theCalibratedPads[i];
427  maxpad[iclstr] = i;
428  }
429  } else if ((flg_clstr == kTRUE) && (std::isnan(theCalibratedPads[i]))) {
430  // the previous point should be the end of the cluster as we have reached another NAN
431  flg_clstr = kFALSE; // Reset flag
432  clstr[iclstr][1] = i - 1; // set right edge of cluster
433  clstr[iclstr][2] = i - clstr[iclstr][0]; // Set width of cluster
434  // if (maxpad[iclstr] < qmax) {
435  if (maxchg[iclstr] < qmax) { // As pointed out by Sasano-san 2015/3/9
436  // check to see if this cluster had a large enough maximum charge.
437  // if it didn't decrement iclster so that the entry in clstr[][] is
438  // overwritten
439  iclstr = iclstr - 1;
440  }
441  }
442  }
443 
444  // if a cluster is located at the end of the cathode
445  if (flg_clstr == kTRUE) {
446  // flg_clstr == kTRUE means that the above search never found NAN
447  // after it found a cluster. IE it is at the end of the pad plane
448  clstr[iclstr][1] = S800_FP_CRDC_CHANNELS - 1;
449  clstr[iclstr][2] = S800_FP_CRDC_CHANNELS - clstr[iclstr][0];
450  }
451 
452  // gclstr is the index of the "good" cluster in clstr[][]
453  if (iclstr == 0) {
454  // There is only one possible good cluster. Use that one
455  gclstr = 0;
456  } else if (iclstr > 0) {
457  // There is more than one possible good cluster.
458  Float_t tmp_qmax = 0.0;
459  /*********************************************************************
460  NOTE: MAY HAVE TO THROW ALWAY EVENTS WITH MORE THAN ONE CLUSTER
461  **********************************************************************/
462 
463  // When there is more than one good cluster this function will use the largest
464  // one
465 
466  tmp_qmax = maxchg[0];
467  // look for the GOOD cluster (gclstr) to be used to the analysis
468  // (the cluster with the max charge is used)
469  for (Int_t i = 0; i < iclstr + 1; i++) {
470  if (maxchg[i] > tmp_qmax) {
471  tmp_qmax = maxchg[i];
472  gclstr = i;
473  }
474  }
475  } else {
476  // NO Clusters have been found return NAN
477  return sqrt(-1.0);
478  }
479 
480  theCRDC->SetMaxChg((Float_t)maxchg[gclstr]);
481  theCRDC->SetMaxPad((Float_t)maxpad[gclstr]);
482  theCRDC->SetNumClusters(iclstr + 1); // iclstr is 0 when there is 1 cluster
483  theCRDC->SetMaxClusterWidth(clstr[gclstr][2]);
484 
485  Int_t j = 0;
486  Double_t xpad[S800_FP_CRDC_CHANNELS], qcal[S800_FP_CRDC_CHANNELS]; // (I know this is too many...)
487  Float_t sum_q = 0.0, sum_qx = 0.0, sum_qxx = 0.0;
488 
489  // clstr[][0] is left edge clstr[][1] right edge clstr[][2] is width
490  for (UShort_t i = clstr[gclstr][0]; i <= clstr[gclstr][1]; i++) {
491  if (IsBad(i, theCRDC->GetID()))
492  continue;
493  if (theCalibratedPads[i] < qthr)
494  continue;
495  // if (thePedSubtractedPads[i] < 90) continue;
496  sum_q += theCalibratedPads[i];
497  sum_qx += theCalibratedPads[i] * i;
498  sum_qxx += theCalibratedPads[i] * i * i;
499  // for fit
500  xpad[j] = (Double_t)i;
501  qcal[j] = (Double_t)theCalibratedPads[i];
502  // debug
503  // std::cout << j << " " << xpad[j] << " " << qcal[j] << std::endl;
504  j++;
505  }
506 
507  // fcrdc.SetXpad(xpad,j);
508  // fcrdc.SetYpad(qcal,j);
509 
510  Double_t xcog = (Double_t)sum_qx / sum_q;
511  auto sigma = (Double_t)TMath::Sqrt(sum_qxx / sum_q - (sum_qx / sum_q) * (sum_qx / sum_q));
512  if (xcog < 0 || xcog > S800_FP_CRDC_CHANNELS) { // no gravity center found
513  xcog = sqrt(-1.0);
514  std::cout << "Something strange happens with the CRDC data." << std::endl;
515  }
516 
517  theCRDC->SetXcog((Float_t)xcog);
518  theCRDC->SetCathode((Float_t)sum_q);
519 
520  if (fSett->XFit()) {
521 
522  // Do fit
523  Double_t xfit;
524  Double_t par[3];
525  Int_t n_par = 3; // number of parameters in model function f
526 
527  lm_status_struct status;
529  control.printflags = 0; // monitor status (+1) and parameters (+2)
530 
531  // Initial guess
532  par[0] = (Double_t)maxchg[gclstr];
533  par[1] = xcog;
534  par[2] = sigma;
535 
536  // sechs is a function defined in lmfit.h
537  // xpad and qcal are pad numbers and charges for the "good" cluster
538  if (fSett->XFitFunc() == 1) {
539  // Secant Hyperbolic Squared
540  lmcurve_fit(n_par, par, j, xpad, qcal, sechs, &control, &status);
541  } else if (fSett->XFitFunc() == 2) {
542  // gaussian
543  // lmcurve_fit( n_par, par, j, xpad, qcal, gauss, &control, &status );
544  }
545 
546  xfit = par[1]; // the [1] parameter is the position
547  theCRDC->SetXfit((Float_t)xfit);
548  theCRDC->SetFitPrm(0, (Float_t)par[0]);
549  theCRDC->SetFitPrm(1, (Float_t)par[1]);
550  theCRDC->SetFitPrm(2, (Float_t)par[2]);
551  theCRDC->SetFnorm(status.fnorm);
552  return (Float_t)xfit;
553  }
554 
555  // If we do not do fit, return xcog
556  return (Float_t)xcog;
557 }
558 
559 Float_t S800Calibration::TimeOffset(Float_t time1, Float_t time2)
560 {
561  return time1 - time2;
562 }
563 
564 Float_t S800Calibration::TimeOffset(Float_t time)
565 {
566  return time - fts800;
567 }
568 
570 {
571  ftof.Set(TimeOffset(tof->GetRF()), TimeOffset(tof->GetOBJ()), TimeOffset(tof->GetXFP()));
572  ftof.SetTAC(tof->GetTACOBJ(), tof->GetTACXFP());
573 }
574 
575 void S800Calibration::ReadICCalibration(const char *filename)
576 {
577  auto iccal = std::make_unique<TEnv>(filename);
578  for (int i = 0; i < S800_FP_IC_CHANNELS; i++) {
579  fICoffset[i] = iccal->GetValue(Form("IonChamber.Offset.%d", i), 0.0);
580  fICslope[i] = iccal->GetValue(Form("IonChamber.Slope.%d", i), 1.0);
581  }
582  fde_slope = iccal->GetValue("IonChamber.Slope.DE", 1.0);
583  fde_offset = iccal->GetValue("IonChamber.Offset.DE", 0.0);
584 }
585 
586 std::vector<Float_t> S800Calibration::ICCal(std::vector<int> chan, std::vector<float> raw)
587 {
588  std::vector<Float_t> cal;
589  cal.resize(S800_FP_IC_CHANNELS);
590  if (chan.size() != raw.size()) {
591  std::cerr << " channel (" << chan.size() << ") and data (" << raw.size() << " have different sizes " << std::endl;
592  return cal;
593  }
594  for (unsigned int f = 0; f < chan.size(); f++) {
595  if ((chan[f] > -1) && (chan[f] < S800_FP_IC_CHANNELS)) {
596  cal[chan[f]] = raw[f] * fICslope[chan[f]] + fICoffset[chan[f]];
597  } else {
598  std::cerr << " channel " << chan[f] << " not found!" << std::endl;
599  }
600  }
601  return cal;
602 }
603 Float_t S800Calibration::ICSum(std::vector<Float_t> cal)
604 {
605  Short_t ch = 0;
606  Float_t sum = 0;
607  for (float j : cal) {
608  if (j > 0) {
609  sum += j;
610  ch++;
611  }
612  }
613  if (ch > 0)
614  sum /= ch;
615  else
616  sum = sqrt(-1.0);
617 
618  return sum;
619 }
620 Float_t S800Calibration::ICDE(Float_t sum, Float_t x, Float_t y)
621 {
622  // something needs to be done...
623  // if(!isnan(sum) && !isnan(ftrack.GetAFP())){
624  // if(!isnan(y))
625  // sum += sum*fSett->dE_ytilt()*y;
626  // if(!isnan(x) && x < fSett->dE_x0tilt())
627  // sum *= exp(fSett->dE_xtilt()* (fSett->dE_x0tilt() -x) );
628  // fs800valid = 0;
629  // return sum * fde_slope + fde_offset;
630  // }
631  // else return sqrt(-1.0);
632  return sum;
633 }
634 
635 void S800Calibration::MakeCalibratedCRDC(CRDC *theCRDC, std::vector<Short_t> channels, std::vector<Short_t> data,
636  Float_t tac, Float_t anode, Int_t id)
637 {
638 
639  theCRDC->Clear(); // Clear the object being passed in
640  theCRDC->SetID(id);
641  vector<Float_t> PedSubtractedPads;
642  // Sets a vector in the CRDC object that stores the calibrated pad values.
643  vector<Float_t> calibratedPads = GetCalibratedCrdcPads(channels, data, id, PedSubtractedPads);
644 
645  theCRDC->SetCal(calibratedPads);
646  theCRDC->SetPedSubtractedPads(PedSubtractedPads);
647 
648  // this->CrdcCal(channel,data,id);
649  // fcrdc.SetCal(fcrdccal);
650 
651  // cout<<"ID IS "<<id<<endl;
652  // for (int i=0;i<fcrdccal.size();i++){
653  // cout<<fcrdccal[i]<<" ";
654  // }cout<<endl;
655  // cin.get();
656 
657  // debug
658  // std::cout << "\n" << id << std::endl;
659  // for (int i = 0; i < channel.size(); i++) {
660  // std::cout << channel[i] << " " << data[i] << std::endl;
661  // }
662  double x = fSett->XOffset(id) + fSett->XSlope(id) * this->CalcX2(theCRDC);
663  double y = fSett->YOffset(id) + fSett->YSlope(id) * tac;
664 
665  // std::cout <<x<<" "<<y<<" "<<fSett->XOffset(id) << " " << fSett->XSlope(id) << std::endl;
666 
667  theCRDC->SetX(x);
668  theCRDC->SetY(y);
669  theCRDC->SetTAC(tac);
670  theCRDC->SetAnode(anode);
671 }
672 
674 {
675  // s800
676  TOF tof;
677  SCINT scint[3];
678  HODOSCOPE hodoscope[32];
679  IC ich;
680 
681  ich.Clear();
682  tof.Clear();
683  bool icgood = false;
684 
685  out->Clear();
686  out->SetTimeS800(in->GetTrigger()->GetS800());
687  SetTS800(in->GetTrigger()->GetS800());
688 
689  // timestamp
690  out->SetTS(in->GetTS());
691 
692  // TOF
693  tof.Clear();
694  this->SetTof(in->GetTimeOfFlight());
695  tof = this->GetTof();
696 
697  // Copy over the GTrigger Object
698  Trigger tempTrigger;
699  tempTrigger.Set(in->GetTrigger()->GetRegistr(), in->GetTrigger()->GetS800(), in->GetTrigger()->GetExternal1(),
700  in->GetTrigger()->GetExternal2(), in->GetTrigger()->GetSecondary());
701  out->SetTrigger(tempTrigger);
702 
703  // CRDC
704  for (UShort_t k = 0; k < 2; k++) {
705  MakeCalibratedCRDC(out->GetCRDC(k), in->GetCrdc(k)->GetChannels(), in->GetCrdc(k)->GetData(),
706  in->GetCrdc(k)->GetTAC(), in->GetCrdc(k)->GetAnode(), k);
707  }
708 
709  // SCINTILLAtOR
710  for (UShort_t s = 0; s < 3; s++) {
711  scint[s].Clear();
712  scint[s].SetTime(TimeOffset(in->GetScintillator(s)->GetTime_up()),
714  scint[s].SetDE(in->GetScintillator(s)->GetDE_up(), in->GetScintillator(s)->GetDE_down());
715  }
716 
717  // HODOSCOPE
718  for (UShort_t s = 0; s < 32; s++) {
719  hodoscope[s].Clear();
720  hodoscope[s].SetEnergy(in->GetHodoscope(s)->GetEnergy());
721  }
722 
723  // IC
724  ich.SetCal(ICCal(in->GetIonChamber()->GetChannels(), in->GetIonChamber()->GetData()));
725  ich.SetSum(ICSum(ich.GetCal()));
726  // Removed because icgood was never read/used
727  /*if (ich.GetSum() > 400) {
728  icgood = true;
729  }
730  */
731  // ich.SetDE(ICDE(ich.GetSum(), crdc[0].GetX(), crdc[0].GetY()));
732 
733  // set Calculated S800
734  out->SetTOF(tof);
735  for (UShort_t s = 0; s < 3; s++) {
736  out->SetSCINT(scint[s], s);
737  }
738  for (UShort_t s = 0; s < 32; s++) {
739  out->SetHODOSCOPE(hodoscope[s], s);
740  }
741  out->SetIC(ich);
742 
743  // There is no calibration to do for the MultiHit TDC
744  // Just copy the information from the Raw S800 object
745  // into the S800Calc object
746  MultiHitTOF temp;
747 
748  temp.fE1Up = in->GetMultiHitTOF()->fE1Up;
749  temp.fE1Down = in->GetMultiHitTOF()->fE1Down;
750  temp.fXf = in->GetMultiHitTOF()->fXf;
751  temp.fObj = in->GetMultiHitTOF()->fObj;
752  temp.fGalotte = in->GetMultiHitTOF()->fGalotte;
753  temp.fRf = in->GetMultiHitTOF()->fRf;
754  temp.fHodoscope = in->GetMultiHitTOF()->fHodoscope;
755 
756  out->SetMultiHitTOF(temp);
757 }
lmmin.h
S800::GetTS
long long int GetTS()
Definition: S800.h:365
GMultiHitTOF::fXf
vector< Float_t > fXf
Definition: S800.h:295
GHodoscope::GetEnergy
Float_t GetEnergy()
Definition: S800.h:177
S800Calibration::ICDE
Float_t ICDE(Float_t sum, Float_t x, Float_t y)
Definition: S800Calibration.cxx:620
IC::Clear
void Clear(Option_t *="")
Definition: S800Calc.h:360
CRDC::SetFnorm
void SetFnorm(Float_t fnorm)
Definition: S800Calc.h:97
S800::GetCrdc
GCrdc * GetCrdc(int id)
Definition: S800.h:364
S800_FP_IC_CHANNELS
#define S800_FP_IC_CHANNELS
Definition: S800defs.h:46
S800Calibration::CalcX2
Float_t CalcX2(CRDC *theCRDC)
Definition: S800Calibration.cxx:394
MultiHitTOF::fXf
vector< Float_t > fXf
Definition: S800Calc.h:272
MultiHitTOF::fRf
vector< Float_t > fRf
Definition: S800Calc.h:275
MultiHitTOF::fHodoscope
vector< Float_t > fHodoscope
Definition: S800Calc.h:276
GTimeOfFlight
Definition: S800.h:22
S800Calibration::CrdcCal
void CrdcCal(std::vector< Short_t > channel, std::vector< Short_t > data, Int_t id)
Definition: S800Calibration.cxx:124
MultiHitTOF
Definition: S800Calc.h:197
S800Settings::CalFile
const char * CalFile()
Definition: S800Settings.h:30
TOF
Definition: S800Calc.h:147
MultiHitTOF::fObj
vector< Float_t > fObj
Definition: S800Calc.h:273
lm_control_struct
Definition: lmmin.h:23
IC::SetCal
void SetCal(std::vector< Float_t > cal)
Definition: S800Calc.h:367
S800Calibration::ReadCrdcCalibration
void ReadCrdcCalibration(const char *filename, const char *pedestalfile)
Definition: S800Calibration.cxx:72
CRDC::SetY
void SetY(Float_t y)
Definition: S800Calc.h:88
S800::GetScintillator
GScintillator * GetScintillator(int id)
Definition: S800.h:361
S800Settings::XSlope
Float_t XSlope(int ch)
Definition: S800Settings.h:27
S800Calc
Definition: S800Calc.h:455
S800Calibration::S800Calibration
S800Calibration()
Definition: S800Calibration.cxx:20
f
double(* f)(double t, const double *par)
Definition: lmcurve.cxx:21
S800Calibration::ReadICCalibration
void ReadICCalibration(const char *filename)
Definition: S800Calibration.cxx:575
GTrigger::GetSecondary
Short_t GetSecondary()
Definition: S800.h:107
S800Calibration::SetTS800
void SetTS800(Short_t ts800)
Definition: S800Calibration.h:87
S800Settings.h
CRDC::SetCal
void SetCal(const std::vector< Float_t > &cal)
Definition: S800Calc.h:61
S800Settings::YSlope
Float_t YSlope(int ch)
Definition: S800Settings.h:29
GTrigger::GetExternal2
Short_t GetExternal2()
Definition: S800.h:106
lm_status_struct
Definition: lmmin.h:35
S800_FP_CRDC_CHANNELS
#define S800_FP_CRDC_CHANNELS
Definition: S800defs.h:43
CRDC::SetYpad
void SetYpad(Double_t ypad[300], Int_t j)
Definition: S800Calc.h:78
S800Calibration::TimeOffset
Float_t TimeOffset(Float_t time1, Float_t time2)
Definition: S800Calibration.cxx:559
CRDC::SetXcog
void SetXcog(Float_t x_cog)
Definition: S800Calc.h:89
CRDC::SetID
void SetID(int id)
Definition: S800Calc.h:86
SCINT::SetTime
void SetTime(Float_t tup, Float_t tdown)
Definition: S800Calc.h:304
GMultiHitTOF::fHodoscope
vector< Float_t > fHodoscope
Definition: S800.h:299
CRDC::GetCal
std::vector< Float_t > GetCal()
Definition: S800Calc.h:112
HODOSCOPE::Clear
void Clear(Option_t *="")
Definition: S800Calc.h:337
sechs
double sechs(double x, const double *p)
Definition: lmfit.cxx:15
CRDC::GetID
Int_t GetID()
Definition: S800Calc.h:104
lm_control_struct::printflags
int printflags
Definition: lmmin.h:31
Trigger::Set
void Set(int registr, int s800, int external1, int external2, int secondary)
Definition: S800Calc.h:418
GIonChamber::GetChannels
std::vector< int > GetChannels()
Definition: S800.h:207
lmfit.h
GTrigger::GetExternal1
Short_t GetExternal1()
Definition: S800.h:105
S800Calibration::IsBad
bool IsBad(int ch, int CrdcId)
Definition: S800Calibration.h:31
S800Calc::SetTimeS800
void SetTimeS800(Float_t time)
Definition: S800Calc.h:477
CRDC::SetXpad
void SetXpad(Double_t xpad[300], Int_t j)
Definition: S800Calc.h:72
HODOSCOPE::SetEnergy
void SetEnergy(Float_t energy)
Definition: S800Calc.h:341
MultiHitTOF::fGalotte
vector< Float_t > fGalotte
Definition: S800Calc.h:274
S800defs.h
TOF::Clear
void Clear(Option_t *="")
Definition: S800Calc.h:159
S800Calc::SetSCINT
void SetSCINT(SCINT scint, int id)
Definition: S800Calc.h:481
S800Calibration::S800Calculate
void S800Calculate(S800 *in, S800Calc *out)
Definition: S800Calibration.cxx:673
S800Calc::SetTS
void SetTS(long long int ts)
Definition: S800Calc.h:500
GTimeOfFlight::GetTACOBJ
Short_t GetTACOBJ()
Definition: S800.h:59
S800Calc::SetIC
void SetIC(IC ic)
Definition: S800Calc.h:480
CRDC
Definition: S800Calc.h:21
CRDC::SetX
void SetX(Float_t x)
Definition: S800Calc.h:87
S800::GetHodoscope
GHodoscope * GetHodoscope(int id)
Definition: S800.h:363
GMultiHitTOF::fGalotte
vector< Float_t > fGalotte
Definition: S800.h:297
GTimeOfFlight::GetTACXFP
Short_t GetTACXFP()
Definition: S800.h:60
CRDC::SetPedSubtractedPads
void SetPedSubtractedPads(vector< Float_t > v)
Definition: S800Calc.h:85
GMultiHitTOF::fObj
vector< Float_t > fObj
Definition: S800.h:296
SCINT
Definition: S800Calc.h:282
S800
Definition: S800.h:338
CRDC::SetXfit
void SetXfit(Float_t x_fit)
Definition: S800Calc.h:90
GTimeOfFlight::GetXFP
Short_t GetXFP()
Definition: S800.h:57
S800Calibration::GetCalibratedCrdcPads
std::vector< Float_t > GetCalibratedCrdcPads(std::vector< Short_t > channels, std::vector< Short_t > data, Int_t id, vector< Float_t > &PedSubtractedPads)
Definition: S800Calibration.cxx:161
S800Calibration::~S800Calibration
~S800Calibration()
Definition: S800Calibration.cxx:58
S800::GetIonChamber
GIonChamber * GetIonChamber()
Definition: S800.h:362
S800Calc::Clear
void Clear(Option_t *="")
Definition: S800Calc.h:459
S800Settings::XOffset
Float_t XOffset(int ch)
Definition: S800Settings.h:26
GMultiHitTOF::fE1Up
vector< Float_t > fE1Up
Definition: S800.h:293
y
const double * y
Definition: lmcurve.cxx:20
CRDC::Clear
void Clear(Option_t *="")
Definition: S800Calc.h:43
GTimeOfFlight::GetRF
Short_t GetRF()
Definition: S800.h:55
S800Calc::SetHODOSCOPE
void SetHODOSCOPE(HODOSCOPE hodoscope, int id)
Definition: S800Calc.h:482
S800Settings::PedestalFile
const char * PedestalFile()
Definition: S800Settings.h:31
S800Calibration::ICSum
Float_t ICSum(std::vector< Float_t > cal)
Definition: S800Calibration.cxx:603
IC
Definition: S800Calc.h:350
GScintillator::GetTime_up
Float_t GetTime_up()
Definition: S800.h:155
S800Calibration::SetCrdc
void SetCrdc(std::vector< Short_t > channel, std::vector< Short_t > data, Float_t tac, Float_t anode, Int_t id)
Definition: S800Calibration.cxx:216
Trigger
Definition: S800Calc.h:399
GCrdc::GetChannels
std::vector< Short_t > GetChannels()
Definition: S800.h:258
CRDC::GetPedSubtractedPads
std::vector< Float_t > & GetPedSubtractedPads()
Definition: S800Calc.h:121
GMultiHitTOF::fRf
vector< Float_t > fRf
Definition: S800.h:298
lmcurve_fit
void lmcurve_fit(int n_par, double *par, int m_dat, const double *t, const double *y, double(*f)(double t, const double *par), const lm_control_struct *control, lm_status_struct *status)
Definition: lmcurve.cxx:33
S800Calc::SetTrigger
void SetTrigger(Trigger in)
Definition: S800Calc.h:485
S800Settings::XFit
int XFit()
Definition: S800Settings.h:24
SCINT::SetDE
void SetDE(Float_t de_up, Float_t de_down)
Definition: S800Calc.h:310
GTimeOfFlight::GetOBJ
Short_t GetOBJ()
Definition: S800.h:56
GScintillator::GetDE_up
Float_t GetDE_up()
Definition: S800.h:154
GCrdc::GetData
std::vector< Short_t > GetData()
Definition: S800.h:256
S800Settings::CalFileIC
const char * CalFileIC()
Definition: S800Settings.h:33
MultiHitTOF::fE1Down
vector< Float_t > fE1Down
Definition: S800Calc.h:271
S800Calibration::ReadCrdcBadPads
void ReadCrdcBadPads(const char *filename)
Definition: S800Calibration.cxx:104
S800Calc::GetCRDC
CRDC * GetCRDC(int id)
Definition: S800Calc.h:489
S800Calibration::ICCal
std::vector< Float_t > ICCal(std::vector< int > chan, std::vector< float > raw)
Definition: S800Calibration.cxx:586
GTrigger::GetRegistr
Short_t GetRegistr()
Definition: S800.h:103
SCINT::Clear
void Clear(Option_t *="")
Definition: S800Calc.h:292
S800Calibration::CalcX
Float_t CalcX()
Definition: S800Calibration.cxx:243
CRDC::SetTAC
void SetTAC(float tac)
Definition: S800Calc.h:91
GScintillator::GetTime_down
Float_t GetTime_down()
Definition: S800.h:157
S800.h
CRDC::SetMaxPad
void SetMaxPad(Short_t maxpad)
Definition: S800Calc.h:94
CRDC::SetNumClusters
void SetNumClusters(Int_t n)
Definition: S800Calc.h:98
S800::GetTrigger
GTrigger * GetTrigger()
Definition: S800.h:360
lmcurve.h
GMultiHitTOF::fE1Down
vector< Float_t > fE1Down
Definition: S800.h:294
S800Settings
Definition: S800Settings.h:13
S800Calibration::SetTof
void SetTof(GTimeOfFlight *tof)
Definition: S800Calibration.cxx:569
S800Calc::SetMultiHitTOF
void SetMultiHitTOF(MultiHitTOF f)
Definition: S800Calc.h:484
GIonChamber::GetData
std::vector< float > GetData()
Definition: S800.h:208
S800Settings::BadFile
const char * BadFile()
Definition: S800Settings.h:32
IC::SetSum
void SetSum(Float_t sum)
Definition: S800Calc.h:378
HODOSCOPE
Definition: S800Calc.h:333
IC::GetCal
std::vector< Float_t > GetCal()
Definition: S800Calc.h:383
TOF::Set
void Set(Float_t rf, Float_t obj, Float_t xfp)
Definition: S800Calc.h:169
S800Settings::YOffset
Float_t YOffset(int ch)
Definition: S800Settings.h:28
TOF::SetTAC
void SetTAC(Float_t obj, Float_t xfp)
Definition: S800Calc.h:175
lm_control_double
const lm_control_struct lm_control_double
Definition: lmmin.cxx:58
S800Calc::SetTOF
void SetTOF(TOF tof)
Definition: S800Calc.h:479
S800::GetTimeOfFlight
GTimeOfFlight * GetTimeOfFlight()
Definition: S800.h:359
GCrdc::GetAnode
Float_t GetAnode()
Definition: S800.h:254
S800::GetMultiHitTOF
GMultiHitTOF * GetMultiHitTOF()
Definition: S800.h:371
S800Calibration::GetTof
TOF GetTof()
Definition: S800Calibration.h:80
S800Settings::XFitFunc
int XFitFunc()
Definition: S800Settings.h:25
CRDC::SetMaxChg
void SetMaxChg(Float_t maxchg)
Definition: S800Calc.h:95
S800Calibration::MakeCalibratedCRDC
void MakeCalibratedCRDC(CRDC *theCRDC, std::vector< Short_t > channels, std::vector< Short_t > data, Float_t tac, Float_t anode, Int_t id)
Definition: S800Calibration.cxx:635
GTrigger::GetS800
Short_t GetS800()
Definition: S800.h:104
S800Calibration.h
c
constexpr auto c
Definition: AtRadialChargeModel.cxx:20
lm_status_struct::fnorm
double fnorm
Definition: lmmin.h:36
GScintillator::GetDE_down
Float_t GetDE_down()
Definition: S800.h:156
MultiHitTOF::fE1Up
vector< Float_t > fE1Up
Definition: S800Calc.h:270
CRDC::SetCathode
void SetCathode(float cathode)
Definition: S800Calc.h:93
CRDC::SetMaxClusterWidth
void SetMaxClusterWidth(Float_t w)
Definition: S800Calc.h:99
CRDC::SetAnode
void SetAnode(float anode)
Definition: S800Calc.h:92
CRDC::SetFitPrm
void SetFitPrm(Short_t i, Float_t prm)
Definition: S800Calc.h:96
GCrdc::GetTAC
Float_t GetTAC()
Definition: S800.h:255