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