TRD module
[u/mrichter/AliRoot.git] / TRD / TRDbase / AliTRDCalPad.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 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 //  TRD calibration class for parameters which saved per pad                 //
21 //                                                                           //
22 ///////////////////////////////////////////////////////////////////////////////
23
24 #include <TMath.h>
25 #include <TH2F.h>
26 #include <TH1F.h>
27 #include <TStyle.h>
28
29 //#include "AliMathBase.h"
30
31 #include "AliTRDCalPad.h"
32 #include "AliTRDCalROC.h"
33 #include "AliTRDCalDet.h"
34 #include "AliTRDpadPlane.h"
35 #include "AliTRDgeometry.h"
36
37 ClassImp(AliTRDCalPad)
38
39 //_____________________________________________________________________________
40 AliTRDCalPad::AliTRDCalPad():TNamed()
41 {
42   //
43   // AliTRDCalPad default constructor
44   //
45
46   for (Int_t idet = 0; idet < kNdet; idet++) {
47     fROC[idet] = 0;
48   }
49
50 }
51
52 //_____________________________________________________________________________
53 AliTRDCalPad::AliTRDCalPad(const Text_t *name, const Text_t *title)
54                 :TNamed(name,title)
55 {
56   //
57   // AliTRDCalPad constructor
58   //
59
60   for (Int_t isec = 0; isec < kNsect; isec++) {
61     for (Int_t ipla = 0; ipla < kNplan; ipla++) {
62       for (Int_t icha = 0; icha < kNcham; icha++) {
63         Int_t idet = GetDet(ipla,icha,isec);
64         fROC[idet] = new AliTRDCalROC(ipla,icha);
65       }
66     }
67   }
68
69 }
70
71 //_____________________________________________________________________________
72 AliTRDCalPad::AliTRDCalPad(const AliTRDCalPad &c)
73   :TNamed(c)
74 {
75   //
76   // AliTRDCalPad copy constructor
77   //
78
79   for (Int_t idet = 0; idet < kNdet; idet++) {
80     fROC[idet] = new AliTRDCalROC(*((AliTRDCalPad &) c).fROC[idet]);
81   }
82
83 }
84
85 //_____________________________________________________________________________
86 AliTRDCalPad::~AliTRDCalPad()
87 {
88   //
89   // AliTRDCalPad destructor
90   //
91
92   for (Int_t idet = 0; idet < kNdet; idet++) {
93     if (fROC[idet]) {
94       delete fROC[idet];
95       fROC[idet] = 0;
96     }
97   }
98
99 }
100
101 //_____________________________________________________________________________
102 AliTRDCalPad &AliTRDCalPad::operator=(const AliTRDCalPad &c)
103 {
104   //
105   // Assignment operator
106   //
107
108   if (this != &c) ((AliTRDCalPad &) c).Copy(*this);
109   return *this;
110
111 }
112
113 //_____________________________________________________________________________
114 void AliTRDCalPad::Copy(TObject &c) const
115 {
116   //
117   // Copy function
118   //
119
120   for (Int_t idet = 0; idet < kNdet; idet++) {
121     if (((AliTRDCalPad &) c).fROC[idet]) {
122       delete ((AliTRDCalPad &) c).fROC[idet];
123     }
124     ((AliTRDCalPad &) c).fROC[idet] = new AliTRDCalROC();
125     if (fROC[idet]) {
126       fROC[idet]->Copy(*((AliTRDCalPad &) c).fROC[idet]);
127     }
128   }
129
130   TObject::Copy(c);
131
132 }
133
134 //_____________________________________________________________________________
135 Bool_t AliTRDCalPad::ScaleROCs(const AliTRDCalDet* values)
136 {
137   // 
138   // Scales ROCs of this class with the values from the class <values>
139   // Is used if an AliTRDCalPad object defines local variations of a parameter
140   // defined per detector using a AliTRDCalDet class
141   //
142   
143   if (!values)
144     return kFALSE;
145   Bool_t result = kTRUE;
146   for (Int_t idet = 0; idet < kNdet; idet++) {
147     if (fROC[idet]) { 
148       if(!fROC[idet]->Multiply(values->GetValue(idet))) result = kFALSE;
149     }
150   }
151   return result;
152 }
153
154 //_____________________________________________________________________________
155 void AliTRDCalPad::SetCalROC(Int_t det, AliTRDCalROC* calroc)
156 {
157   // 
158   // Set the AliTRDCalROC to this one
159   //
160   
161   if (!calroc) return;
162   if (fROC[det]) { 
163     for(Int_t icol = 0; icol < calroc->GetNcols(); icol++){
164       for(Int_t irow = 0; irow < calroc->GetNrows(); irow++){
165         fROC[det]->SetValue(icol,irow,calroc->GetValue(icol,irow));
166       }
167     }
168   }
169
170 }
171 //_____________________________________________________________________________
172 Double_t AliTRDCalPad::GetMeanRMS(Double_t &rms, const AliTRDCalDet *calDet, Int_t type)
173 {
174     //
175     // Calculate mean an RMS of all rocs
176     // If calDet correct the CalROC from the detector coefficient
177     // type == 0 for gain and vdrift
178     // type == 1 for t0 
179     //
180   Double_t factor = 0.0;
181   if(type == 0) factor = 1.0;
182   Double_t sum = 0, sum2 = 0, n=0, val=0;
183   for (Int_t idet = 0; idet < kNdet; idet++) {
184     if(calDet) factor = calDet->GetValue(idet);
185     AliTRDCalROC *calRoc = fROC[idet];
186     if ( calRoc ){
187       for (Int_t irow=0; irow<calRoc->GetNrows(); irow++){
188         for (Int_t icol=0; icol<calRoc->GetNcols(); icol++){
189           if(type == 0) val = calRoc->GetValue(icol,irow)*factor;
190           else  val = calRoc->GetValue(icol,irow)+factor;
191           sum+=val;
192           sum2+=val*val;
193           n++;
194         }
195       }
196     }
197   }
198   Double_t n1 = 1./n;
199   Double_t mean = sum*n1;
200   rms  = TMath::Sqrt(TMath::Abs(sum2*n1-mean*mean));
201   return mean;
202 }
203
204 //_____________________________________________________________________________
205 Double_t AliTRDCalPad::GetMean(const AliTRDCalDet *calDet, Int_t type
206                              , AliTRDCalPad* const outlierPad)
207 {
208     //
209     // return mean of the mean of all ROCs
210     // If calDet correct the CalROC from the detector coefficient
211     // type == 0 for gain and vdrift
212     // type == 1 for t0 
213     //
214   Double_t factor = 0.0;
215   if(type == 0) factor = 1.0;
216   Double_t arr[kNdet];
217   Int_t n=0;
218   for (Int_t idet = 0; idet < kNdet; idet++) {
219     if(calDet) factor = calDet->GetValue(idet);
220     AliTRDCalROC *calRoc = fROC[idet];
221     if ( calRoc ){
222       AliTRDCalROC* outlierROC = 0;
223       if (outlierPad) outlierROC = outlierPad->GetCalROC(idet);
224       if(type == 0)  arr[n] = calRoc->GetMean(outlierROC)*factor;
225       else arr[n] = calRoc->GetMean(outlierROC)+factor;
226       n++;
227     }
228   }
229   return TMath::Mean(n,arr);
230 }
231
232 //_____________________________________________________________________________
233 Double_t AliTRDCalPad::GetRMS(const AliTRDCalDet *calDet, Int_t type
234                             , AliTRDCalPad* const outlierPad)
235 {
236     //
237     // return mean of the RMS of all ROCs
238     // If calDet correct the CalROC from the detector coefficient
239     // type == 0 for gain and vdrift
240     // type == 1 for t0 
241     //
242   Double_t factor = 0.0;
243   if(type == 0) factor = 1.0;
244   Double_t arr[kNdet];
245   Int_t n=0;
246   for (Int_t idet = 0; idet < kNdet; idet++) {
247     if(calDet) factor = calDet->GetValue(idet);
248     AliTRDCalROC *calRoc = fROC[idet];
249     if ( calRoc ){
250       AliTRDCalROC* outlierROC = 0;
251       if (outlierPad) outlierROC = outlierPad->GetCalROC(idet);
252       if(type == 0)  arr[n] = calRoc->GetRMS(outlierROC)*factor;
253       else  arr[n] = calRoc->GetRMS(outlierROC);
254       n++;
255     }
256   }
257     return TMath::Mean(n,arr);
258 }
259
260 //_____________________________________________________________________________
261 Double_t AliTRDCalPad::GetMedian(const AliTRDCalDet *calDet, Int_t type
262                                , AliTRDCalPad* const outlierPad)
263 {
264     //
265     // return mean of the median of all ROCs
266     // If AliTRDCalDet, the correct the CalROC from the detector coefficient
267     // type == 0 for gain and vdrift
268     // type == 1 for t0 
269     //
270   Double_t factor = 0.0;
271   if(type == 0) factor = 1.0;
272   Double_t arr[kNdet];
273   Int_t n=0;
274   for (Int_t idet = 0; idet < kNdet; idet++) {
275     if(calDet) factor = calDet->GetValue(idet);
276     AliTRDCalROC *calRoc = fROC[idet];
277     if ( calRoc ){
278       AliTRDCalROC* outlierROC = 0;
279       if (outlierPad) outlierROC = outlierPad->GetCalROC(idet);
280       if(type == 0)  arr[n] = calRoc->GetMedian(outlierROC)*factor;
281       else  arr[n] = calRoc->GetMedian(outlierROC)+factor;
282       n++;
283     }
284   }
285   return TMath::Mean(n,arr);
286 }
287
288 //_____________________________________________________________________________
289 Double_t AliTRDCalPad::GetLTM(Double_t *sigma, Double_t fraction
290                             , const AliTRDCalDet *calDet, Int_t type
291                             , AliTRDCalPad* const outlierPad)
292 {
293     //
294     // return mean of the LTM and sigma of all ROCs
295     // If calDet correct the CalROC from the detector coefficient
296     // type == 0 for gain and vdrift
297     // type == 1 for t0 
298     //
299   Double_t factor = 0.0;
300   if(type == 0) factor = 1.0;
301   Double_t arrm[kNdet];
302   Double_t arrs[kNdet];
303   Double_t *sTemp=0x0;
304   Int_t n=0;
305   
306   for (Int_t idet = 0; idet < kNdet; idet++) {
307     if(calDet) factor = calDet->GetValue(idet);
308     AliTRDCalROC *calRoc = fROC[idet];
309     if ( calRoc ){
310       if ( sigma ) sTemp=arrs+n;
311       AliTRDCalROC* outlierROC = 0;
312       if (outlierPad) outlierROC = outlierPad->GetCalROC(idet);
313       if(type == 0)  arrm[n] = calRoc->GetLTM(sTemp,fraction, outlierROC)*factor;
314       else arrm[n] = calRoc->GetLTM(sTemp,fraction, outlierROC)+factor;
315       n++;
316     }
317   }
318   if ( sigma ) *sigma = TMath::Mean(n,arrs);
319   return TMath::Mean(n,arrm);
320 }
321
322 //_____________________________________________________________________________
323 TH1F * AliTRDCalPad::MakeHisto1D(const AliTRDCalDet *calDet, Int_t typedet
324                                , Float_t min, Float_t max,Int_t type)
325 {
326   //
327   // make 1D histo
328   // type -1 = user defined range
329   //       0 = nsigma cut nsigma=min
330   // If calDet correct the CalROC from the detector coefficient
331   // typedet == 0 for gain and vdrift
332   // typedet == 1 for t0
333   //
334   Float_t kEpsilonr = 0.005;
335
336   Double_t factor = 0.0;
337   if(typedet == 0) factor = 1.0;
338  
339   if (type>=0){
340     if (type==0){
341       // nsigma range 
342       Float_t mean  = GetMean(calDet,typedet);
343       Float_t sigma = 0.0;
344       if(GetRMS(calDet,typedet) > kEpsilonr) sigma = GetRMS(calDet,typedet);
345       else {
346         Double_t rms = 0.0;
347         sigma = GetMeanRMS(rms,calDet,typedet);
348       }
349       Float_t nsigma = TMath::Abs(min);
350       sigma *= nsigma;
351       if(sigma < kEpsilonr) sigma = kEpsilonr;
352       min = mean-sigma;
353       max = mean+sigma;
354     }
355     if (type==1){
356       // fixed range
357       Float_t mean   = GetMedian(calDet,typedet);
358       Float_t  delta = min;
359       min = mean-delta;
360       max = mean+delta;
361     }
362     if (type==2){
363       //
364       // LTM mean +- nsigma
365       //
366       Double_t sigma;
367       Float_t mean  = GetLTM(&sigma,max,calDet,typedet);
368       sigma*=min;
369       if(sigma < kEpsilonr) sigma = kEpsilonr;
370       min = mean-sigma;
371       max = mean+sigma;
372     }
373   }
374   char  name[1000];
375   snprintf(name,1000,"%s Pad 1D",GetTitle());
376   TH1F * his = new TH1F(name,name,100, min,max);
377     for (Int_t idet = 0; idet < kNdet; idet++) {
378       if(calDet) factor = calDet->GetValue(idet);
379       if (fROC[idet]){
380         for (Int_t irow=0; irow<fROC[idet]->GetNrows(); irow++){
381           for (Int_t icol=0; icol<fROC[idet]->GetNcols(); icol++){
382             if(typedet == 0) his->Fill(fROC[idet]->GetValue(irow,icol)*factor);
383             else his->Fill(fROC[idet]->GetValue(irow,icol)+factor);
384           }
385         }
386       }
387     }
388     return his;
389 }
390
391 //_____________________________________________________________________________
392 TH2F *AliTRDCalPad::MakeHisto2DSmPl(Int_t sm, Int_t pl, const AliTRDCalDet *calDet
393                                   , Int_t typedet, Float_t min, Float_t max,Int_t type)
394 {
395   //
396   // Make 2D graph
397   // sm    - supermodule number
398   // pl    - plane number
399   // If calDet correct the CalROC from the detector coefficient
400   // typedet == 0 for gain and vdrift
401   // typedet == 1 for t0
402   //
403   gStyle->SetPalette(1);
404   Double_t factor = 0.0;
405   if(typedet == 0) factor = 1.0;
406
407   Float_t kEpsilon = 0.000000000001;
408   Float_t kEpsilonr = 0.005;
409
410   AliTRDgeometry *trdGeo = new AliTRDgeometry();
411
412   if (type>=0){
413     if (type==0){
414       // nsigma range
415       Float_t mean  = GetMean(calDet,typedet);
416       Float_t sigma = 0.0;
417       if(GetRMS(calDet,typedet) > kEpsilonr) sigma = GetRMS(calDet,typedet);
418       else {
419         Double_t rms = 0.0;
420         sigma = GetMeanRMS(rms,calDet,typedet);
421       }
422       Float_t nsigma = TMath::Abs(min);
423       sigma *= nsigma;
424       if(sigma < kEpsilonr) sigma = kEpsilonr;
425       min = mean-sigma;
426       max = mean+sigma;
427     }
428     if (type==1){
429       // fixed range
430       Float_t mean   = GetMedian(calDet,typedet);
431       Float_t  delta = min;
432       min = mean-delta;
433       max = mean+delta;
434     }
435     if (type==2){
436       //
437       // LTM mean +- nsigma
438       //
439       Double_t sigma;
440       Float_t mean  = GetLTM(&sigma,max,calDet,typedet);
441       sigma*=min;
442       if(sigma < kEpsilonr) sigma = kEpsilonr;
443       min = mean-sigma;
444       max = mean+sigma;
445     }
446   }
447   
448   AliTRDpadPlane *padPlane0 = trdGeo->GetPadPlane(pl,0);
449   Double_t row0    = padPlane0->GetRow0();
450   Double_t col0    = padPlane0->GetCol0();
451
452   char  name[1000];
453   snprintf(name,1000,"%s Pad 2D sm %d pl %d",GetTitle(),sm,pl);
454   TH2F * his = new TH2F( name, name, 76,-TMath::Abs(row0),TMath::Abs(row0),144,-TMath::Abs(col0),TMath::Abs(col0));
455
456   // Where we begin
457   Int_t offsetsmpl = 30*sm+pl;
458   
459
460   for (Int_t k = 0; k < kNcham; k++){
461     Int_t det = offsetsmpl+k*6;
462     if(calDet) factor = calDet->GetValue(det);
463     if (fROC[det]){
464       AliTRDCalROC * calRoc = fROC[det];
465       for (Int_t irow=0; irow<calRoc->GetNrows(); irow++){
466         for (Int_t icol=0; icol<calRoc->GetNcols(); icol++){
467           if (TMath::Abs(calRoc->GetValue(icol,irow))>kEpsilon){
468             Int_t binz     = 0;
469             Int_t kb       = kNcham-1-k;
470             Int_t krow     = calRoc->GetNrows()-1-irow;
471             Int_t kcol     = calRoc->GetNcols()-1-icol;
472             if(kb > 2) binz = 16*(kb-1)+12+krow+1;
473             else binz = 16*kb+krow+1; 
474             Int_t biny = kcol+1;
475             Float_t value = calRoc->GetValue(icol,irow);
476             if(typedet == 0) his->SetBinContent(binz,biny,value*factor);
477             else his->SetBinContent(binz,biny,value+factor);
478           }
479         }
480       }
481     }
482   }
483   his->SetXTitle("z (cm)");
484   his->SetYTitle("y (cm)");
485   his->SetStats(0);
486   his->SetMaximum(max);
487   his->SetMinimum(min);
488   delete trdGeo;
489   return his;
490 }
491
492 //_____________________________________________________________________________
493 TH2F *AliTRDCalPad::MakeHisto2DCh(Int_t ch, const AliTRDCalDet *calDet, Int_t typedet
494                                 , Float_t min, Float_t max,Int_t type)
495 {
496   //
497   // Make 2D graph mean value in z direction
498   // ch    - chamber
499   // If calDet correct the CalROC from the detector coefficient
500   // typedet == 0 for gain and vdrift
501   // typedet == 1 for t0
502   //
503   gStyle->SetPalette(1);
504   Double_t factor = 0.0;
505   if(typedet == 0) factor = 1.0;
506
507   Float_t kEpsilonr = 0.005;
508   
509   if (type>=0){
510     if (type==0){
511       // nsigma range
512       Float_t mean  = GetMean(calDet,typedet);
513       Float_t sigma = 0.0;
514       if(GetRMS(calDet,typedet) > kEpsilonr) sigma = GetRMS(calDet,typedet);
515       else {
516         Double_t rms = 0.0;
517         sigma = GetMeanRMS(rms,calDet,typedet);
518       }
519       Float_t nsigma = TMath::Abs(min);
520       sigma *= nsigma;
521       if(sigma < kEpsilonr) sigma = kEpsilonr;
522       min = mean-sigma;
523       max = mean+sigma;
524     }
525     if (type==1){
526       // fixed range
527       Float_t mean   = GetMedian(calDet,typedet);
528       Float_t  delta = min;
529       min = mean-delta;
530       max = mean+delta;
531     }
532     if (type==2){
533       //
534       // LTM mean +- nsigma
535       //
536       Double_t sigma;
537       Float_t mean  = GetLTM(&sigma,max,calDet,typedet);
538       sigma*=min;
539       if(sigma < kEpsilonr) sigma = kEpsilonr;
540       min = mean-sigma;
541       max = mean+sigma;
542     }
543   }
544
545   AliTRDgeometry *trdGeo = new AliTRDgeometry();
546       
547   Float_t kEpsilon = 0.000000000001;
548
549   Double_t poslocal[3]  = {0.0,0.0,0.0};
550   Double_t posglobal[3] = {0.0,0.0,0.0};
551   
552   char  name[1000];
553   snprintf(name,1000,"%s Pad 2D ch %d",GetTitle(),ch);
554   TH2F * his = new TH2F( name, name, 400,-400.0,400.0,400,-400.0,400.0);
555
556   // Where we begin
557   Int_t offsetch = 6*ch;
558   
559
560   for (Int_t isec = 0; isec < kNsect; isec++){
561     for(Int_t ipl = 0; ipl < kNplan; ipl++){
562       Int_t det = offsetch+isec*30+ipl;
563       if(calDet) factor = calDet->GetValue(det);
564       if (fROC[det]){
565         AliTRDCalROC * calRoc = fROC[det];
566         AliTRDpadPlane *padPlane = trdGeo->GetPadPlane(ipl,ch);
567         for (Int_t icol=0; icol<calRoc->GetNcols(); icol++){
568           poslocal[0] = trdGeo->GetTime0(ipl);
569           poslocal[2] = padPlane->GetRowPos(0);
570           poslocal[1] = padPlane->GetColPos(icol);
571           trdGeo->RotateBack(det,poslocal,posglobal);
572           Int_t binx = 1+TMath::Nint((posglobal[0]+400.0)*0.5);
573           Int_t biny = 1+TMath::Nint((posglobal[1]+400.0)*0.5);
574           Float_t value = 0.0;
575           Int_t nb = 0;
576           for (Int_t irow=0; irow<calRoc->GetNrows(); irow++){
577             if (TMath::Abs(calRoc->GetValue(icol,irow))>kEpsilon){
578               value += calRoc->GetValue(icol,irow);
579               nb++;         
580             }
581           }
582           if (nb > 0) {
583             value = value/nb;
584           }
585           if(typedet == 0) his->SetBinContent(binx,biny,value*factor);
586           else his->SetBinContent(binx,biny,value+factor);
587         }
588       }
589     }    
590   }
591   his->SetXTitle("x (cm)");
592   his->SetYTitle("y (cm)");
593   his->SetStats(0);
594   his->SetMaximum(max);
595   his->SetMinimum(min);
596   delete trdGeo;
597   return his;
598 }
599
600 //_____________________________________________________________________________
601 Bool_t AliTRDCalPad::Add(Float_t c1)
602 {
603     //
604     // add constant for all channels of all ROCs
605     //
606
607   Bool_t result = kTRUE;
608   for (Int_t idet = 0; idet < kNdet; idet++) {
609     if (fROC[idet]){
610       if(!fROC[idet]->Add(c1)) result = kFALSE;
611     }
612   }
613   return result;
614 }
615
616 //_____________________________________________________________________________
617 Bool_t AliTRDCalPad::Multiply(Float_t c1)
618 {
619     //
620     // multiply constant for all channels of all ROCs
621     //
622   Bool_t result = kTRUE;
623   for (Int_t idet = 0; idet < kNdet; idet++) {
624     if (fROC[idet]){
625       if(!fROC[idet]->Multiply(c1)) result = kFALSE;
626     }
627   }
628   return result;
629 }
630
631 //_____________________________________________________________________________
632 Bool_t AliTRDCalPad::Add(const AliTRDCalPad * pad, Double_t c1
633                        , const AliTRDCalDet * calDet1, const AliTRDCalDet *calDet2
634                        , Int_t type)
635 {
636     //
637     // add calpad channel by channel multiplied by c1 - all ROCs
638     // If calDet1 and calDet2, the correct the CalROC from the detector coefficient
639     // then you have calDet1 and the calPad together
640     // calDet2 and pad together
641     // typedet == 0 for gain and vdrift
642     // typedet == 1 for t0
643     //
644   Float_t kEpsilon = 0.000000000001;
645  
646   Double_t factor1 = 0.0;
647   Double_t factor2 = 0.0;
648   if(type == 0) {
649     factor1 = 1.0;
650     factor2 = 1.0;
651   }
652   Bool_t result = kTRUE;
653   for (Int_t idet = 0; idet < kNdet; idet++) {
654     if(calDet1) factor1 = calDet1->GetValue(idet);
655     if(calDet2) factor2 = calDet2->GetValue(idet);
656     if (fROC[idet]){
657       if(type == 0){
658         if(TMath::Abs(factor1) > kEpsilon){
659           if(!fROC[idet]->Add(pad->GetCalROC(idet),c1*factor2/factor1)) result = kFALSE;
660         }
661         else result = kFALSE;
662       }
663       else{
664         AliTRDCalROC *croc = new AliTRDCalROC((const AliTRDCalROC) *pad->GetCalROC(idet));
665         if(!croc->Add(factor2)) result = kFALSE;
666         if(!fROC[idet]->Add(croc,c1)) result = kFALSE;
667       }
668     }    
669   }
670   return result;
671 }
672
673 //_____________________________________________________________________________
674 Bool_t AliTRDCalPad::Multiply(const AliTRDCalPad * pad, const AliTRDCalDet * calDet1
675                             , const AliTRDCalDet *calDet2, Int_t type)
676 {
677     //
678     // multiply calpad channel by channel - all ROCs
679     // If calDet1 and calDet2, the correct the CalROC from the detector coefficient
680     // then you have calDet1 and the calPad together
681     // calDet2 and pad together
682     // typedet == 0 for gain and vdrift
683     // typedet == 1 for t0
684     //
685   Float_t kEpsilon = 0.000000000001;
686   Bool_t result = kTRUE;
687   Double_t factor1 = 0.0;
688   Double_t factor2 = 0.0;
689   if(type == 0){
690     factor1 = 1.0;
691     factor2 = 1.0;
692   }
693   for (Int_t idet = 0; idet < kNdet; idet++) {
694     if(calDet1) factor1 = calDet1->GetValue(idet);
695     if(calDet2) factor2 = calDet2->GetValue(idet);
696     if (fROC[idet]){
697       if(type == 0){
698         if(TMath::Abs(factor1) > kEpsilon){
699           AliTRDCalROC *croc = new AliTRDCalROC((const AliTRDCalROC) *pad->GetCalROC(idet));
700           if(!croc->Multiply(factor2)) result = kFALSE;
701           if(!fROC[idet]->Multiply(croc)) result = kFALSE;
702         }
703         else result = kFALSE;
704       }
705       else{
706         AliTRDCalROC *croc2 = new AliTRDCalROC((const AliTRDCalROC) *pad->GetCalROC(idet));
707         if(!croc2->Add(factor2)) result = kFALSE;
708         if(!fROC[idet]->Add(factor1)) result = kFALSE;
709         if(!fROC[idet]->Multiply(croc2)) result = kFALSE;
710         if(!fROC[idet]->Add(-factor1)) result = kFALSE;
711       }
712     }
713   }
714   return result;
715 }
716
717 //_____________________________________________________________________________
718 Bool_t AliTRDCalPad::Divide(const AliTRDCalPad * pad, const AliTRDCalDet * calDet1
719                           , const AliTRDCalDet *calDet2, Int_t type)
720 {
721     //
722     // divide calpad channel by channel - all ROCs
723     // If calDet1 and calDet2, the correct the CalROC from the detector coefficient
724     // then you have calDet1 and the calPad together
725     // calDet2 and pad together
726     // typedet == 0 for gain and vdrift
727     // typedet == 1 for t0
728     //
729   Float_t kEpsilon = 0.000000000001;
730   Bool_t result = kTRUE;
731   Double_t factor1 = 0.0;
732   Double_t factor2 = 0.0;
733   if(type == 0){
734     factor1 = 1.0;
735     factor2 = 1.0;
736   }
737   for (Int_t idet = 0; idet < kNdet; idet++) {
738     if(calDet1) factor1 = calDet1->GetValue(idet);
739     if(calDet2) factor2 = calDet2->GetValue(idet);
740     if (fROC[idet]){
741       if(type == 0){
742         if(TMath::Abs(factor1) > kEpsilon){
743           AliTRDCalROC *croc = new AliTRDCalROC((const AliTRDCalROC) *pad->GetCalROC(idet));
744           if(!croc->Multiply(factor2)) result = kFALSE;
745           if(!fROC[idet]->Divide(croc)) result = kFALSE;
746         }
747         else result = kFALSE;
748       }
749       else{
750         AliTRDCalROC *croc2 = new AliTRDCalROC((const AliTRDCalROC) *pad->GetCalROC(idet));
751         if(!croc2->Add(factor2)) result = kFALSE;
752         if(!fROC[idet]->Add(factor1)) result = kFALSE;
753         if(!fROC[idet]->Divide(croc2)) result = kFALSE;
754         if(!fROC[idet]->Add(-factor1)) result = kFALSE;
755       }
756     }
757   }
758   return result;
759 }