Fixes for Coverity warnings (A. Mastroserio)
[u/mrichter/AliRoot.git] / ITS / AliITSOnlineSPDfoAnalyzer.cxx
1 /**************************************************************************
2  * Copyright(c) 2008-2010, 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 ////////////////////////////////////////////////////////////
19 // Author: A. Mastroserio                                 //
20 // This class is used in the detector algorithm framework //
21 // to process the data stored in special container files  //
22 // (see AliITSOnlineSPDfo). The "good" set of DAC values  //
23 // is extracted.                                          //
24 ////////////////////////////////////////////////////////////
25
26 #include <TFile.h>
27 #include <TMath.h>
28 #include <TString.h>
29 #include <TStyle.h>
30 #include <TF1.h>
31 #include <TH1D.h>
32 #include <TH2D.h>
33 #include <TArrayI.h>
34 #include <TCanvas.h>
35 #include <THnSparse.h>
36 #include <TKey.h>
37 #include <iostream>
38 #include <fstream>
39 #include "AliITSOnlineSPDfoChipConfig.h"
40 #include "AliITSOnlineSPDfoChip.h"
41 #include "AliITSOnlineSPDfoInfo.h"
42 #include "AliITSOnlineSPDfo.h"
43 #include "AliITSOnlineSPDfoAnalyzer.h"
44 #include "AliLog.h"
45
46 AliITSOnlineSPDfoAnalyzer::AliITSOnlineSPDfoAnalyzer(const TString fileName, Bool_t readFromGridFile) :
47   fFileName(0),
48   fNdims(0),
49   fNbins(0x0),
50   fXmin(0x0),
51   fXmax(0x0),
52   fFOHandler(0x0),
53   fHighOccupancyCheck(kTRUE)
54 {
55   // constructor
56   fFileName = fileName;
57   for(Int_t iqual =0; iqual<kNqualityFlags; iqual++) fGeneralThresholds[iqual]=0;
58   
59   for (UInt_t chipNr=0; chipNr<10; chipNr++) {
60     for (UInt_t hs=0; hs<6; hs++) {
61       for(Int_t i =0; i< kNqualityFlags; i++) fNh[i][hs][chipNr]=NULL;
62     }
63   }
64   
65   Init(readFromGridFile); 
66 }
67 //-------------------------------------------------------------------
68 AliITSOnlineSPDfoAnalyzer::AliITSOnlineSPDfoAnalyzer(const AliITSOnlineSPDfoAnalyzer& foan) :
69   fFileName(foan.fFileName),
70   fNdims(foan.fNdims),
71   fNbins(foan.fNbins),
72   fXmin(foan.fXmin),
73   fXmax(foan.fXmax),
74   fFOHandler(foan.fFOHandler),
75   fHighOccupancyCheck(foan.fHighOccupancyCheck)
76 {
77   //
78   // copy constructor, only copies the filename and params (not the processed data
79   //
80   
81   for(Int_t iqual =0; iqual<3; iqual++) fGeneralThresholds[iqual] =foan.fGeneralThresholds[iqual];
82   for (UInt_t chipNr=0; chipNr<10; chipNr++) {
83     for (UInt_t hs=0; hs<6; hs++) {
84       for(Int_t i=0; i<kNqualityFlags;i++) fNh[i][hs][chipNr]=NULL;
85     }
86   }
87   
88   Init();
89 }
90 //-------------------------------------------------------------------
91 AliITSOnlineSPDfoAnalyzer::~AliITSOnlineSPDfoAnalyzer() 
92 {
93   //
94   // destructor
95   // 
96   
97   for (UInt_t hs=0; hs<6; hs++) {
98     for (UInt_t chipNr=0; chipNr<10; chipNr++) {
99       for(Int_t i=0; i<kNqualityFlags ; i++ ) if(fNh[i][hs][chipNr]!=NULL) delete fNh[i][hs][chipNr];          
100     }
101   }
102   delete fFOHandler;
103 }
104 //-------------------------------------------------------------------
105 AliITSOnlineSPDfoAnalyzer& AliITSOnlineSPDfoAnalyzer::operator=(const AliITSOnlineSPDfoAnalyzer& foan) 
106 {
107   // assignment operator, only copies the filename and params (not the processed data)
108   if (this!=&foan) {
109     for (UInt_t hs=0; hs<6; hs++) {
110       for (UInt_t chipNr=0; chipNr<10; chipNr++) {
111         for(Int_t i=0; i<kNqualityFlags ; i++ ) if(fNh[i][hs][chipNr]!=NULL) delete fNh[i][hs][chipNr];
112       }
113     }
114     
115     fFileName=foan.fFileName;
116     fHighOccupancyCheck=foan.fHighOccupancyCheck;
117     Init();    
118   }
119   return *this;
120 }
121 //-------------------------------------------------------------------
122 void AliITSOnlineSPDfoAnalyzer::Init(Bool_t readFromGridFile) 
123 {
124   //
125   // first checks type of container and then initializes container obj
126   //
127   if (!readFromGridFile) {
128     TFile* p0 = TFile::Open(fFileName.Data());
129     if (p0 == NULL) {
130       printf("no file open!"); 
131       return;
132     }
133     else { 
134       fFOHandler = new AliITSOnlineSPDfo();
135       fFOHandler->SetFile(fFileName);
136     }
137     p0->Close();   
138   }
139 }
140 //-------------------------------------------------------------------
141 void AliITSOnlineSPDfoAnalyzer::SetGeneralThresholds(Float_t thre[3])
142 {
143   // here the settings for the 3 quality flags are defined
144   for(Int_t i=0; i< 3; i++) fGeneralThresholds[i]=thre[i];  
145 }
146 //-------------------------------------------------------------------
147 void AliITSOnlineSPDfoAnalyzer::SetNdimensions()
148 {
149   //
150   // here the axis of the N-dim histograms are setted 
151   // 
152   if(!fFOHandler) {
153     printf("no fo object. Exiting...\n"); 
154     return;
155   }
156   
157   TArrayI array = fFOHandler->GetDACscanParams();
158   fNdims = array.GetSize()/3;
159   fNbins = new Int_t[fNdims];
160   fXmin = new Double_t[fNdims];
161   fXmax = new Double_t[fNdims];
162   for(Int_t i=0; i< fNdims; i++){
163     fXmin[i] = array.At(3*i)-0.25;
164     fXmax[i] = array.At(3*i+1)+0.25;
165     fNbins[i] = (Int_t)((fXmax[i]-fXmin[i])/0.5)+1;//to avoid Int->Double conversion problems when checking results. 
166   } 
167 }
168 //-------------------------------------------------------------------
169 void AliITSOnlineSPDfoAnalyzer::BuildTHnSparse(Int_t ihs, Int_t ichip)
170 {
171   //
172   // here the N-dim histogram is booked per chip in one HS 
173   //
174   
175   if(!fNdims) SetNdimensions();
176   
177   for(Int_t iqual =0; iqual < 3; iqual++) fNh[iqual][ihs][ichip] = new THnSparseI(Form("h%i_HS%i_C%i",iqual,ihs,ichip), Form("h%i_HS%i_C%i",iqual,ihs,ichip), fNdims, fNbins, fXmin, fXmax);
178 }
179 //-------------------------------------------------------------------
180 Int_t AliITSOnlineSPDfoAnalyzer::Select(const AliITSOnlineSPDfoChip *chip) const
181 {
182   //
183   // Selects the DAC values if in the chip: the I configuration corresponds to
184   // 0% efficiency ( no FO response case). All the others shoud be within the 
185   // predefined thresholds
186   
187   if(!fFOHandler->GetFOscanInfo()) {
188     printf("no general information object in the file. Exiting...\n");
189     return -1;
190   }
191   
192   Double_t npulses = (fFOHandler->GetFOscanInfo())->GetNumTriggers();
193   
194   if(npulses == 0. ) {
195     Info("AliITSOnlineSPDfoAnalyzer::Select","no trigger pulses set. Exiting...");
196     return -999;
197   } 
198   
199   TObjArray *array = chip->GetChipConfigInfo();
200   if(!array) {
201     printf("No measurement array found in the chip!!\n");
202     return 0;
203   }
204   
205   Int_t quality = -1;
206   
207   Float_t counts = 0;
208   
209   Int_t processedconfigurations = chip->GetNumberOfChipConfigs();
210   
211  
212   
213   
214   for(Int_t isteps =0; isteps < processedconfigurations; isteps++){ 
215     
216     Int_t matrixId = ((AliITSOnlineSPDfoChipConfig*)array->At(isteps))->GetChipConfigMatrixId();
217     counts = (Float_t)(((AliITSOnlineSPDfoChipConfig*)array->At(isteps))->GetChipConfigCounter());
218     if(matrixId==0 && counts > 0) return -1;
219     if(fHighOccupancyCheck &&  matrixId ==6) continue;
220     
221     Float_t efficiency = counts/npulses;
222     
223     if(matrixId > 0){
224       Int_t response = IsSelected(efficiency);
225       if( response >=0) {
226         if(quality < response) quality = response;
227       }
228       else return -1; 
229     }
230   }
231   return quality;
232 }
233 //-----------------------------------------------------
234 Int_t AliITSOnlineSPDfoAnalyzer::IsSelected(Float_t eff) const
235 {
236   //
237   // returns the quality of the selection 
238   //
239   
240   for(Int_t i=0; i<3; i++){  
241     if(eff <= 1.+ fGeneralThresholds[i] && eff >= 1. - fGeneralThresholds[i]  ) return i;
242   }
243   return -1;
244 }
245 //----------------------------------------------------
246 void AliITSOnlineSPDfoAnalyzer::Process()
247
248   //
249   // The procedure is the following:
250   // - DAC 4-tuples are checked  
251   // - if the 4-tuple survives the selection, the chip-related histograms are filled.
252   // (- Per each histogram the mean values of each axis are taken)
253   //
254   
255   if(!fFOHandler) { 
256     Warning("AliITSOnlineSPDfoAnalyzer::Process","no fo object. Exiting.. \n");
257     return;
258   } 
259   
260   TKey *key;
261   TIter iter((fFOHandler->GetFile())->GetListOfKeys());  
262   while ((key = (TKey*)(iter.Next()))) {
263     TString classname = key->GetClassName();
264     if(classname.Contains("OnlineSPD")) break;
265     
266     TObjArray *array = (TObjArray*)(fFOHandler->GetFile())->Get(key->GetName()); // array of chips corresponding to the DACS (size 1-60)
267     if(!array){
268       printf("no array found! Exiting...\n");
269       break; 
270     }
271     
272     Double_t *dacvalues = fFOHandler->GetDACvaluesD(key->GetName(), GetFOHandler()->GetFOscanInfo()->GetNumDACindex());
273     
274     for(Int_t i=0; i< array->GetSize(); i++){
275       AliITSOnlineSPDfoChip *chip = (AliITSOnlineSPDfoChip *)array->At(i); 
276           
277       if(!chip) continue;
278       Int_t hs = chip->GetActiveHS();
279       Int_t chipid = chip->GetChipId();     
280       Int_t quality = Select(chip);
281       if(quality<0) continue; 
282       if(!fNh[quality][hs][chipid]) BuildTHnSparse(hs,chipid);
283       fNh[quality][hs][chipid]->Fill(dacvalues);       
284     } 
285
286     if(dacvalues) delete dacvalues;
287   } 
288 }
289 //---------------------------------------------
290 void AliITSOnlineSPDfoAnalyzer::WriteToFile(TString outputfile)
291 {
292   //
293   // The 4-dim histograms are stored into a file
294   //
295   
296   TFile * f = TFile::Open(outputfile.Data(),"recreate");
297   for(Int_t ihs =0; ihs < 6; ihs++) {
298     for(Int_t ichip =0; ichip < 10; ichip++){
299       for(Int_t i=0; i<kNqualityFlags ; i++ ) {
300       if(fNh[i][ihs][ichip]) f->WriteObjectAny(fNh[i][ihs][ichip],"THnSparse",Form("h%i_hs%i_chip%i",i,ihs,ichip));
301       }
302       
303     }
304   }
305   f->Close();
306 }
307 //---------------------------------------------
308 void AliITSOnlineSPDfoAnalyzer::CheckResults(TString filename, Int_t hs, Int_t ichip, Int_t iqual) const
309 {
310   //  
311   //The chip related 4-dim histograms are produced and stored into eps files
312   //    
313   
314   TFile *f = TFile::Open(filename.Data());
315   if(!f) {
316     Info("AliITSOnlineSPDfoAnalyzer::CehckResults","no file open!. Exiting...\n");
317     return; 
318   }
319   
320   THnSparse *hn;
321   TObject *obj;
322   
323   TIter iter(f->GetListOfKeys());
324   while((obj=iter.Next())){
325     TString name = obj->GetName();
326     hn=(THnSparse*)f->Get(name.Data()); 
327     if(name.Contains(Form("hs%i",hs)) && name.Contains(Form("chip%i",ichip)) && name.Contains(Form("h%i",iqual))) GetCanvases(hn,hs,ichip,iqual);
328   } 
329 }
330 //-----------------------------------------------------------------------------------------------
331 void AliITSOnlineSPDfoAnalyzer::GetCanvases(const THnSparse *hn,Int_t hs, Int_t chip, Int_t iqual) const
332 {
333   //
334   // 1-Dim and 2 Dim Projections of 4-dim histograms are visualized in canvases per quality selection
335   //
336   //
337   
338   if(!hn) {printf("no thnsparse...exiting!\n"); return;} 
339   
340   gStyle->SetPalette(1);
341   
342   TString dacname[4];
343   
344   if(  (fFOHandler->GetFOscanInfo())->GetDACindex(0) == 20 ) dacname[0] = "FOPOL";
345   else dacname[0] = "possible DAC-name/ DAC-register-number mismatch";  
346   if(  (fFOHandler->GetFOscanInfo())->GetDACindex(1) == 17 ) dacname[1] = "CONVPOL";
347   else dacname[1] = "possible DAC-name/ DAC-register-number mismatch";
348   if(  (fFOHandler->GetFOscanInfo())->GetDACindex(2) == 16 ) dacname[2] = "COMPREF";
349   else dacname[2] = "possible DAC-name/ DAC-register-number mismatch";
350   if(  (fFOHandler->GetFOscanInfo())->GetDACindex(3) == 39 ) dacname[3] = "pre_VTH";
351   else dacname[3] = "possible DAC-name/ DAC-register-number mismatch";
352   
353   TString titles = Form("|eff-1| <= %f   for CHIP %i  in HS  %i",fGeneralThresholds[iqual],hs,chip);
354   TCanvas *c[3];
355   
356   for(Int_t i=0; i<2; i++) {
357     c[i] = new TCanvas(Form("c%i",i+1),Form(" %i DIM plots. %s ",i+1,titles.Data()),1200,800); 
358     c[i]->Divide(2,2);
359   }
360   
361   
362   for(Int_t idim =0; idim<2; idim++){
363     for(Int_t k=1; k<5; k++){
364       c[idim]->cd(k);
365       
366       TH1D *h1 =0x0;
367       TH2D *h2=0x0;       
368       if(idim == 0) {
369         h1 = hn->Projection(k-1);
370         if(!h1) {
371          printf("no histogram!!...\n\n\n");
372         } else {
373         h1->SetXTitle(Form("DAC %i  ( %s )",k-1,dacname[k-1].Data()));
374         h1->SetYTitle("entries (eff within thresholds)");
375         h1->Draw();
376         }
377       } 
378       
379       if(idim==1) {      
380         if(k<4){
381           h2  = hn->Projection(k-1,k);
382           h2->SetXTitle(Form("DAC %i ( %s )",k,dacname[k].Data())); h2->SetYTitle(Form("DAC %i  ( %s )",k-1,dacname[k-1].Data()));
383           h2->SetTitleOffset(2,"Y"); h2->SetTitleOffset(1.5,"X");
384         } else {
385           h2 = hn->Projection(0,3);
386           h2->SetXTitle(Form("DAC %i ( %s )",3,dacname[3].Data())); h2->SetYTitle(Form("DAC %i  ( %s )",0, dacname[0].Data()));
387           h2->SetTitleOffset(2,"Y"); h2->SetTitleOffset(1.5,"X"); 
388         }    
389         
390         h2->Draw("lego2");
391       }  
392     }// k loop
393     
394     c[idim]->SaveAs(Form("c%iDIM_%i_%i_%i.eps",idim,iqual,hs,chip));   
395   }// idim loop  
396 }
397 //-----------------------------------------------------
398 TArrayI AliITSOnlineSPDfoAnalyzer::ChooseDACValues(Int_t hs, Int_t chip) const
399 {
400   //
401   // here the "best" 4 dacs are chosen. The most present are taken. 
402   // If the n-tuple does not correspond to a meaningful entry, the
403   // closest value to the mean point in the n-dimensional histogram
404   // is taken.
405   
406   TH1D *tmp[5];
407   if(fNdims > 5) printf("AliITSOnlineSPDfoAnalyzer::ChooseDACValues -> N. of dimensions are more than expected! Break! \n");
408   TArrayI dacs(fNdims+1);
409   
410   for(Int_t i=0; i<fNdims+1; i++) dacs.AddAt(-1,i);
411   
412   for(Int_t iqual =0; iqual < kNqualityFlags; iqual++){
413     if(!fNh[iqual][hs][chip]) continue;    
414     if(fNh[iqual][hs][chip]->GetEntries()==0) continue;
415     for(Int_t idim =0; idim<fNdims; idim++){
416       if(dacs.At(idim)>=0) continue;
417       tmp[idim] = fNh[iqual][hs][chip]->Projection(idim);
418       dacs.AddAt((Int_t)tmp[idim]->GetBinLowEdge(tmp[idim]->GetMaximumBin()+1),idim);
419       Int_t bin=-1;
420       if(fFOHandler->GetFOscanInfo()->GetDACindex(idim)==fFOHandler->kIdPreVTH && CorrectPreVTHChioce(tmp[idim],bin)) {
421        dacs.AddAt((Int_t)tmp[idim]->GetBinLowEdge(bin+1),idim);
422       }
423       dacs.AddAt(iqual,fNdims);
424     }//idim
425   }//iqual
426   
427   if(!IsExisting(dacs,hs,chip)  && dacs.At(fNdims)>-1) {   
428    TArrayI centraldacs = GetCentralDACS(dacs.At(fNdims),hs,chip,tmp);
429     dacs = centraldacs;
430   }
431   return dacs; 
432 }
433 //_____________________________________________________
434 Bool_t AliITSOnlineSPDfoAnalyzer::IsExisting(TArrayI dacs,Int_t hs, Int_t chip) const
435 {
436   //
437   // check the N-tuple corresponds to a real one
438   //  
439   
440   if(dacs.At(fNdims)<0) return kFALSE;
441   Bool_t isOk = kFALSE;
442   
443   Int_t size = dacs.GetSize()-1;
444   Double_t *entry = new Double_t[size];
445   for(Int_t i=0; i<size; i++) entry[i] = dacs.At(i);
446   Int_t checkbin = fNh[dacs.At(dacs.GetSize()-1)][hs][chip]->GetBin(entry,kFALSE); // kFALSE does not allocate another bin
447   if(checkbin > -1) isOk = kTRUE;
448   delete [] entry;
449   return isOk; 
450 }
451 //-----------------------------------------------------------
452 TArrayI AliITSOnlineSPDfoAnalyzer::GetCentralDACS(Int_t qualityflag, Int_t hs, Int_t chip, TH1D **hd) const
453 {
454   //
455   // This method gets the DAC values which are closest to the mean point in the N-dim histogram
456   // It is called when the most probable DAC set does not correspond to a real entry in the N-dim
457   // histogram.
458   //
459  
460   TArrayI dacs(fNdims+1);
461    
462   Double_t *mean=new Double_t[fNdims];
463   Int_t *goodbins=new Int_t[fNdims];
464   Double_t distance = 9999999;
465     for(Int_t i=0; i<fNdims ;i++){ 
466     mean[i]=hd[i]->GetMean();
467     goodbins[i]=0;
468     dacs.AddAt(-1,i);
469   }
470   
471   Int_t *bins = new Int_t[fNdims];
472   Double_t *val=new Double_t[fNdims];
473   
474   for(Int_t in=0; in< fNh[qualityflag][hs][chip]->GetNbins() ; in++){
475     
476     fNh[qualityflag][hs][chip]->GetBinContent(in,bins);
477     Double_t r2 = 0;  
478     for(Int_t j=0; j<fNdims; j++) {
479      val[j] = hd[j]->GetBinCenter(bins[j]);
480       r2+=TMath::Power(val[j]-mean[j],2);
481     }
482     
483     if(r2<distance) {
484       distance = r2;
485       fNh[qualityflag][hs][chip]->GetBinContent(in,goodbins);
486     }    
487   }
488   
489   
490   for(Int_t k=0; k<fNdims; k++) {  
491    dacs.AddAt((Int_t)(hd[k]->GetBinCenter(goodbins[k]) + 0.5*hd[k]->GetBinWidth(goodbins[k])),k);
492   }
493  
494   dacs.AddAt(qualityflag,fNdims);
495   
496   
497   delete [] mean;
498   delete [] goodbins;
499   delete [] bins;
500   delete [] val;
501   return dacs;
502 }
503 //-------------------------------------------------------
504 void AliITSOnlineSPDfoAnalyzer::ReadParamsFromLocation(const Char_t *dirName) 
505 {
506   //
507   // opens file (default name) in dir dirName and reads parameters from it
508   // The file should be in database
509   //
510   
511   TString paramsFileName = Form("./%s/focalib_params.txt",dirName);
512   
513   ifstream paramsFile;
514   paramsFile.open(paramsFileName, ifstream::in);
515   if (paramsFile.fail()) {
516     printf("No config file (%s) present. Using default tuning parameters.\n",paramsFileName.Data());
517   }
518   else {
519     while(1) {
520       Char_t paramN[50];
521       Char_t paramV[50];
522       paramsFile >> paramN;
523       if (paramsFile.eof()) break;
524       paramsFile >> paramV;
525       SetParam(paramN,paramV);
526       if (paramsFile.eof()) break;
527     }
528     paramsFile.close();
529   }
530 }
531 //---------------------------------------------------------
532 void AliITSOnlineSPDfoAnalyzer::SetParam(const Char_t *pname, const Char_t *pval) 
533 {
534   //
535   // sets a single parameter when reading from a file in the database
536   //
537   
538   TString name = pname;
539   TString val = pval;
540   
541   
542   if (name.CompareTo("fGeneralThresholds0")==0) {
543     fGeneralThresholds[0] = val.Atof();
544   }
545   else if (name.CompareTo("fGeneralThresholds1")==0) {
546     fGeneralThresholds[1] = val.Atof();
547   }
548   else if (name.CompareTo("fGeneralThresholds2")==0) {
549     fGeneralThresholds[2] = val.Atof();
550   }
551   else {
552     Error("AliITSOnlineSPDscanAnalyzer::SetParam","Parameter %s in configuration file unknown.",name.Data());
553   }
554 }
555 //--------------------------------------------------------
556 Bool_t AliITSOnlineSPDfoAnalyzer::CorrectPreVTHChioce(const TH1D *h,Int_t &bin) const
557 {
558   //
559   // Checks if more maxima of the same height are present in the pre_VTH case
560   //
561   
562   
563   Int_t maxbin = (Int_t)h->GetMaximumBin();
564   Double_t maxentries = h->GetBinContent(maxbin);
565   
566   Int_t binindex = -1;
567   Bool_t check=kFALSE;
568
569   for(Int_t i=0; i< h->GetNbinsX(); i++){    
570      if(h->GetBinContent(i) == maxentries){
571       if(binindex <= i) binindex =i;
572     }
573   }
574   
575   
576   if(binindex>-1) {
577     bin=binindex;
578     check = kTRUE; 
579   }
580   
581   
582   return check; 
583 }