]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONPedestal.cxx
Add a protection against division by 0 (which may occur when a track exit from the...
[u/mrichter/AliRoot.git] / MUON / AliMUONPedestal.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    * 
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
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 **************************************************************************/
15
16 // $Id$
17
18 #include "AliMUONPedestal.h"
19 #include "AliMUONErrorCounter.h"
20 #include "AliMUONVStore.h"
21 #include "AliMUON2DMap.h"
22 #include "AliMUONCalibParamND.h"
23 #include "AliMpConstants.h"
24 #include <TString.h>
25 #include <TTimeStamp.h>
26 #include <TMath.h>
27 #include <TTree.h>
28 #include <TFile.h>
29 #include <TH1F.h>
30 #include <Riostream.h>
31
32 #include <sstream>
33
34 //-----------------------------------------------------------------------------
35 /// \class AliMUONPedestal
36 ///
37 /// Implementation of the pedestal computing
38 ///
39 /// add
40 /// 
41 ///
42 /// \author Alberto Baldisseri, JL Charvet (05/05/2009)
43 //-----------------------------------------------------------------------------
44
45 /// \cond CLASSIMP
46 ClassImp(AliMUONPedestal)
47 /// \endcond
48
49 //______________________________________________________________________________
50 AliMUONPedestal::AliMUONPedestal()
51 : TObject(),
52 //fN(0),
53 fNCurrentEvents(0),
54 fNEvthreshold(0),
55 fNEvents(0),
56 fRunNumber(0),
57 fNChannel(0),
58 fNManu(0),
59 fNManuConfig(0),
60 fConfig(1),
61 fErrorBuspatchTable(new AliMUON2DMap(kFALSE)),
62 fManuBuspatchTable(new AliMUON2DMap(kFALSE)),
63 fManuBPoutofconfigTable(new AliMUON2DMap(kFALSE)),
64 fDate(new TTimeStamp()),
65 fFilcout(0),
66 fHistoFileName(),
67 fPedestalStore(new AliMUON2DMap(kTRUE)),
68 fIndex(-1),
69 fPrefixDA()
70 {
71 /// Default constructor
72 }
73
74 //______________________________________________________________________________
75 AliMUONPedestal::~AliMUONPedestal()
76 {
77 /// Destructor
78   delete fErrorBuspatchTable;
79   delete fManuBuspatchTable;
80   delete fPedestalStore;
81   delete fManuBPoutofconfigTable;
82 }
83
84 //______________________________________________________________________________
85 const char* 
86 AliMUONPedestal::GetHistoFileName() const
87 {
88   /// Return the name of file we use to store histograms
89   return fHistoFileName.Data();
90 }
91
92 //______________________________________________________________________________
93 void AliMUONPedestal::LoadConfig(const char* dbfile)
94 {
95   /// Load MUONTRK configuration from ascii file "dbfile" (in DetDB)
96
97   Int_t manuId;
98   Int_t busPatchId;
99
100   ifstream filein(dbfile,ios::in);
101   
102   while (!filein.eof())
103     { 
104       filein >> busPatchId >> manuId;
105
106       AliMUONErrorCounter* manuCounter;
107       AliMUONVCalibParam* ped = 
108         static_cast<AliMUONVCalibParam*>(fPedestalStore ->FindObject(busPatchId, manuId));
109
110       if (!ped) {
111         fNManuConfig++;
112         fNChannel+=64;
113   ped = new AliMUONCalibParamND(2, AliMpConstants::ManuNofChannels(),busPatchId, manuId, -1.); // put default wise -1, not connected channel
114         fPedestalStore ->Add(ped);  
115
116         if (!(manuCounter = static_cast<AliMUONErrorCounter*>(fManuBuspatchTable->FindObject(busPatchId,manuId))))
117           {
118             // New (buspatch,manu)
119             manuCounter = new AliMUONErrorCounter(busPatchId,manuId);
120             fManuBuspatchTable->Add(manuCounter);
121           }
122       }
123     }
124
125 //______________________________________________________________________________
126 void AliMUONPedestal::MakePed(Int_t busPatchId, Int_t manuId, Int_t channelId, Int_t charge)
127 {
128   static Int_t warn=0;
129   /// Compute pedestals values
130   AliMUONVCalibParam* ped = 
131     static_cast<AliMUONVCalibParam*>(fPedestalStore ->FindObject(busPatchId, manuId));
132
133   if (!ped)   
134     {
135       if(fConfig) 
136         {  // Fill out_of_config (buspatch,manu) table
137           if (!(static_cast<AliMUONErrorCounter*>(fManuBPoutofconfigTable->FindObject(busPatchId,manuId))))
138             fManuBPoutofconfigTable->Add(new AliMUONErrorCounter(busPatchId,manuId));
139           if(warn<10) cout << " !!! WARNING  : busPatchId = " << busPatchId << " manuId = " << manuId << " not in the Detector configuration " << endl;
140           else if(warn==10) cout << " !!! see .log file for an exhaustive list of (busPatchId, manuId) out of Detector configuration \n" << endl; 
141            warn++;
142            (*fFilcout) << " !!! WARNING  : busPatchId = " << busPatchId << " manuId = " << manuId << " not in the Detector configuration " << endl; 
143         }
144       else {fNManu++;}
145       fNChannel+=64;
146       // put default wise -1, not connected channel
147       ped = new AliMUONCalibParamND(2, AliMpConstants::ManuNofChannels(),busPatchId, manuId, -1.); 
148       fPedestalStore ->Add(ped);  
149     }
150
151   // Initialization for the first value
152   if (ped->ValueAsDouble(channelId, 0) == -1)  
153     { 
154       if(fConfig && channelId == 0){fNManu++;}
155       ped->SetValueAsDouble(channelId, 0, 0.);
156     }
157   if (ped->ValueAsDouble(channelId, 1) == -1) ped->SetValueAsDouble(channelId, 1, 0.);
158
159   Double_t pedMean  = ped->ValueAsDouble(channelId, 0) + (Double_t) charge;
160   Double_t pedSigma = ped->ValueAsDouble(channelId, 1) + (Double_t) charge*charge;
161
162   ped->SetValueAsDouble(channelId, 0, pedMean);
163   ped->SetValueAsDouble(channelId, 1, pedSigma);
164
165   AliMUONErrorCounter* manuCounter;
166   if (!(manuCounter = static_cast<AliMUONErrorCounter*>(fManuBuspatchTable->FindObject(busPatchId,manuId))))
167     {
168       // New (buspatch,manu)
169       manuCounter = new AliMUONErrorCounter(busPatchId,manuId);
170       fManuBuspatchTable->Add(manuCounter);
171     }
172   else
173     {
174       // Existing buspatch
175       manuCounter->Increment();
176     }   
177 }
178 //______________________________________________________________________________
179 void AliMUONPedestal::Finalize()
180 {
181   /// final polishing of the store
182   
183   Double_t pedMean;
184   Double_t pedSigma;
185   Double_t pedSigmalimit=0.5;
186   Int_t busPatchId;
187   Int_t manuId;
188   Int_t channelId;
189
190   // print in logfile
191   if (fErrorBuspatchTable->GetSize())
192     {
193       cout<<"\nWarning: Buspatches with less statistics (due to parity errors)"<<endl;
194       (*fFilcout)<<"\nWarning: Buspatches with less statistics (due to parity errors)"<<endl;
195       TIter nextParityError(fErrorBuspatchTable->CreateIterator());
196       AliMUONErrorCounter* parityerror;
197       while((parityerror = static_cast<AliMUONErrorCounter*>(nextParityError())))
198         {
199           cout<<"  bp "<<parityerror->BusPatch()<<": events used = "<<fNEvents-parityerror->Events()<<endl;
200           (*fFilcout)<<"  bp "<<parityerror->BusPatch()<<": events used = "<<fNEvents-parityerror->Events()<<endl;
201         }
202     }
203
204   Int_t nADC4090=0;
205   Int_t nADCmax=0;
206   // iterator over pedestal
207   TIter next(fPedestalStore ->CreateIterator());
208   AliMUONVCalibParam* ped;
209
210   while ( ( ped = dynamic_cast<AliMUONVCalibParam*>(next() ) ) )
211     {
212       busPatchId              = ped->ID0();
213       manuId                  = ped->ID1();
214       if(manuId==0)
215         {
216           cout << "Warning: ManuId = " << manuId << " !!! in  BP = " << busPatchId << endl;
217           (*fFilcout) << "Warning: ManuId = " << manuId << " !!! in  BP = " << busPatchId << endl;
218         }
219       Int_t eventCounter;
220       // Correct the number of events for buspatch with errors
221       AliMUONErrorCounter* errorCounter;
222       if ((errorCounter = (AliMUONErrorCounter*)fErrorBuspatchTable->FindObject(busPatchId)))
223         {
224           eventCounter = fNEvents - errorCounter->Events();
225         }
226       else
227         {
228           eventCounter = fNEvents;
229         }
230       Int_t occupancy=0; // channel missing in raw data or read but rejected (case of parity error)
231       // value of (buspatch, manu) occupancy
232       AliMUONErrorCounter* manuCounter;
233       manuCounter = static_cast<AliMUONErrorCounter*>(fManuBuspatchTable->FindObject(busPatchId,manuId));
234       if(eventCounter>0)occupancy = manuCounter->Events()/64/eventCounter;
235       if(occupancy>1)
236         {
237           cout << "Warning: ManuId = " << manuId << " !!! in  BP = " << busPatchId << " occupancy (>1) = " << occupancy << endl;
238           (*fFilcout) << "Warning: ManuId = " << manuId << " !!! in  BP = " << busPatchId << " occupancy (>1) = " << occupancy <<endl;
239         }
240
241       for (channelId = 0; channelId < ped->Size() ; ++channelId) 
242         {
243           pedMean  = ped->ValueAsDouble(channelId, 0);
244
245           if (pedMean >= 0) // connected channels
246             {
247               ped->SetValueAsDouble(channelId, 0, pedMean/(Double_t)eventCounter);
248               pedMean  = ped->ValueAsDouble(channelId, 0);
249               pedSigma = ped->ValueAsDouble(channelId, 1);
250               ped->SetValueAsDouble(channelId, 1, TMath::Sqrt(TMath::Abs(pedSigma/(Double_t)eventCounter - pedMean*pedMean)));
251
252               if(eventCounter < fNEvthreshold )
253                 { nADCmax++; ped->SetValueAsDouble(channelId, 0, ADCMax());
254                   ped->SetValueAsDouble(channelId, 1, ADCMax());}
255               if( ped->ValueAsDouble(channelId, 1) < pedSigmalimit )
256                 { nADC4090++; ped->SetValueAsDouble(channelId, 0, ADCMax()-5);
257                   ped->SetValueAsDouble(channelId, 1, ADCMax()-5);}
258               if(manuId == 0 || occupancy>1)
259                 { nADCmax++; ped->SetValueAsDouble(channelId, 0, ADCMax());
260                   ped->SetValueAsDouble(channelId, 1, ADCMax());
261                   if(occupancy>1 && channelId==0)ped->SetValueAsDouble(channelId, 0, ADCMax()+occupancy);}
262             }
263           else
264             { nADCmax++; ped->SetValueAsDouble(channelId, 0, ADCMax());
265               ped->SetValueAsDouble(channelId, 1, ADCMax());}
266         }
267     }
268   if(nADCmax>0)
269     { char* detail=Form("Warning: Nb of Channels with bad Pedestal (Ped=4095) = %d over %d",nADCmax,fNChannel);
270       printf("%s\n",detail);
271       (*fFilcout) <<  detail << endl; }
272   if(nADC4090>0)
273     { char* detail=Form("Warning: Nb of Channels with PedSigma<0.5 (Ped=4090) = %d over %d",nADC4090,fNChannel);
274       printf("%s\n",detail);
275       (*fFilcout) <<  detail << endl; }
276 }
277 //______________________________________________________________________________
278 void AliMUONPedestal::MakeASCIIoutput(ostream& out) const
279 {
280   /// put pedestal store in the output stream
281
282   out<<"//===========================================================================" << endl;
283   out<<"//                 Pedestal file calculated by "<< fPrefixDA.Data() << endl;
284   out<<"//===========================================================================" << endl;
285   out<<"//     * Run           : " << fRunNumber << endl; 
286   out<<"//     * Date          : " << fDate->AsString("l") <<endl;
287   out<<"//     * Statictics    : " << fNEvents << endl;
288   if(fConfig)
289     out<<"//     * Nb of MANUS   : " << fNManuConfig << " read in the Det. config. " << endl;
290   out<<"//     * Nb of MANUS   : " << fNManu << " read in raw data " << endl;
291   out<<"//     * Nb of MANUS   : " << fNChannel/64 << " written in pedestal file " << endl;
292   out<<"//     * Nb of channels: " << fNChannel << endl;
293   out<<"//"<<endl;
294   out<<"//     * Below " << fNEvthreshold << " events=> Ped.&sig.=4095" << endl;
295   out<<"//     * PedSigma < 0.5 => Ped.&sig.=4090" << endl;
296
297   if (fErrorBuspatchTable->GetSize())
298     {
299       out<<"//"<<endl;
300       out<<"//    * Buspatches with less statistics (due to parity errors)"<<endl;
301       TIter next(fErrorBuspatchTable->CreateIterator());
302       AliMUONErrorCounter* parityerror;
303       while((parityerror = static_cast<AliMUONErrorCounter*>(next())))
304         {
305           if(fNEvents-parityerror->Events()>fNEvthreshold)
306             { out<<"//      BusPatch = "<<parityerror->BusPatch()<<"\t Nevents used = "<<fNEvents-parityerror->Events()<<endl; }
307           else
308             { out<<"//      BusPatch = "<<parityerror->BusPatch()<<"\t Nevents used = "<<fNEvents-parityerror->Events()<< " (Ped.&sig.=4095)" << endl; }
309         }
310     }  
311   Int_t writitle=0;
312   Int_t occupancy=1;
313   if(occupancy)
314     {
315       TIter next(fPedestalStore ->CreateIterator());
316       AliMUONVCalibParam* ped;
317       while ( ( ped = dynamic_cast<AliMUONVCalibParam*>(next() ) ) )
318         {
319           Int_t busPatchId = ped->ID0();
320           Int_t manuId = ped->ID1();
321           Double_t pedMean  = ped->ValueAsDouble(0, 0); // check pedestal value for channelId=0
322
323           if(pedMean>ADCMax()) 
324             {
325               writitle++;
326               if(writitle==1){ 
327                 out<<"//"<<endl;
328                 out<<"//    * Puzzling (Buspatch,Manu) read in raw data ? (Ped.&sig.=4095)"<<endl;}
329               occupancy=TMath::Nint(pedMean-ADCMax());
330               ped->SetValueAsDouble(0, 0, ADCMax());
331               out<<"//      BusPatch = "<< busPatchId <<"\t ManuId =  "<< manuId << "\t occupancy = " << occupancy  << endl;
332             }
333
334           if (manuId==0 || (fConfig && static_cast<AliMUONErrorCounter*>(fManuBPoutofconfigTable->FindObject(busPatchId,manuId))))
335             {
336               writitle++;
337               if(writitle==1){ 
338                 out<<"//"<<endl;
339                 out<<"//    * Puzzling (Buspatch,Manu) read in raw data ? (Ped.&sig.=4095)"<<endl;}
340               out<<"//      BusPatch = "<< busPatchId <<"\t ManuId =  "<< manuId << "\t missing in the mapping" << endl;
341             }
342         }
343     }
344   out<<"//"<<endl;
345   out<<"//---------------------------------------------------------------------------" << endl;
346   out<<"//---------------------------------------------------------------------------" << endl;
347   out<<"//      BP     MANU     CH.      MEAN    SIGMA"<<endl;
348   out<<"//---------------------------------------------------------------------------" << endl;
349
350   // iterator over pedestal
351   TIter next(fPedestalStore ->CreateIterator());
352   AliMUONVCalibParam* ped;
353   
354   while ( ( ped = dynamic_cast<AliMUONVCalibParam*>(next() ) ) )
355     {
356       Int_t busPatchId = ped->ID0();
357       Int_t manuId = ped->ID1();
358
359       for ( Int_t channelId = 0; channelId < ped->Size(); ++channelId ) 
360         {
361           Double_t pedMean  = ped->ValueAsDouble(channelId, 0);
362           Double_t pedSigma = ped->ValueAsDouble(channelId, 1);
363
364           out << "\t" << busPatchId << "\t" << manuId <<"\t"<< channelId << "\t" << pedMean <<"\t"<< pedSigma << endl;
365         }
366     }
367 }
368
369 //______________________________________________________________________________
370 void AliMUONPedestal::MakeControlHistos()
371 {
372   /// Create control histograms
373   if (fIndex>=0) return; // Pedestal run (fIndex=-1)
374
375   Double_t pedMean;
376   Double_t pedSigma;
377   Double_t evt;
378   Int_t busPatchId;
379   Int_t manuId;
380   Int_t channelId;
381
382 // histo
383   TFile*  histoFile = 0;
384   TTree* tree = 0;
385   TH1F* pedMeanHisto = 0;
386   TH1F* pedSigmaHisto = 0;
387     
388   fHistoFileName=Form("%s.root",fPrefixDA.Data());
389   histoFile = new TFile(fHistoFileName,"RECREATE","MUON Tracking pedestals");
390
391   Char_t name[255];
392   Char_t title[255];
393   sprintf(name,"pedmean_allch");
394   sprintf(title,"Pedestal mean all channels");
395   Int_t nx = ADCMax()+1;
396   Int_t xmin = 0;
397   Int_t xmax = ADCMax(); 
398   pedMeanHisto = new TH1F(name,title,nx,xmin,xmax);
399   pedMeanHisto->SetDirectory(histoFile);
400
401   sprintf(name,"pedsigma_allch");
402   sprintf(title,"Pedestal sigma all channels");
403   nx = 201;
404   xmin = 0;
405   xmax = 200; 
406   pedSigmaHisto = new TH1F(name,title,nx,xmin,xmax);
407   pedSigmaHisto->SetDirectory(histoFile);
408
409   tree = new TTree("t","Pedestal tree");
410   tree->Branch("bp",&busPatchId,"bp/I");
411   tree->Branch("manu",&manuId,",manu/I");
412   tree->Branch("channel",&channelId,",channel/I");
413   tree->Branch("pedMean",&pedMean,",pedMean/D");
414   tree->Branch("pedSigma",&pedSigma,",pedSigma/D");
415   tree->Branch("nevt",&evt,",evt/D");
416
417   // iterator over pedestal
418   TIter next(fPedestalStore ->CreateIterator());
419   AliMUONVCalibParam* ped;
420   AliMUONErrorCounter* manuCounter;
421   
422   while ( ( ped = dynamic_cast<AliMUONVCalibParam*>(next() ) ) )
423   {
424     busPatchId = ped->ID0();
425     manuId = ped->ID1();
426     
427     for ( channelId = 0; channelId < ped->Size(); ++channelId ) 
428     {
429       pedMean  = ped->ValueAsDouble(channelId, 0);
430       pedSigma = ped->ValueAsDouble(channelId, 1);
431       manuCounter = static_cast<AliMUONErrorCounter*>(fManuBuspatchTable->FindObject(busPatchId,manuId));
432       evt = manuCounter->Events()/64;
433           
434       pedMeanHisto->Fill(pedMean);
435       pedSigmaHisto->Fill(pedSigma);
436       tree->Fill();  
437     }
438   }
439     
440   histoFile->Write();  
441   histoFile->Close(); 
442
443 }