1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 #include "AliMUONGain.h"
19 #include "AliMUONPedestal.h"
20 #include "AliMUONErrorCounter.h"
21 #include "AliMUON2DMap.h"
22 #include "AliMUONVCalibParam.h"
23 #include "AliMUONVStore.h"
24 #include "AliMpIntPair.h"
27 #include <THashList.h>
28 #include <TTimeStamp.h>
32 #include <TGraphErrors.h>
34 #include <Riostream.h>
40 //-----------------------------------------------------------------------------
41 /// \class AliMUONGain
43 /// Implementation of calibration computing
48 /// \author Alberto Baldisseri, JL Charvet
49 //-----------------------------------------------------------------------------
57 //______________________________________________________________________________
58 Double_t funcLin (const Double_t *x, const Double_t *par)
61 return par[0] + par[1]*x[0];
64 //______________________________________________________________________________
65 Double_t funcParabolic (const Double_t *x, const Double_t *par)
67 /// Parabolic function
68 return par[0]*x[0]*x[0];
71 //______________________________________________________________________________
72 Double_t funcCalib (const Double_t *x, const Double_t *par)
74 /// Calibration function
75 Double_t xLim= par[3];
77 if(x[0] <= xLim) return par[0] + par[1]*x[0];
79 Double_t yLim = par[0]+ par[1]*xLim;
80 return yLim + par[1]*(x[0] - xLim) + par[2]*(x[0] - xLim)*(x[0] - xLim);
88 //______________________________________________________________________________
89 AliMUONGain::AliMUONGain()
98 /// Default constructor
100 sprintf(fRootDataFileName," "); //Gain
102 // AliMUONPedestal& operator=(const AliMUONPedestal& other); Copy ctor
104 //______________________________________________________________________________
105 AliMUONGain::~AliMUONGain()
110 //______________________________________________________________________________
111 TString AliMUONGain::WriteDummyHeader(void)
115 ostringstream stream;
116 stream<<"//DUMMY FILE (to prevent Shuttle failure)"<< endl;
117 stream<<"//================================================" << endl;
118 stream<<"// MUONTRKda: Calibration run " << endl;
119 stream<<"//================================================" << endl;
120 stream<<"// * Run : " << fRunNumber << endl;
121 stream<<"// * Date : " << fDate->AsString("l") <<endl;
122 stream<<"// * DAC : " << fInjCharge << endl;
123 stream<<"//-------------------------------------------------" << endl;
125 return TString(stream.str().c_str());
128 //______________________________________________________________________________
129 void AliMUONGain::MakePedStoreForGain(TString shuttleFile)
135 Char_t flatFile[256]="";
138 // Store pedestal map in root file
141 // write dummy ascii file -> Shuttle
144 // fileout.open(shuttleFile.Data());
145 // tempstring = WriteDummyHeader();
146 // fileout << tempstring;
148 pfilew = fopen (shuttleFile,"w");
150 fprintf(pfilew,"//DUMMY FILE (to prevent Shuttle failure)\n");
151 fprintf(pfilew,"//================================================\n");
152 fprintf(pfilew,"// MUONTRKda: Calibration run \n");
153 fprintf(pfilew,"//=================================================\n");
154 fprintf(pfilew,"// * Run : %d \n",fRunNumber);
155 fprintf(pfilew,"// * Date : %s \n",fDate->AsString("l"));
156 fprintf(pfilew,"// * DAC : %d \n",fInjCharge);
157 fprintf(pfilew,"//-------------------------------------------------\n");
167 // compute and store mean DAC values (like pedestals)
168 sprintf(flatFile,"%s.ped",fprefixDA);
170 cout << "\n" << fprefixDA << " : Flat file generated : " << flatFile << "\n";
171 if (!outputFile.IsNull())
173 ofstream out(outputFile.Data());
174 MakeASCIIoutput(out);
179 TString mode("UPDATE");
184 TFile* histoFile = new TFile(fRootDataFileName, mode.Data(), "MUON Tracking Gains");
186 // second argument should be the injected charge, taken from config crocus file
187 // put also info about run number could be usefull
188 AliMpIntPair* pair = new AliMpIntPair(fRunNumber,fInjCharge );
190 if (mode.CompareTo("UPDATE") == 0) {
191 tree = (TTree*)histoFile->Get("t");
192 tree->SetBranchAddress("run",&pair);
193 tree->SetBranchAddress("ped",&fPedestalStore);
196 tree = new TTree("t","Pedestal tree");
197 tree->Branch("run", "AliMpIntPair",&pair);
198 tree->Branch("ped", "AliMUON2DMap",&fPedestalStore);
199 tree->SetBranchAddress("run",&pair);
200 tree->SetBranchAddress("ped",&fPedestalStore);
205 tree->Write("t", TObject::kOverwrite); // overwrite the tree
211 //______________________________________________________________________________
212 TString AliMUONGain::WriteGainHeader(Int_t nInit, Int_t nEntries, Int_t nbpf2, Int_t *numrun, Double_t *injCharge)
216 ostringstream stream;
219 stream<<"//================================================" << endl;
220 stream<<"// Calibration file calculated by MUONTRKda" << endl;
221 stream<<"//=================================================" << endl;
222 stream<<"// * Run : " << fRunNumber << endl;
223 stream<<"// * Date : " << fDate->AsString("l") <<endl;
224 stream<<"// * Statictics : " << fNEvents << endl;
225 stream<<"// * # of MANUS : " << fNManu << endl;
226 stream<<"// * # of channels : " << fNChannel << endl;
227 stream<<"//-------------------------------------------------" << endl;
230 stream<<"// "<< nEntries <<" DAC values fit: "<< fnbpf1 << " pts (1st order) " << nbpf2 << " pts (2nd order)" << endl;
232 stream<<"// "<< nEntries <<" DAC values fit: "<< fnbpf1 << " pts (1st order) " << nbpf2 << " pts (2nd order) DAC=0 excluded" << endl;
234 stream<<"// RUN DAC " << endl;
235 stream<<"//-----------------" << endl;
236 for (Int_t i = 0; i < nEntries; ++i) {
237 stream<<Form("// %d %5.0f \n",numrun[i],injCharge[i]);
239 stream<<"//=======================================" << endl;
240 stream<<"// BP MANU CH. a1 a2 thres. q " << endl;
241 stream<<"//=======================================" << endl;
243 return TString(stream.str().c_str());
246 //______________________________________________________________________________
247 TString AliMUONGain::WriteGainData(Int_t BP, Int_t Manu, Int_t ch, Double_t p1, Double_t p2, Int_t threshold, Int_t q)
251 ostringstream stream("");
252 stream << Form("%4i %5i %2i %7.4f %10.3e %4i %2x\n",BP,Manu,ch,p1,p2,threshold,q);
253 return TString(stream.str().c_str());
257 //_______________________________________________________________________________
258 void AliMUONGain::MakeGainStore(TString shuttleFile)
260 /// Store gains in ASCII files
264 Char_t filename[256];
266 Double_t goodA1Min = 0.5;
267 Double_t goodA1Max = 2.;
268 // Double_t goodA1Min = 0.7;
269 // Double_t goodA1Max = 1.7;
270 Double_t goodA2Min = -0.5E-03;
271 Double_t goodA2Max = 1.E-03;
272 // Table for uncalibrated buspatches and manus
273 THashList* uncalBuspatchManuTable = new THashList(1000,2);
277 // open file MUONTRKda_gain_data.root
278 // read again the pedestal for the calibration runs (11 runs)
279 // need the injection charge from config file (to be done)
280 // For each channel make a TGraphErrors (mean, sigma) vs injected charge
281 // Fit with a polynomial fct
282 // store the result in a flat file.
284 TFile* histoFile = new TFile(fRootDataFileName);
286 AliMUON2DMap* map[11];
287 AliMUONVCalibParam* ped[11];
288 AliMpIntPair* run[11];
290 //read back from root file
291 TTree* tree = (TTree*)histoFile->Get("t");
292 Int_t nEntries = tree->GetEntries();
294 Int_t nbpf2 = nEntries - (fnInit + fnbpf1) + 1; // nb pts used for 2nd order fit
297 for (Int_t i = 0; i < nEntries; ++i) {
300 tree->SetBranchAddress("ped",&map[i]);
301 tree->SetBranchAddress("run",&run[i]);
303 // std::cout << map[i] << " " << run[i] << std::endl;
305 // RunNumber extracted from Root data fil
306 if(fIndex==0)fRunNumber=(UInt_t)run[nEntries-1]->GetFirst();
307 // sscanf(getenv("DATE_RUN_NUMBER"),"%d",&gAliRunNumber);
309 Double_t pedMean[11];
310 Double_t pedSigma[11];
311 for ( Int_t i=0 ; i<11 ; i++) {pedMean[i]=0.;pedSigma[i]=1.;};
312 Double_t injCharge[11];
313 Double_t injChargeErr[11];
314 for ( Int_t i=0 ; i<11 ; i++) {injCharge[i]=0.;injChargeErr[i]=1.;};
317 cout<<"\n ******** MUONTRKda for Gain computing (Last Run = " << fRunNumber << ") ********\n" << endl;
318 cout<<" * Date : " << fDate->AsString("l") << "\n" << endl;
319 cout << " Entries = " << nEntries << " DAC values \n" << endl;
320 for (Int_t i = 0; i < nEntries; ++i) {
321 cout<< " Run = " << run[i]->GetFirst() << " DAC = " << run[i]->GetSecond() << endl;
322 numrun[i] = run[i]->GetFirst();
323 injCharge[i] = run[i]->GetSecond();
324 injChargeErr[i] = 0.01*injCharge[i];
325 if(injChargeErr[i] <= 1.) injChargeErr[i]=1.;
329 // print out in .log file
331 (*fFilcout)<<"\n\n//=================================================" << endl;
332 (*fFilcout)<<"// MUONTRKda: Gain Computing Run = " << fRunNumber << endl;
333 (*fFilcout)<<"// RootDataFile = "<< fRootDataFileName << endl;
334 (*fFilcout)<<"//=================================================" << endl;
335 (*fFilcout)<<"//* Date : " << fDate->AsString("l") << "\n" << endl;
339 // why 2 files ? (Ch. F.) => second file contains detailed results
343 sprintf(filename,"%s.param",fprefixDA);
344 cout << " Second fit parameter file = " << filename << "\n";
345 pfilen = fopen (filename,"w");
347 fprintf(pfilen,"//===================================================================\n");
348 fprintf(pfilen,"// BP MANU CH. par[0] [1] [2] [3] xlim P(chi2) p1 P(chi2)2 p2\n");
349 fprintf(pfilen,"//===================================================================\n");
350 fprintf(pfilen,"// * Run : %d \n",fRunNumber);
351 fprintf(pfilen,"//===================================================================\n");
355 // file outputs for gain
358 pfilew.open(shuttleFile.Data());
359 // Write Header Data of the .par file
360 pfilew << WriteGainHeader(fnInit,nEntries,nbpf2,numrun,injCharge);
362 // print mean and sigma values in file
366 sprintf(filename,"%s.peak",fprefixDA);
367 cout << " File containing Peak mean values = " << filename << "\n";
368 pfilep = fopen (filename,"w");
370 fprintf(pfilep,"//==============================================================================================================================\n");
371 fprintf(pfilep,"// * Run : %d \n",fRunNumber);
372 fprintf(pfilep,"//==============================================================================================================================\n");
373 fprintf(pfilep,"// BP MANU CH. Ped. <0> <1> <2> <3> <4> <5> <6> <7> <8> <9> <10> \n");
374 fprintf(pfilep,"//==============================================================================================================================\n");
375 fprintf(pfilep,"// DAC= %9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f fC\n",injCharge[0],injCharge[1],injCharge[2],injCharge[3],injCharge[4],injCharge[5],injCharge[6],injCharge[7],injCharge[8],injCharge[9],injCharge[10]);
376 fprintf(pfilep,"// %9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f\n",injChargeErr[0],injChargeErr[1],injChargeErr[2],injChargeErr[3],injChargeErr[4],injChargeErr[5],injChargeErr[6],injChargeErr[7],injChargeErr[8],injChargeErr[9],injChargeErr[10]);
377 fprintf(pfilep,"//==============================================================================================================================\n");
381 Double_t chi2P2 = 0.;
383 Double_t prChi2P2 =0;
384 Double_t a0=0.,a1=1.,a2=0.;
393 Double_t capa=0.2; // internal capacitor (pF)
397 TFile* gainFile = 0x0;
401 sprintf(fHistoFileName,"%s.root",fprefixDA);
402 gainFile = new TFile(fHistoFileName,"RECREATE","MUON Tracking gains");
403 tg = new TTree("tg","TTree avec class Manu_DiMu");
405 tg->Branch("bp",&busPatchId, "busPatchId/I");
406 tg->Branch("manu",&manuId, "manuId/I");
407 tg->Branch("channel",&channelId, "channelId/I");
409 tg->Branch("a0",&a0, "a0/D");
410 tg->Branch("a1",&a1, "a1/D");
411 tg->Branch("a2",&a2, "a2/D");
412 tg->Branch("Pchi2",&prChi2, "prChi2/D");
413 tg->Branch("Pchi2_2",&prChi2P2, "prChi2P2/D");
414 tg->Branch("Threshold",&threshold, "threshold/I");
415 tg->Branch("q",&q, "q/I");
416 tg->Branch("p1",&p1, "p1/I");
417 tg->Branch("p2",&p2, "p2/I");
418 tg->Branch("gain",&gain, "gain/D");
423 // iterates over the first pedestal run
424 TIter next(map[0]->CreateIterator());
425 AliMUONVCalibParam* p;
428 Int_t nGoodChannel = 0;
429 Int_t nBadChannel = 0;
430 Int_t noFitChannel = 0;
432 Double_t sumProbChi2 = 0.;
434 Double_t sumProbChi2P2 = 0.;
437 Double_t x[11], xErr[11], y[11], yErr[11];
438 Double_t xp[11], xpErr[11], yp[11], ypErr[11];
440 Int_t uncalcountertotal=0 ;
442 while ( ( p = dynamic_cast<AliMUONVCalibParam*>(next() ) ) )
446 busPatchId = p->ID0();
449 // read back pedestal from the other runs for the given (bupatch, manu)
450 for (Int_t i = 1; i < nEntries; ++i) {
451 ped[i] = static_cast<AliMUONVCalibParam*>(map[i]->FindObject(busPatchId, manuId));
454 // compute for each channel the gain parameters
455 for ( channelId = 0; channelId < ped[0]->Size() ; ++channelId )
459 for (Int_t i = 0; i < nEntries; ++i) {
461 if (!ped[i]) continue; //shouldn't happen.
462 pedMean[i] = ped[i]->ValueAsDouble(channelId, 0);
463 pedSigma[i] = ped[i]->ValueAsDouble(channelId, 1);
465 if (pedMean[i] < 0) continue; // not connected
467 if (pedSigma[i] <= 0) pedSigma[i] = 1.; // should not happen.
472 // print_peak_mean_values
476 fprintf(pfilep,"%4i%5i%5i%10.3f",busPatchId,manuId,channelId,0.);
477 fprintf(pfilep,"%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f%9.1f \n",pedMean[0],pedMean[1],pedMean[2],pedMean[3],pedMean[4],pedMean[5],pedMean[6],pedMean[7],pedMean[8],pedMean[9],pedMean[10]);
478 fprintf(pfilep," sig= %9.3f%9.3f%9.3f%9.3f%9.3f%9.3f%9.3f%9.3f%9.3f%9.3f%9.3f \n",pedSigma[0],pedSigma[1],pedSigma[2],pedSigma[3],pedSigma[4],pedSigma[5],pedSigma[6],pedSigma[7],pedSigma[8],pedSigma[9],pedSigma[10]);
484 // Fit Method: Linear fit over gAlinbpf1 points + parabolic fit over nbpf2 points)
485 // nInit=1 : 1st pt DAC=0 excluded
487 // 1. - linear fit over gAlinbpf1 points
489 Double_t par[4] = {0.,0.5,0.,kADCMax};
490 Int_t nbs = nEntries - fnInit;
491 if(nbs < fnbpf1)fnbpf1=nbs;
494 for (Int_t j = 0; j < nbs; ++j)
496 Int_t k = j + fnInit;
498 if(x[j]==0. || x[j]== kADCMax)fitproceed=0;
499 xErr[j] = pedSigma[k];
501 yErr[j] = injChargeErr[k];
505 TGraphErrors *graphErr;
506 if(!fitproceed) { p1=0; p2=0; noFitChannel++;}
511 TF1 *f1 = new TF1("f1",funcLin,0.,kADCMax,2);
512 graphErr = new TGraphErrors(fnbpf1, x, y, xErr, yErr);
514 f1->SetParameters(0,0);
516 graphErr->Fit("f1","RQ");
518 chi2 = f1->GetChisquare();
519 f1->GetParameters(par);
525 prChi2 = TMath::Prob(chi2, fnbpf1 - 2);
527 Double_t xLim = pedMean[fnInit + fnbpf1 - 1];
528 Double_t yLim = par[0]+par[1] * xLim;
533 // 2. - Translation : new origin (xLim, yLim) + parabolic fit over nbf2 points
537 for (Int_t j = 0; j < nbpf2; j++)
539 Int_t k = j + (fnInit + fnbpf1) - 1;
540 xp[j] = pedMean[k] - xLim;
541 xpErr[j] = pedSigma[k];
543 yp[j] = injCharge[k] - yLim - par[1]*xp[j];
544 ypErr[j] = injChargeErr[k];
547 TF1 *f2 = new TF1("f2",funcParabolic,0.,kADCMax,1);
548 graphErr = new TGraphErrors(nbpf2, xp, yp, xpErr, ypErr);
550 graphErr->Fit(f2,"RQ");
551 chi2P2 = f2->GetChisquare();
552 f2->GetParameters(par);
558 prChi2P2 = TMath::Prob(chi2P2, nbpf2-1);
567 if(prChi2>0.999999)prChi2=0.999999 ; if(prChi2P2>0.999999)prChi2P2=0.9999999; // avoiding Pr(Chi2)=1 value
568 p1 = TMath::Nint(floor(prChi2*15))+1; // round down value : floor(2.8)=2.
569 p2 = TMath::Nint(floor(prChi2P2*15))+1;
570 q = p1*16 + p2; // fit quality
572 Double_t x0 = -par[0]/par[1]; // value of x corresponding to à 0 fC
573 threshold = TMath::Nint(ceil(par[3]-x0)); // linear if x < threshold
577 fprintf(pfilen,"%4i %4i %2i",busPatchId,manuId,channelId);
578 fprintf(pfilen," %6.2f %6.4f %10.3e %4.2f %4i %8.6f %8.6f %x %8.6f %8.6f %x\n",
579 par[0], par[1], par[2], par[3], threshold, prChi2, floor(prChi2*15), p1, prChi2P2, floor(prChi2P2*15),p2);
584 if(par[1]< goodA1Min || par[1]> goodA1Max) p1=0;
585 if(par[2]< goodA2Min || par[2]> goodA2Max) p2=0;
589 if(fitproceed && p1>0 && p2>0)
592 sumProbChi2 += prChi2;
594 sumProbChi2P2 += prChi2P2;
597 else // bad calibration
601 par[1]=0.5; a1=0.5; p1=0;
602 par[2]=0.; a2=0.; p2=0;
605 // bad calibration counter
606 char bpmanuname[256];
607 AliMUONErrorCounter* uncalcounter;
609 sprintf(bpmanuname,"bp%dmanu%d",busPatchId,manuId);
610 if (!(uncalcounter = (AliMUONErrorCounter*)uncalBuspatchManuTable->FindObject(bpmanuname)))
612 // New buspatch_manu name
613 uncalcounter= new AliMUONErrorCounter (busPatchId,manuId);
614 uncalcounter->SetName(bpmanuname);
615 uncalBuspatchManuTable->Add(uncalcounter);
619 // Existing buspatch_manu name
620 uncalcounter->Increment();
622 // uncalcounter->Print_uncal()
623 uncalcountertotal ++;
625 gain=1./(par[1]*capa); // mv/fC
630 // if(q==0 and nplot < 100)
631 // if(p1>1 && p2==0 and nplot < 100)
632 if(p1>10 && p2>10 and nplot < 100)
633 // if(p1>=1 and p1<=2 and nplot < 100)
634 // if((p1==1 || p2==1) and nplot < 100)
637 // cout << " nplot = " << nplot << endl;
638 TF1 *f2Calib = new TF1("f2Calib",funcCalib,0.,kADCMax,NFITPARAMS);
640 graphErr = new TGraphErrors(nEntries,pedMean,injCharge,pedSigma,injChargeErr);
642 sprintf(graphName,"BusPatch_%d_Manu_%d_Ch_%d",busPatchId, manuId,channelId);
644 graphErr->SetTitle(graphName);
645 graphErr->SetMarkerColor(3);
646 graphErr->SetMarkerStyle(12);
647 graphErr->Write(graphName);
649 sprintf(graphName,"f2_BusPatch_%d_Manu_%d_Ch_%d",busPatchId, manuId,channelId);
650 f2Calib->SetTitle(graphName);
651 f2Calib->SetLineColor(4);
652 f2Calib->SetParameters(par);
653 f2Calib->Write(graphName);
666 pfilew << WriteGainData(busPatchId,manuId,channelId,par[1],par[2],threshold,q);
669 if(nmanu % 500 == 0)std::cout << " Nb manu = " << nmanu << std::endl;
673 if (uncalBuspatchManuTable->GetSize())
675 uncalBuspatchManuTable->Sort(); // use compare
676 TIterator* iter = uncalBuspatchManuTable->MakeIterator();
677 AliMUONErrorCounter* uncalcounter;
678 (*fFilcout) << "\n List of problematic BusPatch and Manu " << endl;
679 (*fFilcout) << " ========================================" << endl;
680 (*fFilcout) << " BP Manu Nb Channel " << endl ;
681 (*fFilcout) << " ========================================" << endl;
682 while((uncalcounter = (AliMUONErrorCounter*) iter->Next()))
684 (*fFilcout) << "\t" << uncalcounter->BusPatch() << "\t " << uncalcounter->ManuId() << "\t\t" << uncalcounter->Events() << endl;
686 (*fFilcout) << " ========================================" << endl;
688 (*fFilcout) << " Number of bad calibrated Manu = " << uncalBuspatchManuTable->GetSize() << endl ;
689 (*fFilcout) << " Number of bad calibrated channel = " << uncalcountertotal << endl;
694 (*fFilcout) << "\n Nb of channels in raw data = " << nmanu*64 << " (" << nmanu << " Manu)" << endl;
695 (*fFilcout) << " Nb of calibrated channel = " << nGoodChannel << " (" << goodA1Min << "<a1<" << goodA1Max
696 << " and " << goodA2Min << "<a2<" << goodA2Max << ") " << endl;
697 (*fFilcout) << " Nb of uncalibrated channel = " << nBadChannel << " (" << noFitChannel << " unfitted)" << endl;
699 cout << "\n Nb of channels in raw data = " << nmanu*64 << " (" << nmanu << " Manu)" << endl;
700 cout << " Nb of calibrated channel = " << nGoodChannel << " (" << goodA1Min << "<a1<" << goodA1Max
701 << " and " << goodA2Min << "<a2<" << goodA2Max << ") " << endl;
702 cout << " Nb of uncalibrated channel = " << nBadChannel << " (" << noFitChannel << " unfitted)" << endl;
704 Double_t meanA1 = sumA1/(nGoodChannel);
705 Double_t meanProbChi2 = sumProbChi2/(nGoodChannel);
706 Double_t meanA2 = sumA2/(nGoodChannel);
707 Double_t meanProbChi2P2 = sumProbChi2P2/(nGoodChannel);
709 Double_t capaManu = 0.2; // pF
710 (*fFilcout) << "\n linear fit : <a1> = " << meanA1 << "\t <gain> = " << 1./(meanA1*capaManu)
711 << " mV/fC (capa= " << capaManu << " pF)" << endl;
712 (*fFilcout) << " Prob(chi2)> = " << meanProbChi2 << endl;
713 (*fFilcout) << "\n parabolic fit: <a2> = " << meanA2 << endl;
714 (*fFilcout) << " Prob(chi2)> = " << meanProbChi2P2 << "\n" << endl;
716 cout << "\n <gain> = " << 1./(meanA1*capaManu)
717 << " mV/fC (capa= " << capaManu << " pF)"
718 << " Prob(chi2)> = " << meanProbChi2 << endl;
722 if(fPlotLevel>0){tg->Write();histoFile->Close();}
723 if(fPrintLevel>1){fclose(pfilep); fclose(pfilen);}