10#define PRINT_ZDC_CALIBRATION 0
18static void fcn1(Int_t& npar, Double_t* gin, Double_t&
f, Double_t* par, Int_t iflag);
26 for (
int i = 0;
i < 6;
i++)
33 TString CalibrationFile,
34 TString MaxPositionFile)
46 for (
int i = 0;
i < 256;
i++)
53 TString dir = getenv(
"VMCWORKDIR");
54 TString path = dir +
"/input/";
55 in.open((path + mappingFile).Data());
57 printf(
"Loading ZDC Map from file: %s - file open error!\n", mappingFile.Data());
60 printf(
"Loading ZDC Map from file: %s\n", mappingFile.Data());
61 in >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy;
63 int ixmin = -1, ixmax = -1, iymin = -1, iymax = -1;
64 int xmin = 10000., xmax = -10000., ymin = 10000., ymax = -10000.;
66 int id, chan, front_chan, size, ix, iy, used;
68 in >> std::hex >>
id >> std::dec >> chan >> front_chan >> size >> ix >> iy >> x >> y >> used;
72 if (size >= 200 && size <= 223) {
73 if (n_test < MAX_LOG_CHANNELS && chan > 0) {
74 if (is_test[chan - 1] < 0)
75 is_test[chan - 1] = n_test;
77 is_test[128 + chan - 1] = n_test;
78 test_chan[n_test] = chan - 1;
79 test_id[n_test++] = id;
82 if (size > 2 || size < 0)
88 zdc_map_element[n_rec].
id = id;
91 zdc_map_element[n_rec].
adc_chan = chan - 1;
92 if (front_chan > maxchan)
94 zdc_map_element[n_rec].
chan = front_chan - 1;
95 zdc_map_element[n_rec].
size = size - 1;
96 zdc_map_element[n_rec].
ix = ix;
97 zdc_map_element[n_rec].
iy = iy;
98 zdc_map_element[n_rec].
x = x;
99 zdc_map_element[n_rec].
y = y;
100 zdc_map_element[n_rec].
used = used;
123 x_min = zdc_map_element[ixmin].
x - cell_size[zdc_map_element[ixmin].
size];
128 x_max = zdc_map_element[ixmax].
x + cell_size[zdc_map_element[ixmin].
size];
133 y_min = zdc_map_element[iymin].
y - cell_size[zdc_map_element[ixmin].
size];
138 y_max = zdc_map_element[iymax].
y + cell_size[zdc_map_element[ixmin].
size];
144 char filn[128], tit1[32] = {
"Channel"}, tit2[32] = {
"Calibration"}, tit3[32] = {
"Error"};
145 TString path1 = dir +
"/parameters/zdc/";
148 if (strlen(CalibrationFile.Data()) == 0) {
150 sprintf(filn,
"%szdc_muon_calibration.txt", path1.Data());
152 sprintf(filn,
"%szdc_muon_calibration_run%d_%s.txt", path1.Data(), periodId, Run->
GetBeamParticle().Data());
155 sprintf(filn,
"%s%s", path1.Data(), CalibrationFile.Data());
156 fin = fopen(filn,
"r");
157 for (
int i = 0;
i < maxchan;
i++) {
164 printf(
" ZDC: Can't open calibration file %s, use default calibration coefficients 1.\n\n", filn);
166 printf(
"Calibration file %s applied.\n", filn);
168 Float_t ca = 1., cae = 0.;
171 char* readptr = fgets(tit0, 200, fin);
172 int32_t read_res1 = fscanf(fin,
"%d %d %d %d %d %d\n", &digiPar[0], &digiPar[1], &digiPar[2], &digiPar[3],
173 &digiPar[4], &digiPar[5]);
177 int32_t read_res2 = fscanf(fin,
"%s %s %s\n", tit1, tit2, tit3);
178 if ((!readptr) || (read_res1 != 0) || (read_res2 != 0)) {
180 throw std::ios_base::failure(
"Calibration file read error");
183 while (fscanf(fin,
"%d %f %f\n", &ch1, &ca, &cae) == 3) {
184 if (ch1 > 0 && ch1 <= maxchan) {
192 printf(
"\n ZDC calibration coefficients\n\n%s\t%s\t%s\n\n", tit1, tit2, tit3);
193 for (
int i = 0;
i < maxchan;
i++) {
195 printf(
"%d\t%f\t%f\n",
i, cal[
i], cale[
i]);
198 path1 = dir +
"/input/";
201 if (strlen(MaxPositionFile.Data()) == 0) {
202 printf(
"\n ZDC: No cuts on samples wave max position.\n\n");
204 sprintf(filn,
"%s%s", path1.Data(), MaxPositionFile.Data());
205 fin = fopen(filn,
"r");
207 printf(
"\n ZDC: Can't open samples wave max position file %s !\n", filn);
208 printf(
" ZDC: No cuts on samples wave max position.\n\n");
211 Float_t mpos = 10., msig = 2.;
212 while (fscanf(fin,
"%d %f %f\n", &runn, &mpos, &msig) == 3) {
214 MaxPos_min = (int)(mpos - 2. * msig);
215 MaxPos_max = (int)(mpos + 2. * msig + 0.5);
216 printf(
"\n ZDC: Run %d Samples wave Max position range %d - %d\n\n", runn, MaxPos_min, MaxPos_max);
225 use_log_function = 0;
233 shower_norm = 6.461048;
243 SampleProf[j] = NULL;
245 amp_array[
i][j] = 0.;
246 pedestals[
i][j] = 0.;
247 profile_amp[
i][j] = 0.;
248 profile_err[
i][j] = 0.;
252 char tit[128], nam[128];
258 for (
int i = 0;
i < n_test;
i++) {
261 if (test_chan[
i] >= 0) {
262 sprintf(nam,
"htest%d",
i);
263 sprintf(tit,
"Amplitude for adc test channel %d", test_chan[
i]);
264 htest[
i] =
new TH1F(nam, tit, 2000, 0., 16000.);
265 htest[
i]->SetDirectory(0);
266 sprintf(nam,
"ptest%d",
i);
267 sprintf(tit,
"Average sampling wave for adc test channel %d", test_chan[
i]);
268 TestProf[
i] =
new TProfile(nam, tit, 200, 0., 200., -100000., +100000.,
"s");
269 TestProf[
i]->SetDirectory(0);
272 hsum_sim =
new TH1F(
"hsumsim",
"Sum of theoretical amplitudes", 1000, 0., 100.);
273 hsum_sim->SetDirectory(0);
274 hsum_raw =
new TH1F(
"hsumraw",
"Sum of raw amplitudes", 2000, 0., 20000.);
275 hsum_raw->SetDirectory(0);
276 hsum =
new TH1F(
"hsumcal",
"Sum of calibrated amplitudes", 1000, 0., 200.);
277 hsum->SetDirectory(0);
279 hxmean =
new TH1F(
"hxmean",
"Shower mean X", 1000, -500., +500.);
280 hxmean->SetDirectory(0);
281 hymean =
new TH1F(
"hymean",
"Shower mean Y", 1000, -500., +500.);
282 hymean->SetDirectory(0);
284 for (
int i = 0;
i < n_rec;
i++) {
285 sprintf(tit,
"samprof%d", zdc_map_element[
i].chan + 1);
286 sprintf(nam,
"Average sampling wave, module %d", zdc_map_element[
i].chan + 1);
287 SampleProf[
i] =
new TProfile(tit, nam, 200, 0., 200., -100000., +100000.,
"s");
288 SampleProf[
i]->SetDirectory(0);
294 for (
int i = 0;
i < n_test;
i++) {
314 for (
int i = 0;
i < n_rec;
i++) {
316 delete SampleProf[
i];
322 printf(
"id#\tZDC chan\tADC_chan\tsize\tix\tiy\tx\ty\tused\n");
323 for (
int i = 0;
i < n_rec;
i++)
324 printf(
"0x%06lX\t%d\t%d\t%d\t%d\t%d\t%d\t%g\t%g\n", zdc_map_element[
i].
id, zdc_map_element[
i].chan + 1,
325 zdc_map_element[
i].adc_chan + 1, zdc_map_element[
i].size + 1, zdc_map_element[
i].ix,
326 zdc_map_element[
i].iy, zdc_map_element[
i].used, zdc_map_element[
i].x, zdc_map_element[
i].y);
332 double r = 0., dx = 0., dy = 0.;
342 for (
int i = 0;
i < clsize * clsize;
i++) {
346 int ixhalf = -1, iyhalf = -1, i0 = -1, imin = -1;
348 for (
int ind = 0; ind < n_rec; ind++) {
351 dx = x - zdc_map_element[ind].
x;
352 dy = y - zdc_map_element[ind].
y;
353 r = TMath::Sqrt(dx * dx + dy * dy);
358 if (x >= zdc_map_element[ind].x - cell_size[zdc_map_element[ind].size] / 2.
359 && x < zdc_map_element[ind].x + cell_size[zdc_map_element[ind].size] / 2.
360 && y >= zdc_map_element[ind].y - cell_size[zdc_map_element[ind].size] / 2.
361 && y < zdc_map_element[ind].y + cell_size[zdc_map_element[ind].size] / 2)
363 if (x >= zdc_map_element[ind].x)
365 if (y >= zdc_map_element[ind].y)
367 number[ind] = ncells;
368 channel0[ind] = zdc_map_element[ind].
chan;
369 channel1[ncells] = zdc_map_element[ind].
chan;
371 xnear[0] = zdc_map_element[index[ncells]].
x;
372 ynear[0] = zdc_map_element[index[ncells]].
y;
380 if (x < x_min || x > x_max || y < y_min || y > y_max) {
381 printf(
"Beam entry point (%f,%f) outside ZDC area!\n", x, y);
383 }
else if (imin >= 0) {
384 if (x >= zdc_map_element[imin].x)
386 if (y >= zdc_map_element[imin].y)
388 number[imin] = ncells;
389 channel0[imin] = zdc_map_element[imin].
chan;
390 channel1[ncells] = zdc_map_element[imin].
chan;
391 index[ncells] = imin;
392 xnear[0] = zdc_map_element[index[ncells]].
x;
393 ynear[0] = zdc_map_element[index[ncells]].
y;
396 printf(
"Invalid beam entry point (%f,%f)!\n", x, y);
400 for (
int i = 1;
i < clsize;
i++) {
401 xnear[
i] = zdc_map_element[index[0]].
x + ixhalf * cell_size[zdc_map_element[index[0]].
size];
404 for (
int i = 1;
i < clsize;
i++) {
405 ynear[
i] = zdc_map_element[index[0]].
y + iyhalf * cell_size[zdc_map_element[index[0]].
size];
409 for (
int i = 0;
i < clsize;
i++) {
410 for (
int j = 0; j < clsize; j++) {
411 for (
int ind = 0; ind < n_rec; ind++) {
414 if (xnear[
i] >= zdc_map_element[ind].x - cell_size[zdc_map_element[ind].size] / 2.
415 && xnear[
i] < zdc_map_element[ind].x + cell_size[zdc_map_element[ind].size] / 2.
416 && ynear[j] >= zdc_map_element[ind].y - cell_size[zdc_map_element[ind].size] / 2.
417 && ynear[j] < zdc_map_element[ind].y + cell_size[zdc_map_element[ind].size] / 2)
419 number[ind] = ncells;
420 channel0[ind] = zdc_map_element[ind].
chan;
421 channel1[ncells] = zdc_map_element[ind].
chan;
430 float ped = 0., xm = 0., ym = 0., s = 0.;
433 for (
int i = 0;
i < data->GetEntriesFast();
i++) {
437 num_test = is_test[digit->
GetChannel() + 128];
438 if (num_test >= 0 && (digit->
GetSerial() & 0xFFFFFF) == test_id[num_test]) {
441 for (UInt_t j1 = 0; j1 < digit->
GetNSamples(); j1++) {
442 j2 = 1 - j1 % 2 + (j1 / 2) * 2;
443 if (TestProf[num_test])
444 TestProf[num_test]->Fill(j1, samt[j2]);
448 htest[num_test]->Fill(amp);
449 log_amp[num_test] = amp;
454 for (ind = 0; ind < n_rec; ind++)
455 if ((digit->
GetSerial() & 0xFFFFFF) == zdc_map_element[ind].
id
460 if (zdc_map_element[ind].used == 0)
462 if ((num = number[ind]) < 0)
466 for (UInt_t j = 0; j < digit->
GetNSamples(); j++) {
467 j2 = 1 - j % 2 + (j / 2) * 2;
469 SampleProf[num]->Fill(j, sam[j2] >> 4);
472 float signalMin = 0.;
473 float signalMax = 0.;
474 float signalPed = 0.;
475 float signalInt = 0.;
483 xm += amp * cal[zdc_map_element[ind].
chan] * zdc_map_element[ind].
x;
484 ym += amp * cal[zdc_map_element[ind].
chan] * zdc_map_element[ind].
y;
485 s += amp * cal[zdc_map_element[ind].
chan];
486 zdc_amp[zdc_map_element[ind].chan] = amp;
491 hxmean->Fill(xm / s);
493 hymean->Fill(ym / s);
511 for (
int ind = 0; ind < n_rec; ind++) {
512 if (x >= zdc_map_element[ind].x - cell_size[zdc_map_element[ind].size] / 2.
513 && x < zdc_map_element[ind].x + cell_size[zdc_map_element[ind].size] / 2.
514 && y >= zdc_map_element[ind].y - cell_size[zdc_map_element[ind].size] / 2.
515 && y < zdc_map_element[ind].y + cell_size[zdc_map_element[ind].size] / 2)
522 printf(
"Warninig: Beam entry point (%f,%f) outside any ZDC module!\n", x, y);
527 for (
int i = 0;
i < n_rec;
i++) {
530 for (
int ind = 0; ind < n_rec; ind++) {
532 channel0[ind] = zdc_map_element[ind].
chan;
533 channel1[j] = zdc_map_element[ind].
chan;
537 float ped = 0., xm = 0., ym = 0., s = 0.;
540 for (
int i = 0;
i < data->GetEntriesFast();
i++) {
544 num_test = is_test[digit->
GetChannel() + 128];
545 if (num_test >= 0 && (digit->
GetSerial() & 0xFFFFFF) == test_id[num_test]) {
548 for (UInt_t j1 = 0; j1 < digit->
GetNSamples(); j1++) {
549 j2 = 1 - j1 % 2 + (j1 / 2) * 2;
550 if (TestProf[num_test])
551 TestProf[num_test]->Fill(j1, samt[j2]);
555 htest[num_test]->Fill(amp);
556 log_amp[num_test] = amp;
561 for (ind = 0; ind < n_rec; ind++)
562 if ((digit->
GetSerial() & 0xFFFFFF) == zdc_map_element[ind].
id
567 if (zdc_map_element[ind].used == 0)
569 if ((num = number[ind]) < 0)
573 for (UInt_t j1 = 0; j1 < digit->
GetNSamples(); j1++) {
574 j2 = 1 - j1 % 2 + (j1 / 2) * 2;
576 SampleProf[num]->Fill(j1, sam[j2] >> 4);
579 float signalMin = 0.;
580 float signalMax = 0.;
581 float signalPed = 0.;
582 float signalInt = 0.;
590 xm += amp * cal[zdc_map_element[ind].
chan] * zdc_map_element[ind].
x;
591 ym += amp * cal[zdc_map_element[ind].
chan] * zdc_map_element[ind].
y;
592 s += amp * cal[zdc_map_element[ind].
chan];
593 zdc_amp[zdc_map_element[ind].chan] = amp;
598 hxmean->Fill(xm / s);
600 hymean->Fill(ym / s);
610 Float_t amp = 0., ped = 0.;
612 for (
int i = 0;
i < data->GetEntriesFast();
i++) {
616 num_test = is_test[digit->
GetChannel() + 128];
617 if (num_test >= 0 && (digit->
GetSerial() & 0xFFFFFF) == test_id[num_test]) {
621 for (UInt_t j1 = 0; j1 < digit->
GetNSamples(); j1++) {
622 j2 = 1 - j1 % 2 + (j1 / 2) * 2;
623 if (TestProf[num_test])
624 TestProf[num_test]->Fill(j1, samt[j2]);
628 htest[num_test]->Fill(amp);
629 log_amp[num_test] = amp;
634 for (ind = 0; ind < n_rec; ind++) {
635 if ((digit->
GetSerial() & 0xFFFFFF) == zdc_map_element[ind].
id
641 if (zdc_map_element[ind].used == 0)
643 TClonesArray& ar_zdc = *zdcdigit;
645 float signalMin = 0.;
646 float signalMax = 0.;
647 float signalPed = 0.;
648 float signalInt = 0.;
654 amp *= cal[zdc_map_element[ind].
chan];
655 new (ar_zdc[zdcdigit->GetEntriesFast()])
656 BmnZDCDigit(zdc_map_element[ind].ix, zdc_map_element[ind].iy, zdc_map_element[ind].x,
657 zdc_map_element[ind].y, zdc_map_element[ind].size + 1, zdc_map_element[ind].chan + 1, amp,
658 signalMin, signalMax, signalPed, signalInt);
659 zdc_amp[zdc_map_element[ind].chan] = amp;
670 Float_t amp = 0., ped = 0.;
672 for (
int i = 0;
i < data->GetEntriesFast();
i++) {
676 num_test = is_test[digit->
GetChannel() + 128];
677 if (num_test >= 0 && (digit->
GetSerial() & 0xFFFFFF) == test_id[num_test]) {
679 log_amp[num_test] = amp;
684 for (ind = 0; ind < n_rec; ind++)
685 if ((digit->
GetSerial() & 0xFFFFFF) == zdc_map_element[ind].
id
690 if (zdc_map_element[ind].used == 0)
693 float signalMin = 0.;
694 float signalMax = 0.;
695 float signalPed = 0.;
696 float signalInt = 0.;
702 zdc_amp[zdc_map_element[ind].
chan] = amp;
714 double r = 0., dx = 0., dy = 0.;
723 for (
int i = 0;
i < clsize * clsize;
i++) {
727 int ixhalf = -1, iyhalf = -1, i0 = -1, imin = -1;
729 for (
int ind = 0; ind < n_rec; ind++) {
732 dx = x - zdc_map_element[ind].
x;
733 dy = y - zdc_map_element[ind].
y;
734 r = TMath::Sqrt(dx * dx + dy * dy);
739 if (x >= zdc_map_element[ind].x - cell_size[zdc_map_element[ind].size] / 2.
740 && x < zdc_map_element[ind].x + cell_size[zdc_map_element[ind].size] / 2.
741 && y >= zdc_map_element[ind].y - cell_size[zdc_map_element[ind].size] / 2.
742 && y < zdc_map_element[ind].y + cell_size[zdc_map_element[ind].size] / 2)
744 if (x >= zdc_map_element[ind].x)
746 if (y >= zdc_map_element[ind].y)
748 number[ind] = ncells;
749 channel0[ind] = zdc_map_element[ind].
chan;
750 channel1[ncells] = zdc_map_element[ind].
chan;
752 xnear[0] = zdc_map_element[index[ncells]].
x;
753 ynear[0] = zdc_map_element[index[ncells]].
y;
761 if (x < x_min || x > x_max || y < y_min || y > y_max) {
762 printf(
"Beam entry point (%f,%f) outside ZDC area!\n", x, y);
764 }
else if (imin >= 0) {
765 if (x >= zdc_map_element[imin].x)
767 if (y >= zdc_map_element[imin].y)
769 number[imin] = ncells;
770 channel0[imin] = zdc_map_element[imin].
chan;
771 channel1[ncells] = zdc_map_element[imin].
chan;
772 index[ncells] = imin;
773 xnear[0] = zdc_map_element[index[ncells]].
x;
774 ynear[0] = zdc_map_element[index[ncells]].
y;
777 printf(
"Invalid beam entry point (%f,%f)!\n", x, y);
781 for (
int i = 1;
i < clsize;
i++) {
782 xnear[
i] = zdc_map_element[index[0]].
x + ixhalf * cell_size[zdc_map_element[index[0]].
size];
785 for (
int i = 1;
i < clsize;
i++) {
786 ynear[
i] = zdc_map_element[index[0]].
y + iyhalf * cell_size[zdc_map_element[index[0]].
size];
790 for (
int i = 0;
i < clsize;
i++) {
791 for (
int j = 0; j < clsize; j++) {
792 for (
int ind = 0; ind < n_rec; ind++) {
795 if (xnear[
i] >= zdc_map_element[ind].x - cell_size[zdc_map_element[ind].size] / 2.
796 && xnear[
i] < zdc_map_element[ind].x + cell_size[zdc_map_element[ind].size] / 2.
797 && ynear[j] >= zdc_map_element[ind].y - cell_size[zdc_map_element[ind].size] / 2.
798 && ynear[j] < zdc_map_element[ind].y + cell_size[zdc_map_element[ind].size] / 2)
800 number[ind] = ncells;
801 channel0[ind] = zdc_map_element[ind].
chan;
802 channel1[ncells] = zdc_map_element[ind].
chan;
812 for (
int i = 0;
i < ncells;
i++) {
813 amp_array[j][
i] = 0.;
814 profile_amp[j][
i] = 0.;
815 profile_err[j][
i] = 1.;
823 for (
int i = 0;
i < ncells;
i++) {
824 coef[
i] = (0.5 * ((
i + 1) % 4) + 2.4) / 10.;
829 float sum_raw = 0., sum_sim = 0.;
832 for (
int i = 0;
i < data->GetEntriesFast();
i++) {
835 for (ind = 0; ind < n_rec; ind++)
836 if ((digit->
GetSerial() & 0xFFFFFF) == zdc_map_element[ind].
id
841 if (zdc_map_element[ind].used == 0)
843 if ((num = number[ind]) < 0)
846 float signalMin = 0.;
847 float signalMax = 0.;
848 float signalPed = 0.;
849 float signalInt = 0.;
857 amp_array[nevents][num] = amp * cal[zdc_map_element[ind].
chan];
858 pedestals[nevents][num] = ped;
859 sum_raw += amp_array[nevents][num];
862 for (
int i = 0;
i < ncells;
i++) {
863 dx = x - zdc_map_element[index[
i]].
x;
864 dy = y - zdc_map_element[index[
i]].
y;
865 r = TMath::Sqrt(dx * dx + dy * dy);
866 el = shower(r, cell_size[zdc_map_element[index[
i]].size]);
870 for (
int i = 0;
i < ncells;
i++) {
871 dx = x - zdc_map_element[index[
i]].
x;
872 dy = y - zdc_map_element[index[
i]].
y;
873 r = TMath::Sqrt(dx * dx + dy * dy);
874 el = shower(r, cell_size[zdc_map_element[index[
i]].size]);
877 amp = el + gRandom->Gaus() * sigma_amp;
878 amp_array[nevents][
i] = amp * cal[zdc_map_element[index[
i]].
chan];
879 pedestals[nevents][
i] = ped;
880 sum_raw += amp_array[nevents][
i];
883 hsum_raw->Fill(sum_raw);
884 hsum_sim->Fill(sum_sim);
902 double r = 0., dx = 0., dy = 0.;
910 for (
int ind = 0; ind < n_rec; ind++) {
911 if (x >= zdc_map_element[ind].x - cell_size[zdc_map_element[ind].size] / 2.
912 && x < zdc_map_element[ind].x + cell_size[zdc_map_element[ind].size] / 2.
913 && y >= zdc_map_element[ind].y - cell_size[zdc_map_element[ind].size] / 2.
914 && y < zdc_map_element[ind].y + cell_size[zdc_map_element[ind].size] / 2)
921 if (x < x_min || x > x_max || y < y_min || y > y_max) {
922 printf(
"Warning: Beam entry point (%f,%f) outside ZDC area!\n", x, y);
927 for (
int i = 0;
i < ncells;
i++) {
930 for (
int ind = 0; ind < n_rec; ind++) {
933 for (
int j = 0; j < ncells; j++) {
934 if ((cells[j] - 1) == zdc_map_element[ind].chan) {
936 channel0[ind] = zdc_map_element[ind].
chan;
937 channel1[j] = zdc_map_element[ind].
chan;
944 for (
int i = 0;
i < ncells;
i++) {
945 amp_array[j][
i] = 0.;
946 profile_amp[j][
i] = 0.;
947 profile_err[j][
i] = 1.;
952 float sum_raw = 0., sum_sim = 0.;
954 for (
int i = 0;
i < data->GetEntriesFast();
i++) {
957 for (ind = 0; ind < n_rec; ind++)
958 if ((digit->
GetSerial() & 0xFFFFFF) == zdc_map_element[ind].
id
963 if (zdc_map_element[ind].used == 0)
965 if ((num = number[ind]) < 0)
968 float signalMin = 0.;
969 float signalMax = 0.;
970 float signalPed = 0.;
971 float signalInt = 0.;
977 amp_array[nevents][num] = amp * cal[zdc_map_element[ind].
chan];
978 pedestals[nevents][num] = ped;
979 sum_raw += amp_array[nevents][num];
982 for (
int i = 0;
i < ncells;
i++) {
983 dx = x - zdc_map_element[index[
i]].
x;
984 dy = y - zdc_map_element[index[
i]].
y;
985 r = TMath::Sqrt(dx * dx + dy * dy);
986 el = shower(r, cell_size[zdc_map_element[index[
i]].size]);
989 hsum_raw->Fill(sum_raw);
990 hsum_sim->Fill(sum_sim);
1010 for (
int ind = 0; ind < n_rec; ind++) {
1011 if (x >= zdc_map_element[ind].x - cell_size[zdc_map_element[ind].size] / 2.
1012 && x < zdc_map_element[ind].x + cell_size[zdc_map_element[ind].size] / 2.
1013 && y >= zdc_map_element[ind].y - cell_size[zdc_map_element[ind].size] / 2.
1014 && y < zdc_map_element[ind].y + cell_size[zdc_map_element[ind].size] / 2)
1021 printf(
"Warning: Beam entry point (%f,%f) outside any ZDC module!\n", x, y);
1026 for (
int i = 0;
i < n_rec;
i++) {
1029 for (
int ind = 0; ind < n_rec; ind++) {
1031 channel0[ind] = zdc_map_element[ind].
chan;
1032 channel1[j] = zdc_map_element[ind].
chan;
1036 for (
int i = 0;
i < n_rec;
i++) {
1037 amp_array[j1][
i] = 0.;
1038 profile_amp[j1][
i] = 0.;
1039 profile_err[j1][
i] = 1.;
1044 for (
int i = 0;
i < data->GetEntriesFast();
i++) {
1047 for (ind = 0; ind < n_rec; ind++)
1048 if ((digit->
GetSerial() & 0xFFFFFF) == zdc_map_element[ind].
id
1053 if (zdc_map_element[ind].used == 0)
1055 if ((num = number[ind]) < 0)
1058 float signalMin = 0.;
1059 float signalMax = 0.;
1060 float signalPed = 0.;
1061 float signalInt = 0.;
1067 amp_array[nevents][num] = amp * cal[zdc_map_element[ind].
chan];
1068 pedestals[nevents][num] = ped;
1071 cellWeight(nevents);
1076void BmnZDCRaw2Digit::cellWeight(
int ievent)
1079 double s = 0., e = 0., r = 0., x0 = 0., y0 = 0.;
1081 for (
int i = 0;
i < ncells;
i++) {
1082 x0 += zdc_map_element[index[
i]].
x * amp_array[ievent][
i];
1083 y0 += zdc_map_element[index[
i]].
y * amp_array[ievent][
i];
1084 s += amp_array[ievent][
i];
1092 for (
int i = 0;
i < ncells;
i++) {
1093 r = TMath::Sqrt((zdc_map_element[index[
i]].x - x0) * (zdc_map_element[index[
i]].x - x0)
1094 + (zdc_map_element[index[
i]].y - y0) * (zdc_map_element[index[
i]].y - y0));
1095 e = shower(r, cell_size[zdc_map_element[index[
i]].size]);
1096 profile_amp[ievent][
i] = e;
1097 profile_err[ievent][
i] = sigma_amp * sigma_amp;
1108 TMinuit* gMinuit1 =
new TMinuit(ncells + 1);
1109 gMinuit1->SetFCN(fcn1);
1115 gMinuit1->mnexcm(
"SET ERR", arglist, 1, ierflg);
1118 char name[32] = {
""};
1120 for (
int i = 0;
i < ncells;
i++) {
1123 sprintf(name,
"Coeff_%03d", channel1[
i] + 1);
1124 gMinuit1->mnparm(
i, name, vstart[
i], step[
i], vmin, vmax, ierflg);
1130 gMinuit1->mnexcm(
"MIGRAD", arglist, 2, ierflg);
1133 Double_t amin, edm, errdef;
1134 Int_t nvpar, nparx, icstat;
1135 gMinuit1->mnstat(amin, edm, errdef, nvpar, nparx, icstat);
1136 gMinuit1->mnprin(3, amin);
1140 for (
int i = 0;
i < maxchan;
i++) {
1141 cal_out[
i] = cal[
i];
1142 cale_out[
i] = cale[
i];
1145 for (
int i = 0;
i < ncells;
i++) {
1146 gMinuit1->GetParameter(
i, par[
i], epar[
i]);
1147 cal_out[channel1[
i]] = cal[channel1[
i]] * par[
i];
1148 cale_out[channel1[
i]] = cal[channel1[
i]] * epar[
i];
1151 TString dir = getenv(
"VMCWORKDIR");
1152 TString path = dir +
"/parameters/zdc/";
1154 char filn[128], tit1[32] = {
"Channel"}, tit2[32] = {
"Calibration"}, tit3[32] = {
"Error"};
1155 sprintf(filn,
"%szdc_period%d_run%d_calibration_out.txt", path.Data(), periodId, runId);
1156 fout = fopen(filn,
"w");
1158 printf(
"Can't open output calibration file %s\n", filn);
1160 fprintf(fout,
"%s\t%s\t%s\n", tit1, tit2, tit3);
1161 for (
int i = 0;
i < maxchan;
i++) {
1162 fprintf(fout,
"%3d\t%f\t%f\n",
i + 1, cal_out[
i], cale_out[
i]);
1166 printf(
"%s\t%s\t%s\n", tit1, tit2, tit3);
1167 for (
int i = 0;
i < maxchan;
i++) {
1168 printf(
"%3d\t%f\t%f\n",
i + 1, cal_out[
i], cale_out[
i]);
1172 for (
int j = 0; j < nevents; j++) {
1174 for (
int i = 0;
i < ncells;
i++) {
1176 sum += amp_array[j][
i] * par[
i];
1184static void fcn1(Int_t& npar, Double_t* gin, Double_t&
f, Double_t* par, Int_t iflag)
1186 double chi = 0., le = 0., laA = 0.;
1187 for (
int j = 0; j < nevents; j++) {
1188 for (
int i = 0;
i < npar;
i++) {
1191 if (use_log_function) {
1192 le = TMath::Log10(profile_amp[j][
i]);
1193 laA = TMath::Log10(par[
i] * amp_array[j][
i]);
1195 le = profile_amp[j][
i];
1196 laA = par[
i] * amp_array[j][
i];
1198 chi += (le - laA) * (le - laA) / profile_err[j][
i];
1205double BmnZDCRaw2Digit::ch(
double x,
double r)
1207 double amp = (
exp(x / r) +
exp(-x / r)) / 2.;
1210double BmnZDCRaw2Digit::sh(
double x,
double r)
1212 double amp = (
exp(x / r) -
exp(-x / r)) / 2.;
1217double BmnZDCRaw2Digit::PP1(
double x,
double h)
1220 double a1, a2, b1, b2, B;
1222 double bb2 = 6. * ss1;
1223 double bb1 = 1.4 * ss1;
1225 double E = shower_energy;
1227 a2 = 0.105 - 0.014 *
log(E);
1228 b1 = bb1 - 0.120 *
log(E);
1229 b2 = bb2 - 0.260 *
log(E);
1232 B = (a1 * b1 + a2 * b2);
1235 fff = (a1 * b1 * (1. -
exp(-h / (2. * b1)) * ch(x, b1)) + a2 * b2 * (1. -
exp(-h / (2. * b2)) * ch(x, b2)))
1241double BmnZDCRaw2Digit::PP2(
double x,
double h)
1244 double a1, a2, b1, b2, B;
1246 double bb2 = 6. * ss1;
1247 double bb1 = 1.4 * ss1;
1249 double E = shower_energy;
1251 a2 = 0.105 - 0.014 *
log(E);
1252 b1 = bb1 - 0.120 *
log(E);
1253 b2 = bb2 - 0.260 *
log(E);
1256 B = (a1 * b1 + a2 * b2);
1259 fff = (a1 * b1 *
exp(-x / b1) * sh(h, 2. * b1)) / (h * B) + (a2 * b2 *
exp(-x / b2) * sh(h, 2. * b2)) / (h * B);
1263double BmnZDCRaw2Digit::shower(
double x,
double h)
1265 double amp = PP1(x / 10., h / 10.) + PP2(x / 10., h / 10.);
1266 return shower_energy * shower_norm * amp;
1269float BmnZDCRaw2Digit::wave2amp(UChar_t ns,
1277 float pedest = 0., ampl = 0., signal_max = 0.;
1280 float ampl_max = -32768.;
1281 float ampl_min = 32768.;
1283 int pedBegin = digiPar[0];
1284 int pedEnd = digiPar[1];
1285 int gateBegin = digiPar[2];
1286 int gateEnd = digiPar[3];
1288 int signalThresh = digiPar[4];
1289 int signalType = digiPar[5];
1291 float scaleSignal = -1.0 / 16.;
1293 float integral = 0.;
1296 for (
int m = 0;
m < ns;
m++) {
1298 float value = scaleSignal * (Short_t)s[
m];
1300 if (
m >= pedBegin &&
m <= pedEnd) {
1303 pedest /= (pedEnd - pedBegin + 1);
1305 }
else if (
m >= gateBegin &&
m <= gateEnd) {
1306 ampl = value - pedest;
1308 if (ampl > ampl_max) {
1312 if (ampl < ampl_min) {
1321 if (signalType == 0)
1322 signal_max = ampl_max;
1324 signal_max = integral;
1332 if (
fabs(ampl_max - ampl_min) < signalThresh)
1422float BmnZDCRaw2Digit::testwave2amp(UChar_t ns, UShort_t* s, Float_t* pedestal)
1424 float pedest = 0., ampl = 0., signal = 0., signal_max = 0.;
1425 int nsignal = 0, nsignal_max = 0, m1 = 0;
1426 float ampl_max = 0.;
1428 for (
int m = 0;
m < ns;
m++) {
1429 m1 = 1 - (
m % 2) + (
m / 2) * 2;
1430 if (
m < ped_samples) {
1431 pedest += (Short_t)s[m1] >> 4;
1432 if (
m == (ped_samples - 1)) {
1433 pedest /= ped_samples;
1437 ampl = -(
float)((Short_t)
s[m1] >> 4) + pedest;
1441 if (ampl > ampl_max) {
1446 if (nsignal < min_samples) {
1449 }
else if (nsignal > nsignal_max) {
1450 signal_max = signal;
1451 nsignal_max = nsignal;
1457 if (nsignal_max > 0 || ampl_max > 0.) {
1459 signal_max = ampl_max;
1474 TCanvas* callbe0 =
new TCanvas(
"callbe0",
"ZDC mapping", 800, 800);
1475 gPad->Range(x_min - 10., y_min - 10., x_max + 10., y_max + 10.);
1478 double x1, x2, y1, y2;
1483 for (
i = 0;
i < n_rec;
i++) {
1484 x1 = zdc_map_element[
i].
x - cell_size[zdc_map_element[
i].
size] / 2.;
1485 x2 = zdc_map_element[
i].
x + cell_size[zdc_map_element[
i].
size] / 2.;
1486 y1 = zdc_map_element[
i].
y - cell_size[zdc_map_element[
i].
size] / 2.;
1487 y2 = zdc_map_element[
i].
y + cell_size[zdc_map_element[
i].
size] / 2.;
1489 b[
i] =
new TBox(x1, y1, x2, y2);
1491 if (ncells > 0 && number[
i] >= 0)
1492 b[
i]->SetLineColor(kRed);
1493 b[
i]->SetFillStyle(0);
1494 b[
i]->SetLineStyle(0);
1495 sprintf(text,
"%d", zdc_map_element[
i].chan + 1);
1496 t[
i] =
new TText(zdc_map_element[
i].x, zdc_map_element[
i].y, text);
1498 if (ncells > 0 && number[
i] >= 0) {
1499 t[
i]->SetTextColor(kRed);
1500 t[
i]->SetTextAlign(21);
1502 t[
i]->SetTextAlign(21);
1504 t[
i]->SetTextSize(0.02);
1508 sprintf(text,
"%6.3f", cal_out[zdc_map_element[
i].chan]);
1509 tc[
i] =
new TText(zdc_map_element[
i].x, zdc_map_element[
i].y, text);
1511 if (ncells > 0 && number[
i] >= 0)
1512 tc[
i]->SetTextColor(kRed);
1513 tc[
i]->SetTextAlign(23);
1514 tc[
i]->SetTextSize(0.02);
1518 if ((hsum_raw == NULL && hsum == NULL) || nohist)
1521 TCanvas* calres =
new TCanvas(
"calres",
"ZDC calibration", 800, 800);
1523 calres->Divide(1, 2);
1527 gPad->AddExec(
"exselt",
"select_hist()");
1531 gPad->AddExec(
"exselt",
"select_hist()");
1540 TCanvas* csampro =
new TCanvas(
"csampro",
"ZDC sample profiles", 800, 800);
1543 csampro->Divide(2, 2);
1544 else if (ncells <= 9)
1545 csampro->Divide(3, 3);
1546 else if (ncells <= 16)
1547 csampro->Divide(4, 4);
1548 else if (ncells <= 25)
1549 csampro->Divide(5, 5);
1550 else if (ncells <= 36)
1551 csampro->Divide(6, 6);
1552 else if (ncells <= 49)
1553 csampro->Divide(7, 7);
1554 else if (ncells <= 49)
1555 csampro->Divide(7, 7);
1557 csampro->Divide(8, 7);
1558 for (
int i = 0;
i < ncells;
i++) {
1561 SampleProf[
i]->Draw();
1562 gPad->AddExec(
"exselt",
"select_hist()");
1565 TCanvas* calres =
new TCanvas(
"calres",
"ZDC mean X and Y", 800, 800);
1567 calres->Divide(1, 2);
1571 gPad->AddExec(
"exselt",
"select_hist()");
1575 gPad->AddExec(
"exselt",
"select_hist()");
1582 if (htest[0] == NULL)
1584 TCanvas* ctest =
new TCanvas(
"ctest",
"ZDC test channel", 800, 800);
1586 ctest->Divide(2, n_test);
1587 for (
int i = 0;
i < n_test;
i++) {
1588 ctest->cd(
i * 2 + 1);
1590 ctest->cd(
i * 2 + 2);
1591 TestProf[
i]->Draw();
1592 gPad->AddExec(
"exselt",
"select_hist()");
#define PRINT_ZDC_CALIBRATION
friend F32vec4 fabs(const F32vec4 &a)
friend F32vec4 log(const F32vec4 &a)
friend F32vec4 exp(const F32vec4 &a)
UInt_t GetNSamples() const
UShort_t GetChannel() const
UShort_t * GetUShortValue() const
int fillCalibrateCluster(TClonesArray *data, Float_t x, Float_t y, Float_t e, Int_t clsize)
void fillEvent(TClonesArray *data, TClonesArray *zdcdigit)
void drawzdc(int nohist=0)
void fillSampleProfilesAll(TClonesArray *data, Float_t x, Float_t y, Float_t e)
int fillCalibrateAll(TClonesArray *data, Float_t x, Float_t y, Float_t e)
int fillCalibrateNumbers(TClonesArray *data, Float_t x, Float_t y, Float_t e, Int_t ncells, Int_t *numbers)
virtual ~BmnZDCRaw2Digit()
void fillSampleProfiles(TClonesArray *data, Float_t x, Float_t y, Float_t e, Int_t clsize)
void fillAmplitudes(TClonesArray *data)
static UniRun * GetRun(int period_number, int run_number)
get run from the database
TString GetBeamParticle()
get beam particle of the current run