Coding conventions
[u/mrichter/AliRoot.git] / ITS / AliITSPreprocessorSDD.cxx
1 /**************************************************************************
2  * Copyright(c) 2007-2009, 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 //                                                               //
20 // Implementation of the class for SDD preprocessing             //
21 // Origin: E.Crescio, Torino, crescio@to.infn.it                 //
22 //         F.Prino, Torino, prino@to.infn.it                     //
23 //                                                               //
24 ///////////////////////////////////////////////////////////////////
25
26 #include "AliITSPreprocessorSDD.h"
27 #include "AliITSCalibrationSDD.h"
28 #include "AliITSDriftSpeedSDD.h"
29 #include "AliITSDriftSpeedArraySDD.h"
30 #include "AliITSDCSAnalyzerSDD.h"
31 #include "AliShuttleInterface.h"
32 #include "AliCDBEntry.h"
33 #include "AliCDBMetaData.h"
34 #include "TObjArray.h"
35 #include "AliLog.h"
36 #include <TObjString.h>
37 #include <TSystem.h>
38 #include <TList.h>
39 #include <TF1.h>
40 #include <TH1D.h>
41
42 const TString AliITSPreprocessorSDD::fgkNameHistoPedestals = "hpedestal";
43 const TString AliITSPreprocessorSDD::fgkNameHistoNoise = "hnoise";
44 ClassImp(AliITSPreprocessorSDD)
45
46 //______________________________________________________________________
47 AliITSPreprocessorSDD::AliITSPreprocessorSDD( AliShuttleInterface* shuttle):
48     AliPreprocessor("SDD", shuttle)
49 {
50   // constructor
51   AddRunType("PULSER");
52   AddRunType("INJECTOR");
53   AddRunType("PHYSICS"); 
54 }
55
56 //______________________________________________________________________
57 UInt_t AliITSPreprocessorSDD::Process(TMap* dcsAliasMap){
58
59
60   // Get DDL map from OCDB
61   AliCDBEntry* entry = GetFromOCDB("Calib", "DDLMapSDD");
62   if(!entry){
63     Log("DDL map file not found in OCDB.");  
64     return 2;
65   }
66   AliITSDDLModuleMapSDD* ddlmap = (AliITSDDLModuleMapSDD*)entry->GetObject();
67   if(!ddlmap){ 
68     Log("AliITSDDLModuleMapSDD object not in file.");
69     return 2;
70   }
71   ddlmap->PrintDDLMap();
72
73   //preprocessing
74   TString runType = GetRunType();
75   Int_t retcode=0;
76
77   if (runType == "PULSER"){
78     Log("Process FXS files from PULSER RUN");
79     retcode=ProcessPulser(ddlmap);
80   }else if(runType== "INJECTOR"){
81     Log("Process FXS files from INJECTOR RUN");
82     retcode=ProcessInjector(ddlmap);
83   }
84   if(retcode!=0) return retcode;
85
86   Log("Process DCS data");
87   Bool_t retcodedcs =ProcessDCSDataPoints(dcsAliasMap);
88   if(retcodedcs) return 0; 
89   else return 1;           
90
91 }
92 //______________________________________________________________________
93 UInt_t AliITSPreprocessorSDD::ProcessPulser(AliITSDDLModuleMapSDD* ddlmap){
94   // Process FXS files from PULSER run (baseline, noise, gain)
95   // returns 0 in case of success, 
96   //         1 in case of storage error, 
97   //         2 in case of error with input files
98   TObjArray calSDD(kNumberOfSDD);
99   calSDD.SetOwner(kFALSE);
100
101   Float_t baseline,rawnoise,cmn,corn,gain;
102   Int_t isgoodan,i,im,is,isgoodmod,basmin,basoff;
103   Int_t th,tl;
104   Int_t numOfBadChannels[kNumberOfSDD];
105   
106   TList* sourceList = GetFileSources(kDAQ, "SDD_Calib");
107   if (!sourceList){ 
108     Log("Error: no sources found for SDD_Calib");
109     return 2;
110   }
111
112   Int_t ind = 0;
113   while (sourceList->At(ind)!=NULL) {
114     TObjString* tarId = (TObjString*) sourceList->At(ind);
115     TString tarName = GetFile(kDAQ, "SDD_Calib", tarId->GetString().Data());
116     if(tarName.Length()==0){
117       Log(Form("Baseline tar file from source %d not found.",ind));
118       return 2;
119     }
120     TString command;
121     command.Form("tar -xf %s",tarName.Data());
122     gSystem->Exec(command);
123     ind++;
124   }
125   delete sourceList;
126   // Read ADC sampling frequency from fee.conf
127   Int_t amSamplFreq=40;
128   Int_t retfscf;
129   FILE* feefil=fopen("fee.conf","r");
130   if(feefil){
131     retfscf=fscanf(feefil,"%d \n",&amSamplFreq);
132     fclose(feefil);
133     Log(Form("AM sampling frequency = %d MHz",amSamplFreq));
134   }else{
135     Log("File fee.conf not found. AM sampling set at 40 MHz by default");
136   }
137   
138   for(Int_t iddl=0;iddl<kNumberOfDDL;iddl++){
139     for(Int_t imod=0;imod<kModulesPerDDL;imod++){
140       Int_t modID=ddlmap->GetModuleNumber(iddl,imod);
141       if(modID==-1) continue;
142       modID-=240; // to have SDD modules numbering from 0 to 260
143       AliITSCalibrationSDD *cal = new AliITSCalibrationSDD("simulated");
144       if(amSamplFreq!=40) cal->SetAMAt20MHz();
145       numOfBadChannels[modID]=0;
146       Int_t badch[kNumberOfChannels];
147       Bool_t sid0ok=kTRUE;
148       Bool_t sid1ok=kTRUE;
149       for(Int_t isid=0;isid<=1;isid++){
150         TString inpFileName;
151         inpFileName.Form("./SDDbase_ddl%02dc%02d_sid%d.data",iddl,imod,isid);
152
153         FILE* basFil = fopen(inpFileName,"read");
154         if (basFil == 0) {
155           Log(Form("File %s not found.",inpFileName.Data()));
156           if(isid==0){
157             sid0ok=kFALSE;
158             for(Int_t iChip=0; iChip<4; iChip++) cal->SetChipBad(iChip);
159             cal->SetDeadChannels(cal->GetDeadChannels()+256);
160             for(Int_t iAnode=0; iAnode<256; iAnode++) cal->SetBadChannel(iAnode,iAnode);
161           }else{
162             sid1ok=kFALSE;
163             for(Int_t iChip=4; iChip<8; iChip++) cal->SetChipBad(iChip);
164             cal->SetDeadChannels(cal->GetDeadChannels()+256);
165             for(Int_t iAnode=0; iAnode<256; iAnode++) cal->SetBadChannel(iAnode,iAnode+256);
166           }
167           continue;
168         }
169
170         retfscf=fscanf(basFil,"%d %d %d\n",&im,&is,&isgoodmod);
171         if(!isgoodmod){
172           if(isid==0){
173             sid0ok=kFALSE;
174             for(Int_t iChip=0; iChip<4; iChip++) cal->SetChipBad(iChip);
175           }else{
176             sid1ok=kFALSE;
177             for(Int_t iChip=4; iChip<8; iChip++) cal->SetChipBad(iChip);
178           }
179         }
180         retfscf=fscanf(basFil,"%d\n",&th);
181         retfscf=fscanf(basFil,"%d\n",&tl);
182         cal->SetZSLowThreshold(isid,tl);
183         cal->SetZSHighThreshold(isid,th);
184         for(Int_t ian=0;ian<(kNumberOfChannels/2);ian++){
185           retfscf=fscanf(basFil,"%d %d %f %d %d %f %f %f %f\n",&i,&isgoodan,&baseline,&basmin,&basoff,&rawnoise,&cmn,&corn,&gain);
186           Int_t ich=ian;
187           if(isid==1) ich+=256;
188           if(!isgoodan){ 
189             Int_t ibad=numOfBadChannels[modID];
190             badch[ibad]=ich;
191             numOfBadChannels[modID]++;
192           }
193           cal->SetBaseline(ich,baseline-basoff);
194           cal->SetNoiseAfterElectronics(ich,rawnoise);
195           cal->SetGain(ich,gain);
196         }
197         cal->SetDeadChannels(numOfBadChannels[modID]);
198         for(Int_t ibad=0;ibad<numOfBadChannels[modID];ibad++){
199           cal->SetBadChannel(ibad,badch[ibad]);
200         }
201         fclose(basFil);
202       }
203       if(!sid0ok && !sid1ok) cal->SetBad();
204       Log(Form("Put calib obj for module %d (DDL %d  Carlos %d)",modID,iddl,imod));
205       calSDD.AddAt(cal,modID);
206     }
207   }
208   AliCDBMetaData *md= new AliCDBMetaData();
209   md->SetResponsible("Francesco Prino");
210   md->SetBeamPeriod(0);
211   md->SetComment("AliITSCalibrationSDD from PEDESTAL+PULSER runs");
212   Bool_t retCode = Store("Calib","CalibSDD",&calSDD,md, 0, kTRUE);
213   if(retCode) return 0;
214   else return 1;
215 }
216 //______________________________________________________________________
217 UInt_t AliITSPreprocessorSDD::ProcessInjector(AliITSDDLModuleMapSDD* ddlmap){
218   // Process FXS files from injector events (INJECTOR or PHYSICS runs)
219   // returns 0 in case of success, 
220   //         1 in case of storage error, 
221   //         2 in case of error with input files
222   TObjArray vdrift(2*kNumberOfSDD);
223   vdrift.SetOwner(kFALSE);
224   Int_t evNumb,polDeg; 
225   UInt_t timeStamp,statusInj;
226   Bool_t modSet[2*kNumberOfSDD]; // flag modules with good inj.
227   for(Int_t ihyb=0; ihyb<2*kNumberOfSDD; ihyb++) modSet[ihyb]=0;
228   Double_t nPtLay3 = 0;
229   Double_t nPtLay4 = 0;
230
231   Double_t param[4];    // parameters of poly fit
232   Double_t minValP0=5.; // min value for param[0]
233   Double_t maxValP0=8.; // max value for param[0]
234   Double_t minValP1=0.; // min value for param[1]
235   Double_t aveCoefLay3[4]={0.,0.,0.,0.};  // average param for good mod.
236   Double_t aveCoefLay4[4]={0.,0.,0.,0.};  // average param for good mod.
237   Double_t defCoef[4]={6.53227,0.00128941,-5.14493e-06,0};  // default values for param
238   Float_t auxP;
239
240   TList* sourceList = GetFileSources(kDAQ, "SDD_Injec");
241   if (!sourceList){ 
242     Log("Error: no sources found for SDD_Injec");
243     return 2;
244   }
245   Int_t ind = 0;
246   while (sourceList->At(ind)!=NULL) {
247     TObjString* tarId = (TObjString*) sourceList->At(ind);
248     TString tarName = GetFile(kDAQ, "SDD_Injec", tarId->GetString().Data());
249     if(tarName.Length()==0){
250       Log(Form("Injector tar file from source %d not found.",ind));
251       return 2;
252     }
253     TString command;
254     command.Form("tar -xf %s",tarName.Data());
255     gSystem->Exec(command);
256     ind++;
257   }
258   delete sourceList;
259   Int_t retfscf;
260   
261
262   for(Int_t iddl=0;iddl<kNumberOfDDL;iddl++){
263     for(Int_t imod=0;imod<kModulesPerDDL;imod++){
264       Int_t modID=ddlmap->GetModuleNumber(iddl,imod);
265       if(modID==-1) continue;
266       modID-=240; // to have SDD modules numbering from 0 to 260
267       for(Int_t isid=0;isid<=1;isid++){
268         AliITSDriftSpeedArraySDD *arr=new AliITSDriftSpeedArraySDD();
269         TString inpFileName;
270         inpFileName.Form("./SDDinj_ddl%02dc%02d_sid%d.data",iddl,imod,isid);
271         FILE* injFil = fopen(inpFileName,"read");
272         if (injFil == 0) {
273           Log(Form("File %s not found.",inpFileName.Data()));
274           continue;
275         }
276         retfscf=fscanf(injFil,"%d",&polDeg);
277         while (!feof(injFil)){
278           retfscf=fscanf(injFil,"%d %u ",&evNumb,&timeStamp);
279           if(evNumb==-99){
280             statusInj=timeStamp;
281             arr->SetInjectorStatus(statusInj);
282           }else{
283             if(feof(injFil)) break;
284             for(Int_t ic=0;ic<4;ic++){ 
285               retfscf=fscanf(injFil,"%f ",&auxP);
286               param[ic]=auxP;
287             }
288
289             if(polDeg>=0 && polDeg<=AliITSDriftSpeedSDD::GetMaxPolDeg() && 
290                param[0]>minValP0 && param[0]<maxValP0 && param[1]>minValP1){
291               if(polDeg==3){
292                 if(modID<kNumberOfSDDLay3){ 
293                   for(Int_t ic=0;ic<4;ic++) aveCoefLay3[ic]+=param[ic];
294                   nPtLay3++;
295                 }else{ 
296                   for(Int_t ic=0;ic<4;ic++) aveCoefLay4[ic]+=param[ic];
297                   nPtLay4++;
298                 }
299               }
300               AliITSDriftSpeedSDD *dsp=new AliITSDriftSpeedSDD(evNumb,timeStamp,polDeg,param);
301               arr->AddDriftSpeed(dsp);
302               modSet[2*modID+isid]=1;
303             }else{
304               Log(Form("Module %d side %d not accepted, degree=%d, params=%g %g %g %g",modID+240,isid,polDeg,param[0],param[1],param[2],param[3]));
305             }
306           }
307         }
308         fclose(injFil);
309         Log(Form("Put calib obj for hybrid %d (DDL %d  Carlos %d)",2*modID+isid,iddl,imod));
310         if(modSet[2*modID+isid]) vdrift.AddAt(arr,2*modID+isid);
311       }
312     }
313   }
314
315   // set drift speed for modules with bad injectors
316   for(Int_t ic=0;ic<4;ic++){ 
317     if(nPtLay3>0) aveCoefLay3[ic]/=nPtLay3; // mean parameters
318     else aveCoefLay3[ic]=defCoef[ic]; // default parameters
319     if(nPtLay4>0) aveCoefLay4[ic]/=nPtLay4; // mean parameters
320     else aveCoefLay4[ic]=defCoef[ic]; // default parameters
321   }
322   AliITSDriftSpeedSDD *avdsp3=new AliITSDriftSpeedSDD(evNumb,timeStamp,3,aveCoefLay3);
323   AliITSDriftSpeedSDD *avdsp4=new AliITSDriftSpeedSDD(evNumb,timeStamp,3,aveCoefLay4);
324
325   // Check status of golden modules
326   Int_t idGoldenMod=-1, idGoldenSide=-1;
327   Int_t idGoldenModList[5]={319,319,321,243,243};
328   Int_t idGoldenSideList[5]={0,1,0,0,1};
329   AliITSDriftSpeedSDD* refSpeed=0x0;
330   for(Int_t iGold=0; iGold<5; iGold++){
331     Int_t indexG=2*(idGoldenModList[iGold]-240)+idGoldenSideList[iGold];
332     if(modSet[indexG]){
333       idGoldenMod=idGoldenModList[iGold];
334       idGoldenSide=idGoldenSideList[iGold];
335       AliITSDriftSpeedArraySDD* arrRef=(AliITSDriftSpeedArraySDD*)vdrift.At(indexG);
336       refSpeed=arrRef->GetDriftSpeedObject(0);
337       break;
338     }
339   }
340   TList* correctionList=0x0;
341   if(idGoldenMod>=240 && idGoldenSide>=0){
342     // Get rescaling corrections from OCDB
343     AliCDBEntry* entry = GetFromOCDB("Calib", "RescaleDriftSpeedSDD");
344     if(!entry){
345       Log("RescaleDriftSpeedSDD file not found in OCDB.");  
346     }
347     TList* fullList=(TList*)entry->GetObject();
348     if(!fullList){ 
349       Log("TList object not found in file.");
350     }
351     TString listName=Form("RefMod%d_Side%d",idGoldenMod,idGoldenSide);
352     correctionList=(TList*)fullList->FindObject(listName.Data());
353     if(!correctionList){
354       Log(Form("TList for requested module %d side %d not found",idGoldenMod,idGoldenSide));
355     }else{
356       Log(Form("Use module %d side %d as reference module",idGoldenMod,idGoldenSide));
357       if(refSpeed){
358         Log(Form("Drift speed params for golden module = %g %g %g %g",refSpeed->GetDriftSpeedParameter(0),refSpeed->GetDriftSpeedParameter(1),refSpeed->GetDriftSpeedParameter(2),refSpeed->GetDriftSpeedParameter(3)));
359       }else{
360         AliError("No drift speed object for golden module");
361       }
362     }
363   }
364   
365   for(Int_t ihyb=0; ihyb<2*kNumberOfSDDLay3; ihyb++){
366     AliITSDriftSpeedArraySDD *arr=new AliITSDriftSpeedArraySDD();
367     if(modSet[ihyb]==0){ 
368       Int_t iBadMod=ihyb/2+240;
369       Int_t iBadSide=ihyb%2;
370       Bool_t goldenUsed=kFALSE;
371       if(correctionList && refSpeed){
372         Double_t *params=RescaleDriftSpeedModule(correctionList,iBadMod,iBadSide,refSpeed);
373         if(params){
374           AliWarning(Form("No good injector events for mod. %d side %d --> use rescaled values from golden module",iBadMod,iBadSide));
375           AliITSDriftSpeedSDD* dspres=new AliITSDriftSpeedSDD(0,refSpeed->GetEventTimestamp(),3,params);
376           arr->AddDriftSpeed(dspres);
377           arr->SetInjectorStatus(1);
378           goldenUsed=kTRUE;
379         }
380       }
381       if(!goldenUsed){
382         AliWarning(Form("No good injector events for mod. %d side %d --> use average values for layer 3",iBadMod,iBadSide));
383         arr->AddDriftSpeed(avdsp3);
384         arr->SetInjectorStatus(0);
385       }
386       vdrift.AddAt(arr,ihyb);
387     }
388   }
389
390   for(Int_t ihyb=2*kNumberOfSDDLay3; ihyb<2*kNumberOfSDD; ihyb++){
391     if(modSet[ihyb]==0){ 
392       AliWarning(Form("No good injector events for mod. %d side %d --> use average values for layer 4",ihyb/2,ihyb%2));
393       AliITSDriftSpeedArraySDD *arr=new AliITSDriftSpeedArraySDD();
394       arr->AddDriftSpeed(avdsp4);
395       arr->SetInjectorStatus(0);
396       vdrift.AddAt(arr,ihyb);
397     }
398   }
399
400   AliCDBMetaData *md= new AliCDBMetaData();
401   md->SetResponsible("Francesco Prino");
402   md->SetBeamPeriod(0);
403   md->SetComment("AliITSDriftSpeedSDD from injector events");
404   Bool_t retCode = Store("Calib","DriftSpeedSDD",&vdrift,md,0, kTRUE);
405   if(retCode) return 0;
406   else return 1;
407 }
408
409 //______________________________________________________________________
410 Double_t* AliITSPreprocessorSDD::RescaleDriftSpeedModule(TList* theList,
411                                                          Int_t iBadMod, 
412                                                          Int_t iBadSide,
413                                                          const AliITSDriftSpeedSDD* refSpeed)
414   const
415 {
416   // Rescale driftSpeed for a drift region starting from values of golden module
417
418   if(!refSpeed) return 0x0;
419   TString hisName=Form("hRatioMod%d_Side%d",iBadMod,iBadSide);
420   TH1D* h=(TH1D*)theList->FindObject(hisName.Data());
421   if(!h) return 0x0;
422
423   TF1* fpoly=new TF1("fpoly","pol3",0.,255.);
424   for(Int_t iAnode=0; iAnode<256; iAnode++){
425     Double_t vref=refSpeed->GetDriftSpeedAtAnode((Double_t)iAnode);
426     Double_t vcorr=h->GetBinContent(iAnode+1)*vref;
427     h->SetBinContent(iAnode+1,vcorr);
428   }
429   h->Fit(fpoly,"RNQ");
430   Double_t *params=new Double_t[4];
431   for(Int_t iPar=0; iPar<4; iPar++) params[iPar]=fpoly->GetParameter(iPar);
432   delete fpoly;
433   return params;
434 }
435
436 //______________________________________________________________________
437 Bool_t AliITSPreprocessorSDD::ProcessDCSDataPoints(TMap* dcsAliasMap){
438   // Process DCS data
439   AliITSDCSAnalyzerSDD *dcs=new AliITSDCSAnalyzerSDD();
440   dcs->AnalyzeData(dcsAliasMap);
441   TObjArray refDCS(kNumberOfSDD);
442   refDCS.SetOwner(kFALSE);
443   for(Int_t imod=0;imod<kNumberOfSDD;imod++){
444     AliITSDCSDataSDD *dcsdata=dcs->GetDCSData(imod);
445     refDCS.Add(dcsdata);
446   }    
447   AliCDBMetaData *md= new AliCDBMetaData();
448   md->SetResponsible("Francesco Prino");
449   md->SetBeamPeriod(0);
450   md->SetComment("AliITSDCSDataSDD objects from DCS DB");
451   Bool_t retCode = StoreReferenceData("DCS","DataSDD",&refDCS,md);
452   return retCode;
453 }
454