16 const char * dir = getenv(
"VMCWORKDIR");
19 Error(__func__,
"No ECAL in run %lu\n", runId);
30 else if (runId < 5186) {
32 if (runId < 3503) pos = 2;
33 else if (runId < 3514) pos = 1;
34 else if (runId < 3589) pos = 2;
35 else if (runId < 4153) pos = 3;
36 else if (runId < 4307) pos = 4;
37 else if (runId < 4906) pos = 5;
38 else if (runId < 4976) pos = 4;
43 TString map = TString::Format(
"%s/input/ECAL_map_period_%d.txt",dir,
run);
44 TString cal = TString::Format(
"%s/parameters/ecal/ECAL_calibration_run%d.txt",dir,
run);
45 TString geo = TString::Format(
"%s/geometry/ECAL_v3_run%d_pos%d.root",dir,
run,pos);
50 Error(__func__,
"Unable to determine ECAL position for runId %lu\n",runId);
63 if (fECALMapArray[chan].GetChan() != -1) {
64 fECALMapArray[chan].
Print();
67 printf(
"Pedestal: "); fPedestal.Print();
68 printf(
"Signal: "); fSignal.Print();
73 in.open(map_file_name);
76 Fatal(__func__,
"Loading ECAL Map from file: %s - file open error!\n", map_file_name);
79 Info(__func__,
"Loading ECAL Map from file: %s\n", map_file_name);
81 in >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy;
87 in >> std::hex >> adcId >> std::dec >> adcChan >> chan >> x >> y;
88 if (!in.good())
break;
89 if (adcId == 0 || adcChan == 0 || chan <= 0)
continue;
90 fECALMapArray[chan].
SetAdcMap(chan,adcId,adcChan);
98 in.open(calibr_file_name);
101 Fatal(__func__,
"Loading ECAL Calibration from file: %s - file open error!\n", calibr_file_name);
104 Info(__func__,
"Loading ECAL Calibration from file: %s\n", calibr_file_name);
106 in >> dummy >> dummy >> dummy >> dummy;
110 in >> chan >> coeff >> err;
111 if (!in.good())
break;
112 if (chan <= 0)
continue;
113 fECALMapArray[chan].
SetCoeff(chan,coeff);
120 TGeoVolume *top = TGeoVolume::Import(geo_file_name,
"TOP");
122 Fatal(__func__,
"Volume TOP not found in %s\n",geo_file_name);
125 TGeoNode * ecal = top->GetNode(0);
127 Fatal(__func__,
"Unexpected geometry %s\n",geo_file_name);
131 TGeoNode * ecal1 = ecal->GetDaughter(0);
133 Int_t n = ecal1->GetNdaughters();
135 Fatal(__func__,
"Expected ecal node 1 with 504 daughters or less in %s\n",geo_file_name);
138 for (Int_t
i = 0;
i < n;
i++) {
139 Int_t ch = ecal1->GetDaughter(
i)->GetNumber();
140 if (ch < 1 || ch > 504) {
141 Fatal(__func__,
"Unexpected chan=%d at ecal node 1 in %s\n",ch,geo_file_name);
144 fECALMapArray[ch].
SetCoords(ecal1->GetDaughter(
i),ecal1);
148 TGeoNode * ecal2 = ecal->GetDaughter(1);
150 Int_t n = ecal2->GetNdaughters();
152 Fatal(__func__,
"Expected ecal node 2 with 504 daughters or less in %s\n",geo_file_name);
155 for (Int_t
i = 0;
i < n;
i++) {
156 Int_t ch = ecal2->GetDaughter(
i)->GetNumber();
157 if (ch < 505 || ch > 1008) {
158 Fatal(__func__,
"Unexpected chan=%d at ecal node 2 in %s\n",ch,geo_file_name);
161 fECALMapArray[ch].
SetCoords(ecal2->GetDaughter(
i),ecal2);
170 Int_t N = data->GetEntriesFast();
171 for (Int_t
i = 0;
i < N;
i++) {
175 if (fECALMapArray[chan].GetChan() != chan)
continue;
179 UseNovosibirskFit(digit, chan, ecaldigit);
183Bool_t BmnECALRaw2Digit::UseNovosibirskFit(
BmnADCDigit* digit, Int_t chan, TClonesArray *ecaldigit) {
187 Float_t pedestal = 0.;
188 for (Int_t
i = fPedestal.sample0;
i < fPedestal.sample0 + fPedestal.samples;
i++) {
189 if (
i >= (Int_t)N)
return 0;
190 pedestal += (Float_t) s[
i];
193 pedestal /= fPedestal.samples;
194 if (pedestal < fPedestal.min || pedestal > fPedestal.max)
return 0;
200 Float_t scale = fECALMapArray[chan].
GetCoeff();
201 for (Int_t n = 0; n < (Int_t)N; n++)
208 }
else if (min_v ==
v) {
214 y = (y - pedestal) * scale;
215 graph.SetPoint(n, n, y);
218 if (min_v > fSignal.max || min_n - min_cnt < fSignal.sample0 || min_n > fSignal.sample0 + fSignal.samples) {
223 TF1 pFit(
"Novosibirsk", Novosibirsk, 0., N, 4);
224 pFit.SetParameters(min_v, 0.01, 5., min_n);
227 while (min_cnt-- > 0) {
228 graph.RemovePoint(min_n--);
231 graph.Fit(
"Novosibirsk",
"QR0",
"");
233 if (!gMinuit->fCstatu.EqualTo(
"CONVERGED "))
return kFALSE;
234 TF1 *pRes = graph.GetFunction(
"Novosibirsk");
236 Float_t Tp = pRes->GetMinimumX();
237 if (Tp < fSignal.sample0)
return kFALSE;
238 if (Tp > fSignal.sample0 + fSignal.samples)
return kFALSE;
240 Float_t Vp = pRes->GetMinimum();
243 Float_t To = pRes->GetX(0.5 * Vp, 0, Tp);
245 Float_t dVdT = pRes->Derivative(To);
246 if (dVdT >= 0)
return kFALSE;
248 To = To - 0.5 * Vp / dVdT;
250 if (To < fPedestal.sample0)
return kFALSE;
251 if (To > fSignal.sample0 + fSignal.samples)
return kFALSE;
253 Float_t V = pRes->Integral(To, To + fSignal.samples) / fSignal.samples;
256 ecal->
Set(fECALMapArray + chan, -V, -Vp, To, Tp);
261Double_t BmnECALRaw2Digit::Novosibirsk(Double_t* x, Double_t* p) {
267 if (TMath::Abs(tail) < 1.e-7)
268 return p[0] * TMath::Exp(-0.5 * TMath::Power(((x[0] - peak) / width), 2));
269 Double_t arg = 1.0 - (x[0] - peak) * tail / width;
270 if (arg < 1.e-6)
return 0.0;
272 Double_t
log = TMath::Log(arg);
273 static const Double_t xi = 2.3548200450309494;
274 Double_t width_zero = (2.0 / xi) * TMath::ASinH(tail * xi * 0.5);
275 Double_t width_zero2 = width_zero * width_zero;
276 Double_t exponent = (-0.5 / (width_zero2) * log * log) - (width_zero2 * 0.5);
278 return p[0] * TMath::Exp(exponent);
friend F32vec4 log(const F32vec4 &a)
UInt_t GetNSamples() const
UShort_t GetChannel() const
UShort_t * GetUShortValue() const
void Set(BmnECALMapElement *e, Float_t amp=0., Float_t peakAmp=0., Float_t startTime=0., Float_t peakTime=0.)
void SetCoords(TGeoNode *cell, TGeoNode *mother)
void SetCoeff(Int_t chan, Double_t coeff)
void SetAdcMap(Int_t chan, ULong_t adcId, UShort_t adcChan)
void fillEvent(TClonesArray *data, TClonesArray *ecaldigit)
Bool_t LoadCalibration(const char *calibr_file_name)
Bool_t LoadGeometry(const char *geo_file_name)
Bool_t LoadAdcMap(const char *map_file_name)
#define MAX_ECAL_CHANNELS