BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnECALRaw2Digit.cxx
Go to the documentation of this file.
1#include "BmnECALRaw2Digit.h"
2
3#include "TBox.h"
4#include "TCanvas.h"
5#include "TMath.h"
6#include "TRandom.h"
7#include "TSystem.h"
8#include "TText.h"
9
10#include <TError.h>
11#include <TF1.h>
12#include <TMinuit.h>
13#include <fstream>
14
15#define SHIFT 0
16
17using namespace std;
18
20{
21 const char* dir = getenv("VMCWORKDIR");
22
23 if (runId < 1170) {
24 Error(__func__, "No ECAL in run %lu\n", runId);
25 return;
26 }
27
28 Int_t run = 0;
29 Int_t pos = 0;
30
31 if (runId < 2000) {
32 run = 6;
33 pos = 1;
34 } else if (runId < 5186) {
35 run = 7;
36 if (runId < 3503)
37 pos = 2; // 2579..3500 - Pos. 2
38 else if (runId < 3514)
39 pos = 1; // 3503..3513 - Pos. 1
40 else if (runId < 3589)
41 pos = 2; // 3514..3588 - Pos. 2
42 else if (runId < 4153)
43 pos = 3; // 3589..4152 - Pos. 3
44 else if (runId < 4307)
45 pos = 4; // 4153..4305 - Pos. 4
46 else if (runId < 4906)
47 pos = 5; // 4307..4905 - Pos. 5
48 else if (runId < 4976)
49 pos = 4; // 4906..4972 - Pos. 4
50 else
51 pos = 5; // 4976..5184 - Pos. 5
52 }
53
54 if (run && pos) {
55 TString map = TString::Format("%s/input/ECAL_map_period_%d.txt", dir, run);
56 TString cal = TString::Format("%s/parameters/ecal/ECAL_calibration_run%d.txt", dir, run);
57 TString geo = TString::Format("%s/geometry/ECAL_v3_run%d_pos%d.root", dir, run, pos);
58 LoadAdcMap(map.Data());
59 LoadCalibration(cal.Data());
60 LoadGeometry(geo.Data());
61 } else {
62 Error(__func__, "Unable to determine ECAL position for runId %lu\n", runId);
63 }
64}
65
66BmnECALRaw2Digit::BmnECALRaw2Digit(const char* map_file_name, const char* calibr_file_name, const char* geo_file_name)
67{
68 LoadAdcMap(map_file_name);
69 LoadCalibration(calibr_file_name);
70 LoadGeometry(geo_file_name);
71}
72
74{
76 for (Int_t chan = 1; chan < MAX_ECAL_CHANNELS + 1; chan++) {
77 if (fECALMapArray[chan].GetChan() != -1) {
78 fECALMapArray[chan].Print();
79 }
80 }
81 printf("Pedestal: ");
82 fPedestal.Print();
83 printf("Signal: ");
84 fSignal.Print();
85}
86
87Bool_t BmnECALRaw2Digit::LoadAdcMap(const char* map_file_name)
88{
89 ifstream in;
90 in.open(map_file_name);
91 if (!in.is_open()) {
92 Fatal(__func__, "Loading ECAL Map from file: %s - file open error!\n", map_file_name);
93 return kFALSE;
94 }
95 Info(__func__, "Loading ECAL Map from file: %s\n", map_file_name);
96 TString dummy;
97 in >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy;
98 while (!in.eof()) {
99 ULong_t adcId;
100 UShort_t adcChan;
101 Int_t chan;
102 Float_t x, y;
103 in >> std::hex >> adcId >> std::dec >> adcChan >> chan >> x >> y;
104 if (!in.good())
105 break;
106 if (adcId == 0 || adcChan == 0 || chan <= 0)
107 continue;
108 fECALMapArray[chan].SetAdcMap(chan, adcId, adcChan);
109 }
110 in.close();
111 return kTRUE;
112}
113
114Bool_t BmnECALRaw2Digit::LoadCalibration(const char* calibr_file_name)
115{
116 ifstream in;
117 in.open(calibr_file_name);
118 if (!in.is_open()) {
119 Fatal(__func__, "Loading ECAL Calibration from file: %s - file open error!\n", calibr_file_name);
120 return kFALSE;
121 }
122 Info(__func__, "Loading ECAL Calibration from file: %s\n", calibr_file_name);
123 TString dummy;
124 in >> dummy >> dummy >> dummy >> dummy;
125 while (!in.eof()) {
126 int chan;
127 float coeff, err;
128 in >> chan >> coeff >> err;
129 if (!in.good())
130 break;
131 if (chan <= 0)
132 continue;
133 fECALMapArray[chan].SetCoeff(chan, coeff);
134 }
135 in.close();
136 return kTRUE;
137}
138
139Bool_t BmnECALRaw2Digit::LoadGeometry(const char* geo_file_name)
140{
141 TGeoVolume* top = TGeoVolume::Import(geo_file_name, "TOP");
142 if (!top) {
143 Fatal(__func__, "Volume TOP not found in %s\n", geo_file_name);
144 return kFALSE;
145 }
146 TGeoNode* ecal = top->GetNode(0);
147 if (!ecal) {
148 Fatal(__func__, "Unexpected geometry %s\n", geo_file_name);
149 return kFALSE;
150 }
151
152 TGeoNode* ecal1 = ecal->GetDaughter(0);
153 if (ecal1) {
154 Int_t n = ecal1->GetNdaughters();
155 if (n > 504) {
156 Fatal(__func__, "Expected ecal node 1 with 504 daughters or less in %s\n", geo_file_name);
157 return kFALSE;
158 }
159 for (Int_t i = 0; i < n; i++) {
160 Int_t ch = ecal1->GetDaughter(i)->GetNumber();
161 if (ch < 1 || ch > 504) {
162 Fatal(__func__, "Unexpected chan=%d at ecal node 1 in %s\n", ch, geo_file_name);
163 return kFALSE;
164 }
165 fECALMapArray[ch].SetCoords(ecal1->GetDaughter(i), ecal1);
166 }
167 }
168
169 TGeoNode* ecal2 = ecal->GetDaughter(1);
170 if (ecal2) {
171 Int_t n = ecal2->GetNdaughters();
172 if (n > 504) {
173 Fatal(__func__, "Expected ecal node 2 with 504 daughters or less in %s\n", geo_file_name);
174 return kFALSE;
175 }
176 for (Int_t i = 0; i < n; i++) {
177 Int_t ch = ecal2->GetDaughter(i)->GetNumber();
178 if (ch < 505 || ch > 1008) {
179 Fatal(__func__, "Unexpected chan=%d at ecal node 2 in %s\n", ch, geo_file_name);
180 return kFALSE;
181 }
182 fECALMapArray[ch].SetCoords(ecal2->GetDaughter(i), ecal2);
183 }
184 }
185
186 return kTRUE;
187}
188
190{
191 Int_t N = data->GetEntriesFast();
192 for (Int_t i = 0; i < N; i++) {
194 Int_t chan;
195 for (chan = 1; chan < MAX_ECAL_CHANNELS + 1; chan++) {
196 if (fECALMapArray[chan].GetChan() != chan)
197 continue;
198 if (fECALMapArray[chan].IsAdcMatch(digit->GetSerial(), digit->GetChannel()))
199 break;
200 }
201 if (chan > MAX_ECAL_CHANNELS)
202 continue;
203 UseNovosibirskFit(digit, chan, ecaldigit);
204 }
205}
206
208{
209 UInt_t N = digit->GetNSamples();
210 // Short_t* s = (Short_t*)digit->GetValue();
211 auto& s = digit->GetValue();
212
213 Float_t pedestal = 0.;
214 for (Int_t i = fPedestal.sample0; i < fPedestal.sample0 + fPedestal.samples; i++) {
215 if (i >= (Int_t)N)
216 return 0;
217 pedestal += (Float_t)s[i];
218 }
219
220 pedestal /= fPedestal.samples;
221 if (pedestal < fPedestal.min || pedestal > fPedestal.max)
222 return 0;
223
224 TGraph graph(N);
225 Int_t min_n = 0;
226 Int_t min_cnt = 0;
227 Short_t min_v = 0;
228 Float_t scale = fECALMapArray[chan].GetCoeff();
229 for (Int_t n = 0; n < (Int_t)N; n++) {
230 Short_t& v = s[n];
231 if (min_v > v) {
232 min_v = v;
233 min_n = n;
234 min_cnt = 1;
235 } else if (min_v == v) {
236 min_n = n;
237 min_cnt++;
238 }
239
240 Float_t y = v;
241 y = (y - pedestal) * scale;
242 graph.SetPoint(n, n, y);
243 }
244
245 if (min_v > fSignal.max || min_n - min_cnt < fSignal.sample0 || min_n > fSignal.sample0 + fSignal.samples) {
246 return 0;
247 }
248
249 // Initialize fitting function
250 TF1 pFit("Novosibirsk", Novosibirsk, 0., N, 4);
251 pFit.SetParameters(min_v, 0.01, 5., min_n);
252
253 // Remove points at the flat peak if any
254 while (min_cnt-- > 0) {
255 graph.RemovePoint(min_n--);
256 }
257
258 graph.Fit("Novosibirsk", "QR0", "");
259
260 if (!gMinuit->fCstatu.EqualTo("CONVERGED "))
261 return kFALSE;
262 TF1* pRes = graph.GetFunction("Novosibirsk");
263
264 Float_t Tp = pRes->GetMinimumX();
265 if (Tp < fSignal.sample0)
266 return kFALSE;
267 if (Tp > fSignal.sample0 + fSignal.samples)
268 return kFALSE;
269
270 Float_t Vp = pRes->GetMinimum();
271 // if (Vp > fSignal.max || Vp < fSignal.min) return kFALSE;
272
273 Float_t To = pRes->GetX(0.5 * Vp, 0, Tp);
274
275 Float_t dVdT = pRes->Derivative(To);
276 if (dVdT >= 0)
277 return kFALSE;
278
279 To = To - 0.5 * Vp / dVdT;
280
281 if (To < fPedestal.sample0)
282 return kFALSE;
283 if (To > fSignal.sample0 + fSignal.samples)
284 return kFALSE;
285
286 Float_t V = pRes->Integral(To, To + fSignal.samples) / fSignal.samples;
287
288 BmnECALDigit* ecal = (BmnECALDigit*)ecaldigit->ConstructedAt(ecaldigit->GetEntriesFast());
289 ecal->Set(fECALMapArray + chan, -V, -Vp, To, Tp);
290
291 return kTRUE;
292}
293
295{
296 // As Defined in RooNovosibirsk.cxx
297 // If tail=eta=0 the Belle distribution becomes gaussia
298 double tail = p[1];
299 double width = p[2];
300 double peak = p[3];
301 if (TMath::Abs(tail) < 1.e-7)
302 return p[0] * TMath::Exp(-0.5 * TMath::Power(((x[0] - peak) / width), 2));
303 Double_t arg = 1.0 - (x[0] - peak) * tail / width;
304 if (arg < 1.e-6)
305 return 0.0; // Argument of logaritem negative. Real continuation -> function equals zero
306
307 Double_t log = TMath::Log(arg);
308 static const Double_t xi = 2.3548200450309494; // 2 Sqrt( Ln(4) )
309 Double_t width_zero = (2.0 / xi) * TMath::ASinH(tail * xi * 0.5);
310 Double_t width_zero2 = width_zero * width_zero;
311 Double_t exponent = (-0.5 / (width_zero2)*log * log) - (width_zero2 * 0.5);
312
313 return p[0] * TMath::Exp(exponent);
314}
__m128 v
Definition P4_F32vec4.h:1
int i
Definition P4_F32vec4.h:22
bool Bool_t
unsigned short UShort_t
int Int_t
float Float_t
short Short_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
void Info(const char *location, const char *msgfmt,...)
void Error(const char *location, const char *msgfmt,...)
void Fatal(const char *location, const char *msgfmt,...)
R__EXTERN TMinuit * gMinuit
uint32_t GetNSamples()
Definition BmnADCDigit.h:53
uint32_t GetSerial() const
Definition BmnADCDigit.h:49
vector< IntType > & GetValue()
Definition BmnADCDigit.h:55
uint16_t GetChannel() const
Definition BmnADCDigit.h:51
void Set(BmnECALMapElement *e, Float_t amp=0., Float_t peakAmp=0., Float_t startTime=0., Float_t peakTime=0.)
static void PrintTitle()
struct BmnECALRaw2Digit::@112334167373002213270221073046060023217272110234 fSignal
static Double_t Novosibirsk(Double_t *x, Double_t *p)
void FillEvent(TClonesArray *data, TClonesArray *ecaldigit)
Bool_t UseNovosibirskFit(BmnADCDigit< Short_t > *digit, Int_t chan, TClonesArray *ecaldigit)
struct BmnECALRaw2Digit::@112334167373002213270221073046060023217272110234 fPedestal
Bool_t LoadCalibration(const char *calibr_file_name)
BmnECALMapElement fECALMapArray[MAX_ECAL_CHANNELS+1]
Bool_t LoadGeometry(const char *geo_file_name)
Bool_t LoadAdcMap(const char *map_file_name)
TObject * ConstructedAt(Int_t idx)
virtual Double_t GetMinimumX(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
virtual Double_t GetMinimum(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
virtual Double_t Derivative(Double_t x, Double_t *params=nullptr, Double_t epsilon=0.001) const
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
virtual Double_t GetX(Double_t y, Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
virtual void SetParameters(const Double_t *params)
Int_t GetNdaughters() const
TGeoNode * GetDaughter(Int_t ind) const
Int_t GetNumber() const
TGeoNode * GetNode(const char *name) const
static TGeoVolume * Import(const char *filename, const char *name="", Option_t *option="")
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
TF1 * GetFunction(const char *name) const
virtual TFitResultPtr Fit(const char *formula, Option_t *option="", Option_t *goption="", Axis_t xmin=0, Axis_t xmax=0)
virtual Int_t RemovePoint()
Int_t GetEntriesFast() const
TObject * At(Int_t idx) const override
const char * Data() const
static TString Format(const char *fmt,...)
RVec< PromoteType< T > > log(const RVec< T > &v)
#define MAX_ECAL_CHANNELS
*brief user defined string literal for JSON values *sa std::size_t n
Definition json.hpp:20362
Double_t Exp(Double_t x)
Double_t ASinH(Double_t)
Double_t Power(Double_t x, Double_t y)
Double_t Log(Double_t x)
Double_t Abs(Double_t d)
Definition json.hpp:4446