]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDCalibraFillHisto.cxx
hopefully the last refinements for correct type conversion in calibration
[u/mrichter/AliRoot.git] / TRD / AliTRDCalibraFillHisto.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 // AliTRDCalibraFillHisto                                                               
21 //                                                                             
22 // This class is for the TRD calibration of the relative gain factor, the drift velocity,
23 // the time 0 and the pad response function. It fills histos or vectors.        
24 // It can be used for the calibration per chamber but also per group of pads and eventually per pad.
25 // The user has to choose with the functions SetNz and SetNrphi the precision of the
26 // calibration (see AliTRDCalibraMode). 
27 // 2D Histograms (Histo2d) or vectors (Vector2d), then converted in Trees, will be filled
28 // from RAW DATA in a run or from reconstructed TRD tracks during the offline tracking 
29 // in the function "FollowBackProlongation" (AliTRDtracker)
30 // Per default the functions to fill are off.                                   
31 //                        
32 // Author:
33 //   R. Bailhache (R.Bailhache@gsi.de)
34 //                            
35 //////////////////////////////////////////////////////////////////////////////////////
36
37 #include <TTree.h>
38 #include <TProfile2D.h>
39 #include <TProfile.h>
40 #include <TFile.h>
41 #include <TChain.h>
42 #include <TStyle.h>
43 #include <TCanvas.h>
44 #include <TGraphErrors.h>
45 #include <TObjArray.h>
46 #include <TH1F.h>
47 #include <TH2I.h>
48 #include <TH2.h>
49 #include <TStopwatch.h>
50 #include <TMath.h>
51 #include <TDirectory.h>
52 #include <TROOT.h>
53
54 #include "AliLog.h"
55 #include "AliCDBManager.h"
56
57 #include "AliTRDCalibraFillHisto.h"
58 #include "AliTRDCalibraMode.h"
59 #include "AliTRDCalibraVector.h"
60 #include "AliTRDcalibDB.h"
61 #include "AliTRDCommonParam.h"
62 #include "AliTRDmcmTracklet.h"
63 #include "AliTRDpadPlane.h"
64 #include "AliTRDcluster.h"
65 #include "AliTRDtrack.h"
66
67
68 ClassImp(AliTRDCalibraFillHisto)
69
70 AliTRDCalibraFillHisto* AliTRDCalibraFillHisto::fgInstance = 0;
71 Bool_t AliTRDCalibraFillHisto::fgTerminated = kFALSE;
72
73 //_____________singleton implementation_________________________________________________
74 AliTRDCalibraFillHisto *AliTRDCalibraFillHisto::Instance()
75 {
76   //
77   // Singleton implementation
78   //
79
80   if (fgTerminated != kFALSE) {
81     return 0;
82   }
83
84   if (fgInstance == 0) {
85     fgInstance = new AliTRDCalibraFillHisto();
86   }
87
88   return fgInstance;
89
90 }
91
92 //______________________________________________________________________________________
93 void AliTRDCalibraFillHisto::Terminate()
94 {
95   //
96   // Singleton implementation
97   // Deletes the instance of this class
98   //
99
100   fgTerminated = kTRUE;
101
102   if (fgInstance != 0) {
103     delete fgInstance;
104     fgInstance = 0;
105   }
106
107 }
108
109 //______________________________________________________________________________________
110 AliTRDCalibraFillHisto::AliTRDCalibraFillHisto()
111   :TObject()
112   ,fMITracking(kFALSE)
113   ,fMcmTracking(kFALSE)
114   ,fMcmCorrectAngle(kFALSE)
115   ,fCH2dOn(kFALSE)
116   ,fPH2dOn(kFALSE)
117   ,fPRF2dOn(kFALSE)
118   ,fHisto2d(kFALSE)
119   ,fVector2d(kFALSE)
120   ,fRelativeScale(0)
121   ,fCountRelativeScale(0)
122   ,fRelativeScaleAuto(kFALSE)
123   ,fThresholdClusterPRF1(0.0)
124   ,fThresholdClusterPRF2(0.0)
125   ,fCenterOfflineCluster(kFALSE)
126   ,fWriteName(0)
127   ,fCalibraMode(0)
128   ,fDetectorAliTRDtrack(kFALSE)
129   ,fChamberAliTRDtrack(-1)
130   ,fDetectorPreviousTrack(-1)
131   ,fGoodTrack(kTRUE)
132   ,fAmpTotal(0x0)
133   ,fPHPlace(0x0)
134   ,fPHValue(0x0)
135   ,fNumberClusters(0)
136   ,fProcent(0.0)
137   ,fDifference(0)
138   ,fNumberTrack(0)
139   ,fTimeMax(0)
140   ,fSf(0.0)
141   ,fNumberBinCharge(0)
142   ,fNumberBinPRF(0)
143   ,fCalibraVector(0)
144   ,fPH2d(0x0)
145   ,fPRF2d(0x0)
146   ,fCH2d(0x0)
147 {
148   //
149   // Default constructor
150   //
151
152   fCalibraMode = new AliTRDCalibraMode();
153
154   // Write
155   for (Int_t i = 0; i < 3; i++) {
156     fWrite[i]     = kFALSE;
157   }
158
159   // Init
160   Init();
161   
162 }
163
164 //______________________________________________________________________________________
165 AliTRDCalibraFillHisto::AliTRDCalibraFillHisto(const AliTRDCalibraFillHisto &c)
166   :TObject(c)
167   ,fMITracking(kFALSE)
168   ,fMcmTracking(kFALSE)
169   ,fMcmCorrectAngle(kFALSE)
170   ,fCH2dOn(kFALSE)
171   ,fPH2dOn(kFALSE)
172   ,fPRF2dOn(kFALSE)
173   ,fHisto2d(kFALSE)
174   ,fVector2d(kFALSE)
175   ,fRelativeScale(0)
176   ,fCountRelativeScale(0)
177   ,fRelativeScaleAuto(kFALSE)
178   ,fThresholdClusterPRF1(0.0)
179   ,fThresholdClusterPRF2(0.0)
180   ,fCenterOfflineCluster(kFALSE)
181   ,fWriteName(0)
182   ,fCalibraMode(0)
183   ,fDetectorAliTRDtrack(kFALSE)
184   ,fChamberAliTRDtrack(-1)
185   ,fDetectorPreviousTrack(-1)
186   ,fGoodTrack(kTRUE)
187   ,fAmpTotal(0x0)
188   ,fPHPlace(0x0)
189   ,fPHValue(0x0)
190   ,fNumberClusters(0)
191   ,fProcent(0.0)
192   ,fDifference(0)
193   ,fNumberTrack(0)
194   ,fTimeMax(0)
195   ,fSf(0.0)
196   ,fNumberBinCharge(0)
197   ,fNumberBinPRF(0)
198   ,fCalibraVector(0)
199   ,fPH2d(0x0)
200   ,fPRF2d(0x0)
201   ,fCH2d(0x0) 
202 {
203   //
204   // Copy constructor
205   //
206
207 }
208
209 //____________________________________________________________________________________
210 AliTRDCalibraFillHisto::~AliTRDCalibraFillHisto()
211 {
212   //
213   // AliTRDCalibraFillHisto destructor
214   //
215
216   ClearHistos();
217   
218 }
219
220 //_____________________________________________________________________________
221 void AliTRDCalibraFillHisto::Destroy() 
222 {
223   //
224   // Delete instance 
225   //
226
227   if (fgInstance) {
228     delete fgInstance;
229     fgInstance = 0x0;
230   }
231
232 }
233
234 //_____________________________________________________________________________
235 void AliTRDCalibraFillHisto::ClearHistos() 
236 {
237   //
238   // Delete the histos
239   //
240
241   if (fPH2d) {
242     delete fPH2d;
243     fPH2d  = 0x0;
244   }
245   if (fCH2d) {
246     delete fCH2d;
247     fCH2d  = 0x0;
248   }
249   if (fPRF2d) {
250     delete fPRF2d;
251     fPRF2d = 0x0;
252   }
253
254 }
255
256 //_____________________________________________________________________________
257 void AliTRDCalibraFillHisto::Init() 
258 {
259   //
260   // Init some default values
261   //
262
263   // How to fill the 2D
264   fThresholdClusterPRF1 = 2.0;
265   fThresholdClusterPRF2 = 15.0;
266   
267   // Store the Info
268   fNumberBinCharge      = 100;
269   fNumberBinPRF         = 40;
270   
271   // Write
272   fWriteName            = "TRD.calibration.root";
273   
274   // Internal variables
275   
276   // Fill the 2D histos in the offline tracking
277   fDetectorPreviousTrack = -1;
278   fChamberAliTRDtrack    = -1;
279   fGoodTrack             = kTRUE;
280
281   fProcent               = 6.0;
282   fDifference            = 17;
283   fNumberClusters        = 18;
284   fNumberTrack           = 0;
285   fNumberUsedCh[0]       = 0;
286   fNumberUsedCh[1]       = 0;
287   fNumberUsedPh[0]       = 0;
288   fNumberUsedPh[1]       = 0;
289  
290 }
291
292 //____________Functions for initialising the AliTRDCalibraFillHisto in the code_________
293 Bool_t AliTRDCalibraFillHisto::Init2Dhistos()
294 {
295   //
296   // For the offline tracking
297   // This function will be called in the function AliReconstruction::Run() 
298   // Init the calibration mode (Nz, Nrphi), the 2D histograms if fHisto2d = kTRUE, 
299   //
300
301   // DB Setting
302   // Get cal
303   AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
304   if (!cal) {
305     AliInfo("Could not get calibDB");
306     return kFALSE;
307   }
308   AliTRDCommonParam *parCom = AliTRDCommonParam::Instance();
309   if (!parCom) {
310     AliInfo("Could not get CommonParam");
311     return kFALSE;
312   }
313
314   // Some parameters
315   fTimeMax = cal->GetNumberOfTimeBins();
316   fSf      = parCom->GetSamplingFrequency();
317   if (fRelativeScaleAuto) {
318     fRelativeScale = 0;
319   }
320   else {
321     fRelativeScale = 20;
322   }
323
324   //If vector method On initialised all the stuff
325   if(fVector2d){
326     fCalibraVector = new AliTRDCalibraVector();
327   }
328
329
330   // Create the 2D histos corresponding to the pad groupCalibration mode
331   if (fCH2dOn) {
332
333     AliInfo(Form("The pad calibration mode for the relative gain calibration: Nz %d, and Nrphi %d"
334                 ,fCalibraMode->GetNz(0)
335                 ,fCalibraMode->GetNrphi(0)));
336     
337     // Calcul the number of Xbins
338     Int_t Ntotal0 = 0;
339     fCalibraMode->ModePadCalibration(2,0);
340     fCalibraMode->ModePadFragmentation(0,2,0,0);
341     fCalibraMode->SetDetChamb2(0);
342     Ntotal0 += 6 * 18 * fCalibraMode->GetDetChamb2(0);
343     fCalibraMode->ModePadCalibration(0,0);
344     fCalibraMode->ModePadFragmentation(0,0,0,0);
345     fCalibraMode->SetDetChamb0(0);
346     Ntotal0 += 6 * 4 * 18 * fCalibraMode->GetDetChamb0(0);
347     AliInfo(Form("Total number of Xbins: %d",Ntotal0));
348
349     // Create the 2D histo
350     if (fHisto2d) {
351       CreateCH2d(Ntotal0);
352     }
353     if (fVector2d) {
354       fCalibraVector->SetNumberBinCharge(fNumberBinCharge);
355     }
356
357     // Variable
358     fAmpTotal = new Float_t[TMath::Max(fCalibraMode->GetDetChamb2(0),fCalibraMode->GetDetChamb0(0))];
359     for (Int_t k = 0; k < TMath::Max(fCalibraMode->GetDetChamb2(0),fCalibraMode->GetDetChamb0(0)); k++) {
360       fAmpTotal[k] = 0.0;
361     } 
362
363   }
364
365   if (fPH2dOn) {
366
367     AliInfo(Form("The pad calibration mode for the drift velocity calibration: Nz %d, and Nrphi %d"
368                 ,fCalibraMode->GetNz(1)
369                 ,fCalibraMode->GetNrphi(1)));
370     
371     // Calcul the number of Xbins
372     Int_t Ntotal1 = 0;
373     fCalibraMode->ModePadCalibration(2,1);
374     fCalibraMode->ModePadFragmentation(0,2,0,1);
375     fCalibraMode->SetDetChamb2(1);
376     Ntotal1 += 6 * 18 * fCalibraMode->GetDetChamb2(1);
377     fCalibraMode->ModePadCalibration(0,1);
378     fCalibraMode->ModePadFragmentation(0,0,0,1);
379     fCalibraMode->SetDetChamb0(1);
380     Ntotal1 += 6 * 4 * 18 * fCalibraMode->GetDetChamb0(1);
381     AliInfo(Form("Total number of Xbins: %d",Ntotal1));
382
383     // Create the 2D histo
384     if (fHisto2d) {
385       CreatePH2d(Ntotal1);
386     }
387     if (fVector2d) {
388       fCalibraVector->SetTimeMax(fTimeMax);
389     }
390    
391     // Variable
392     fPHPlace = new Short_t[fTimeMax];
393     for (Int_t k = 0; k < fTimeMax; k++) {
394       fPHPlace[k] = -1;
395     } 
396     fPHValue = new Float_t[fTimeMax];
397     for (Int_t k = 0; k < fTimeMax; k++) {
398       fPHValue[k] = 0.0;
399     }
400
401   }
402
403   if (fPRF2dOn) {
404
405     AliInfo(Form("The pad calibration mode for the PRF calibration: Nz %d, and Nrphi %d"
406                 ,fCalibraMode->GetNz(2)
407                 ,fCalibraMode->GetNrphi(2)));
408     
409     // Calcul the number of Xbins
410     Int_t Ntotal2 = 0;
411     fCalibraMode->ModePadCalibration(2,2);
412     fCalibraMode->ModePadFragmentation(0,2,0,2);
413     fCalibraMode->SetDetChamb2(2);
414     Ntotal2 += 6 * 18 * fCalibraMode->GetDetChamb2(2);
415     fCalibraMode->ModePadCalibration(0,2);
416     fCalibraMode->ModePadFragmentation(0,0,0,2);
417     fCalibraMode->SetDetChamb0(2);
418     Ntotal2 += 6 * 4 * 18 * fCalibraMode->GetDetChamb0(2);
419     AliInfo(Form("Total number of Xbins: %d",Ntotal2));
420
421     // Create the 2D histo
422     if (fHisto2d) {
423       CreatePRF2d(Ntotal2);
424     }
425     if (fVector2d) {
426       fCalibraVector->SetNumberBinPRF(fNumberBinPRF);
427     }
428   
429   }
430
431   return kTRUE;
432
433 }
434
435 //____________Functions for filling the histos in the code_____________________
436
437 //____________Offine tracking in the AliTRDtracker_____________________________
438 Bool_t AliTRDCalibraFillHisto::ResetTrack()
439 {
440   //
441   // For the offline tracking
442   // This function will be called in the function
443   // AliTRDtracker::FollowBackPropagation() at the beginning 
444   // Reset the parameter to know we have a new TRD track
445   //
446   
447   fDetectorAliTRDtrack = kFALSE;
448   return kTRUE;
449
450 }
451
452 //____________Offline tracking in the AliTRDtracker____________________________
453 Bool_t AliTRDCalibraFillHisto::UpdateHistograms(AliTRDcluster *cl, AliTRDtrack *t)
454 {
455   //
456   // For the offline tracking
457   // This function will be called in the function
458   // AliTRDtracker::FollowBackPropagation() in the loop over the clusters
459   // of TRD tracks 
460   // Fill the 2D histos or the vectors with the info of the clusters at
461   // the end of a detectors if the track is "good"
462   //
463
464   // Get the parameter object
465   AliTRDCommonParam *parCom = AliTRDCommonParam::Instance();
466   if (!parCom) {
467     AliInfo("Could not get CommonParam");
468     return kFALSE;
469   }
470
471   // Get the parameter object
472   AliTRDcalibDB     *cal    = AliTRDcalibDB::Instance();
473   if (!cal) {
474     AliInfo("Could not get calibDB");
475     return kFALSE;
476   }
477  
478   // Localisation of the detector
479   Int_t detector = cl->GetDetector();
480   Int_t chamber  = GetChamber(detector);
481   Int_t plane    = GetPlane(detector);
482
483   // Fill the infos for the previous clusters if not the same
484   // detector anymore or if not the same track
485   if (((detector != fDetectorPreviousTrack) || (!fDetectorAliTRDtrack)) && 
486       (fDetectorPreviousTrack != -1)) {
487     
488     fNumberTrack++;   
489     
490     // If the same track, then look if the previous detector is in
491     // the same plane, if yes: not a good track
492     if (fDetectorAliTRDtrack && 
493         (GetPlane(detector) <= GetPlane(fDetectorPreviousTrack))) {
494       fGoodTrack = kFALSE;
495     }
496
497     // Fill only if the track doesn't touch a masked pad or doesn't
498     // appear in the middle (fGoodTrack)
499     if (fGoodTrack) {
500
501       // Gain calibration
502       if (fCH2dOn) {
503         FillTheInfoOfTheTrackCH();
504       }
505       
506       // PH calibration
507       if (fPH2dOn) {
508         FillTheInfoOfTheTrackPH();    
509       }
510       
511     } // if a good track
512     
513     ResetfVariables();
514     
515   } // Fill at the end the charge
516   
517   // Calcul the position of the detector
518   if (detector != fDetectorPreviousTrack) {
519     LocalisationDetectorXbins(detector);
520   }
521
522   // Reset the good track for the PRF
523   Bool_t good = kTRUE;
524   
525   // Localisation of the cluster
526   Double_t pos[3] = { 0.0, 0.0, 0.0 };
527   pos[0] = cl->GetX();
528   pos[1] = cl->GetY();
529   pos[2] = cl->GetZ();
530   Int_t    time   = cl->GetLocalTimeBin();
531   
532   // Reset the detector
533   fDetectorPreviousTrack = detector;
534   fDetectorAliTRDtrack   = kTRUE;
535   
536   // Position of the cluster
537   AliTRDpadPlane *padplane = parCom->GetPadPlane(plane,chamber);
538   Int_t    row        = padplane->GetPadRowNumber(pos[2]);
539   Double_t offsetz    = padplane->GetPadRowOffset(row,pos[2]);
540   Double_t offsettilt = padplane->GetTiltOffset(offsetz);
541   Int_t    col        = padplane->GetPadColNumber(pos[1]+offsettilt);
542   
543   // See if we are not near a masked pad
544   if (!IsPadOn(detector,col,row)) {
545     good       = kFALSE;
546     fGoodTrack = kFALSE;
547   }
548
549   if (col > 0) {
550     if (!IsPadOn(detector,col-1,row)) {
551       fGoodTrack = kFALSE;
552       good       = kFALSE;
553     }
554   }
555
556   if (col < 143) {
557     if (!IsPadOn(detector,col+1,row)) {
558       fGoodTrack = kFALSE;
559       good       = kFALSE;
560     }
561   }
562
563   // Row of the cluster and position in the pad groups
564   Int_t posr[3] = { 0, 0, 0 };
565   if ((fCH2dOn)  && (fCalibraMode->GetNnZ(0) != 0)) {
566     posr[0] = (Int_t) row / fCalibraMode->GetNnZ(0);
567   }
568   if ((fPH2dOn)  && (fCalibraMode->GetNnZ(1) != 0)) {
569     posr[1] = (Int_t) row / fCalibraMode->GetNnZ(1);
570   }
571   if ((fPRF2dOn) && (fCalibraMode->GetNnZ(2) != 0)) {
572     posr[2] = (Int_t) row / fCalibraMode->GetNnZ(2);
573   }  
574       
575   // Col of the cluster and position in the pad groups
576   Int_t posc[3] = { 0, 0, 0 };
577   if ((fCH2dOn)  && (fCalibraMode->GetNnRphi(0) != 0)) {
578     posc[0] = (Int_t) col / fCalibraMode->GetNnRphi(0);
579   }
580   if ((fPH2dOn)  && (fCalibraMode->GetNnRphi(1) != 0)) {
581     posc[1] = (Int_t) col / fCalibraMode->GetNnRphi(1);
582   }
583   if ((fPRF2dOn) && (fCalibraMode->GetNnRphi(2) != 0)) {
584     posc[2] = (Int_t) col / fCalibraMode->GetNnRphi(2);
585   }
586
587   // Charge in the cluster
588   // For the moment take the abs
589   Float_t  q        = TMath::Abs(cl->GetQ());
590   Short_t  *signals = cl->GetSignals();
591  
592   // Correction due to the track angle
593   Float_t correction    = 1.0;
594   Float_t normalisation = 6.67;
595   if ((q >0) && (t->GetNdedx() > 0)) {
596     correction = t->GetClusterdQdl((t->GetNdedx() - 1)) / (normalisation);
597   }
598
599   // Fill the fAmpTotal with the charge
600   if (fCH2dOn) {
601     fAmpTotal[(Int_t) (posc[0]*fCalibraMode->GetNfragZ(0)+posr[0])] += correction;
602   }
603
604   // Fill the fPHPlace and value
605   if (fPH2dOn) {
606     fPHPlace[time] = posc[1]*fCalibraMode->GetNfragZ(1)+posr[1];
607     fPHValue[time] = correction;
608   }
609
610   // Fill direct the PRF
611   if ((fPRF2dOn) && (good)) {
612
613     Float_t yminus  = 0.0;
614     Float_t xcenter = 0.0;
615     Float_t ycenter = 0.0;
616     Float_t ymax    = 0.0;
617     Bool_t  echec   = kFALSE;
618     
619     if ((cl->From3pad()) && (!cl->IsUsed())) { 
620          
621       // Center 3 balanced and cut on the cluster shape
622       if ((((Float_t) signals[3]) > fThresholdClusterPRF2) && 
623           (((Float_t) signals[2]) > fThresholdClusterPRF2) && 
624           (((Float_t) signals[4]) > fThresholdClusterPRF2) && 
625           (((Float_t) signals[1]) < fThresholdClusterPRF1) && 
626           (((Float_t) signals[5]) < fThresholdClusterPRF1) && 
627           ((((Float_t) signals[2])*((Float_t) signals[4])/(((Float_t) signals[3])*((Float_t) signals[3]))) < 0.06)) {
628
629
630         //First calculate the position of the cluster and the y
631         //echec enables to repair cases where it fails
632         //
633         // Col correspond to signals[3]
634         if (fCenterOfflineCluster) {
635           xcenter = cl->GetCenter();
636         }
637         else {
638           // Security if the denomiateur is 0 
639           if ((((Float_t) (((Float_t) signals[3]) * ((Float_t) signals[3]))) / 
640                            ((Float_t) (((Float_t) signals[2]) * ((Float_t) signals[4])))) != 1.0) {
641             xcenter = 0.5 * (TMath::Log((Float_t) (((Float_t) signals[4]) / ((Float_t) signals[2]))))
642                           / (TMath::Log(((Float_t) (((Float_t) signals[3]) * ((Float_t) signals[3]))) 
643                                       / ((Float_t) (((Float_t) signals[2]) * ((Float_t) signals[4])))));
644           }
645           else {
646             echec = kTRUE;
647           }
648         }
649         //after having calculating the position calculate the y
650         if (TMath::Abs(xcenter) < 0.5) {
651           ycenter = (Float_t) (((Float_t) signals[3]) 
652                             / (((Float_t) signals[2]) + ((Float_t) signals[3]) + (((Float_t) signals[4]))));
653           yminus  = (Float_t) (((Float_t) signals[2]) 
654                             / (((Float_t) signals[2]) + ((Float_t) signals[3]) + (((Float_t) signals[4]))));
655           ymax    = (Float_t) (((Float_t) signals[4]) 
656                             / (((Float_t) signals[2]) + ((Float_t) signals[3]) + (((Float_t) signals[4]))));
657           //If the charge of the cluster is too far away from the corrected one cut
658           if ((TMath::Abs(((Float_t) signals[2]) + ((Float_t) signals[3]) + (((Float_t) signals[4])) - q) > 10.0)) {
659             echec = kTRUE;
660           }
661         }
662         else {
663           echec = kTRUE;
664         }
665       
666         //Then Fill the histo if no echec
667         //
668         // Fill only if it is in the drift region!
669         if ((((Float_t) (((Float_t) time) / fSf)) > 0.3) && (!echec)) {
670           if (fHisto2d) {
671             fPRF2d->Fill((fCalibraMode->GetXbins(2)+posc[2]*fCalibraMode->GetNfragZ(2)+posr[2]+0.5),xcenter,ycenter);
672             fPRF2d->Fill((fCalibraMode->GetXbins(2)+posc[2]*fCalibraMode->GetNfragZ(2)+posr[2]+0.5),-(xcenter+1.0),yminus);
673             fPRF2d->Fill((fCalibraMode->GetXbins(2)+posc[2]*fCalibraMode->GetNfragZ(2)+posr[2]+0.5),1.0-xcenter,ymax);
674           }
675           if (fVector2d) {
676             fCalibraVector->UpdateVectorPRF(fCalibraMode->GetXbins(2)+posc[2]*fCalibraMode->GetNfragZ(2)+posr[2],xcenter,ycenter);
677             fCalibraVector->UpdateVectorPRF(fCalibraMode->GetXbins(2)+posc[2]*fCalibraMode->GetNfragZ(2)+posr[2],-(xcenter+1.0),yminus);
678             fCalibraVector->UpdateVectorPRF(fCalibraMode->GetXbins(2)+posc[2]*fCalibraMode->GetNfragZ(2)+posr[2],1.0-xcenter,ymax);
679           }
680         } // If in the drift region
681       } // center 3 balanced and cut on the cluster shape
682     } // Cluster isole
683   } // PRF2dOn  
684   
685   return kTRUE;
686   
687 }
688
689 //____________Online trackling in AliTRDtrigger________________________________
690 Bool_t AliTRDCalibraFillHisto::UpdateHistogramcm(AliTRDmcmTracklet *trk)
691 {
692   //
693   // For the tracking
694   // This function will be called in the function AliTRDtrigger::TestTracklet
695   // before applying the pt cut on the tracklets 
696   // Fill the infos for the tracklets fTrkTest if the tracklets is "good"
697   //
698   
699   // Localisation of the Xbins involved
700   Int_t idect = trk->GetDetector();
701   LocalisationDetectorXbins(idect);
702
703   // Get the parameter object
704   AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
705   if (!cal) {
706     AliInfo("Could not get calibDB");
707     return kFALSE;
708   }
709    
710   // Reset
711   ResetfVariables();
712  
713   // Row of the tracklet and position in the pad groups
714   Int_t row     = trk->GetRow();
715   Int_t posr[3] = { 0, 0, 0 };
716   if ((fCH2dOn)  && (fCalibraMode->GetNnZ(0) != 0)) {
717     posr[0] = (Int_t) row / fCalibraMode->GetNnZ(0);
718   }
719   if ((fPH2dOn)  && (fCalibraMode->GetNnZ(1) != 0)) {
720     posr[1] = (Int_t) row / fCalibraMode->GetNnZ(1);
721   }
722   if ((fPRF2dOn) && (fCalibraMode->GetNnZ(2) != 0)) {
723     posr[2] = (Int_t) row / fCalibraMode->GetNnZ(2);
724   }
725  
726   // Eventuelle correction due to track angle in z direction
727   Float_t correction = 1.0;
728   if (fMcmCorrectAngle) {
729     Float_t z = trk->GetRowz();
730     Float_t r = trk->GetTime0();
731     correction = r / TMath::Sqrt((r*r+z*z));
732   }
733
734   // Boucle sur les clusters
735   // Condition on number of cluster: don't come from the middle of the detector
736   if (trk->GetNclusters() >= fNumberClusters) {
737
738     for (Int_t icl = 0; icl < trk->GetNclusters(); icl++) {
739
740       Float_t amp[3] = { 0.0, 0.0, 0.0 };
741       Int_t   time   = trk->GetClusterTime(icl);
742       Int_t   col    = trk->GetClusterCol(icl);
743             
744       amp[0] = trk->GetClusterADC(icl)[0] * correction;
745       amp[1] = trk->GetClusterADC(icl)[1] * correction;
746       amp[2] = trk->GetClusterADC(icl)[2] * correction;
747
748       
749       if ((amp[0] < 0.0) || 
750           (amp[1] < 0.0) || 
751           (amp[2] < 0.0)) {
752         continue;
753       }
754
755       // Col of cluster and position in the pad groups
756       Int_t posc[3] = { 0, 0, 0 };
757       if ((fCH2dOn)  && (fCalibraMode->GetNnRphi(0) != 0)) {
758         posc[0] = (Int_t) col / fCalibraMode->GetNnRphi(0);
759       }
760       if ((fPH2dOn)  && (fCalibraMode->GetNnRphi(1) != 0)) {
761         posc[1] = (Int_t) col / fCalibraMode->GetNnRphi(1);
762       }
763       if ((fPRF2dOn) && (fCalibraMode->GetNnRphi(2) != 0)) {
764         posc[2] = (Int_t) col / fCalibraMode->GetNnRphi(2);
765       }
766
767       // See if we are not near a masked pad
768       Bool_t good = kTRUE;
769       if (!IsPadOn(idect,col,row)) {
770         fGoodTrack = kFALSE;
771         good       = kFALSE;
772       }
773
774       if (col >   0) {
775         if (!IsPadOn(idect,col-1,row)) {
776           fGoodTrack = kFALSE;
777           good       = kFALSE;
778         }
779       }
780       
781       if (col < 143) {
782         if (!IsPadOn(idect,col+1,row)) {
783           fGoodTrack = kFALSE;
784           good       = kFALSE;
785         }
786       }
787
788       // Total spectrum
789       if (fPH2dOn) {
790         fPHPlace[time] = posc[1] * fCalibraMode->GetNfragZ(1) + posr[1];
791       }
792
793       if (fCH2dOn) {
794         fAmpTotal[(Int_t) (posc[0]*fCalibraMode->GetNfragZ(0)+posr[0])] += (Float_t) (amp[0]+amp[1]+amp[2]);
795       }
796       if (fPH2dOn) {
797         fPHValue[time] = (Float_t) (amp[0]+amp[1]+amp[2]);
798       }
799       
800             
801       // Fill PRF direct
802       if (fPRF2dOn && good) {
803         
804         if ((amp[0] > fThresholdClusterPRF2) && 
805             (amp[1] > fThresholdClusterPRF2) && 
806             (amp[2] > fThresholdClusterPRF2) && 
807             ((amp[0]*amp[2]/(amp[1]*amp[1])) < 0.06)) {
808         
809           // Security of the denomiateur is 0
810           if ((((Float_t) (((Float_t) amp[1]) * ((Float_t) amp[1]))) 
811              / ((Float_t) (((Float_t) amp[0]) * ((Float_t) amp[2])))) != 1.0) {
812             Float_t xcenter = 0.5 * (TMath::Log(amp[2] / amp[0]))
813                                   / (TMath::Log((amp[1]*amp[1]) / (amp[0]*amp[2])));
814             Float_t ycenter = amp[1] / (amp[0] + amp[1] + amp[2]);
815
816             if (TMath::Abs(xcenter) < 0.5) {
817               Float_t yminus = amp[0] / (amp[0]+amp[1]+amp[2]);
818               Float_t ymax   = amp[2] / (amp[0]+amp[1]+amp[2]);
819               // Fill only if it is in the drift region!
820               if (((Float_t) time / fSf) > 0.3) {
821                 if (fHisto2d) {
822                   fPRF2d->Fill((fCalibraMode->GetXbins(2)+posc[2]*fCalibraMode->GetNfragZ(2)+posr[2]+0.5),xcenter,ycenter);
823                   fPRF2d->Fill((fCalibraMode->GetXbins(2)+posc[2]*fCalibraMode->GetNfragZ(2)+posr[2]+0.5),-(xcenter+1.0),yminus);
824                   fPRF2d->Fill((fCalibraMode->GetXbins(2)+posc[2]*fCalibraMode->GetNfragZ(2)+posr[2]+0.5),(1.0-xcenter),ymax);
825                 }
826                 if (fVector2d) {
827                   fCalibraVector->UpdateVectorPRF((fCalibraMode->GetXbins(2)+posc[2]*fCalibraMode->GetNfragZ(2)+posr[2]),xcenter,ycenter);
828                   fCalibraVector->UpdateVectorPRF(fCalibraMode->GetXbins(2)+posc[2]*fCalibraMode->GetNfragZ(2)+posr[2],-(xcenter+1.0),yminus);
829                   fCalibraVector->UpdateVectorPRF(fCalibraMode->GetXbins(2)+posc[2]*fCalibraMode->GetNfragZ(2)+posr[2],(1.0-xcenter),ymax);
830                 }
831               }//in the drift region 
832             }//in the middle
833           }//denominateur security
834         }//cluster shape and thresholds
835       }//good and PRF On
836       
837     } // Boucle clusters
838     
839     // Fill the charge
840     if (fCH2dOn && fGoodTrack) {
841       FillTheInfoOfTheTrackCH();
842     }
843
844     // PH calibration
845     if (fPH2dOn && fGoodTrack) {
846       FillTheInfoOfTheTrackPH();        
847     }
848
849     fNumberTrack++;
850         
851   } // Condition on number of clusters
852
853   return kTRUE;
854   
855 }
856
857 //_____________________________________________________________________________
858 Bool_t AliTRDCalibraFillHisto::IsPadOn(Int_t detector, Int_t col, Int_t row) const
859 {
860   //
861   // Look in the choosen database if the pad is On.
862   // If no the track will be "not good"
863   //
864
865   // Get the parameter object
866   AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
867   if (!cal) {
868     AliInfo("Could not get calibDB");
869     return kFALSE;
870   }
871   
872   if (!cal->IsChamberInstalled(detector)     || 
873        cal->IsChamberMasked(detector)        ||
874        cal->IsPadMasked(detector,col,row)) {
875     return kFALSE;
876   }
877   else {
878     return kTRUE;
879   }
880   
881 }
882
883 //____________Functions for plotting the 2D____________________________________
884
885 //_____________________________________________________________________________
886 void AliTRDCalibraFillHisto::Plot2d()
887 {
888   //
889   // Plot the 2D histos 
890   //
891  
892   if (fPH2dOn) {
893     TCanvas *cph2d = new TCanvas("cph2d","",50,50,600,800);
894     cph2d->cd();
895     fPH2d->Draw("LEGO");
896   }
897   if (fCH2dOn) {
898     TCanvas *cch2d = new TCanvas("cch2d","",50,50,600,800);
899     cch2d->cd();
900     fCH2d->Draw("LEGO");
901   }
902   if (fPRF2dOn) {
903     TCanvas *cPRF2d = new TCanvas("cPRF2d","",50,50,600,800);
904     cPRF2d->cd();
905     fPRF2d->Draw("LEGO");
906   }
907
908 }
909
910 //____________Writing the 2D___________________________________________________
911
912 //_____________________________________________________________________________
913 Bool_t AliTRDCalibraFillHisto::Write2d()
914 {
915   //
916   // Write the 2D histograms or the vectors converted in trees in the file
917   // "TRD.calibration.root" 
918   //
919   
920   TFile *fout = TFile::Open(fWriteName,"RECREATE");
921   // Check if the file could be opened
922   if (!fout || !fout->IsOpen()) {
923     AliInfo("No File found!");
924     return kFALSE;
925   }
926   AliInfo(Form("Numbertrack: %d Numberusedch[0]: %d, Numberusedch[1]: %d Numberusedph[0]: %d, Numberusedph[1]: %d"
927               ,fNumberTrack
928               ,fNumberUsedCh[0]
929               ,fNumberUsedCh[1]
930               ,fNumberUsedPh[0]
931               ,fNumberUsedPh[1]));
932   
933   TStopwatch stopwatch;
934   stopwatch.Start();
935   AliInfo("Write2d");
936
937   if ((fCH2dOn ) && (fWrite[0])) {
938     if (fHisto2d) {
939       fout->WriteTObject(fCH2d);
940     }
941     if (fVector2d) {
942       TString name("Nz");
943       name += fCalibraMode->GetNz(0);
944       name += "Nrphi";
945       name += fCalibraMode->GetNrphi(0);
946       TTree *treeCH2d = fCalibraVector->ConvertVectorCTTreeHisto(fCalibraVector->GetVectorCH(),fCalibraVector->GetPlaCH(),"treeCH2d",(const char *) name);
947       fout->WriteTObject(treeCH2d);
948     }
949   }
950   if ((fPH2dOn ) && (fWrite[1])) {
951     if (fHisto2d) {
952       fout->WriteTObject(fPH2d);
953     }
954     if (fVector2d) {
955       TString name("Nz");
956       name += fCalibraMode->GetNz(1);
957       name += "Nrphi";
958       name += fCalibraMode->GetNrphi(1);
959       TTree *treePH2d = fCalibraVector->ConvertVectorPTreeHisto(fCalibraVector->GetVectorPH(),fCalibraVector->GetPlaPH(),"treePH2d",(const char *) name);
960       fout->WriteTObject(treePH2d);
961     }
962   }
963   if ((fPRF2dOn ) && (fWrite[2])) {
964     if (fHisto2d) {
965       fout->WriteTObject(fPRF2d);
966     }
967     if (fVector2d) {
968       TString name("Nz");
969       name += fCalibraMode->GetNz(2);
970       name += "Nrphi";
971       name += fCalibraMode->GetNrphi(2);
972       TTree *treePRF2d = fCalibraVector->ConvertVectorPTreeHisto(fCalibraVector->GetVectorPRF(),fCalibraVector->GetPlaPRF(),"treePRF2d",(const char *) name);
973       fout->WriteTObject(treePRF2d);
974     }
975   }
976   
977   fout->Close();
978   
979   AliInfo(Form("Execution time Write2d: R:%.2fs C:%.2fs"
980               ,stopwatch.RealTime(),stopwatch.CpuTime()));
981
982   return kTRUE;
983   
984 }
985
986 //____________Probe the histos_________________________________________________
987 Double_t *AliTRDCalibraFillHisto::StatH(TH2 *h, Int_t i)
988 {
989   //
990   // Check the number of stats in h, 0 is TH2I 1 is TProfile2D
991   // debug mode with 2 for TH2I and 3 for TProfile2D
992   // It gives a pointer to a Double_t[7] with the info following...
993   // [0] : number of calibration groups with entries
994   // [1] : minimal number of entries found
995   // [2] : calibration group number of the min
996   // [3] : maximal number of entries found
997   // [4] : calibration group number of the max
998   // [5] : mean number of entries found
999   // [6] : mean relativ error
1000   //
1001
1002   Double_t *info = new Double_t[7];
1003    
1004   // Number of Xbins (detectors or groups of pads)
1005   Int_t    nbins   = h->GetNbinsX(); //number of calibration groups
1006   Int_t    nybins  = h->GetNbinsY(); //number of bins per histo
1007
1008   // Initialise
1009   Double_t nbwe = 0; //number of calibration groups with entries
1010   Double_t minentries = 0; //minimal number of entries found
1011   Double_t maxentries = 0; //maximal number of entries found
1012   Double_t placemin = 0; //calibration group number of the min
1013   Double_t placemax = -1; //calibration group number of the max
1014   Double_t meanstats = 0.0; //mean number of entries over the calibration group with at least ome entry
1015   Double_t meanrelativerror = 0.0; //mean relativ error in the TProfile2D
1016
1017   Double_t counter = 0;
1018
1019   //Debug
1020   TH1F *NbEntries = 0x0;//distribution of the number of entries
1021   TH1F *NbEntriesPerGroup = 0x0;//Number of entries per group
1022   TProfile *NbEntriesPerSp = 0x0;//Number of entries for one supermodule
1023     
1024   // Beginning of the loop over the calibration groups 
1025   for (Int_t idect = 0; idect < nbins; idect++) {
1026
1027     TH1I *projch = (TH1I *) h->ProjectionY("projch",idect+1,idect+1,(Option_t *)"e");
1028     projch->SetDirectory(0);
1029     
1030     // Number of entries for this calibration group
1031     Double_t nentries = 0.0;
1032     if((i%2) == 0){
1033       for (Int_t k = 0; k < nybins; k++) {
1034         nentries += h->GetBinContent(h->GetBin(idect+1,k+1));
1035       }
1036     }
1037     else{
1038       for (Int_t k = 0; k < nybins; k++) {
1039         nentries += ((TProfile2D *)h)->GetBinEntries(h->GetBin(idect+1,k+1));
1040         if(h->GetBinContent(h->GetBin(idect+1,k+1)) != 0) {
1041           meanrelativerror += (h->GetBinError(h->GetBin(idect+1,k+1))
1042                             / (TMath::Abs(h->GetBinContent(h->GetBin(idect+1,k+1)))));
1043           counter++;
1044         } 
1045       }
1046     }
1047
1048     //Debug
1049     if(i > 1){
1050       if((!((Bool_t)NbEntries)) && (nentries > 0)){
1051         NbEntries = new TH1F("Number of entries","Number of entries"
1052                                ,100,(Int_t)nentries/2,nentries*2);
1053         NbEntries->SetDirectory(0);
1054         NbEntriesPerGroup = new TH1F("Number of entries per group","Number of entries per group"
1055                                ,nbins,0,nbins);
1056         NbEntriesPerGroup->SetDirectory(0);
1057         NbEntriesPerSp = new TProfile("Number of entries per supermodule","Number of entries per supermodule"
1058                                ,(Int_t)(nbins/18),0,(Int_t)(nbins/18));
1059         NbEntriesPerSp->SetDirectory(0);
1060       }
1061       if(NbEntries){
1062         if(nentries > 0) NbEntries->Fill(nentries);
1063         NbEntriesPerGroup->Fill(idect+0.5,nentries);
1064         NbEntriesPerSp->Fill((idect%((Int_t)(nbins/18)))+0.5,nentries);
1065       }
1066     }
1067
1068     //min amd max
1069     if(nentries > maxentries){
1070       maxentries = nentries;
1071       placemax = idect;
1072     }
1073     if(idect == 0) {
1074       minentries = nentries;
1075     }
1076     if(nentries < minentries){
1077       minentries = nentries;
1078       placemin = idect;
1079     }
1080     //nbwe
1081     if(nentries > 0) {
1082       nbwe++;
1083       meanstats += nentries;
1084     }
1085
1086   }//calibration groups loop
1087   
1088   if(nbwe > 0) meanstats /= nbwe;
1089   if(counter > 0) meanrelativerror /= counter;
1090
1091   AliInfo(Form("There are %f calibration groups with entries",nbwe));
1092   AliInfo(Form("The minimum number of entries is %f for the group %f",minentries,placemin));
1093   AliInfo(Form("The maximum number of entries is %f for the group %f",maxentries,placemax));
1094   AliInfo(Form("The mean number of entries is %f",meanstats));
1095   if((i%2) == 1) AliInfo(Form("The mean relative error is %f",meanrelativerror));
1096
1097   info[0] = nbwe;
1098   info[1] = minentries;
1099   info[2] = placemin;
1100   info[3] = maxentries;
1101   info[4] = placemax;
1102   info[5] = meanstats;
1103   info[6] = meanrelativerror;
1104
1105   if(i > 1){
1106     gStyle->SetPalette(1);
1107     gStyle->SetOptStat(1111);
1108     gStyle->SetPadBorderMode(0);
1109     gStyle->SetCanvasColor(10);
1110     gStyle->SetPadLeftMargin(0.13);
1111     gStyle->SetPadRightMargin(0.01);
1112     TCanvas *stat = new TCanvas("stat","",50,50,600,800);
1113     stat->Divide(2,1);
1114     stat->cd(1);
1115     NbEntries->Draw("");
1116     stat->cd(2);
1117     NbEntriesPerSp->SetStats(0);
1118     NbEntriesPerSp->Draw("");
1119     TCanvas *stat1 = new TCanvas("stat1","",50,50,600,800);
1120     stat1->cd();
1121     NbEntriesPerGroup->SetStats(0);
1122     NbEntriesPerGroup->Draw("");
1123   }
1124
1125   return info;
1126
1127 }
1128
1129 //_____________________________________________________________________________
1130 void AliTRDCalibraFillHisto::SetRelativeScale(Float_t RelativeScale)
1131 {
1132   //
1133   // Set the factor that will divide the deposited charge
1134   // to fit in the histo range [0,300]
1135   //
1136  
1137   if (RelativeScale > 0.0) {
1138     fRelativeScale = RelativeScale;
1139   } 
1140   else {
1141     AliInfo("RelativeScale must be strict positif!");
1142   }
1143
1144
1145
1146 //_____________________________________________________________________________
1147 void AliTRDCalibraFillHisto::SetNz(Int_t i, Short_t Nz)
1148 {
1149   //
1150   // Set the mode of calibration group in the z direction for the parameter i
1151   // 
1152
1153   if ((Nz >= 0) && 
1154       (Nz <  5)) {
1155     fCalibraMode->SetNz(i, Nz); 
1156   }
1157   else { 
1158     AliInfo("You have to choose between 0 and 4");
1159   }
1160
1161 }
1162
1163 //_____________________________________________________________________________
1164 void AliTRDCalibraFillHisto::SetNrphi(Int_t i, Short_t Nrphi)
1165 {
1166   //
1167   // Set the mode of calibration group in the rphi direction for the parameter i
1168   //
1169  
1170   if ((Nrphi >= 0) && 
1171       (Nrphi <  7)) {
1172     fCalibraMode->SetNrphi(i ,Nrphi); 
1173   }
1174   else {
1175     AliInfo("You have to choose between 0 and 6");
1176   }
1177
1178 }
1179
1180 //____________Protected Functions______________________________________________
1181 //____________Create the 2D histo to be filled online__________________________
1182 //
1183
1184 //_____________________________________________________________________________
1185 void AliTRDCalibraFillHisto::CreatePRF2d(Int_t nn)
1186 {
1187   //
1188   // Create the 2D histos
1189   //
1190
1191   TString name("Nz");
1192   name += fCalibraMode->GetNz(2);
1193   name += "Nrphi";
1194   name += fCalibraMode->GetNrphi(2);
1195
1196   fPRF2d = new TProfile2D("PRF2d",(const Char_t *) name
1197                                  ,nn,0,nn,fNumberBinPRF,-1.5,1.5);
1198   fPRF2d->SetXTitle("Det/pad groups");
1199   fPRF2d->SetYTitle("Position x/W [pad width units]");
1200   fPRF2d->SetZTitle("Q_{i}/Q_{total}");
1201   fPRF2d->SetStats(0);
1202
1203 }
1204
1205 //_____________________________________________________________________________
1206 void AliTRDCalibraFillHisto::CreatePH2d(Int_t nn)
1207 {
1208   //
1209   // Create the 2D histos
1210   //
1211
1212   TString name("Nz");
1213   name += fCalibraMode->GetNz(1);
1214   name += "Nrphi";
1215   name += fCalibraMode->GetNrphi(1);
1216
1217   fPH2d = new TProfile2D("PH2d",(const Char_t *) name
1218                                ,nn,0,nn,fTimeMax
1219                                ,-0.5/fSf,(Float_t) (fTimeMax-0.5)/fSf);
1220   fPH2d->SetXTitle("Det/pad groups");
1221   fPH2d->SetYTitle("time [#mus]");
1222   fPH2d->SetZTitle("<PH> [a.u.]");
1223   fPH2d->SetStats(0);
1224
1225 }
1226
1227 //_____________________________________________________________________________
1228 void AliTRDCalibraFillHisto::CreateCH2d(Int_t nn)
1229 {
1230   //
1231   // Create the 2D histos
1232   //
1233
1234   TString name("Nz");
1235   name += fCalibraMode->GetNz(0);
1236   name += "Nrphi";
1237   name += fCalibraMode->GetNrphi(0);
1238
1239   fCH2d = new TH2I("CH2d",(const Char_t *) name
1240                          ,nn,0,nn,fNumberBinCharge,0,300);
1241   fCH2d->SetXTitle("Det/pad groups");
1242   fCH2d->SetYTitle("charge deposit [a.u]");
1243   fCH2d->SetZTitle("counts");
1244   fCH2d->SetStats(0);
1245   fCH2d->Sumw2();
1246
1247 }
1248
1249 //____________Offine tracking in the AliTRDtracker_____________________________
1250 void AliTRDCalibraFillHisto::FillTheInfoOfTheTrackCH()
1251 {
1252   //
1253   // For the offline tracking or mcm tracklets
1254   // This function will be called in the functions UpdateHistogram... 
1255   // to fill the info of a track for the relativ gain calibration
1256   //
1257         
1258   Int_t nb =  0; // Nombre de zones traversees
1259   Int_t fd = -1; // Premiere zone non nulle
1260   
1261   
1262   // See if the track goes through different zones
1263   for (Int_t k = 0; k < fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0); k++) {
1264     if (fAmpTotal[k] > 0.0) {
1265       nb++;
1266       if (nb == 1) {
1267         fd = k;
1268       }
1269     }
1270   }
1271  
1272   // If automatic scale
1273   if ((fCountRelativeScale < 100) && (fRelativeScaleAuto)) {
1274     // Take only the one zone track
1275     if (nb == 1) {
1276       fRelativeScale += fAmpTotal[fd] * 0.014 * 0.01;
1277       fCountRelativeScale++;
1278     }
1279   }
1280
1281   // We fill the CH2d after having scale with the first 100
1282   if ((fCountRelativeScale >= 100) && (fRelativeScaleAuto)) {
1283     // Case of track with only one zone
1284     if (nb == 1) {
1285       if (fHisto2d) {
1286         fCH2d->Fill(fCalibraMode->GetXbins(0)+fd+0.5,fAmpTotal[fd]/fRelativeScale);
1287       }
1288       if (fVector2d) {
1289         fCalibraVector->UpdateVectorCH(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1290       }
1291     } // Case 1 zone
1292     // Case of track with two zones
1293     if (nb == 2) {
1294       // Two zones voisines sinon rien!
1295       if ((fAmpTotal[fd]   > 0.0) && 
1296           (fAmpTotal[fd+1] > 0.0)) {
1297         // One of the two very big
1298         if (fAmpTotal[fd] > fProcent*fAmpTotal[fd+1]) {
1299           if (fHisto2d) {
1300             fCH2d->Fill(fCalibraMode->GetXbins(0)+fd+0.5,fAmpTotal[fd]/fRelativeScale);
1301           }
1302           if (fVector2d) {
1303             fCalibraVector->UpdateVectorCH(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1304           }
1305         }
1306         if (fAmpTotal[fd+1] > fProcent*fAmpTotal[fd])  {
1307           if (fHisto2d) {
1308             fCH2d->Fill(fCalibraMode->GetXbins(0)+fd+1.5,fAmpTotal[fd+1]/fRelativeScale);
1309           }
1310           if (fVector2d) {
1311             fCalibraVector->UpdateVectorCH(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd+1]/fRelativeScale);
1312           }
1313         }
1314       }
1315     } // Case 2 zones
1316   }
1317
1318   // Fill with no automatic scale
1319   if (!fRelativeScaleAuto) {
1320     // Case of track with only one zone
1321     if (nb == 1) {
1322       fNumberUsedCh[0]++;
1323       if (fHisto2d) {
1324         fCH2d->Fill(fCalibraMode->GetXbins(0)+fd+0.5,fAmpTotal[fd]/fRelativeScale);
1325       }
1326       if (fVector2d) {
1327         fCalibraVector->UpdateVectorCH(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1328       }
1329     } // Case 1 zone
1330     // Case of track with two zones
1331     if (nb == 2) {
1332       // Two zones voisines sinon rien!
1333       // Case 1
1334       if ((fAmpTotal[fd]   > 0.0) && 
1335           (fAmpTotal[fd+1] > 0.0)) {
1336         // One of the two very big
1337         if (fAmpTotal[fd] > fProcent*fAmpTotal[fd+1]) {
1338           if (fHisto2d) {
1339             fCH2d->Fill(fCalibraMode->GetXbins(0)+fd+0.5,fAmpTotal[fd]/fRelativeScale);
1340           }
1341           if (fVector2d) {
1342             fCalibraVector->UpdateVectorCH(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1343           }
1344           fNumberUsedCh[1]++;
1345         }
1346         if (fAmpTotal[fd+1] > fProcent*fAmpTotal[fd]) {
1347           if (fHisto2d) {
1348             fCH2d->Fill(fCalibraMode->GetXbins(0)+fd+1.5,fAmpTotal[fd+1]/fRelativeScale);
1349           }
1350           if (fVector2d) {
1351             fCalibraVector->UpdateVectorCH(fCalibraMode->GetXbins(0)+fd+1,fAmpTotal[fd+1]/fRelativeScale);
1352           }
1353           fNumberUsedCh[1]++;
1354         }
1355       }
1356       // Case 2
1357       if (fCalibraMode->GetNfragZ(0) > 1) {
1358         if (fAmpTotal[fd] > 0.0) {
1359           if ((fd+fCalibraMode->GetNfragZ(0)) < (fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0))) {
1360             if (fAmpTotal[fd+fCalibraMode->GetNfragZ(0)] > 0.0) {
1361               // One of the two very big
1362               if (fAmpTotal[fd] > fProcent*fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]) {
1363                 if (fHisto2d) {
1364                   fCH2d->Fill(fCalibraMode->GetXbins(0)+fd+0.5,fAmpTotal[fd]/fRelativeScale);
1365                 }
1366                 if (fVector2d) {
1367                   fCalibraVector->UpdateVectorCH(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1368                 }
1369                 fNumberUsedCh[1]++;
1370               }
1371               if (fAmpTotal[fd+fCalibraMode->GetNfragZ(0)] > fProcent*fAmpTotal[fd]) {
1372                 if (fHisto2d) {
1373                   fCH2d->Fill(fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0)
1374                             + 0.5,fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/fRelativeScale);
1375                 }
1376                 fNumberUsedCh[1]++;
1377                 if (fVector2d) {
1378                   fCalibraVector->UpdateVectorCH(fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0)
1379                                                 ,fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/fRelativeScale);
1380                 }
1381               }
1382             }
1383           }
1384         }
1385       }
1386     } // Case 2 zones
1387
1388   }
1389
1390 }
1391
1392 //____________Offine tracking in the AliTRDtracker_____________________________
1393 void AliTRDCalibraFillHisto::ResetfVariables()
1394 {
1395   //
1396   // Reset values of fAmpTotal, fPHValue and fPHPlace for
1397   // the updateHistogram... functions
1398   //
1399
1400   // Reset the good track
1401   fGoodTrack = kTRUE;
1402   
1403   // Reset the fAmpTotal where we put value
1404   if (fCH2dOn) {
1405     for (Int_t k = 0; k < fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0); k++) {
1406       fAmpTotal[k] = 0.0;
1407     }
1408   }
1409   
1410   // Reset the fPHValue
1411   if (fPH2dOn) {
1412     for (Int_t k = 0; k < fTimeMax; k++) {
1413       fPHValue[k] = 0.0;
1414       fPHPlace[k] = -1;
1415     }
1416   }
1417
1418 }
1419
1420 //____________Offine tracking in the AliTRDtracker_____________________________
1421 void AliTRDCalibraFillHisto::FillTheInfoOfTheTrackPH()
1422 {
1423   //
1424   // For the offline tracking or mcm tracklets
1425   // This function will be called in the functions UpdateHistogram... 
1426   // to fill the info of a track for the drift velocity  calibration
1427   //
1428     
1429   Int_t nb  =  1; // Nombre de zones traversees 1, 2 ou plus de 3
1430   Int_t fd1 = -1; // Premiere zone non nulle
1431   Int_t fd2 = -1; // Deuxieme zone non nulle
1432   Int_t k1  = -1; // Debut de la premiere zone
1433   Int_t k2  = -1; // Debut de la seconde zone
1434
1435   // See if the track goes through different zones
1436   for (Int_t k = 0; k < fTimeMax; k++) {
1437     if (fPHValue[k] > 0.0) {
1438       if (fd1 == -1) {
1439         fd1 = fPHPlace[k];
1440         k1  = k;              
1441       }
1442       if (fPHPlace[k] != fd1) {
1443         if (fd2 == -1) {
1444           k2  = k;
1445           fd2 = fPHPlace[k];
1446           nb  = 2;
1447         }
1448         if (fPHPlace[k] != fd2) {
1449           nb = 3;
1450         }
1451       }
1452     }
1453   }
1454   
1455   // Fill 
1456   // Case of track with only one zone
1457   if (nb == 1) {
1458     fNumberUsedPh[0]++;
1459     //fd1 is the only zone
1460     for (Int_t i = 0; i < fTimeMax; i++) {
1461       if (fHisto2d) {
1462         fPH2d->Fill((fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) i/fSf,(Float_t) fPHValue[i]);
1463       }
1464       if (fVector2d) {
1465         fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd1),i,fPHValue[i]);
1466       }
1467     }
1468   } // Case 1 zone
1469   // Case of track with two zones
1470   if (nb == 2) {
1471     // Two zones voisines sinon rien!
1472     // Case 1
1473     if ((fd1 == fd2+1) || 
1474         (fd2 == fd1+1)) {
1475       // One of the two fast all the think
1476       if (k2 > (k1+fDifference)) {
1477         //we choose to fill the fd1 with all the values
1478         fNumberUsedPh[1]++;
1479         for (Int_t i = 0; i < fTimeMax; i++) {
1480           if (fHisto2d) {
1481             fPH2d->Fill((fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) i/fSf,(Float_t) fPHValue[i]);
1482           }
1483           if (fVector2d) {
1484             fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd1),i,fPHValue[i]);
1485           }
1486         }
1487       }
1488       if ((k2+fDifference) < fTimeMax) {
1489         //we choose to fill the fd2 with all the values
1490         fNumberUsedPh[1]++;
1491         for (Int_t i = 0; i < fTimeMax; i++) {
1492           if (fHisto2d) {
1493             fPH2d->Fill((fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) i/fSf,(Float_t) fPHValue[i]);
1494           }
1495           if (fVector2d) {
1496             fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd2),i,fPHValue[i]);
1497           }
1498         }
1499       }
1500     }
1501     // Two zones voisines sinon rien!
1502     if (fCalibraMode->GetNfragZ(1) > 1) {
1503       // Case 2
1504       if ((fd1+fCalibraMode->GetNfragZ(1)) < (fCalibraMode->GetNfragZ(1)*fCalibraMode->GetNfragRphi(1))) {
1505         if (fd2 == (fd1+fCalibraMode->GetNfragZ(1))) {
1506           // One of the two fast all the think
1507           if (k2 > (k1+fDifference)) {
1508             //we choose to fill the fd1 with all the values
1509             fNumberUsedPh[1]++;
1510             for (Int_t i = 0; i < fTimeMax; i++) {
1511               if (fHisto2d) {
1512                 fPH2d->Fill((fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) i/fSf,(Float_t) fPHValue[i]);
1513               }
1514               if (fVector2d) {
1515                 fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd1),i,fPHValue[i]);
1516               }
1517             }
1518           }
1519           if ((k2+fDifference) < fTimeMax) {
1520             //we choose to fill the fd2 with all the values
1521             fNumberUsedPh[1]++;
1522             for (Int_t i = 0; i < fTimeMax; i++) {
1523               if (fHisto2d) {
1524                 fPH2d->Fill((fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) i/fSf,(Float_t) fPHValue[i]);
1525               }
1526               if (fVector2d) {
1527                 fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd2),i,fPHValue[i]);
1528               }
1529             }
1530           }
1531         }
1532       }
1533       // Two zones voisines sinon rien!
1534       // Case 3
1535       if ((fd1 - fCalibraMode->GetNfragZ(1)) >= 0) {
1536         if (fd2 == (fd1 - fCalibraMode->GetNfragZ(1))) {
1537           // One of the two fast all the think
1538           if (k2 > (k1 + fDifference)) {
1539             //we choose to fill the fd1 with all the values
1540             fNumberUsedPh[1]++;
1541             for (Int_t i = 0; i < fTimeMax; i++) {
1542               if (fHisto2d) {
1543                 fPH2d->Fill((fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) i/fSf,(Float_t) fPHValue[i]);
1544               }
1545               if (fVector2d) {
1546                 fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd1),i,fPHValue[i]);
1547               }
1548             }
1549           }
1550           if ((k2+fDifference) < fTimeMax) {
1551             //we choose to fill the fd2 with all the values
1552             fNumberUsedPh[1]++;
1553             for (Int_t i = 0; i < fTimeMax; i++) {
1554               if (fHisto2d) {
1555                 fPH2d->Fill((fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) i/fSf,(Float_t) fPHValue[i]);
1556               }
1557               if (fVector2d) {
1558                 fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd2),i,fPHValue[i]);
1559               }
1560             }
1561           }
1562         }
1563       }
1564     }
1565
1566   } // case 2 zones
1567
1568 }
1569
1570 //____________Set the pad calibration variables for the detector_______________
1571 Bool_t AliTRDCalibraFillHisto::LocalisationDetectorXbins(Int_t detector)
1572 {
1573   //
1574   // For the detector calcul the first Xbins and set the number of row
1575   // and col pads per calibration groups, the number of calibration
1576   // groups in the detector.
1577   //
1578   
1579   // first Xbins of the detector
1580   if (fCH2dOn) {
1581     fCalibraMode->CalculXBins(detector,0);
1582   }
1583   if (fPH2dOn) {
1584     fCalibraMode->CalculXBins(detector,1);
1585   }
1586   if (fPRF2dOn) {
1587     fCalibraMode->CalculXBins(detector,2);
1588   }
1589
1590   // fragmentation of idect
1591   for (Int_t i = 0; i < 3; i++) {
1592     fCalibraMode->ModePadCalibration((Int_t) GetChamber(detector),i);
1593     fCalibraMode->ModePadFragmentation((Int_t) GetPlane(detector)
1594                        , (Int_t) GetChamber(detector)
1595                        , (Int_t) GetSector(detector),i);
1596   }
1597   
1598   return kTRUE;
1599
1600 }
1601
1602 //
1603 //____________Some basic geometry function_____________________________________
1604 //
1605
1606 //_____________________________________________________________________________
1607 Int_t AliTRDCalibraFillHisto::GetPlane(Int_t d) const
1608 {
1609   //
1610   // Reconstruct the plane number from the detector number
1611   //
1612
1613   return ((Int_t) (d % 6));
1614
1615 }
1616
1617 //_____________________________________________________________________________
1618 Int_t AliTRDCalibraFillHisto::GetChamber(Int_t d) const
1619 {
1620   //
1621   // Reconstruct the chamber number from the detector number
1622   //
1623   Int_t fgkNplan = 6;
1624
1625   return ((Int_t) (d % 30) / fgkNplan);
1626
1627 }
1628
1629 //_____________________________________________________________________________
1630 Int_t AliTRDCalibraFillHisto::GetSector(Int_t d) const
1631 {
1632   //
1633   // Reconstruct the sector number from the detector number
1634   //
1635   Int_t fg = 30;
1636
1637   return ((Int_t) (d / fg));
1638
1639 }