BmnRoot
Loading...
Searching...
No Matches
BmnECALRaw2Digit.cxx
Go to the documentation of this file.
1#include "BmnECALRaw2Digit.h"
2#include <TError.h>
3#include <TF1.h>
4#include <TMinuit.h>
5#include "TMath.h"
6#include "TSystem.h"
7#include "TBox.h"
8#include "TText.h"
9#include "TCanvas.h"
10#include "TRandom.h"
11#include <fstream>
12
13#define SHIFT 0
14
16 const char * dir = getenv("VMCWORKDIR");
17
18 if (runId < 1170) {
19 Error(__func__,"No ECAL in run %lu\n", runId);
20 return;
21 }
22
23 Int_t run = 0;
24 Int_t pos = 0;
25
26 if (runId < 2000) {
27 run = 6;
28 pos = 1;
29 }
30 else if (runId < 5186) {
31 run = 7;
32 if (runId < 3503) pos = 2; //2579..3500 - Pos. 2
33 else if (runId < 3514) pos = 1; //3503..3513 - Pos. 1
34 else if (runId < 3589) pos = 2; //3514..3588 - Pos. 2
35 else if (runId < 4153) pos = 3; //3589..4152 - Pos. 3
36 else if (runId < 4307) pos = 4; //4153..4305 - Pos. 4
37 else if (runId < 4906) pos = 5; //4307..4905 - Pos. 5
38 else if (runId < 4976) pos = 4; //4906..4972 - Pos. 4
39 else pos = 5; //4976..5184 - Pos. 5
40 }
41
42 if (run && pos) {
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);
46 LoadAdcMap(map.Data());
47 LoadCalibration(cal.Data());
48 LoadGeometry(geo.Data());
49 } else {
50 Error(__func__,"Unable to determine ECAL position for runId %lu\n",runId);
51 }
52}
53
54BmnECALRaw2Digit::BmnECALRaw2Digit(const char * map_file_name, const char * calibr_file_name, const char * geo_file_name) {
55 LoadAdcMap(map_file_name);
56 LoadCalibration(calibr_file_name);
57 LoadGeometry(geo_file_name);
58}
59
62 for (Int_t chan = 1; chan < MAX_ECAL_CHANNELS + 1; chan++) {
63 if (fECALMapArray[chan].GetChan() != -1) {
64 fECALMapArray[chan].Print();
65 }
66 }
67 printf("Pedestal: "); fPedestal.Print();
68 printf("Signal: "); fSignal.Print();
69}
70
71Bool_t BmnECALRaw2Digit::LoadAdcMap(const char* map_file_name) {
72 ifstream in;
73 in.open(map_file_name);
74 if (!in.is_open())
75 {
76 Fatal(__func__,"Loading ECAL Map from file: %s - file open error!\n", map_file_name);
77 return kFALSE;
78 }
79 Info(__func__,"Loading ECAL Map from file: %s\n", map_file_name);
80 TString dummy;
81 in >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy;
82 while (!in.eof()) {
83 ULong_t adcId;
84 UShort_t adcChan;
85 Int_t chan;
86 Float_t x, y;
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);
91 }
92 in.close();
93 return kTRUE;
94}
95
96Bool_t BmnECALRaw2Digit::LoadCalibration(const char* calibr_file_name) {
97 ifstream in;
98 in.open(calibr_file_name);
99 if (!in.is_open())
100 {
101 Fatal(__func__,"Loading ECAL Calibration from file: %s - file open error!\n", calibr_file_name);
102 return kFALSE;
103 }
104 Info(__func__,"Loading ECAL Calibration from file: %s\n", calibr_file_name);
105 TString dummy;
106 in >> dummy >> dummy >> dummy >> dummy;
107 while (!in.eof()) {
108 int chan;
109 float coeff, err;
110 in >> chan >> coeff >> err;
111 if (!in.good()) break;
112 if (chan <= 0) continue;
113 fECALMapArray[chan].SetCoeff(chan,coeff);
114 }
115 in.close();
116 return kTRUE;
117}
118
119Bool_t BmnECALRaw2Digit::LoadGeometry(const char* geo_file_name) {
120 TGeoVolume *top = TGeoVolume::Import(geo_file_name,"TOP");
121 if (!top) {
122 Fatal(__func__,"Volume TOP not found in %s\n",geo_file_name);
123 return kFALSE;
124 }
125 TGeoNode * ecal = top->GetNode(0);
126 if (!ecal) {
127 Fatal(__func__,"Unexpected geometry %s\n",geo_file_name);
128 return kFALSE;
129 }
130
131 TGeoNode * ecal1 = ecal->GetDaughter(0);
132 if (ecal1) {
133 Int_t n = ecal1->GetNdaughters();
134 if (n > 504) {
135 Fatal(__func__,"Expected ecal node 1 with 504 daughters or less in %s\n",geo_file_name);
136 return kFALSE;
137 }
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);
142 return kFALSE;
143 }
144 fECALMapArray[ch].SetCoords(ecal1->GetDaughter(i),ecal1);
145 }
146 }
147
148 TGeoNode * ecal2 = ecal->GetDaughter(1);
149 if (ecal2) {
150 Int_t n = ecal2->GetNdaughters();
151 if (n > 504) {
152 Fatal(__func__,"Expected ecal node 2 with 504 daughters or less in %s\n",geo_file_name);
153 return kFALSE;
154 }
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);
159 return kFALSE;
160 }
161 fECALMapArray[ch].SetCoords(ecal2->GetDaughter(i),ecal2);
162 }
163 }
164
165 return kTRUE;
166}
167
168
169void BmnECALRaw2Digit::fillEvent(TClonesArray *data, TClonesArray *ecaldigit) {
170 Int_t N = data->GetEntriesFast();
171 for (Int_t i = 0; i < N; i++) {
172 BmnADCDigit * digit = (BmnADCDigit*) data->At(i);
173 Int_t chan;
174 for (chan = 1; chan < MAX_ECAL_CHANNELS+1; chan++) {
175 if (fECALMapArray[chan].GetChan() != chan) continue;
176 if (fECALMapArray[chan].IsAdcMatch(digit->GetSerial(), digit->GetChannel())) break;
177 }
178 if (chan > MAX_ECAL_CHANNELS) continue;
179 UseNovosibirskFit(digit, chan, ecaldigit);
180 }
181}
182
183Bool_t BmnECALRaw2Digit::UseNovosibirskFit(BmnADCDigit* digit, Int_t chan, TClonesArray *ecaldigit) {
184 UInt_t N = digit->GetNSamples();
185 Short_t* s = (Short_t*)digit->GetUShortValue();
186
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];
191 }
192
193 pedestal /= fPedestal.samples;
194 if (pedestal < fPedestal.min || pedestal > fPedestal.max) return 0;
195
196 TGraph graph(N);
197 Int_t min_n = 0;
198 Int_t min_cnt = 0;
199 Short_t min_v = 0;
200 Float_t scale = fECALMapArray[chan].GetCoeff();
201 for (Int_t n = 0; n < (Int_t)N; n++)
202 {
203 Short_t v = s[n];
204 if (min_v > v) {
205 min_v = v;
206 min_n = n;
207 min_cnt = 1;
208 } else if (min_v == v) {
209 min_n = n;
210 min_cnt++;
211 }
212
213 Float_t y = v;
214 y = (y - pedestal) * scale;
215 graph.SetPoint(n, n, y);
216 }
217
218 if (min_v > fSignal.max || min_n - min_cnt < fSignal.sample0 || min_n > fSignal.sample0 + fSignal.samples) {
219 return 0;
220 }
221
222 // Initialize fitting function
223 TF1 pFit("Novosibirsk", Novosibirsk, 0., N, 4);
224 pFit.SetParameters(min_v, 0.01, 5., min_n);
225
226 // Remove points at the flat peak if any
227 while (min_cnt-- > 0) {
228 graph.RemovePoint(min_n--);
229 }
230
231 graph.Fit("Novosibirsk", "QR0", "");
232
233 if (!gMinuit->fCstatu.EqualTo("CONVERGED ")) return kFALSE;
234 TF1 *pRes = graph.GetFunction("Novosibirsk");
235
236 Float_t Tp = pRes->GetMinimumX();
237 if (Tp < fSignal.sample0) return kFALSE;
238 if (Tp > fSignal.sample0 + fSignal.samples) return kFALSE;
239
240 Float_t Vp = pRes->GetMinimum();
241 //if (Vp > fSignal.max || Vp < fSignal.min) return kFALSE;
242
243 Float_t To = pRes->GetX(0.5 * Vp, 0, Tp);
244
245 Float_t dVdT = pRes->Derivative(To);
246 if (dVdT >= 0) return kFALSE;
247
248 To = To - 0.5 * Vp / dVdT;
249
250 if (To < fPedestal.sample0) return kFALSE;
251 if (To > fSignal.sample0 + fSignal.samples) return kFALSE;
252
253 Float_t V = pRes->Integral(To, To + fSignal.samples) / fSignal.samples;
254
255 BmnECALDigit * ecal = (BmnECALDigit *) ecaldigit->ConstructedAt(ecaldigit->GetEntriesFast());
256 ecal->Set(fECALMapArray + chan, -V, -Vp, To, Tp);
257
258 return kTRUE;
259}
260
261Double_t BmnECALRaw2Digit::Novosibirsk(Double_t* x, Double_t* p) {
262 //As Defined in RooNovosibirsk.cxx
263 //If tail=eta=0 the Belle distribution becomes gaussia
264 double tail = p[1];
265 double width = p[2];
266 double peak = p[3];
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; //Argument of logaritem negative. Real continuation -> function equals zero
271
272 Double_t log = TMath::Log(arg);
273 static const Double_t xi = 2.3548200450309494; // 2 Sqrt( Ln(4) )
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);
277
278 return p[0] * TMath::Exp(exponent);
279}
280
__m128 v
Definition P4_F32vec4.h:1
int i
Definition P4_F32vec4.h:22
friend F32vec4 log(const F32vec4 &a)
Definition P4_F32vec4.h:123
UInt_t GetNSamples() const
Definition BmnADCDigit.h:35
UShort_t GetChannel() const
Definition BmnADCDigit.h:33
UInt_t GetSerial() const
Definition BmnADCDigit.h:31
UShort_t * GetUShortValue() const
Definition BmnADCDigit.h:37
void Set(BmnECALMapElement *e, Float_t amp=0., Float_t peakAmp=0., Float_t startTime=0., Float_t peakTime=0.)
Double_t GetCoeff()
static void PrintTitle()
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
-clang-format