Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-03 08:20:22

0001 //
0002 // Do a recalibration of the mip from the saved histograms
0003 //
0004 #include <TSpectrum.h>
0005 #include <mbd/MbdCalib.h>
0006 
0007 #include "get_runstr.h"
0008 
0009 
0010 #if defined(__CLING__)
0011 //R__LOAD_LIBRARY(libmbd_io.so)
0012 R__LOAD_LIBRARY(libmbd.so)
0013 #endif
0014 
0015 //using namespace MBDRUNS;
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 // Two gaussians
0038 // [0] = ampl, peak 1
0039 // [1] = mean
0040 // [2] = sigma
0041 // [3] = ampl, peak 2
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 // Two gaussians + expo
0057 // [0] = ampl, peak 1
0058 // [1] = mean
0059 // [2] = sigma
0060 // [3] = ampl, peak 2
0061 // [4] = ampl, woods-saxon
0062 // [5] = a, woods-saxon 
0063 // [6] = slope, expo
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   //Double_t e = par[4]*TMath::Exp(-par[5]*xx);
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   //Fit parameters:
0084   //par[0]=Width (scale) parameter of Landau density
0085   //par[1]=Most Probable (MP, location) parameter of Landau density
0086   //par[2]=Total area (integral -inf to inf, normalization constant)
0087   //par[3]=Width (sigma) of convoluted Gaussian function
0088   //
0089   //In the Landau distribution (represented by the CERNLIB approximation),
0090   //the maximum is located at x=-0.22278298 with the location parameter=0.
0091   //This shift is corrected within this function, so that the actual
0092   //maximum is identical to the MP parameter.
0093 
0094   // Numeric constants
0095   Double_t invsq2pi = 0.3989422804014;   // (2 pi)^(-1/2)
0096   Double_t mpshift  = -0.22278298;       // Landau maximum location
0097 
0098   // Control constants
0099   Double_t np = 100.0;      // number of convolution steps
0100   Double_t sc =   5.0;      // convolution extends to +-sc Gaussian sigmas
0101 
0102   // Variables
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   // MP shift correction
0113   mpc = par[1] - mpshift * par[0];
0114 
0115   // Range of convolution integral
0116   xlow = x[0] - sc * par[3];
0117   xupp = x[0] + sc * par[3];
0118 
0119   step = (xupp-xlow) / np;
0120 
0121   // Convolution integral of Landau and Gaussian by sum
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 // find the threshold
0137 // may also want to consider getting threshold from turn-on curves
0138 void FindThreshold(TH1 *h, double& threshold)
0139 {
0140   threshold = 0.;
0141   double absolute_min = 10.;
0142   double absolute_max = 70.;    // max adc where the threshold could be
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         //cout << ibin << "\t" << ratio << endl;
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     // no exponential before mip peak, use max jump to find threshold
0181     // (Note: should raise gain for this channel)
0182     threshold = h->GetBinLowEdge( maxjumpbin );
0183   }
0184   else
0185   {
0186     // use max bin in threshold range
0187     threshold = h->GetBinLowEdge( maxbin );
0188   }
0189   //cout << threshold << endl;
0190 }
0191 
0192 
0193 // xmin and xmax are the min and max range of the peak
0194 // This version uses TSpectrum to find the peaks
0195 /*
0196 void FindPeakRange(TH1 *h, double& xmin, double& peak, double& xmax, double threshold)
0197 {
0198   int verbose = 1;    // Peak finder
0199   if ( verbose )
0200   {
0201     static TCanvas *ac = new TCanvas("cpeak","peakfinder",800,600);
0202     ac->cd();
0203     h->GetXaxis()->SetRangeUser( qmin, qmax );
0204     h->Draw();
0205   }
0206 
0207   const Int_t maxPeaks = 1;
0208   TSpectrum spectrum(maxPeaks);
0209 
0210   // sigma: minimum expected width of a peak in bins (e.g., sigma=2 means width ≈ 4 bins)
0211   Double_t sigma = 5;
0212 
0213   // Threshold = minimum relative height (0.1 = 10% of max)
0214   Int_t nPeaks = spectrum.Search(h, sigma, "", 0.1);
0215 
0216   std::cout << "Found " << nPeaks << " peaks:\n";
0217 
0218   // Get peak positions
0219   Double_t* peaksX = spectrum.GetPositionX();
0220   for (Int_t i = 0; i < nPeaks; ++i) {
0221     Double_t x = peaksX[i];
0222     Double_t y = h->GetBinContent(h->FindBin(x));
0223     std::cout << "  Peak at x = " << x << ", height = " << y << "\n";
0224   }
0225 
0226   if ( verbose )
0227   {
0228     gPad->Modified();
0229     gPad->Update();
0230     std::string junk;
0231     std::cout << "? ";
0232     std::cin >> junk;
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; // the minimum y val
0244   int nabove = 0;     // num points above the min
0245 
0246   // look for 1st min
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; // new min, reset nabove
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     // if we see this many above the min, the signal is rising
0268     if ( nabove==20 )
0269     {
0270       xmin = h->GetBinCenter( ibin-20 );
0271       break;
0272     }
0273 
0274     ibin++;
0275   }
0276 
0277   // now look for peak after first min
0278   double ymax = 0; // the minimum y val
0279   int nbelow = 0;     // num points below the max
0280   while ( ibin<=maxbin )
0281   {
0282     double val = h->GetBinContent( ibin );
0283     if ( val > ymax )
0284     {
0285       ymax = val;
0286       nbelow = 0; // new max, reset nbelow
0287     }
0288     else
0289     {
0290       nbelow++;
0291     }
0292 
0293     // if we see this many below the max, the signal is falling
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 // type0: auau200
0309 // type1: pp200
0310 // method0:  TSpectrum bkg + 2 gaus fit
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   //const int NUM_PMT = 2;
0318   const int NUM_ARMS = 2;
0319 
0320   // Create new TFile
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   // Read in TFile with h_q
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     //h_q[ipmt] = new TH1F(name,title,15100/4,-100,15000);
0342     h_q[ipmt] = (TH1*)oldfile->Get(name);
0343     if ( type == MBDRUNS::AUAU200 )
0344     {
0345       //h_q[ipmt]->Rebin(2);
0346     }
0347     else if ( type == MBDRUNS::PP200 )
0348     {
0349       //h_q[ipmt]->Rebin(4);  // b-off
0350       //h_q[ipmt]->Rebin(2);
0351     }
0352 
0353     name = "h_tq"; name += ipmt;
0354     title = "tq"; title += ipmt;
0355     //h_tq[ipmt] = new TH1F(name,title,7000,-150,31*17.76);
0356     h_tq[ipmt] = (TH1*)oldfile->Get(name);
0357   }
0358   //TH2 *h2_tq = new TH2F("h2_tq","ch vs tq",900,-150,150,NUM_PMT,-0.5,NUM_PMT-0.5);
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   // Load in calib constants
0368 
0369   TCanvas *ac[100];
0370   int cvindex = 0;
0371 
0372   //q
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   // Fit ranges
0390   // Run23AuAu
0391   qmin = 25.;
0392   qmax = 1600;
0393 
0394   if ( type==MBDRUNS::PP200 )
0395   {
0396     cout << "setting up for pp200" << endl;
0397     //qmin = 200;
0398     //qmax = 10000;       // Run24pp boff
0399     //qmin = 100;
0400     //qmin = 50;
0401     qmin = 10;
0402     qmax = 2000;       // Run24pp bon
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];  // background histogram
0414   TH1 *h_mip[NUM_PMT];  // mip signal histogram
0415   TH1 *h_bkgmip[NUM_PMT];  // bkg + fit histogram
0416 
0417   //TF1 *fws = new TF1("fws",woodssaxon,0,1000,3);
0418   //fws->SetParameters(-85.27,559.8,99.77);
0419 
0420   // Set up output pdf to save plots
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         //h_bkg[ipmt]->Add( fws );
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            Int_t nfound = s.Search(h_q[ipmt],sigma,"",0.1);
0456            Double_t *xpeaks = s.GetPositionX();
0457 
0458         //h_bkg[ipmt] = s.Background( h_q[ipmt] );
0459 
0460         double best_peak = xpeaks[0];
0461         if ( best_peak < 50. )
0462         {
0463         best_peak = xpeaks[1];
0464         }
0465 
0466         cout << "peaks\t" << ipmt << "\t" << nfound << "\t" << best_peak << endl;
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         // Fit background
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         //h_bkg[ipmt]->Fit(bkgf[ipmt],"MR");
0486         h_bkg[ipmt]->Fit(bkgf[ipmt],"R");
0487 
0488         // get mip histogram
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       // Fit the mip peak after background subtraction
0502       name = "mipfit"; name += ipmt;
0503       /*
0504       // Laudau fit
0505       mipfit[ipmt] = new TF1(name,"landau",qmin,qmax);
0506       mipfit[ipmt]->SetLineColor(4);
0507       mipfit[ipmt]->SetParameter( 0, 5.0*h_mip[ipmt]->GetMaximum() );
0508       Double_t seedmean = h_mip[ipmt]->GetBinCenter( h_mip[ipmt]->GetMaximumBin() );
0509       cout << "SEEDMEAN " << seedmean << endl;
0510       mipfit[ipmt]->SetParameter( 1, seedmean );
0511       mipfit[ipmt]->SetParameter( 2, 20. );
0512       */
0513       // Two gaussian fit
0514       mipfit[ipmt] = new TF1(name,gaus2,qmin,qmax,4);
0515       //mipfit[ipmt] = new TF1(name,gaus2expo,qmin,qmax,7);
0516       //mipfit[ipmt] = new TF1(name,"gaus",qmin,qmax,4);
0517 
0518       //mipfit[ipmt] = new TF1(name,langaufun,qmin,qmax,4);
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.);  // b-on
0530         //seedsigma = 50;  // b-on
0531         //seedsigma = 200;  // b-off
0532       }
0533 
0534       mipfit[ipmt]->SetLineColor(4);
0535       // for langaus
0536       /*
0537          mipfit[ipmt]->SetParameter( 0, seedsigma );
0538          mipfit[ipmt]->SetParameter( 1, seedmean );
0539          mipfit[ipmt]->SetParameter( 2, mipfit[ipmt]->GetParameter(0)*0.1 );
0540          mipfit[ipmt]->SetParameter( 3, 0.12*seedsigma );
0541          */
0542       // for gaus2
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       //mipfit[ipmt]->SetParameter( 4, mipfit[ipmt]->GetParameter(0)*0.01 );
0548       //mipfit[ipmt]->SetParameter( 5, 200.);
0549       //mipfit[ipmt]->SetParameter( 6, 20.);
0550       //mipfit[ipmt]->SetParameter( 4, mipfit[ipmt]->GetParameter(1) );
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       // Get full fit
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          gPad->Modified();
0580          gPad->Update();
0581       //mipfit->SetRange( xpeaks[0]-2.5*sigma, 600 );
0582       mipfit->SetRange( qmin, 600 );
0583       mipfit->SetParameter( 0, 1000 );
0584       mipfit->SetParameter( 1, best_peak );
0585       mipfit->SetParameter( 2, sigma );
0586 
0587       mipfit->SetParameter( 8, f_expo->GetParameter(0) );
0588       mipfit->SetParameter( 9, f_expo->GetParameter(1) );
0589       h_q[ipmt]->Fit( mipfit, "R" );
0590       */
0591 
0592 
0593       /*
0594          int npar = f_bkg->GetNpar();
0595          for (int ipar=0; ipar<npar; ipar++)
0596          {
0597          f_bkg->SetParameter( ipar, mipfit->GetParameter(ipar+3) );
0598          }
0599          */
0600 
0601       // Now draw the full dist, plus fit
0602       ac[cvindex]->cd(1);
0603       gPad->SetLogy(1);
0604       h_q[ipmt]->GetXaxis()->SetRangeUser( qmin, qmax );
0605       //h_q[ipmt]->SetMinimum(10.);
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          string junk;
0620          cout << "? ";
0621          cin >> junk;
0622          */
0623 
0624       //name = dir + "h_qfit"; name += ipmt; name += ".png";
0625       title = "h_qfit"; title += ipmt;
0626       //cout << pdfname << " " << title << endl;
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     // Convert to CDB format
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