A bulk of changes to calculate statistical values corresponding to
[u/mrichter/AliRoot.git] / TPC / AliTPCcalibDButil.cxx
CommitLineData
892226be 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
17///////////////////////////////////////////////////////////////////////////////
18// //
19// Class providing the calculation of derived quantities (mean,rms,fits,...) //
20// of calibration entries //
21/*
22
23
24*/
25////////////////////////////////////////////////////////////////////////////////
26
27#include <TMath.h>
28#include <TVectorT.h>
29#include <TObjArray.h>
30#include <TGraph.h>
7390f655 31#include <TFile.h>
32#include <TDirectory.h>
892226be 33
34#include <AliDCSSensorArray.h>
35#include <AliDCSSensor.h>
36#include "AliTPCcalibDB.h"
37#include "AliTPCCalPad.h"
38#include "AliTPCCalROC.h"
39#include "AliTPCROC.h"
40#include "AliTPCmapper.h"
41#include "AliTPCParam.h"
6e7d7dc4 42#include "AliTPCCalibRaw.h"
892226be 43
44#include "AliTPCcalibDButil.h"
45
46ClassImp(AliTPCcalibDButil)
47AliTPCcalibDButil::AliTPCcalibDButil() :
48 TObject(),
49 fCalibDB(AliTPCcalibDB::Instance()),
50 fPadNoise(0x0),
51 fPedestals(0x0),
52 fPulserTmean(0x0),
53 fPulserTrms(0x0),
54 fPulserQmean(0x0),
55 fPulserOutlier(new AliTPCCalPad("PulserOutliers","PulserOutliers")),
56 fCETmean(0x0),
57 fCETrms(0x0),
58 fCEQmean(0x0),
59 fALTROMasked(0x0),
6e7d7dc4 60 fCalibRaw(0x0),
7390f655 61 fRefPadNoise(0x0),
62 fRefPedestals(0x0),
63 fRefPulserTmean(0x0),
64 fRefPulserTrms(0x0),
65 fRefPulserQmean(0x0),
66 fRefPulserOutlier(new AliTPCCalPad("RefPulserOutliers","RefPulserOutliers")),
67 fRefCETmean(0x0),
68 fRefCETrms(0x0),
69 fRefCEQmean(0x0),
70 fRefALTROMasked(0x0),
71 fRefCalibRaw(0x0),
892226be 72 fGoofieArray(0x0),
73 fMapper(new AliTPCmapper(0x0)),
74 fNpulserOutliers(-1),
7390f655 75 fIrocTimeOffset(0),
892226be 76 fCETmaxLimitAbs(1.5),
77 fPulTmaxLimitAbs(1.5),
78 fPulQmaxLimitAbs(5),
79 fPulQminLimit(11)
80{
81 //
82 // Default ctor
83 //
84}
85//_____________________________________________________________________________________
86AliTPCcalibDButil::~AliTPCcalibDButil()
87{
88 //
89 // dtor
90 //
91 delete fPulserOutlier;
7390f655 92 delete fRefPulserOutlier;
892226be 93 delete fMapper;
7390f655 94 if (fRefPadNoise) delete fRefPadNoise;
95 if (fRefPedestals) delete fRefPedestals;
96 if (fRefPulserTmean) delete fRefPulserTmean;
97 if (fRefPulserTrms) delete fRefPulserTrms;
98 if (fRefPulserQmean) delete fRefPulserQmean;
99 if (fRefCETmean) delete fRefCETmean;
100 if (fRefCETrms) delete fRefCETrms;
101 if (fRefCEQmean) delete fRefCEQmean;
102 if (fRefALTROMasked) delete fRefALTROMasked;
103 if (fRefCalibRaw) delete fRefCalibRaw;
104
892226be 105}
106//_____________________________________________________________________________________
107void AliTPCcalibDButil::UpdateFromCalibDB()
108{
109 //
110 // Update pointers from calibDB
111 //
112 fPadNoise=fCalibDB->GetPadNoise();
113 fPedestals=fCalibDB->GetPedestals();
114 fPulserTmean=fCalibDB->GetPulserTmean();
115 fPulserTrms=fCalibDB->GetPulserTrms();
116 fPulserQmean=fCalibDB->GetPulserQmean();
117 fCETmean=fCalibDB->GetCETmean();
118 fCETrms=fCalibDB->GetCETrms();
119 fCEQmean=fCalibDB->GetCEQmean();
120 fALTROMasked=fCalibDB->GetALTROMasked();
121 fGoofieArray=fCalibDB->GetGoofieSensors(fCalibDB->GetRun());
6e7d7dc4 122 fCalibRaw=fCalibDB->GetCalibRaw();
892226be 123 UpdatePulserOutlierMap();
124}
125//_____________________________________________________________________________________
7390f655 126void AliTPCcalibDButil::ProcessCEdata(const char* fitFormula, TVectorD &fitResultsA, TVectorD &fitResultsC,
127 Int_t &noutliersCE, AliTPCCalPad *outCE)
892226be 128{
129 //
130 // Process the CE data for this run
131 // the return TVectorD arrays contian the results of the fit
132 // noutliersCE contains the number of pads marked as outliers,
133 // not including masked and edge pads
134 //
135
136 //retrieve CE and ALTRO data
137 if (!fCETmean){
138 TString fitString(fitFormula);
139 fitString.ReplaceAll("++","#");
140 Int_t ndim=fitString.CountChar('#')+2;
141 fitResultsA.ResizeTo(ndim);
142 fitResultsC.ResizeTo(ndim);
143 fitResultsA.Zero();
144 fitResultsC.Zero();
145 noutliersCE=-1;
146 return;
147 }
148 noutliersCE=0;
149 //create outlier map
7390f655 150 AliTPCCalPad *out=0;
151 if (outCE) out=outCE;
152 else out=new AliTPCCalPad("outCE","outCE");
892226be 153 AliTPCCalROC *rocMasked=0x0;
154 //loop over all channels
155 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
156 AliTPCCalROC *rocData=fCETmean->GetCalROC(iroc);
157 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(iroc);
7390f655 158 AliTPCCalROC *rocOut=out->GetCalROC(iroc);
6e7d7dc4 159 if (!rocData) {
160 noutliersCE+=AliTPCROC::Instance()->GetNChannels(iroc);
7390f655 161 rocOut->Add(1.);
6e7d7dc4 162 continue;
163 }
892226be 164 //add time offset to IROCs
165 if (iroc<AliTPCROC::Instance()->GetNInnerSector())
166 rocData->Add(fIrocTimeOffset);
167 //select outliers
168 UInt_t nrows=rocData->GetNrows();
169 for (UInt_t irow=0;irow<nrows;++irow){
170 UInt_t npads=rocData->GetNPads(irow);
171 for (UInt_t ipad=0;ipad<npads;++ipad){
7390f655 172 rocOut->SetValue(irow,ipad,0);
892226be 173 //exclude masked pads
174 if (rocMasked && rocMasked->GetValue(irow,ipad)) {
7390f655 175 rocOut->SetValue(irow,ipad,1);
892226be 176 continue;
177 }
732e90a8 178 //exclude first two rows in IROC and last two rows in OROC
179 if (iroc<36){
180 if (irow<2) rocOut->SetValue(irow,ipad,1);
181 } else {
182 if (irow>nrows-3) rocOut->SetValue(irow,ipad,1);
183 }
892226be 184 //exclude edge pads
7390f655 185 if (ipad==0||ipad==npads-1) rocOut->SetValue(irow,ipad,1);
186 Float_t valTmean=rocData->GetValue(irow,ipad);
892226be 187 //exclude values that are exactly 0
188 if (valTmean==0) {
7390f655 189 rocOut->SetValue(irow,ipad,1);
892226be 190 ++noutliersCE;
191 }
192 // exclude channels with too large variations
193 if (TMath::Abs(valTmean)>fCETmaxLimitAbs) {
7390f655 194 rocOut->SetValue(irow,ipad,1);
892226be 195 ++noutliersCE;
196 }
197 }
198 }
199 }
200 //perform fit
201 TMatrixD dummy;
202 Float_t chi2A,chi2C;
7390f655 203 fCETmean->GlobalSidesFit(out,fitFormula,fitResultsA,fitResultsC,dummy,dummy,chi2A,chi2C);
204 if (!outCE) delete out;
892226be 205}
206//_____________________________________________________________________________________
207void AliTPCcalibDButil::ProcessCEgraphs(TVectorD &vecTEntries, TVectorD &vecTMean, TVectorD &vecTRMS, TVectorD &vecTMedian,
208 TVectorD &vecQEntries, TVectorD &vecQMean, TVectorD &vecQRMS, TVectorD &vecQMedian,
209 Float_t &driftTimeA, Float_t &driftTimeC )
210{
211 //
212 // Calculate statistical information from the CE graphs for drift time and charge
213 //
214
215 //reset arrays
216 vecTEntries.ResizeTo(72);
217 vecTMean.ResizeTo(72);
218 vecTRMS.ResizeTo(72);
219 vecTMedian.ResizeTo(72);
220 vecQEntries.ResizeTo(72);
221 vecQMean.ResizeTo(72);
222 vecQRMS.ResizeTo(72);
223 vecQMedian.ResizeTo(72);
224 vecTEntries.Zero();
225 vecTMean.Zero();
226 vecTRMS.Zero();
227 vecTMedian.Zero();
228 vecQEntries.Zero();
229 vecQMean.Zero();
230 vecQRMS.Zero();
231 vecQMedian.Zero();
232 driftTimeA=0;
233 driftTimeC=0;
234 TObjArray *arrT=fCalibDB->GetCErocTtime();
235 TObjArray *arrQ=fCalibDB->GetCErocQtime();
236 if (arrT){
237 for (Int_t isec=0;isec<74;++isec){
238 TGraph *gr=(TGraph*)arrT->At(isec);
239 if (!gr) continue;
240 TVectorD values;
241 Int_t npoints = gr->GetN();
242 values.ResizeTo(npoints);
243 Int_t nused =0;
6e7d7dc4 244 //skip first points, theres always some problems with finding the CE position
245 for (Int_t ipoint=4; ipoint<npoints; ipoint++){
246 if (gr->GetY()[ipoint]>500 && gr->GetY()[ipoint]<1020 ){
892226be 247 values[nused]=gr->GetY()[ipoint];
248 nused++;
249 }
250 }
251 //
252 if (isec<72) vecTEntries[isec]= nused;
253 if (nused>1){
254 if (isec<72){
255 vecTMedian[isec] = TMath::Median(nused,values.GetMatrixArray());
256 vecTMean[isec] = TMath::Mean(nused,values.GetMatrixArray());
257 vecTRMS[isec] = TMath::RMS(nused,values.GetMatrixArray());
258 } else if (isec==72){
259 driftTimeA=TMath::Median(nused,values.GetMatrixArray());
260 } else if (isec==73){
261 driftTimeC=TMath::Median(nused,values.GetMatrixArray());
262 }
263 }
264 }
265 }
266 if (arrQ){
6e7d7dc4 267 for (Int_t isec=0;isec<arrQ->GetEntriesFast();++isec){
892226be 268 TGraph *gr=(TGraph*)arrQ->At(isec);
269 if (!gr) continue;
270 TVectorD values;
271 Int_t npoints = gr->GetN();
272 values.ResizeTo(npoints);
273 Int_t nused =0;
274 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
275 if (gr->GetY()[ipoint]>500 && gr->GetY()[ipoint]<1000 ){
276 values[nused]=gr->GetY()[ipoint];
277 nused++;
278 }
279 }
280 //
6e7d7dc4 281 vecQEntries[isec]= nused;
892226be 282 if (nused>1){
283 vecQMedian[isec] = TMath::Median(nused,values.GetMatrixArray());
284 vecQMean[isec] = TMath::Mean(nused,values.GetMatrixArray());
285 vecQRMS[isec] = TMath::RMS(nused,values.GetMatrixArray());
286 }
287 }
288 }
289}
290
291//_____________________________________________________________________________________
292void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseMeanSenRegions,
293 TVectorD &vNoiseRMS, TVectorD &vNoiseRMSSenRegions,
294 Int_t &nonMaskedZero)
295{
296 //
297 // process noise data
298 // vNoiseMean/RMS contains the Mean/RMS noise of the complete TPC [0], IROCs only [1],
299 // OROCs small pads [2] and OROCs large pads [3]
300 // vNoiseMean/RMSsenRegions constains the same information, but only for the sensitive regions (edge pads, corners, IROC spot)
301 // nonMaskedZero contains the number of pads which show zero noise and were not masked. This might indicate an error
302 //
303
304 //set proper size and reset
305 const UInt_t infoSize=4;
306 vNoiseMean.ResizeTo(infoSize);
307 vNoiseMeanSenRegions.ResizeTo(infoSize);
308 vNoiseRMS.ResizeTo(infoSize);
309 vNoiseRMSSenRegions.ResizeTo(infoSize);
310 vNoiseMean.Zero();
311 vNoiseMeanSenRegions.Zero();
312 vNoiseRMS.Zero();
313 vNoiseRMSSenRegions.Zero();
314 nonMaskedZero=0;
315 //counters
316 TVectorD c(infoSize);
317 TVectorD cs(infoSize);
318 //tpc parameters
319 AliTPCParam par;
320 par.Update();
321 //retrieve noise and ALTRO data
322 if (!fPadNoise) return;
323 AliTPCCalROC *rocMasked=0x0;
324 //create IROC, OROC1, OROC2 and sensitive region masks
325 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
326 AliTPCCalROC *noiseROC=fPadNoise->GetCalROC(isec);
327 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec);
328 UInt_t nrows=noiseROC->GetNrows();
329 for (UInt_t irow=0;irow<nrows;++irow){
330 UInt_t npads=noiseROC->GetNPads(irow);
331 for (UInt_t ipad=0;ipad<npads;++ipad){
332 //don't use masked channels;
333 if (rocMasked && rocMasked->GetValue(irow,ipad)) continue;
334 Float_t noiseVal=noiseROC->GetValue(irow,ipad);
335 //check if noise==0
336 if (noiseVal==0) {
337 ++nonMaskedZero;
338 continue;
339 }
340 //check for nan
341 if ( !(noiseVal<10000000) ){
342 printf ("Warning: nan detected in (sec,row,pad - val): %02d,%02d,%03d - %.1f\n",isec,irow,ipad,noiseVal);
343 continue;
344 }
345 Int_t cpad=(Int_t)ipad-(Int_t)npads/2;
346 Int_t masksen=1; // sensitive pards are not masked (0)
347 if (ipad<2||npads-ipad-1<2) masksen=0; //don't mask edge pads (sensitive)
348 if (isec<AliTPCROC::Instance()->GetNInnerSector()){
349 //IROCs
350 if (irow>19&&irow<46){
351 if (TMath::Abs(cpad)<7) masksen=0; //IROC spot
352 }
353 Int_t type=1;
354 vNoiseMean[type]+=noiseVal;
355 vNoiseRMS[type]+=noiseVal*noiseVal;
356 ++c[type];
357 if (!masksen){
358 vNoiseMeanSenRegions[type]+=noiseVal;
359 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
360 ++cs[type];
361 }
362 } else {
363 //OROCs
364 //define sensive regions
365 if ((nrows-irow-1)<3) masksen=0; //last three rows in OROCs are sensitive
366 if ( irow>75 ){
367 Int_t padEdge=(Int_t)TMath::Min(ipad,npads-ipad);
368 if (padEdge<((((Int_t)irow-76)/4+1))*2) masksen=0; //OROC outer corners are sensitive
369 }
370 if ((Int_t)irow<par.GetNRowUp1()){
371 //OROC1
372 Int_t type=2;
373 vNoiseMean[type]+=noiseVal;
374 vNoiseRMS[type]+=noiseVal*noiseVal;
375 ++c[type];
376 if (!masksen){
377 vNoiseMeanSenRegions[type]+=noiseVal;
378 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
379 ++cs[type];
380 }
381 }else{
382 //OROC2
383 Int_t type=3;
384 vNoiseMean[type]+=noiseVal;
385 vNoiseRMS[type]+=noiseVal*noiseVal;
386 ++c[type];
387 if (!masksen){
388 vNoiseMeanSenRegions[type]+=noiseVal;
389 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
390 ++cs[type];
391 }
392 }
393 }
394 //whole tpc
395 Int_t type=0;
396 vNoiseMean[type]+=noiseVal;
397 vNoiseRMS[type]+=noiseVal*noiseVal;
398 ++c[type];
399 if (!masksen){
400 vNoiseMeanSenRegions[type]+=noiseVal;
401 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
402 ++cs[type];
403 }
404 }//end loop pads
405 }//end loop rows
406 }//end loop sectors (rocs)
407
408 //calculate mean and RMS
409 const Double_t verySmall=0.0000000001;
410 for (UInt_t i=0;i<infoSize;++i){
411 Double_t mean=0;
412 Double_t rms=0;
413 Double_t meanSen=0;
414 Double_t rmsSen=0;
415
416 if (c[i]>verySmall){
417// printf ("i: %d - m: %.3f, c: %.0f, r: %.3f\n",i,vNoiseMean[i],c[i],vNoiseRMS[i]);
418 mean=vNoiseMean[i]/c[i];
419 rms=vNoiseRMS[i];
420 rms=TMath::Sqrt(TMath::Abs(rms/c[i]-mean*mean));
421 }
422 vNoiseMean[i]=mean;
423 vNoiseRMS[i]=rms;
424
425 if (cs[i]>verySmall){
426 meanSen=vNoiseMeanSenRegions[i]/cs[i];
427 rmsSen=vNoiseRMSSenRegions[i];
428 rmsSen=TMath::Sqrt(TMath::Abs(rmsSen/cs[i]-meanSen*meanSen));
429 }
430 vNoiseMeanSenRegions[i]=meanSen;
431 vNoiseRMSSenRegions[i]=rmsSen;
432 }
433}
434
435//_____________________________________________________________________________________
436void AliTPCcalibDButil::ProcessPulser(TVectorD &vMeanTime)
437{
438 //
439 // Process the Pulser information
440 // vMeanTime: pulser mean time position in IROC-A, IROC-C, OROC-A, OROC-C
441 //
442
443 const UInt_t infoSize=4;
444 //reset counters to error number
445 vMeanTime.ResizeTo(infoSize);
446 vMeanTime.Zero();
447 //counter
448 TVectorD c(infoSize);
449 //retrieve pulser and ALTRO data
450 if (!fPulserTmean) return;
451 //
452 //get Outliers
453 AliTPCCalROC *rocOut=0x0;
454 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
455 AliTPCCalROC *tmeanROC=fPulserTmean->GetCalROC(isec);
456 if (!tmeanROC) continue;
457 rocOut=fPulserOutlier->GetCalROC(isec);
458 UInt_t nchannels=tmeanROC->GetNchannels();
459 for (UInt_t ichannel=0;ichannel<nchannels;++ichannel){
460 if (rocOut && rocOut->GetValue(ichannel)) continue;
461 Float_t val=tmeanROC->GetValue(ichannel);
462 Int_t type=isec/18;
463 vMeanTime[type]+=val;
464 ++c[type];
465 }
466 }
467 //calculate mean
468 for (UInt_t itype=0; itype<infoSize; ++itype){
469 if (c[itype]>0) vMeanTime[itype]/=c[itype];
470 else vMeanTime[itype]=0;
471 }
472}
473//_____________________________________________________________________________________
474void AliTPCcalibDButil::ProcessALTROConfig(Int_t &nMasked)
475{
476 //
477 // Get Values from ALTRO configuration data
478 //
479 nMasked=-1;
480 if (!fALTROMasked) return;
481 nMasked=0;
482 for (Int_t isec=0;isec<fALTROMasked->kNsec; ++isec){
483 AliTPCCalROC *rocMasked=fALTROMasked->GetCalROC(isec);
484 for (UInt_t ichannel=0; ichannel<rocMasked->GetNchannels();++ichannel){
485 if (rocMasked->GetValue(ichannel)) ++nMasked;
486 }
487 }
488}
489//_____________________________________________________________________________________
490void AliTPCcalibDButil::ProcessGoofie(TVectorD & vecEntries, TVectorD & vecMedian, TVectorD &vecMean, TVectorD &vecRMS)
491{
492 //
493 // Proces Goofie values, return statistical information of the currently set goofieArray
494 // The meaning of the entries are given below
495 /*
496 1 TPC_ANODE_I_A00_STAT
497 2 TPC_DVM_CO2
498 3 TPC_DVM_DriftVelocity
499 4 TPC_DVM_FCageHV
500 5 TPC_DVM_GainFar
501 6 TPC_DVM_GainNear
502 7 TPC_DVM_N2
503 8 TPC_DVM_NumberOfSparks
504 9 TPC_DVM_PeakAreaFar
505 10 TPC_DVM_PeakAreaNear
506 11 TPC_DVM_PeakPosFar
507 12 TPC_DVM_PeakPosNear
508 13 TPC_DVM_PickupHV
509 14 TPC_DVM_Pressure
510 15 TPC_DVM_T1_Over_P
511 16 TPC_DVM_T2_Over_P
512 17 TPC_DVM_T_Over_P
513 18 TPC_DVM_TemperatureS1
514 */
515 if (!fGoofieArray){
516 Int_t nsensors=19;
517 vecEntries.ResizeTo(nsensors);
518 vecMedian.ResizeTo(nsensors);
519 vecMean.ResizeTo(nsensors);
520 vecRMS.ResizeTo(nsensors);
521 vecEntries.Zero();
522 vecMedian.Zero();
523 vecMean.Zero();
524 vecRMS.Zero();
525 return;
526 }
527 Double_t kEpsilon=0.0000000001;
528 Double_t kBig=100000000000.;
529 Int_t nsensors = fGoofieArray->NumSensors();
530 vecEntries.ResizeTo(nsensors);
531 vecMedian.ResizeTo(nsensors);
532 vecMean.ResizeTo(nsensors);
533 vecRMS.ResizeTo(nsensors);
534 TVectorF values;
535 for (Int_t isensor=0; isensor<fGoofieArray->NumSensors();isensor++){
536 AliDCSSensor *gsensor = fGoofieArray->GetSensor(isensor);
537 if (gsensor && gsensor->GetGraph()){
538 Int_t npoints = gsensor->GetGraph()->GetN();
539 // filter zeroes
540 values.ResizeTo(npoints);
541 Int_t nused =0;
542 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
543 if (TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])>kEpsilon &&
544 TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])<kBig ){
545 values[nused]=gsensor->GetGraph()->GetY()[ipoint];
546 nused++;
547 }
548 }
549 //
550 vecEntries[isensor]= nused;
551 if (nused>1){
552 vecMedian[isensor] = TMath::Median(nused,values.GetMatrixArray());
553 vecMean[isensor] = TMath::Mean(nused,values.GetMatrixArray());
554 vecRMS[isensor] = TMath::RMS(nused,values.GetMatrixArray());
555 }
556 }
557 }
558}
7390f655 559//_____________________________________________________________________________________
560void AliTPCcalibDButil::ProcessPedestalVariations(TVectorF &pedestalDeviations)
561{
562 //
563 // check the variations of the pedestal data to the reference pedestal data
564 // thresholds are 0.5, 1.0, 1.5 and 2 timebins respectively.
565 //
566 const Int_t npar=4;
567 TVectorF vThres(npar); //thresholds
568 Int_t nActive=0; //number of active channels
569
570 //reset and set thresholds
571 pedestalDeviations.ResizeTo(npar);
572 for (Int_t i=0;i<npar;++i){
573 pedestalDeviations.GetMatrixArray()[i]=0;
574 vThres.GetMatrixArray()[i]=(i+1)*.5;
575 }
576 //check all needed data is available
577 if (!fRefPedestals || !fPedestals || !fALTROMasked || !fRefALTROMasked) return;
578 //loop over all channels
579 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
580 AliTPCCalROC *pROC=fPedestals->GetCalROC(isec);
581 AliTPCCalROC *pRefROC=fRefPedestals->GetCalROC(isec);
582 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
583 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
584 UInt_t nrows=mROC->GetNrows();
585 for (UInt_t irow=0;irow<nrows;++irow){
586 UInt_t npads=mROC->GetNPads(irow);
587 for (UInt_t ipad=0;ipad<npads;++ipad){
588 //don't use masked channels;
589 if (mROC ->GetValue(irow,ipad)) continue;
590 if (mRefROC->GetValue(irow,ipad)) continue;
591 Float_t deviation=TMath::Abs(pROC->GetValue(irow,ipad)-pRefROC->GetValue(irow,ipad));
592 for (Int_t i=0;i<npar;++i){
593 if (deviation>vThres[i])
594 ++pedestalDeviations.GetMatrixArray()[i];
595 }
596 ++nActive;
597 }//end ipad
598 }//ind irow
599 }//end isec
600 if (nActive>0){
601 for (Int_t i=0;i<npar;++i){
602 pedestalDeviations.GetMatrixArray()[i]/=nActive;
603 }
604 }
605}
606//_____________________________________________________________________________________
607void AliTPCcalibDButil::ProcessNoiseVariations(TVectorF &noiseDeviations)
608{
609 //
610 // check the variations of the noise data to the reference noise data
611 // thresholds are 5, 10, 15 and 20 percent respectively.
612 //
613 const Int_t npar=4;
614 TVectorF vThres(npar); //thresholds
615 Int_t nActive=0; //number of active channels
616
617 //reset and set thresholds
618 noiseDeviations.ResizeTo(npar);
619 for (Int_t i=0;i<npar;++i){
620 noiseDeviations.GetMatrixArray()[i]=0;
621 vThres.GetMatrixArray()[i]=(i+1)*.05;
622 }
623 //check all needed data is available
624 if (!fRefPadNoise || !fPadNoise || !fALTROMasked || !fRefALTROMasked) return;
625 //loop over all channels
626 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
627 AliTPCCalROC *nROC=fPadNoise->GetCalROC(isec);
628 AliTPCCalROC *nRefROC=fRefPadNoise->GetCalROC(isec);
629 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
630 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
631 UInt_t nrows=mROC->GetNrows();
632 for (UInt_t irow=0;irow<nrows;++irow){
633 UInt_t npads=mROC->GetNPads(irow);
634 for (UInt_t ipad=0;ipad<npads;++ipad){
635 //don't use masked channels;
636 if (mROC ->GetValue(irow,ipad)) continue;
637 if (mRefROC->GetValue(irow,ipad)) continue;
638 Float_t deviation=(nROC->GetValue(irow,ipad)/nRefROC->GetValue(irow,ipad))-1;
639 for (Int_t i=0;i<npar;++i){
640 if (deviation>vThres[i])
641 ++noiseDeviations.GetMatrixArray()[i];
642 }
643 ++nActive;
644 }//end ipad
645 }//ind irow
646 }//end isec
647 if (nActive>0){
648 for (Int_t i=0;i<npar;++i){
649 noiseDeviations.GetMatrixArray()[i]/=nActive;
650 }
651 }
652}
653//_____________________________________________________________________________________
654void AliTPCcalibDButil::ProcessPulserVariations(TVectorF &pulserQdeviations, Float_t &varQMean,
655 Int_t &npadsOutOneTB, Int_t &npadsOffAdd)
656{
657 //
658 // check the variations of the pulserQmean data to the reference pulserQmean data: pulserQdeviations
659 // thresholds are .5, 1, 5 and 10 percent respectively.
660 //
661 //
662 const Int_t npar=4;
663 TVectorF vThres(npar); //thresholds
664 Int_t nActive=0; //number of active channels
665
666 //reset and set thresholds
667 pulserQdeviations.ResizeTo(npar);
668 for (Int_t i=0;i<npar;++i){
669 pulserQdeviations.GetMatrixArray()[i]=0;
670 }
671 npadsOutOneTB=0;
672 npadsOffAdd=0;
673 varQMean=0;
674 vThres.GetMatrixArray()[0]=.005;
675 vThres.GetMatrixArray()[1]=.01;
676 vThres.GetMatrixArray()[2]=.05;
677 vThres.GetMatrixArray()[3]=.1;
678 //check all needed data is available
679 if (!fRefPulserTmean || !fPulserTmean || !fPulserQmean || !fRefPulserQmean || !fALTROMasked || !fRefALTROMasked) return;
680 //
681 UpdateRefPulserOutlierMap();
682 //loop over all channels
732e90a8 683 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
7390f655 684 AliTPCCalROC *pqROC=fPulserQmean->GetCalROC(isec);
685 AliTPCCalROC *pqRefROC=fRefPulserQmean->GetCalROC(isec);
686 AliTPCCalROC *ptROC=fPulserTmean->GetCalROC(isec);
732e90a8 687// AliTPCCalROC *ptRefROC=fRefPulserTmean->GetCalROC(isec);
7390f655 688 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
689 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
690 AliTPCCalROC *oROC=fPulserOutlier->GetCalROC(isec);
691 Float_t pt_mean=ptROC->GetMean(oROC);
692 UInt_t nrows=mROC->GetNrows();
693 for (UInt_t irow=0;irow<nrows;++irow){
694 UInt_t npads=mROC->GetNPads(irow);
695 for (UInt_t ipad=0;ipad<npads;++ipad){
696 //don't use masked channels;
697 if (mROC ->GetValue(irow,ipad)) continue;
698 if (mRefROC->GetValue(irow,ipad)) continue;
699 //don't user edge pads
700 if (ipad==0||ipad==npads-1) continue;
701 //data
702 Float_t pq=pqROC->GetValue(irow,ipad);
703 Float_t pqRef=pqRefROC->GetValue(irow,ipad);
704 Float_t pt=ptROC->GetValue(irow,ipad);
705// Float_t ptRef=ptRefROC->GetValue(irow,ipad);
706 //comparisons q
707 Float_t deviation=TMath::Abs(pq/pqRef-1);
708 for (Int_t i=0;i<npar;++i){
709 if (deviation>vThres[i])
710 ++pulserQdeviations.GetMatrixArray()[i];
711 }
712 if (pqRef>11&&pq<11) ++npadsOffAdd;
713 varQMean+=pq-pqRef;
714 //comparisons t
715 if (TMath::Abs(pt-pt_mean)>1) ++npadsOutOneTB;
716 ++nActive;
717 }//end ipad
718 }//ind irow
719 }//end isec
720 if (nActive>0){
721 for (Int_t i=0;i<npar;++i){
722 pulserQdeviations.GetMatrixArray()[i]/=nActive;
723 varQMean/=nActive;
724 }
725 }
726}
892226be 727//_____________________________________________________________________________________
728void AliTPCcalibDButil::UpdatePulserOutlierMap()
7390f655 729{
730 //
731 //
732 //
733 PulserOutlierMap(fPulserOutlier,fPulserTmean, fPulserQmean);
734}
735//_____________________________________________________________________________________
736void AliTPCcalibDButil::UpdateRefPulserOutlierMap()
737{
738 //
739 //
740 //
741 PulserOutlierMap(fRefPulserOutlier,fRefPulserTmean, fRefPulserQmean);
742}
743//_____________________________________________________________________________________
744void AliTPCcalibDButil::PulserOutlierMap(AliTPCCalPad *pulOut, const AliTPCCalPad *pulT, const AliTPCCalPad *pulQ)
892226be 745{
746 //
747 // Create a map that contains outliers from the Pulser calibration data.
748 // The outliers include masked channels, edge pads and pads with
749 // too large timing and charge variations.
7390f655 750 // fNpulserOutliers is the number of outliers in the Pulser calibration data.
892226be 751 // those do not contain masked and edge pads
752 //
7390f655 753 if (!pulT||!pulQ) {
892226be 754 //reset map
7390f655 755 pulOut->Multiply(0.);
892226be 756 fNpulserOutliers=-1;
757 return;
758 }
759 AliTPCCalROC *rocMasked=0x0;
760 fNpulserOutliers=0;
761
762 //Create Outlier Map
763 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
7390f655 764 AliTPCCalROC *tmeanROC=pulT->GetCalROC(isec);
765 AliTPCCalROC *qmeanROC=pulQ->GetCalROC(isec);
766 AliTPCCalROC *outROC=pulOut->GetCalROC(isec);
892226be 767 if (!tmeanROC||!qmeanROC) {
768 //reset outliers in this ROC
769 outROC->Multiply(0.);
770 continue;
771 }
772 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec);
773// Double_t dummy=0;
774// Float_t qmedian=qmeanROC->GetLTM(&dummy,.5);
775// Float_t tmedian=tmeanROC->GetLTM(&dummy,.5);
776 UInt_t nrows=tmeanROC->GetNrows();
777 for (UInt_t irow=0;irow<nrows;++irow){
778 UInt_t npads=tmeanROC->GetNPads(irow);
779 for (UInt_t ipad=0;ipad<npads;++ipad){
780 Int_t outlier=0,masked=0;
781 Float_t q=qmeanROC->GetValue(irow,ipad);
782 Float_t t=tmeanROC->GetValue(irow,ipad);
783 //masked channels are outliers
784 if (rocMasked && rocMasked->GetValue(irow,ipad)) masked=1;
785 //edge pads are outliers
786 if (ipad==0||ipad==npads-1) masked=1;
787 //channels with too large charge or timing deviation from the meadian are outliers
788// if (TMath::Abs(q-qmedian)>fPulQmaxLimitAbs || TMath::Abs(t-tmedian)>fPulTmaxLimitAbs) outlier=1;
789 if (q<fPulQminLimit && !masked) outlier=1;
790 //check for nan
791 if ( !(q<10000000) || !(t<10000000)) outlier=1;
792 outROC->SetValue(irow,ipad,outlier+masked);
793 fNpulserOutliers+=outlier;
794 }
795 }
796 }
797}
798//_____________________________________________________________________________________
799AliTPCCalPad* AliTPCcalibDButil::CreatePadTime0(Int_t model)
800{
801 //
802 // Create pad time0 object from pulser and/or CE data, depending on the selected model
803 // Model 0: normalise each readout chamber to its mean, outlier cutted, only Pulser
804 // Model 1: normalise IROCs/OROCs of each readout side to its mean, only Pulser
732e90a8 805 // Model 2: use CE data and a combination CE fit + pulser in the outlier regions.
892226be 806 //
807
808 AliTPCCalPad *padTime0=new AliTPCCalPad("PadTime0",Form("PadTime0-Model_%d",model));
809 // decide between different models
810 if (model==0||model==1){
811 TVectorD vMean;
812 if (model==1) ProcessPulser(vMean);
813 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
814 AliTPCCalROC *rocPulTmean=fPulserTmean->GetCalROC(isec);
815 if (!rocPulTmean) continue;
816 AliTPCCalROC *rocTime0=padTime0->GetCalROC(isec);
817 AliTPCCalROC *rocOut=fPulserOutlier->GetCalROC(isec);
818 Float_t mean=rocPulTmean->GetMean(rocOut);
819 //treat case where a whole partition is masked
820 if (mean==0) mean=rocPulTmean->GetMean();
821 if (model==1) {
822 Int_t type=isec/18;
823 mean=vMean[type];
824 }
825 UInt_t nrows=rocTime0->GetNrows();
826 for (UInt_t irow=0;irow<nrows;++irow){
827 UInt_t npads=rocTime0->GetNPads(irow);
828 for (UInt_t ipad=0;ipad<npads;++ipad){
829 Float_t time=rocPulTmean->GetValue(irow,ipad);
830 //in case of an outlier pad use the mean of the altro values.
831 //This should be the most precise guess in that case.
832 if (rocOut->GetValue(irow,ipad)) {
833 time=GetMeanAltro(rocPulTmean,irow,ipad,rocOut);
834 if (time==0) time=mean;
835 }
836 Float_t val=time-mean;
837 rocTime0->SetValue(irow,ipad,val);
838 }
839 }
840 }
732e90a8 841 } else if (model==2){
842 TVectorD vA,vC;
843 AliTPCCalPad outCE("outCE","outCE");
844 Int_t nOut;
845 ProcessCEdata("(sector<36)++gy++gx++(lx-134)++(sector<36)*(lx-134)",vA,vC,nOut,&outCE);
846 AliTPCCalPad *padFit=AliTPCCalPad::CreateCalPadFit("1++0++gy++0++(lx-134)++0",vA,vC);
847// AliTPCCalPad *padFit=AliTPCCalPad::CreateCalPadFit("1++(sector<36)++gy++gx++(lx-134)++(sector<36)*(lx-134)",vA,vC);
848 if (!padFit) return 0;
849 padTime0->Add(fCETmean);
850 padTime0->Add(padFit,-1);
851 TVectorD vFitROC;
852 TMatrixD mFitROC;
853 Float_t chi2;
854 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
855 AliTPCCalROC *rocPulTmean=fPulserTmean->GetCalROC(isec);
856 AliTPCCalROC *rocTime0=padTime0->GetCalROC(isec);
857 AliTPCCalROC *rocOutPul=fPulserOutlier->GetCalROC(isec);
858 AliTPCCalROC *rocOutCE=outCE.GetCalROC(isec);
859 rocTime0->GlobalFit(rocOutCE,kFALSE,vFitROC,mFitROC,chi2);
860 AliTPCCalROC *rocCEfit=AliTPCCalROC::CreateGlobalFitCalROC(vFitROC, isec);
861 Float_t mean=rocPulTmean->GetMean(rocOutPul);
862 if (mean==0) mean=rocPulTmean->GetMean();
863 UInt_t nrows=rocTime0->GetNrows();
864 for (UInt_t irow=0;irow<nrows;++irow){
865 UInt_t npads=rocTime0->GetNPads(irow);
866 for (UInt_t ipad=0;ipad<npads;++ipad){
867 Float_t timePulser=rocPulTmean->GetValue(irow,ipad)-mean;
868 if (rocOutCE->GetValue(irow,ipad)){
869 Float_t valOut=rocCEfit->GetValue(irow,ipad);
870 if (!rocOutPul->GetValue(irow,ipad)) valOut+=timePulser;
871 rocTime0->SetValue(irow,ipad,valOut);
872 }
873 }
874 }
875 delete rocCEfit;
876 }
877 delete padFit;
892226be 878 }
879
892226be 880 return padTime0;
881}
882//_____________________________________________________________________________________
883Float_t AliTPCcalibDButil::GetMeanAltro(const AliTPCCalROC *roc, const Int_t row, const Int_t pad, AliTPCCalROC *rocOut)
884{
885 if (roc==0) return 0.;
886 const Int_t sector=roc->GetSector();
887 AliTPCROC *tpcRoc=AliTPCROC::Instance();
888 const UInt_t altroRoc=fMapper->GetFEC(sector,row,pad)*8+fMapper->GetChip(sector,row,pad);
889 Float_t mean=0;
890 Int_t n=0;
891
892 //loop over a small range around the requested pad (+-10 rows/pads)
893 for (Int_t irow=row-10;irow<row+10;++irow){
894 if (irow<0||irow>(Int_t)tpcRoc->GetNRows(sector)-1) continue;
895 for (Int_t ipad=pad-10; ipad<pad+10;++ipad){
896 if (ipad<0||ipad>(Int_t)tpcRoc->GetNPads(sector,irow)-1) continue;
897 const UInt_t altroCurr=fMapper->GetFEC(sector,irow,ipad)*8+fMapper->GetChip(sector,irow,ipad);
898 if (altroRoc!=altroCurr) continue;
899 if ( rocOut && rocOut->GetValue(irow,ipad) ) continue;
900 Float_t val=roc->GetValue(irow,ipad);
901 mean+=val;
902 ++n;
903 }
904 }
905 if (n>0) mean/=n;
906 return mean;
907}
7390f655 908//_____________________________________________________________________________________
909void AliTPCcalibDButil::SetRefFile(const char* filename)
910{
911 //
912 // load cal pad objects form the reference file
913 //
914 TDirectory *currDir=gDirectory;
915 TFile f(filename);
916 fRefPedestals=(AliTPCCalPad*)f.Get("Pedestals");
917 fRefPadNoise=(AliTPCCalPad*)f.Get("PadNoise");
918 //pulser data
919 fRefPulserTmean=(AliTPCCalPad*)f.Get("PulserTmean");
920 fRefPulserTrms=(AliTPCCalPad*)f.Get("PulserTrms");
921 fRefPulserQmean=(AliTPCCalPad*)f.Get("PulserQmean");
922 //CE data
923 fRefCETmean=(AliTPCCalPad*)f.Get("CETmean");
924 fRefCETrms=(AliTPCCalPad*)f.Get("CETrms");
925 fRefCEQmean=(AliTPCCalPad*)f.Get("CEQmean");
926 //Altro data
927// fRefALTROAcqStart=(AliTPCCalPad*)f.Get("ALTROAcqStart");
928// fRefALTROZsThr=(AliTPCCalPad*)f.Get("ALTROZsThr");
929// fRefALTROFPED=(AliTPCCalPad*)f.Get("ALTROFPED");
930// fRefALTROAcqStop=(AliTPCCalPad*)f.Get("ALTROAcqStop");
931 fRefALTROMasked=(AliTPCCalPad*)f.Get("ALTROMasked");
932 f.Close();
933 currDir->cd();
934}
935