File indexing completed on 2025-12-16 09:23:59
0001 #ifndef MACRO_RECAL_MBD_MIP_C
0002 #define MACRO_RECAL_MBD_MIP_C
0003
0004
0005
0006 #include "get_runstr.h"
0007
0008 #include <mbd/MbdCalib.h>
0009
0010 #include <TCanvas.h>
0011 #include <TF1.h>
0012 #include <TFile.h>
0013 #include <TH1.h>
0014 #include <TH2.h>
0015 #include <TMath.h>
0016 #include <TPad.h>
0017 #include <TSpectrum.h>
0018 #include <TSystem.h>
0019
0020 #include <fstream>
0021
0022 R__LOAD_LIBRARY(libmbd.so)
0023
0024
0025
0026 Double_t qmin = 25.;
0027 Double_t qmax = 1600;
0028 TF1 *bkgf[128]{nullptr};
0029
0030 double minrej = 2000.;
0031 double peak = 2000.;
0032 double maxrej = 5000.;
0033 Double_t powerlaw(Double_t *x, Double_t *par)
0034 {
0035 Float_t xx =x[0];
0036 if ( xx>minrej && xx<maxrej )
0037 {
0038 TF1::RejectPoint();
0039 return 0;
0040 }
0041 Double_t f = par[0]*pow((par[1]/(par[1]+xx)),par[2]);
0042 return f;
0043 }
0044
0045
0046
0047
0048
0049
0050
0051 Double_t gaus2(Double_t *x, Double_t *par)
0052 {
0053 Double_t xx =x[0];
0054 Double_t f = par[0]*TMath::Gaus(xx,par[1],par[2]) + par[3]*TMath::Gaus(xx,2.0*par[1],sqrt(2)*par[2]);
0055 return f;
0056 }
0057
0058 Double_t woodssaxon(Double_t *x, Double_t *par)
0059 {
0060 Double_t xx =x[0];
0061 Double_t e = par[0]/(1.0+exp((xx-par[1])/par[2]));
0062 return e;
0063 }
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 Double_t gaus2ws(Double_t *x, Double_t *par)
0074 {
0075 Double_t xx =x[0];
0076 Double_t f = par[0]*TMath::Gaus(xx,par[1],par[2]) + par[3]*TMath::Gaus(xx,2.0*par[1],sqrt(2)*par[2]);
0077
0078 Double_t e = par[4]/(1.0+exp((xx-par[5])/par[6]));
0079 return f + e;
0080 }
0081
0082
0083 Double_t landau2(Double_t *x, Double_t *par)
0084 {
0085 Double_t xx =x[0];
0086 Double_t f = par[0]*TMath::Landau(xx,par[1],par[2]) + par[3]*TMath::Landau(xx,2.0*par[1],par[4]);
0087 return f;
0088 }
0089
0090 Double_t langaufun(Double_t *x, Double_t *par)
0091 {
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 Double_t invsq2pi = 0.3989422804014;
0105 Double_t mpshift = -0.22278298;
0106
0107
0108 Double_t np = 100.0;
0109 Double_t sc = 5.0;
0110
0111
0112 Double_t xx;
0113 Double_t mpc;
0114 Double_t fland;
0115 Double_t sum = 0.0;
0116 Double_t xlow;
0117 Double_t xupp;
0118 Double_t step;
0119 Double_t i;
0120
0121
0122
0123 mpc = par[1] - mpshift * par[0];
0124
0125
0126 xlow = x[0] - sc * par[3];
0127 xupp = x[0] + sc * par[3];
0128
0129 step = (xupp-xlow) / np;
0130
0131
0132 for(i=1.0; i<=np/2; i++) {
0133 xx = xlow + (i-.5) * step;
0134 fland = TMath::Landau(xx,mpc,par[0]) / par[0];
0135 sum += fland * TMath::Gaus(x[0],xx,par[3]);
0136
0137 xx = xupp - (i-.5) * step;
0138 fland = TMath::Landau(xx,mpc,par[0]) / par[0];
0139 sum += fland * TMath::Gaus(x[0],xx,par[3]);
0140 }
0141
0142 return (par[2] * step * sum * invsq2pi / par[3]);
0143 }
0144
0145
0146
0147
0148 void FindThreshold(TH1 *h, double& threshold)
0149 {
0150 threshold = 0.;
0151 double absolute_min = 10.;
0152 double absolute_max = 70.;
0153 int absminbin = h->FindBin( absolute_min );
0154 int absmaxbin = h->FindBin( absolute_max );
0155 double absmaxval = h->GetBinContent( h->GetMaximumBin() );
0156 int maxbin = 0;
0157 double maxval = 0.;
0158 double prev_val = 0.;
0159 int maxjumpbin = 0;
0160 double maxratio = 0.;
0161
0162 for (int ibin=absminbin; ibin<=absmaxbin; ibin++)
0163 {
0164 double val = h->GetBinContent(ibin);
0165 if ( val > maxval )
0166 {
0167 maxval = val;
0168 maxbin = ibin;
0169 }
0170
0171 if ( val>0. && prev_val>0. )
0172 {
0173 double ratio = val/prev_val;
0174 if ( val>(absmaxval*0.25) )
0175 {
0176
0177 if ( ratio>maxratio )
0178 {
0179 maxratio = ratio;
0180 maxjumpbin = ibin;
0181 }
0182 }
0183 }
0184
0185 prev_val = val;
0186 }
0187
0188 if ( maxbin==absmaxbin )
0189 {
0190
0191
0192 threshold = h->GetBinLowEdge( maxjumpbin );
0193 }
0194 else
0195 {
0196
0197 threshold = h->GetBinLowEdge( maxbin );
0198 }
0199
0200 }
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 void FindPeakRange(TH1 *h, double& xmin, double& thispeak, double& xmax, double threshold)
0248 {
0249 int verbose = 1;
0250
0251 int bin = h->FindBin( threshold );
0252 int maxbin = h->FindBin( qmax );
0253 double ymin = 1e12;
0254 int nabove = 0;
0255
0256
0257 int ibin = bin;
0258 while ( ibin<=maxbin )
0259 {
0260 double val = h->GetBinContent( ibin );
0261 if ( val < ymin )
0262 {
0263 ymin = val;
0264 nabove = 0;
0265 }
0266 else
0267 {
0268 nabove++;
0269 }
0270
0271 if ( verbose )
0272 {
0273 double x = h->GetBinCenter( ibin );
0274 std::cout << "bin x y nabove " << ibin << "\t" << x << "\t" << val << "\t" << nabove << std::endl;
0275 }
0276
0277
0278 if ( nabove==20 )
0279 {
0280 xmin = h->GetBinCenter( ibin-20 );
0281 break;
0282 }
0283
0284 ibin++;
0285 }
0286
0287
0288 double ymax = 0;
0289 int nbelow = 0;
0290 while ( ibin<=maxbin )
0291 {
0292 double val = h->GetBinContent( ibin );
0293 if ( val > ymax )
0294 {
0295 ymax = val;
0296 nbelow = 0;
0297 }
0298 else
0299 {
0300 nbelow++;
0301 }
0302
0303
0304 if ( nbelow==20 )
0305 {
0306 thispeak = h->GetBinCenter( ibin-20 );
0307 break;
0308 }
0309
0310 ibin++;
0311 }
0312
0313 xmax = thispeak + 4*(thispeak - xmin);
0314
0315 }
0316
0317
0318
0319
0320
0321 void recal_mbd_mip(const char *tfname = "DST_MBDUNCAL-00020869-0000.root", const int pass = 3, const int type = 0, const int method = 0)
0322 {
0323 std::cout << "recal_mbd_mip(), type method " << type << " " << method << std::endl;
0324 std::cout << "tfname " << tfname << std::endl;
0325
0326 const int NUM_PMT = 128;
0327
0328
0329
0330
0331 int runnumber = get_runnumber(tfname);
0332 TString dir = "results/";
0333 dir += runnumber;
0334 dir += "/";
0335 TString name = "mkdir -p "; name += dir;
0336 gSystem->Exec( name );
0337
0338 name = dir; name += "calmbdpass2.3_q-"; name += runnumber; name += ".root";
0339
0340
0341 TFile *oldfile = new TFile(name,"READ");
0342
0343 TH1 *h_q[NUM_PMT];
0344 TH1 *h_tq[NUM_PMT];
0345
0346 TString title;
0347 for (int ipmt=0; ipmt<NUM_PMT; ipmt++)
0348 {
0349 name = "h_q"; name += ipmt;
0350 title = "q"; title += ipmt;
0351
0352 h_q[ipmt] = (TH1*)oldfile->Get(name);
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363 name = "h_tq"; name += ipmt;
0364 title = "tq"; title += ipmt;
0365
0366 h_tq[ipmt] = (TH1*)oldfile->Get(name);
0367 }
0368
0369
0370
0371 name = dir;
0372 name += "recalmbd_pass"; name += pass; name += ".root";
0373 std::cout << name << std::endl;
0374
0375 TFile *savefile = new TFile(name,"RECREATE");
0376
0377
0378
0379 TCanvas *ac[100];
0380 int cvindex = 0;
0381
0382
0383 ac[cvindex] = new TCanvas("cal_q","q",425*1.5,550*1.5);
0384 if ( pass>0 )
0385 {
0386 ac[cvindex]->Divide(1,2);
0387 ac[cvindex]->cd(1);
0388 }
0389
0390 std::ofstream cal_mip_file;
0391 TString calfname;
0392 if ( pass==3 )
0393 {
0394 calfname = dir; calfname += "mbd_qfit.calib";
0395 cal_mip_file.open( calfname );
0396 std::cout << "Writing to " << calfname << std::endl;
0397 }
0398
0399
0400
0401 qmin = 25.;
0402 qmax = 1600;
0403
0404 if ( type==MBDRUNS::PP200 )
0405 {
0406 std::cout << "setting up for pp200" << std::endl;
0407
0408
0409
0410
0411 qmin = 10;
0412 qmax = 2000;
0413 }
0414
0415 if ( type==MBDRUNS::SIMAUAU200 || type==MBDRUNS::SIMPP200 )
0416 {
0417 qmin = 0.25;
0418 qmax = 6.;
0419 }
0420
0421 TF1 *mipfit[128];
0422
0423 TH1 *h_bkg[NUM_PMT];
0424 TH1 *h_mip[NUM_PMT];
0425 TH1 *h_bkgmip[NUM_PMT];
0426
0427
0428
0429
0430
0431 TString pdfname = dir; pdfname += "calmbdpass2."; pdfname += pass; pdfname += "_mip-"; pdfname += runnumber; pdfname += ".pdf";
0432 std::cout << pdfname << std::endl;
0433 ac[cvindex]->Print( pdfname + "[" );
0434
0435 for (int ipmt=0; ipmt<NUM_PMT; ipmt++)
0436 {
0437 if (pass>0)
0438 {
0439 h_bkg[ipmt] = (TH1*)h_q[ipmt]->Clone();
0440 name = h_q[ipmt]->GetName(); name.ReplaceAll("q","bkg");
0441 h_bkg[ipmt]->SetName( name );
0442 h_bkg[ipmt]->SetTitle( name );
0443 h_bkg[ipmt]->SetLineColor(2);
0444 double threshold = qmin + 2.;
0445 FindThreshold( h_q[ipmt], threshold );
0446 std::cout << "threshold " << ipmt << "\t" << threshold << std::endl;
0447 h_q[ipmt]->GetXaxis()->SetRangeUser( threshold, qmax );
0448 h_q[ipmt]->Sumw2();
0449
0450 double sigma = 20;
0451 double seedmean = 0;
0452 TSpectrum s{};
0453 if ( method==0 )
0454 {
0455 h_bkg[ipmt] = s.Background( h_q[ipmt] );
0456
0457
0458 h_mip[ipmt] = (TH1*)h_q[ipmt]->Clone();
0459 name = h_q[ipmt]->GetName(); name.ReplaceAll("q","mip");
0460 h_mip[ipmt]->SetName( name );
0461 h_mip[ipmt]->SetTitle( name );
0462 h_mip[ipmt]->Add( h_bkg[ipmt], -1.0 );
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479 }
0480 else if ( method==1 )
0481 {
0482 FindPeakRange( h_bkg[ipmt], minrej, peak, maxrej, threshold );
0483 std::cout << "peak range\t" << minrej << "\t" << peak << "\t" << maxrej << std::endl;
0484 sigma = peak-minrej;
0485 seedmean = peak;
0486
0487
0488 name = "bkgf"; name += ipmt;
0489 bkgf[ipmt] = new TF1(name,powerlaw,qmin,qmax,3);
0490 bkgf[ipmt]->SetParameter(0,240e-5);
0491 bkgf[ipmt]->SetParameter(1,1240);
0492 bkgf[ipmt]->SetParameter(2,2);
0493 bkgf[ipmt]->SetLineColor(3);
0494 h_bkg[ipmt]->Draw();
0495
0496 h_bkg[ipmt]->Fit(bkgf[ipmt],"R");
0497
0498
0499 h_mip[ipmt] = (TH1*)h_q[ipmt]->Clone();
0500 name = h_q[ipmt]->GetName(); name.ReplaceAll("q","mip");
0501 h_mip[ipmt]->SetName( name );
0502 h_mip[ipmt]->SetTitle( name );
0503
0504
0505
0506 minrej = 0.;
0507 maxrej = 0.;
0508 h_mip[ipmt]->Add( bkgf[ipmt], -1.0 );
0509 }
0510
0511
0512 name = "mipfit"; name += ipmt;
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524 mipfit[ipmt] = new TF1(name,gaus2,qmin,qmax,4);
0525
0526
0527
0528
0529
0530 seedmean = h_mip[ipmt]->GetBinCenter( h_mip[ipmt]->GetMaximumBin() );
0531 std::cout << "SEEDMEAN " << seedmean << std::endl;
0532 Double_t seedsigma = sigma;
0533 if ( type==MBDRUNS::SIMAUAU200 )
0534 {
0535 seedsigma = 0.2;
0536 }
0537 else if ( type==MBDRUNS::PP200 )
0538 {
0539 seedsigma = seedmean*(116./719.);
0540
0541
0542 }
0543
0544 mipfit[ipmt]->SetLineColor(4);
0545
0546
0547
0548
0549
0550
0551
0552
0553 mipfit[ipmt]->SetParameter( 0, 5.0*h_mip[ipmt]->GetMaximum() );
0554 mipfit[ipmt]->SetParameter( 1, seedmean );
0555 mipfit[ipmt]->SetParameter( 2, seedsigma );
0556 mipfit[ipmt]->SetParameter( 3, mipfit[ipmt]->GetParameter(0)*0.1 );
0557
0558
0559
0560
0561
0562 h_mip[ipmt]->Fit( mipfit[ipmt], "RM" );
0563
0564 double integ = mipfit[ipmt]->GetParameter(0);
0565 double best_peak = mipfit[ipmt]->GetParameter(1);
0566 double width = mipfit[ipmt]->GetParameter(2);
0567 double integerr = mipfit[ipmt]->GetParError(0);
0568 double best_peakerr = mipfit[ipmt]->GetParError(1);
0569 double widtherr = mipfit[ipmt]->GetParError(2);
0570 double chi2 = mipfit[ipmt]->GetChisquare();
0571 double ndf = mipfit[ipmt]->GetNDF();
0572
0573 cal_mip_file << ipmt << "\t" << integ << "\t" << best_peak << "\t" << width << "\t"
0574 << integerr << "\t" << best_peakerr << "\t" << widtherr << "\t"
0575 << chi2/ndf << std::endl;
0576 std::cout << ipmt << "\t" << integ << "\t" << best_peak << "\t" << width << "\t"
0577 << integerr << "\t" << best_peakerr << "\t" << widtherr << "\t"
0578 << chi2/ndf << std::endl;
0579
0580
0581 h_bkgmip[ipmt] = (TH1*)h_bkg[ipmt]->Clone();
0582 name = h_q[ipmt]->GetName(); name.ReplaceAll("q","bkgmip");
0583 h_bkgmip[ipmt]->SetName( name );
0584 h_bkgmip[ipmt]->SetTitle( name );
0585 h_bkgmip[ipmt]->Add( mipfit[ipmt] );
0586 h_bkgmip[ipmt]->SetLineColor( 8 );
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612 ac[cvindex]->cd(1);
0613 gPad->SetLogy(1);
0614 h_q[ipmt]->GetXaxis()->SetRangeUser( qmin, qmax );
0615
0616 h_q[ipmt]->Draw();
0617 h_bkg[ipmt]->Draw("same");
0618 h_bkgmip[ipmt]->Draw("same");
0619
0620 gPad->Modified();
0621 gPad->Update();
0622
0623 ac[cvindex]->cd(2);
0624 h_mip[ipmt]->Draw();
0625 gPad->Modified();
0626 gPad->Update();
0627
0628
0629
0630
0631
0632
0633
0634
0635 title = "h_qfit"; title += ipmt;
0636
0637 ac[cvindex]->Print( pdfname, title );
0638 }
0639
0640 }
0641
0642 ac[cvindex]->Print( pdfname + "]" );
0643 ++cvindex;
0644
0645 if ( pass==3 )
0646 {
0647 cal_mip_file.close();
0648
0649
0650 MbdCalib mcal;
0651 mcal.Download_Gains( calfname.Data() );
0652 calfname.ReplaceAll(".calib",".root");
0653 mcal.Write_CDB_Gains( calfname.Data() );
0654 }
0655
0656 savefile->Write();
0657 savefile->Close();
0658 }
0659 #endif