1 //**************************************************************************
2 // * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 // * Author: The ALICE Off-line Project. *
5 // * Contributors are mentioned in the code where appropriate. *
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 //**************************************************************************/
18 /////////////////////////////////////////////////////////////////////////////////
20 // AliTRDCalibraFillHisto
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 calibration (see AliTRDCalibraMode).
26 // 2D Histograms (Histo2d) or vectors (Vector2d), then converted in Trees, will be filled
27 // from RAW DATA in a run or from reconstructed TRD tracks during the offline tracking
28 // in the function "FollowBackProlongation" (AliTRDtracker)
29 // Per default the functions to fill are off.
32 // R. Bailhache (R.Bailhache@gsi.de, rbailhache@ikf.uni-frankfurt.de)
33 // J. Book (jbook@ikf.uni-frankfurt.de)
35 //////////////////////////////////////////////////////////////////////////////////////
37 #include <TProfile2D.h>
42 #include <TObjArray.h>
47 #include <TStopwatch.h>
49 #include <TDirectory.h>
50 #include <TTreeStream.h>
52 #include <TLinearFitter.h>
56 #include "AliTRDCalibraFillHisto.h"
57 #include "AliTRDCalibraMode.h"
58 #include "AliTRDCalibraVector.h"
59 #include "AliTRDCalibraVdriftLinearFit.h"
60 #include "AliTRDcalibDB.h"
61 #include "AliTRDCommonParam.h"
62 #include "AliTRDpadPlane.h"
63 #include "AliTRDcluster.h"
64 #include "AliTRDtrackV1.h"
65 #include "AliRawReader.h"
66 #include "AliRawReaderDate.h"
67 #include "AliTRDgeometry.h"
68 #include "./Cal/AliTRDCalROC.h"
69 #include "./Cal/AliTRDCalPad.h"
70 #include "./Cal/AliTRDCalDet.h"
72 #include "AliTRDdigitsManager.h"
73 #include "AliTRDdigitsParam.h"
74 #include "AliTRDSignalIndex.h"
75 #include "AliTRDarrayADC.h"
77 #include "AliTRDrawStream.h"
79 #include "AliCDBEntry.h"
80 #include "AliCDBManager.h"
87 ClassImp(AliTRDCalibraFillHisto)
89 AliTRDCalibraFillHisto* AliTRDCalibraFillHisto::fgInstance = 0;
90 Bool_t AliTRDCalibraFillHisto::fgTerminated = kFALSE;
92 //_____________singleton implementation_________________________________________________
93 AliTRDCalibraFillHisto *AliTRDCalibraFillHisto::Instance()
96 // Singleton implementation
99 if (fgTerminated != kFALSE) {
103 if (fgInstance == 0) {
104 fgInstance = new AliTRDCalibraFillHisto();
111 //______________________________________________________________________________________
112 void AliTRDCalibraFillHisto::Terminate()
115 // Singleton implementation
116 // Deletes the instance of this class
119 fgTerminated = kTRUE;
121 if (fgInstance != 0) {
128 //______________________________________________________________________________________
129 AliTRDCalibraFillHisto::AliTRDCalibraFillHisto()
139 ,fLinearFitterOn(kFALSE)
140 ,fLinearFitterDebugOn(kFALSE)
142 ,fThresholdClusterPRF2(15.0)
143 ,fLimitChargeIntegration(kFALSE)
144 ,fFillWithZero(kFALSE)
145 ,fNormalizeNbOfCluster(kFALSE)
150 ,fSubVersionGainUsed(0)
151 ,fFirstRunGainLocal(0)
152 ,fVersionGainLocalUsed(0)
153 ,fSubVersionGainLocalUsed(0)
155 ,fVersionVdriftUsed(0)
156 ,fSubVersionVdriftUsed(0)
157 ,fCalibraMode(new AliTRDCalibraMode())
160 ,fDetectorPreviousTrack(-1)
164 ,fNumberClustersf(30)
165 ,fNumberClustersProcent(0.5)
166 ,fThresholdClustersDAQ(120.0)
174 ,fNumberBinCharge(50)
180 ,fGoodTracklet(kTRUE)
181 ,fLinearFitterTracklet(0x0)
183 ,fEntriesLinearFitter(0x0)
188 ,fLinearFitterArray(540)
189 ,fLinearVdriftFit(0x0)
194 // Default constructor
198 // Init some default values
201 fNumberUsedCh[0] = 0;
202 fNumberUsedCh[1] = 0;
203 fNumberUsedPh[0] = 0;
204 fNumberUsedPh[1] = 0;
206 fGeo = new AliTRDgeometry();
207 fCalibDB = AliTRDcalibDB::Instance();
210 //______________________________________________________________________________________
211 AliTRDCalibraFillHisto::AliTRDCalibraFillHisto(const AliTRDCalibraFillHisto &c)
218 ,fPRF2dOn(c.fPRF2dOn)
219 ,fHisto2d(c.fHisto2d)
220 ,fVector2d(c.fVector2d)
221 ,fLinearFitterOn(c.fLinearFitterOn)
222 ,fLinearFitterDebugOn(c.fLinearFitterDebugOn)
223 ,fRelativeScale(c.fRelativeScale)
224 ,fThresholdClusterPRF2(c.fThresholdClusterPRF2)
225 ,fLimitChargeIntegration(c.fLimitChargeIntegration)
226 ,fFillWithZero(c.fFillWithZero)
227 ,fNormalizeNbOfCluster(c.fNormalizeNbOfCluster)
228 ,fMaxCluster(c.fMaxCluster)
229 ,fNbMaxCluster(c.fNbMaxCluster)
230 ,fFirstRunGain(c.fFirstRunGain)
231 ,fVersionGainUsed(c.fVersionGainUsed)
232 ,fSubVersionGainUsed(c.fSubVersionGainUsed)
233 ,fFirstRunGainLocal(c.fFirstRunGainLocal)
234 ,fVersionGainLocalUsed(c.fVersionGainLocalUsed)
235 ,fSubVersionGainLocalUsed(c.fSubVersionGainLocalUsed)
236 ,fFirstRunVdrift(c.fFirstRunVdrift)
237 ,fVersionVdriftUsed(c.fVersionVdriftUsed)
238 ,fSubVersionVdriftUsed(c.fSubVersionVdriftUsed)
241 ,fDebugLevel(c.fDebugLevel)
242 ,fDetectorPreviousTrack(c.fDetectorPreviousTrack)
243 ,fMCMPrevious(c.fMCMPrevious)
244 ,fROBPrevious(c.fROBPrevious)
245 ,fNumberClusters(c.fNumberClusters)
246 ,fNumberClustersf(c.fNumberClustersf)
247 ,fNumberClustersProcent(c.fNumberClustersProcent)
248 ,fThresholdClustersDAQ(c.fThresholdClustersDAQ)
249 ,fNumberRowDAQ(c.fNumberRowDAQ)
250 ,fNumberColDAQ(c.fNumberColDAQ)
251 ,fProcent(c.fProcent)
252 ,fDifference(c.fDifference)
253 ,fNumberTrack(c.fNumberTrack)
254 ,fTimeMax(c.fTimeMax)
256 ,fNumberBinCharge(c.fNumberBinCharge)
257 ,fNumberBinPRF(c.fNumberBinPRF)
258 ,fNgroupprf(c.fNgroupprf)
262 ,fGoodTracklet(c.fGoodTracklet)
263 ,fLinearFitterTracklet(0x0)
265 ,fEntriesLinearFitter(0x0)
270 ,fLinearFitterArray(540)
271 ,fLinearVdriftFit(0x0)
278 if(c.fCalibraMode) fCalibraMode = new AliTRDCalibraMode(*c.fCalibraMode);
279 if(c.fCalibraVector) fCalibraVector = new AliTRDCalibraVector(*c.fCalibraVector);
281 fPH2d = new TProfile2D(*c.fPH2d);
282 fPH2d->SetDirectory(0);
285 fPRF2d = new TProfile2D(*c.fPRF2d);
286 fPRF2d->SetDirectory(0);
289 fCH2d = new TH2I(*c.fCH2d);
290 fCH2d->SetDirectory(0);
292 if(c.fLinearVdriftFit){
293 fLinearVdriftFit = new AliTRDCalibraVdriftLinearFit(*c.fLinearVdriftFit);
296 if(c.fCalDetGain) fCalDetGain = new AliTRDCalDet(*c.fCalDetGain);
297 if(c.fCalROCGain) fCalROCGain = new AliTRDCalROC(*c.fCalROCGain);
302 fGeo = new AliTRDgeometry();
303 fCalibDB = AliTRDcalibDB::Instance();
305 fNumberUsedCh[0] = 0;
306 fNumberUsedCh[1] = 0;
307 fNumberUsedPh[0] = 0;
308 fNumberUsedPh[1] = 0;
312 //____________________________________________________________________________________
313 AliTRDCalibraFillHisto::~AliTRDCalibraFillHisto()
316 // AliTRDCalibraFillHisto destructor
320 if ( fDebugStreamer ) delete fDebugStreamer;
322 if ( fCalDetGain ) delete fCalDetGain;
323 if ( fCalROCGain ) delete fCalROCGain;
325 if( fLinearFitterTracklet ) { delete fLinearFitterTracklet; }
329 delete [] fEntriesCH;
330 delete [] fEntriesLinearFitter;
333 for(Int_t idet=0; idet<AliTRDgeometry::kNdet; idet++){
334 TLinearFitter *f = (TLinearFitter*)fLinearFitterArray.At(idet);
337 if(fLinearVdriftFit) delete fLinearVdriftFit;
343 //_____________________________________________________________________________
344 void AliTRDCalibraFillHisto::Destroy()
355 //_____________________________________________________________________________
356 void AliTRDCalibraFillHisto::DestroyDebugStreamer()
359 // Delete DebugStreamer
362 if ( fDebugStreamer ) delete fDebugStreamer;
363 fDebugStreamer = 0x0;
366 //_____________________________________________________________________________
367 void AliTRDCalibraFillHisto::ClearHistos()
387 //////////////////////////////////////////////////////////////////////////////////
388 // calibration with AliTRDtrackV1: Init, Update
389 //////////////////////////////////////////////////////////////////////////////////
390 //____________Functions for initialising the AliTRDCalibraFillHisto in the code_________
391 Bool_t AliTRDCalibraFillHisto::Init2Dhistos(Int_t nboftimebin)
394 // Init the histograms and stuff to be filled
399 AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
401 AliInfo("Could not get calibDB");
404 AliTRDCommonParam *parCom = AliTRDCommonParam::Instance();
406 AliInfo("Could not get CommonParam");
411 if(nboftimebin > 0) fTimeMax = nboftimebin;
412 else fTimeMax = cal->GetNumberOfTimeBinsDCS();
413 if(fTimeMax <= 0) fTimeMax = 30;
414 printf("////////////////////////////////////////////\n");
415 printf("Number of time bins in calibration component %d\n",fTimeMax);
416 printf("////////////////////////////////////////////\n");
417 fSf = parCom->GetSamplingFrequency();
418 if(!fNormalizeNbOfCluster) fRelativeScale = 20.0;
419 else fRelativeScale = 1.18;
420 fNumberClustersf = fTimeMax;
421 fNumberClusters = (Int_t)(fNumberClustersProcent*fTimeMax);
423 // Init linear fitter
424 if(!fLinearFitterTracklet) {
425 fLinearFitterTracklet = new TLinearFitter(2,"pol1");
426 fLinearFitterTracklet->StoreData(kTRUE);
429 // Calcul Xbins Chambd0, Chamb2
430 Int_t ntotal0 = CalculateTotalNumberOfBins(0);
431 Int_t ntotal1 = CalculateTotalNumberOfBins(1);
432 Int_t ntotal2 = CalculateTotalNumberOfBins(2);
434 // If vector method On initialised all the stuff
436 fCalibraVector = new AliTRDCalibraVector();
437 fCalibraVector->SetNumberBinCharge(fNumberBinCharge);
438 fCalibraVector->SetTimeMax(fTimeMax);
439 if(fNgroupprf != 0) {
440 fCalibraVector->SetNumberBinPRF(2*fNgroupprf*fNumberBinPRF);
441 fCalibraVector->SetPRFRange((Float_t)(3.0*fNgroupprf));
444 fCalibraVector->SetNumberBinPRF(fNumberBinPRF);
445 fCalibraVector->SetPRFRange(1.5);
447 for(Int_t k = 0; k < 3; k++){
448 fCalibraVector->SetDetCha0(k,fCalibraMode->GetDetChamb0(k));
449 fCalibraVector->SetDetCha2(k,fCalibraMode->GetDetChamb2(k));
451 fCalibraVector->SetNzNrphi(0,fCalibraMode->GetNz(0),fCalibraMode->GetNrphi(0));
452 fCalibraVector->SetNzNrphi(1,fCalibraMode->GetNz(1),fCalibraMode->GetNrphi(1));
453 fCalibraVector->SetNzNrphi(2,fCalibraMode->GetNz(2),fCalibraMode->GetNrphi(2));
454 fCalibraVector->SetNbGroupPRF(fNgroupprf);
457 // Create the 2D histos corresponding to the pad groupCalibration mode
460 AliInfo(Form("The pad calibration mode for the relative gain calibration: Nz %d, and Nrphi %d"
461 ,fCalibraMode->GetNz(0)
462 ,fCalibraMode->GetNrphi(0)));
464 // Create the 2D histo
469 fAmpTotal = new Float_t[TMath::Max(fCalibraMode->GetDetChamb2(0),fCalibraMode->GetDetChamb0(0))];
470 for (Int_t k = 0; k < TMath::Max(fCalibraMode->GetDetChamb2(0),fCalibraMode->GetDetChamb0(0)); k++) {
474 fEntriesCH = new Int_t[ntotal0];
475 for(Int_t k = 0; k < ntotal0; k++){
482 AliInfo(Form("The pad calibration mode for the drift velocity calibration: Nz %d, and Nrphi %d"
483 ,fCalibraMode->GetNz(1)
484 ,fCalibraMode->GetNrphi(1)));
486 // Create the 2D histo
491 fPHPlace = new Short_t[fTimeMax];
492 for (Int_t k = 0; k < fTimeMax; k++) {
495 fPHValue = new Float_t[fTimeMax];
496 for (Int_t k = 0; k < fTimeMax; k++) {
500 if (fLinearFitterOn) {
501 if(fLinearFitterDebugOn) {
502 fLinearFitterArray.SetName("ArrayLinearFitters");
503 fEntriesLinearFitter = new Int_t[540];
504 for(Int_t k = 0; k < 540; k++){
505 fEntriesLinearFitter[k] = 0;
508 fLinearVdriftFit = new AliTRDCalibraVdriftLinearFit();
513 AliInfo(Form("The pad calibration mode for the PRF calibration: Nz %d, and Nrphi %d"
514 ,fCalibraMode->GetNz(2)
515 ,fCalibraMode->GetNrphi(2)));
516 // Create the 2D histo
518 CreatePRF2d(ntotal2);
525 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
526 Bool_t AliTRDCalibraFillHisto::InitCalDet()
529 // Init the Gain Cal Det
534 AliCDBEntry *entry = AliCDBManager::Instance()->Get("TRD/Calib/ChamberGainFactor",fFirstRunGain,fVersionGainUsed,fSubVersionGainUsed);
536 AliError("No gain det calibration entry found");
539 AliTRDCalDet *calDet = (AliTRDCalDet *)entry->GetObject();
541 AliError("No calDet gain found");
547 fCalDetGain->~AliTRDCalDet();
548 new(fCalDetGain) AliTRDCalDet(*(calDet));
549 }else fCalDetGain = new AliTRDCalDet(*(calDet));
554 name += fVersionGainUsed;
556 name += fSubVersionGainUsed;
558 name += fFirstRunGain;
560 name += fCalibraMode->GetNz(0);
562 name += fCalibraMode->GetNrphi(0);
564 fCH2d->SetTitle(name);
567 TString namee("Ver");
568 namee += fVersionVdriftUsed;
570 namee += fSubVersionVdriftUsed;
572 namee += fFirstRunVdrift;
574 namee += fCalibraMode->GetNz(1);
576 namee += fCalibraMode->GetNrphi(1);
578 fPH2d->SetTitle(namee);
584 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
585 Bool_t AliTRDCalibraFillHisto::InitCalPad(Int_t detector)
588 // Init the Gain Cal Pad
593 AliCDBEntry *entry = AliCDBManager::Instance()->Get("TRD/Calib/LocalGainFactor",AliCDBManager::Instance()->GetRun(),fVersionGainLocalUsed,fSubVersionGainLocalUsed);
595 AliError("No gain pad calibration entry found");
598 AliTRDCalPad *calPad = (AliTRDCalPad *)entry->GetObject();
600 AliError("No calPad gain found");
603 AliTRDCalROC *calRoc = (AliTRDCalROC *)calPad->GetCalROC(detector);
605 AliError("No calRoc gain found");
610 fCalROCGain->~AliTRDCalROC();
611 new(fCalROCGain) AliTRDCalROC(*(calRoc));
612 }else fCalROCGain = new AliTRDCalROC(*(calRoc));
621 //____________Offline tracking in the AliTRDtracker____________________________
622 Bool_t AliTRDCalibraFillHisto::UpdateHistogramsV1(const AliTRDtrackV1 *t)
625 // Use AliTRDtrackV1 for the calibration
629 const AliTRDseedV1 *tracklet = 0x0; // tracklet per plane
630 AliTRDcluster *cl = 0x0; // cluster attached now to the tracklet
631 AliTRDcluster *cls = 0x0; // shared cluster attached now to the tracklet
632 Bool_t newtr = kTRUE; // new track
635 // AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
638 AliInfo("Could not get calibDB");
643 AliInfo("Could not get calibDB");
648 ///////////////////////////
649 // loop over the tracklet
650 ///////////////////////////
651 for(Int_t itr = 0; itr < 6; itr++){
653 if(!(tracklet = t->GetTracklet(itr))) continue;
654 if(!tracklet->IsOK()) continue;
656 ResetfVariablestracklet();
658 //////////////////////////////////////////
659 // localisation of the tracklet and dqdl
660 //////////////////////////////////////////
661 Int_t layer = tracklet->GetPlane();
663 while(!(cl = tracklet->GetClusters(ic++))) continue;
664 Int_t detector = cl->GetDetector();
665 if (detector != fDetectorPreviousTrack) {
666 // if not a new track
668 // don't use the rest of this track if in the same plane
669 if (layer == GetLayer(fDetectorPreviousTrack)) {
670 //printf("bad tracklet, same layer for detector %d\n",detector);
674 //Localise the detector bin
675 LocalisationDetectorXbins(detector);
677 if(!fIsHLT) InitCalPad(detector);
680 fDetectorPreviousTrack = detector;
684 ////////////////////////////
685 // loop over the clusters
686 ////////////////////////////
687 Int_t nbclusters = 0;
688 for(int jc=0; jc<AliTRDseedV1::kNtb; jc++){
689 if(!(cl = tracklet->GetClusters(jc))) continue;
692 // Store the info bis of the tracklet
693 Int_t row = cl->GetPadRow();
694 Int_t col = cl->GetPadCol();
695 CheckGoodTrackletV1(cl);
696 Int_t group[2] = {0,0};
697 if(fCH2dOn) group[0] = CalculateCalibrationGroup(0,row,col);
698 if(fPH2dOn) group[1] = CalculateCalibrationGroup(1,row,col);
699 // Add the charge if shared cluster
700 cls = tracklet->GetClusters(jc+AliTRDseedV1::kNtb);
702 StoreInfoCHPHtrack(cl, tracklet->GetdQdl(jc),group,row,col,cls);
705 ////////////////////////////////////////
706 // Fill the stuffs if a good tracklet
707 ////////////////////////////////////////
710 // drift velocity unables to cut bad tracklets
711 Bool_t pass = FindP1TrackPHtrackletV1(tracklet, nbclusters);
713 //printf("pass %d and nbclusters %d\n",pass,nbclusters);
717 FillTheInfoOfTheTrackCH(nbclusters);
722 FillTheInfoOfTheTrackPH();
725 if(pass && fPRF2dOn) HandlePRFtrackletV1(tracklet,nbclusters);
727 } // if a good tracklet
733 ///////////////////////////////////////////////////////////////////////////////////
734 // Routine inside the update with AliTRDtrack
735 ///////////////////////////////////////////////////////////////////////////////////
736 //____________Offine tracking in the AliTRDtracker_____________________________
737 Bool_t AliTRDCalibraFillHisto::FindP1TrackPHtrackletV1(const AliTRDseedV1 *tracklet, Int_t nbclusters)
740 // Drift velocity calibration:
741 // Fit the clusters with a straight line
742 // From the slope find the drift velocity
745 ////////////////////////////////////////////////
746 //Number of points: if less than 3 return kFALSE
747 /////////////////////////////////////////////////
748 if(nbclusters <= 2) return kFALSE;
753 // results of the linear fit
754 Double_t dydt = 0.0; // dydt tracklet after straight line fit
755 Double_t errorpar = 0.0; // error after straight line fit on dy/dt
756 Double_t pointError = 0.0; // error after straight line fit
757 // pad row problemes: avoid tracklet that cross pad rows, tilting angle in the constant
758 Int_t crossrow = 0; // if it crosses a pad row
759 Int_t rowp = -1; // if it crosses a pad row
760 Float_t tnt = tracklet->GetTilt(); // tan tiltingangle
761 fLinearFitterTracklet->ClearPoints();
764 ///////////////////////////////////////////
765 // Take the parameters of the track
766 //////////////////////////////////////////
767 // take now the snp, tnp and tgl from the track
768 Double_t snp = tracklet->GetSnp(); // sin dy/dx at the end of the chamber
769 Double_t tnp = 0.0; // dy/dx at the end of the chamber
770 if( TMath::Abs(snp) < 1.){
771 tnp = snp / TMath::Sqrt((1.-snp)*(1.+snp));
773 Double_t tgl = tracklet->GetTgl(); // dz/dl
774 Double_t dzdx = tgl*TMath::Sqrt(1+tnp*tnp); // dz/dx calculated from dz/dl
776 //Double_t tnp = tracklet->GetYref(1); // dy/dx at the entrance of the chamber
777 //Double_t tgl = tracklet->GetZref(1); // dz/dl at the entrance of the chamber
778 //Double_t dzdx = tgl; //*TMath::Sqrt(1+tnp*tnp); // dz/dx from dz/dl
779 // at the end with correction due to linear fit
780 //Double_t tnp = tracklet->GetYfit(1); // dy/dx at the end of the chamber after fit correction
781 //Double_t tgl = tracklet->GetZfit(1); // dz/dl at the end of the chamber after fit correction
784 ////////////////////////////
785 // loop over the clusters
786 ////////////////////////////
788 AliTRDcluster *cl = 0x0;
789 //////////////////////////////
790 // Check no shared clusters
791 //////////////////////////////
792 for(int icc=AliTRDseedV1::kNtb; icc<AliTRDseedV1::kNclusters; icc++){
793 cl = tracklet->GetClusters(icc);
796 //////////////////////////////////
798 //////////////////////////////////
799 for(int ic=0; ic<AliTRDseedV1::kNtb; ic++){
800 if(!(cl = tracklet->GetClusters(ic))) continue;
801 if((fLimitChargeIntegration) && (!cl->IsInChamber())) continue;
803 Double_t ycluster = cl->GetY();
804 Int_t time = cl->GetPadTime();
805 Double_t timeis = time/fSf;
806 //See if cross two pad rows
807 Int_t row = cl->GetPadRow();
808 if(rowp==-1) rowp = row;
809 if(row != rowp) crossrow = 1;
811 fLinearFitterTracklet->AddPoint(&timeis,ycluster,1);
817 ////////////////////////////////////
818 // Do the straight line fit now
819 ///////////////////////////////////
821 fLinearFitterTracklet->ClearPoints();
825 fLinearFitterTracklet->Eval();
826 fLinearFitterTracklet->GetParameters(pars);
827 pointError = TMath::Sqrt(fLinearFitterTracklet->GetChisquare()/(nbli-2));
828 errorpar = fLinearFitterTracklet->GetParError(1)*pointError;
830 //printf("chis %f, nbli %d, pointError %f, parError %f, errorpar %f\n",fLinearFitterTracklet->GetChisquare(),nbli,pointError,fLinearFitterTracklet->GetParError(1),errorpar);
831 fLinearFitterTracklet->ClearPoints();
833 ////////////////////////////////
835 ///////////////////////////////
839 if ( !fDebugStreamer ) {
841 TDirectory *backup = gDirectory;
842 fDebugStreamer = new TTreeSRedirector("TRDdebugCalibraFill.root");
843 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
847 Int_t layer = GetLayer(fDetectorPreviousTrack);
849 (* fDebugStreamer) << "FindP1TrackPHtrackletV1"<<
850 //"snpright="<<snpright<<
852 "nbclusters="<<nbclusters<<
853 "detector="<<fDetectorPreviousTrack<<
861 "crossrow="<<crossrow<<
862 "errorpar="<<errorpar<<
863 "pointError="<<pointError<<
868 /////////////////////////
870 ////////////////////////
872 if(nbclusters < fNumberClusters) return kFALSE;
873 if(nbclusters > fNumberClustersf) return kFALSE;
874 if(pointError >= 0.3) return kFALSE;
875 if(crossrow == 1) return kTRUE;
877 ///////////////////////
879 //////////////////////
882 //Add to the linear fitter of the detector
883 if( TMath::Abs(snp) < 1.){
884 Double_t x = tnp-dzdx*tnt;
885 if(fLinearFitterDebugOn) {
886 (GetLinearFitter(fDetectorPreviousTrack,kTRUE))->AddPoint(&x,dydt);
887 fEntriesLinearFitter[fDetectorPreviousTrack]++;
889 fLinearVdriftFit->Update(fDetectorPreviousTrack,x,pars[1]);
895 //____________Offine tracking in the AliTRDtracker_____________________________
896 Bool_t AliTRDCalibraFillHisto::HandlePRFtrackletV1(const AliTRDseedV1 *tracklet, Int_t nbclusters)
899 // PRF width calibration
900 // Assume a Gaussian shape: determinate the position of the three pad clusters
901 // Fit with a straight line
902 // Take the fitted values for all the clusters (3 or 2 pad clusters)
903 // Fill the PRF as function of angle of the track
908 ///////////////////////////////////////////
909 // Take the parameters of the track
910 //////////////////////////////////////////
911 // take now the snp, tnp and tgl from the track
912 Double_t snp = tracklet->GetSnp(); // sin dy/dx at the end of the chamber
913 Double_t tnp = 0.0; // dy/dx at the end of the chamber
914 if( TMath::Abs(snp) < 1.){
915 tnp = snp / TMath::Sqrt((1.-snp)*(1.+snp));
917 Double_t tgl = tracklet->GetTgl(); // dz/dl
918 Double_t dzdx = tgl*TMath::Sqrt(1+tnp*tnp); // dz/dx calculated from dz/dl
920 //Double_t tnp = tracklet->GetYref(1); // dy/dx at the entrance of the chamber
921 //Double_t tgl = tracklet->GetZref(1); // dz/dl at the entrance of the chamber
922 //Double_t dzdx = tgl; //*TMath::Sqrt(1+tnp*tnp); // dz/dx from dz/dl
923 // at the end with correction due to linear fit
924 //Double_t tnp = tracklet->GetYfit(1); // dy/dx at the end of the chamber after fit correction
925 //Double_t tgl = tracklet->GetZfit(1); // dz/dl at the end of the chamber after fit correction
927 ///////////////////////////////
928 // Calculate tnp group shift
929 ///////////////////////////////
930 Bool_t echec = kFALSE;
931 Double_t shift = 0.0;
932 //Calculate the shift in x coresponding to this tnp
933 if(fNgroupprf != 0.0){
934 shift = -3.0*(fNgroupprf-1)-1.5;
935 Double_t limithigh = -0.2*(fNgroupprf-1);
936 if((tnp < (-0.2*fNgroupprf)) || (tnp > (0.2*fNgroupprf))) echec = kTRUE;
938 while(tnp > limithigh){
944 // do nothing if out of tnp range
945 //printf("echec %d\n",(Int_t)echec);
946 if(echec) return kFALSE;
948 ///////////////////////
950 //////////////////////
952 Int_t nb3pc = 0; // number of three pads clusters used for fit
953 // to see the difference between the fit and the 3 pad clusters position
954 Double_t padPositions[AliTRDseedV1::kNtb];
955 memset(padPositions, 0, AliTRDseedV1::kNtb*sizeof(Double_t));
956 fLinearFitterTracklet->ClearPoints();
958 //printf("loop clusters \n");
959 ////////////////////////////
960 // loop over the clusters
961 ////////////////////////////
962 AliTRDcluster *cl = 0x0;
963 for(int ic=0; ic<AliTRDseedV1::kNtb; ic++){
964 // reject shared clusters on pad row
965 if((ic+AliTRDseedV1::kNtb) < AliTRDseedV1::kNclusters) {
966 cl = tracklet->GetClusters(ic+AliTRDseedV1::kNtb);
969 cl = tracklet->GetClusters(ic);
971 Double_t time = cl->GetPadTime();
972 if((time<=7) || (time>=21)) continue;
973 Short_t *signals = cl->GetSignals();
974 Float_t xcenter = 0.0;
975 Bool_t echec1 = kTRUE;
977 /////////////////////////////////////////////////////////////
978 // Center 3 balanced: position with the center of the pad
979 /////////////////////////////////////////////////////////////
980 if ((((Float_t) signals[3]) > 0.0) &&
981 (((Float_t) signals[2]) > 0.0) &&
982 (((Float_t) signals[4]) > 0.0)) {
984 // Security if the denomiateur is 0
985 if ((((Float_t) (((Float_t) signals[3]) * ((Float_t) signals[3]))) /
986 ((Float_t) (((Float_t) signals[2]) * ((Float_t) signals[4])))) != 1.0) {
987 xcenter = 0.5 * (TMath::Log((Float_t) (((Float_t) signals[4]) / ((Float_t) signals[2]))))
988 / (TMath::Log(((Float_t) (((Float_t) signals[3]) * ((Float_t) signals[3])))
989 / ((Float_t) (((Float_t) signals[2]) * ((Float_t) signals[4])))));
995 if(TMath::Abs(xcenter) > 0.5) echec1 = kTRUE;
998 ////////////////////////////////////////////////////////
999 //if no echec1: calculate with the position of the pad
1000 // Position of the cluster
1001 // fill the linear fitter
1002 ///////////////////////////////////////////////////////
1003 Double_t padPosition = xcenter + cl->GetPadCol();
1004 padPositions[ic] = padPosition;
1006 fLinearFitterTracklet->AddPoint(&time, padPosition,1);
1011 //printf("Fin loop clusters \n");
1012 //////////////////////////////
1013 // fit with a straight line
1014 /////////////////////////////
1016 fLinearFitterTracklet->ClearPoints();
1019 fLinearFitterTracklet->Eval();
1021 fLinearFitterTracklet->GetParameters(line);
1022 Float_t pointError = -1.0;
1023 if( fLinearFitterTracklet->GetChisquare()>=0.0) {
1024 pointError = TMath::Sqrt( fLinearFitterTracklet->GetChisquare()/(nb3pc-2));
1026 fLinearFitterTracklet->ClearPoints();
1028 //printf("PRF second loop \n");
1029 ////////////////////////////////////////////////
1030 // Fill the PRF: Second loop over clusters
1031 //////////////////////////////////////////////
1032 for(int ic=0; ic<AliTRDseedV1::kNtb; ic++){
1033 // reject shared clusters on pad row
1034 cl = tracklet->GetClusters(ic+AliTRDseedV1::kNtb);
1035 if(((ic+AliTRDseedV1::kNtb) < AliTRDseedV1::kNclusters) && (cl)) continue;
1037 cl = tracklet->GetClusters(ic);
1040 Short_t *signals = cl->GetSignals(); // signal
1041 Double_t time = cl->GetPadTime(); // time bin
1042 Float_t padPosTracklet = line[0]+line[1]*time; // reconstruct position from fit
1043 Float_t padPos = cl->GetPadCol(); // middle pad
1044 Double_t dpad = padPosTracklet - padPos; // reconstruct position relative to middle pad from fit
1045 Float_t ycenter = 0.0; // relative center charge
1046 Float_t ymin = 0.0; // relative left charge
1047 Float_t ymax = 0.0; // relative right charge
1049 ////////////////////////////////////////////////////////////////
1050 // Calculate ycenter, ymin and ymax even for two pad clusters
1051 ////////////////////////////////////////////////////////////////
1052 if(((((Float_t) signals[3]) > 0.0) && (((Float_t) signals[2]) > 0.0)) ||
1053 ((((Float_t) signals[3]) > 0.0) && (((Float_t) signals[4]) > 0.0))){
1054 Float_t sum = ((Float_t) signals[2]) + ((Float_t) signals[3]) + ((Float_t) signals[4]);
1055 if(sum > 0.0) ycenter = ((Float_t) signals[3])/ sum;
1056 if(sum > 0.0) ymin = ((Float_t) signals[2])/ sum;
1057 if(sum > 0.0) ymax = ((Float_t) signals[4])/ sum;
1060 /////////////////////////
1061 // Calibration group
1062 ////////////////////////
1063 Int_t rowcl = cl->GetPadRow(); // row of cluster
1064 Int_t colcl = cl->GetPadCol(); // col of cluster
1065 Int_t grouplocal = CalculateCalibrationGroup(2,rowcl,colcl); // calcul the corresponding group
1066 Int_t caligroup = fCalibraMode->GetXbins(2)+ grouplocal; // calcul the corresponding group
1067 Float_t xcl = cl->GetY(); // y cluster
1068 Float_t qcl = cl->GetQ(); // charge cluster
1069 Int_t layer = GetLayer(fDetectorPreviousTrack); // layer
1070 Int_t stack = GetStack(fDetectorPreviousTrack); // stack
1071 Double_t xdiff = dpad; // reconstructed position constant
1072 Double_t x = dpad; // reconstructed position moved
1073 Float_t ep = pointError; // error of fit
1074 Float_t signal1 = (Float_t)signals[1]; // signal at the border
1075 Float_t signal3 = (Float_t)signals[3]; // signal
1076 Float_t signal2 = (Float_t)signals[2]; // signal
1077 Float_t signal4 = (Float_t)signals[4]; // signal
1078 Float_t signal5 = (Float_t)signals[5]; // signal at the border
1082 /////////////////////
1084 ////////////////////
1086 if(fDebugLevel > 0){
1087 if ( !fDebugStreamer ) {
1089 TDirectory *backup = gDirectory;
1090 fDebugStreamer = new TTreeSRedirector("TRDdebugCalibraFill.root");
1091 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
1096 Float_t y = ycenter;
1097 (* fDebugStreamer) << "HandlePRFtrackletV1"<<
1098 "caligroup="<<caligroup<<
1099 "detector="<<fDetectorPreviousTrack<<
1102 "npoints="<<nbclusters<<
1111 "padPosition="<<padPositions[ic]<<
1112 "padPosTracklet="<<padPosTracklet<<
1117 "signal1="<<signal1<<
1118 "signal2="<<signal2<<
1119 "signal3="<<signal3<<
1120 "signal4="<<signal4<<
1121 "signal5="<<signal5<<
1127 (* fDebugStreamer) << "HandlePRFtrackletV1"<<
1128 "caligroup="<<caligroup<<
1129 "detector="<<fDetectorPreviousTrack<<
1132 "npoints="<<nbclusters<<
1141 "padPosition="<<padPositions[ic]<<
1142 "padPosTracklet="<<padPosTracklet<<
1147 "signal1="<<signal1<<
1148 "signal2="<<signal2<<
1149 "signal3="<<signal3<<
1150 "signal4="<<signal4<<
1151 "signal5="<<signal5<<
1157 (* fDebugStreamer) << "HandlePRFtrackletV1"<<
1158 "caligroup="<<caligroup<<
1159 "detector="<<fDetectorPreviousTrack<<
1162 "npoints="<<nbclusters<<
1171 "padPosition="<<padPositions[ic]<<
1172 "padPosTracklet="<<padPosTracklet<<
1177 "signal1="<<signal1<<
1178 "signal2="<<signal2<<
1179 "signal3="<<signal3<<
1180 "signal4="<<signal4<<
1181 "signal5="<<signal5<<
1187 /////////////////////
1189 /////////////////////
1190 if(nbclusters < fNumberClusters) continue;
1191 if(nbclusters > fNumberClustersf) continue;
1192 if(nb3pc <= 5) continue;
1193 if((time >= 21) || (time < 7)) continue;
1194 if(TMath::Abs(qcl) < 80) continue;
1195 if( TMath::Abs(snp) > 1.) continue;
1198 ////////////////////////
1200 ///////////////////////
1202 if(TMath::Abs(dpad) < 1.5) {
1203 fPRF2d->Fill(shift+dpad,(caligroup+0.5),ycenter);
1204 fPRF2d->Fill(shift-dpad,(caligroup+0.5),ycenter);
1205 //printf("place %f, ycenter %f\n",(shift+dpad),ycenter);
1207 if((ymin > 0.0) && (TMath::Abs(dpad+1.0) < 1.5)) {
1208 fPRF2d->Fill(shift-(dpad+1.0),(caligroup+0.5),ymin);
1209 fPRF2d->Fill(shift+(dpad+1.0),(caligroup+0.5),ymin);
1211 if((ymax > 0.0) && (TMath::Abs(dpad-1.0) < 1.5)) {
1212 fPRF2d->Fill(shift+1.0-dpad,(caligroup+0.5),ymax);
1213 fPRF2d->Fill(shift-1.0+dpad,(caligroup+0.5),ymax);
1218 if(TMath::Abs(dpad) < 1.5) {
1219 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift+dpad,ycenter);
1220 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift-dpad,ycenter);
1222 if((ymin > 0.0) && (TMath::Abs(dpad+1.0) < 1.5)) {
1223 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift-(dpad+1.0),ymin);
1224 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift+(dpad+1.0),ymin);
1226 if((ymax > 0.0) && (TMath::Abs(dpad-1.0) < 1.5)) {
1227 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift+1.0-dpad,ymax);
1228 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift-1.0+dpad,ymax);
1231 } // second loop over clusters
1236 ///////////////////////////////////////////////////////////////////////////////////////
1237 // Pad row col stuff: see if masked or not
1238 ///////////////////////////////////////////////////////////////////////////////////////
1239 //_____________________________________________________________________________
1240 void AliTRDCalibraFillHisto::CheckGoodTrackletV1(const AliTRDcluster *cl)
1243 // See if we are not near a masked pad
1246 if(cl->IsMasked()) fGoodTracklet = kFALSE;
1250 //_____________________________________________________________________________
1251 void AliTRDCalibraFillHisto::CheckGoodTrackletV0(const Int_t detector,const Int_t row,const Int_t col)
1254 // See if we are not near a masked pad
1257 if (!IsPadOn(detector, col, row)) {
1258 fGoodTracklet = kFALSE;
1262 if (!IsPadOn(detector, col-1, row)) {
1263 fGoodTracklet = kFALSE;
1268 if (!IsPadOn(detector, col+1, row)) {
1269 fGoodTracklet = kFALSE;
1274 //_____________________________________________________________________________
1275 Bool_t AliTRDCalibraFillHisto::IsPadOn(Int_t detector, Int_t row, Int_t col) const
1278 // Look in the choosen database if the pad is On.
1279 // If no the track will be "not good"
1282 // Get the parameter object
1283 AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
1285 AliInfo("Could not get calibDB");
1289 if (!cal->IsChamberInstalled(detector) ||
1290 cal->IsChamberMasked(detector) ||
1291 cal->IsPadMasked(detector,col,row)) {
1299 ///////////////////////////////////////////////////////////////////////////////////////
1300 // Calibration groups: calculate the number of groups, localise...
1301 ////////////////////////////////////////////////////////////////////////////////////////
1302 //_____________________________________________________________________________
1303 Int_t AliTRDCalibraFillHisto::CalculateCalibrationGroup(Int_t i, Int_t row, Int_t col) const
1306 // Calculate the calibration group number for i
1309 // Row of the cluster and position in the pad groups
1311 if (fCalibraMode->GetNnZ(i) != 0) {
1312 posr = (Int_t) row / fCalibraMode->GetNnZ(i);
1316 // Col of the cluster and position in the pad groups
1318 if (fCalibraMode->GetNnRphi(i) != 0) {
1319 posc = (Int_t) col / fCalibraMode->GetNnRphi(i);
1322 return posc*fCalibraMode->GetNfragZ(i)+posr;
1325 //____________________________________________________________________________________
1326 Int_t AliTRDCalibraFillHisto::CalculateTotalNumberOfBins(Int_t i)
1329 // Calculate the total number of calibration groups
1335 if((fCalibraMode->GetNz(i)==100) && (fCalibraMode->GetNrphi(i)==100)){
1337 AliInfo(Form("Total number of Xbins: %d for i %d",ntotal,i));
1342 if((fCalibraMode->GetNz(i)==10) && (fCalibraMode->GetNrphi(i)==10)){
1344 AliInfo(Form("Total number of Xbins: %d for i %d",ntotal,i));
1349 fCalibraMode->ModePadCalibration(2,i);
1350 fCalibraMode->ModePadFragmentation(0,2,0,i);
1351 fCalibraMode->SetDetChamb2(i);
1352 ntotal += 6 * 18 * fCalibraMode->GetDetChamb2(i);
1353 fCalibraMode->ModePadCalibration(0,i);
1354 fCalibraMode->ModePadFragmentation(0,0,0,i);
1355 fCalibraMode->SetDetChamb0(i);
1356 ntotal += 6 * 4 * 18 * fCalibraMode->GetDetChamb0(i);
1357 AliInfo(Form("Total number of Xbins: %d for i %d",ntotal,i));
1361 //_____________________________________________________________________________
1362 void AliTRDCalibraFillHisto::SetNz(Int_t i, Short_t Nz)
1365 // Set the mode of calibration group in the z direction for the parameter i
1370 fCalibraMode->SetNz(i, Nz);
1373 AliInfo("You have to choose between 0 and 4");
1377 //_____________________________________________________________________________
1378 void AliTRDCalibraFillHisto::SetNrphi(Int_t i, Short_t Nrphi)
1381 // Set the mode of calibration group in the rphi direction for the parameter i
1386 fCalibraMode->SetNrphi(i ,Nrphi);
1389 AliInfo("You have to choose between 0 and 6");
1394 //_____________________________________________________________________________
1395 void AliTRDCalibraFillHisto::SetAllTogether(Int_t i)
1398 // Set the mode of calibration group all together
1400 if(fVector2d == kTRUE) {
1401 AliInfo("Can not work with the vector method");
1404 fCalibraMode->SetAllTogether(i);
1408 //_____________________________________________________________________________
1409 void AliTRDCalibraFillHisto::SetPerSuperModule(Int_t i)
1412 // Set the mode of calibration group per supermodule
1414 if(fVector2d == kTRUE) {
1415 AliInfo("Can not work with the vector method");
1418 fCalibraMode->SetPerSuperModule(i);
1422 //____________Set the pad calibration variables for the detector_______________
1423 Bool_t AliTRDCalibraFillHisto::LocalisationDetectorXbins(Int_t detector)
1426 // For the detector calcul the first Xbins and set the number of row
1427 // and col pads per calibration groups, the number of calibration
1428 // groups in the detector.
1431 // first Xbins of the detector
1433 fCalibraMode->CalculXBins(detector,0);
1436 fCalibraMode->CalculXBins(detector,1);
1439 fCalibraMode->CalculXBins(detector,2);
1442 // fragmentation of idect
1443 for (Int_t i = 0; i < 3; i++) {
1444 fCalibraMode->ModePadCalibration((Int_t) GetStack(detector),i);
1445 fCalibraMode->ModePadFragmentation((Int_t) GetLayer(detector)
1446 , (Int_t) GetStack(detector)
1447 , (Int_t) GetSector(detector),i);
1453 //_____________________________________________________________________________
1454 void AliTRDCalibraFillHisto::SetNumberGroupsPRF(Short_t numberGroupsPRF)
1457 // Should be between 0 and 6
1460 if ((numberGroupsPRF < 0) || (numberGroupsPRF > 6)) {
1461 AliInfo("The number of groups must be between 0 and 6!");
1464 fNgroupprf = numberGroupsPRF;
1468 ///////////////////////////////////////////////////////////////////////////////////////////
1469 // Per tracklet: store or reset the info, fill the histos with the info
1470 //////////////////////////////////////////////////////////////////////////////////////////
1471 //_____________________________________________________________________________
1472 void AliTRDCalibraFillHisto::StoreInfoCHPHtrack(const AliTRDcluster *cl,const Double_t dqdl,const Int_t *group,const Int_t row,const Int_t col,const AliTRDcluster *cls)
1475 // Store the infos in fAmpTotal, fPHPlace and fPHValue
1476 // Correct from the gain correction before
1477 // cls is shared cluster if any
1480 //printf("StoreInfoCHPHtrack\n");
1482 // time bin of the cluster not corrected
1483 Int_t time = cl->GetPadTime();
1484 Float_t charge = TMath::Abs(cl->GetQ());
1486 charge += TMath::Abs(cls->GetQ());
1487 //printf("AliTRDCalibraFillHisto::Add the cluster charge");
1490 //printf("Store::time %d, amplitude %f\n",time,dqdl);
1492 //Correct for the gain coefficient used in the database for reconstruction
1493 Float_t correctthegain = 1.0;
1494 if(fIsHLT) correctthegain = fCalDetGain->GetValue(fDetectorPreviousTrack);
1495 else correctthegain = fCalDetGain->GetValue(fDetectorPreviousTrack)*fCalROCGain->GetValue(col,row);
1496 Float_t correction = 1.0;
1497 Float_t normalisation = 6.67;
1498 // we divide with gain in AliTRDclusterizer::Transform...
1499 if( correctthegain > 0 ) normalisation /= correctthegain;
1502 // take dd/dl corrected from the angle of the track
1503 correction = dqdl / (normalisation);
1506 // Fill the fAmpTotal with the charge
1508 if((!fLimitChargeIntegration) || (cl->IsInChamber())) {
1509 //printf("Store::group %d, amplitude %f\n",group[0],correction);
1510 fAmpTotal[(Int_t) group[0]] += correction;
1514 // Fill the fPHPlace and value
1516 fPHPlace[time] = group[1];
1517 fPHValue[time] = charge;
1521 //____________Offine tracking in the AliTRDtracker_____________________________
1522 void AliTRDCalibraFillHisto::ResetfVariablestracklet()
1525 // Reset values per tracklet
1528 //Reset good tracklet
1529 fGoodTracklet = kTRUE;
1531 // Reset the fPHValue
1533 //Reset the fPHValue and fPHPlace
1534 for (Int_t k = 0; k < fTimeMax; k++) {
1540 // Reset the fAmpTotal where we put value
1542 for (Int_t k = 0; k < fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0); k++) {
1547 //____________Offine tracking in the AliTRDtracker_____________________________
1548 void AliTRDCalibraFillHisto::FillTheInfoOfTheTrackCH(Int_t nbclusters)
1551 // For the offline tracking or mcm tracklets
1552 // This function will be called in the functions UpdateHistogram...
1553 // to fill the info of a track for the relativ gain calibration
1556 Int_t nb = 0; // Nombre de zones traversees
1557 Int_t fd = -1; // Premiere zone non nulle
1558 Float_t totalcharge = 0.0; // Total charge for the supermodule histo
1560 //printf("CH2d nbclusters %d, fNumberClusters %d, fNumberClustersf %d\n",nbclusters,fNumberClusters,fNumberClustersf);
1562 if(nbclusters < fNumberClusters) return;
1563 if(nbclusters > fNumberClustersf) return;
1566 // Normalize with the number of clusters
1567 Double_t normalizeCst = fRelativeScale;
1568 if(fNormalizeNbOfCluster) normalizeCst = normalizeCst*nbclusters;
1570 //printf("Number of groups in one detector %d\n",fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0));
1572 // See if the track goes through different zones
1573 for (Int_t k = 0; k < fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0); k++) {
1574 //printf("fAmpTotal %f for %d\n",fAmpTotal[k],k);
1575 if (fAmpTotal[k] > 0.0) {
1576 totalcharge += fAmpTotal[k];
1584 //printf("CH2d: nb %d, fd %d, calibration group %d, amplitude %f, detector %d\n",nb,fd,fCalibraMode->GetXbins(0),fAmpTotal[fd]/normalizeCst,fDetectorPreviousTrack);
1590 fEntriesCH[fCalibraMode->GetXbins(0)+fd]++;
1592 FillCH2d(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/normalizeCst);
1593 //fCH2d->Fill(fAmpTotal[fd]/normalizeCst,fCalibraMode->GetXbins(0)+fd+0.5);
1596 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd,fAmpTotal[fd]/normalizeCst);
1600 if ((fAmpTotal[fd] > 0.0) &&
1601 (fAmpTotal[fd+1] > 0.0)) {
1602 // One of the two very big
1603 if (fAmpTotal[fd] > fProcent*fAmpTotal[fd+1]) {
1605 FillCH2d(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/normalizeCst);
1606 //fCH2d->Fill(fAmpTotal[fd]/normalizeCst,fCalibraMode->GetXbins(0)+fd+0.5);
1609 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd,fAmpTotal[fd]/normalizeCst);
1612 fEntriesCH[fCalibraMode->GetXbins(0)+fd]++;
1614 if (fAmpTotal[fd+1] > fProcent*fAmpTotal[fd]) {
1616 FillCH2d(fCalibraMode->GetXbins(0)+fd+1,fAmpTotal[fd+1]/normalizeCst);
1617 //fCH2d->Fill(fAmpTotal[fd+1]/normalizeCst,fCalibraMode->GetXbins(0)+fd+1.5);
1620 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd+1,fAmpTotal[fd+1]/normalizeCst);
1623 fEntriesCH[fCalibraMode->GetXbins(0)+fd+1]++;
1626 if (fCalibraMode->GetNfragZ(0) > 1) {
1627 if (fAmpTotal[fd] > 0.0) {
1628 if ((fd+fCalibraMode->GetNfragZ(0)) < (fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0))) {
1629 if (fAmpTotal[fd+fCalibraMode->GetNfragZ(0)] > 0.0) {
1630 // One of the two very big
1631 if (fAmpTotal[fd] > fProcent*fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]) {
1633 FillCH2d(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/normalizeCst);
1634 //fCH2d->Fill(fAmpTotal[fd]/normalizeCst,fCalibraMode->GetXbins(0)+fd+0.5);
1637 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd,fAmpTotal[fd]/normalizeCst);
1640 fEntriesCH[fCalibraMode->GetXbins(0)+fd]++;
1642 if (fAmpTotal[fd+fCalibraMode->GetNfragZ(0)] > fProcent*fAmpTotal[fd]) {
1644 FillCH2d(fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0),fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/normalizeCst);
1645 //fCH2d->Fill(fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/normalizeCst,fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0)+0.5);
1648 fEntriesCH[fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0)]++;
1650 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd+fCalibraMode->GetNfragZ(0),fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/normalizeCst);
1661 //____________Offine tracking in the AliTRDtracker_____________________________
1662 void AliTRDCalibraFillHisto::FillTheInfoOfTheTrackPH()
1665 // For the offline tracking or mcm tracklets
1666 // This function will be called in the functions UpdateHistogram...
1667 // to fill the info of a track for the drift velocity calibration
1670 Int_t nb = 1; // Nombre de zones traversees 1, 2 ou plus de 3
1671 Int_t fd1 = -1; // Premiere zone non nulle
1672 Int_t fd2 = -1; // Deuxieme zone non nulle
1673 Int_t k1 = -1; // Debut de la premiere zone
1674 Int_t k2 = -1; // Debut de la seconde zone
1675 Int_t nbclusters = 0; // number of clusters
1679 // See if the track goes through different zones
1680 for (Int_t k = 0; k < fTimeMax; k++) {
1681 if (fPHValue[k] > 0.0) {
1687 if (fPHPlace[k] != fd1) {
1693 if (fPHPlace[k] != fd2) {
1700 // See if noise before and after
1701 if(fMaxCluster > 0) {
1702 if(fPHValue[0] > fMaxCluster) return;
1703 if(fTimeMax > fNbMaxCluster) {
1704 for(Int_t k = (fTimeMax-fNbMaxCluster); k < fTimeMax; k++){
1705 if(fPHValue[k] > fMaxCluster) return;
1710 //printf("nbclusters %d, low limit %d, high limit %d\n",nbclusters,fNumberClusters,fNumberClustersf);
1712 if(nbclusters < fNumberClusters) return;
1713 if(nbclusters > fNumberClustersf) return;
1719 for (Int_t i = 0; i < fTimeMax; i++) {
1721 if(fFillWithZero) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1723 if(((Float_t) fPHValue[i] > 0.0)) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1725 //printf("Fill the time bin %d with %f\n",i,fPHValue[i]);
1728 if(fFillWithZero) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1730 if(((Float_t) fPHValue[i] > 0.0)) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1736 if ((fd1 == fd2+1) ||
1738 // One of the two fast all the think
1739 if (k2 > (k1+fDifference)) {
1740 //we choose to fill the fd1 with all the values
1742 for (Int_t i = 0; i < fTimeMax; i++) {
1744 if(fFillWithZero) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1746 if(((Float_t) fPHValue[i] > 0.0)) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1750 if(fFillWithZero) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1752 if(((Float_t) fPHValue[i] > 0.0)) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1757 if ((k2+fDifference) < fTimeMax) {
1758 //we choose to fill the fd2 with all the values
1760 for (Int_t i = 0; i < fTimeMax; i++) {
1762 if(fFillWithZero) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
1764 if(((Float_t) fPHValue[i] > 0.0)) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
1768 if(fFillWithZero) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd2,i,fPHValue[i]);
1770 if(((Float_t) fPHValue[i] > 0.0)) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd2,i,fPHValue[i]);
1776 // Two zones voisines sinon rien!
1777 if (fCalibraMode->GetNfragZ(1) > 1) {
1779 if ((fd1+fCalibraMode->GetNfragZ(1)) < (fCalibraMode->GetNfragZ(1)*fCalibraMode->GetNfragRphi(1))) {
1780 if (fd2 == (fd1+fCalibraMode->GetNfragZ(1))) {
1781 // One of the two fast all the think
1782 if (k2 > (k1+fDifference)) {
1783 //we choose to fill the fd1 with all the values
1785 for (Int_t i = 0; i < fTimeMax; i++) {
1787 if(fFillWithZero) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1789 if(((Float_t) fPHValue[i] > 0.0)) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1793 if(fFillWithZero) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1795 if(((Float_t) fPHValue[i] > 0.0)) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1800 if ((k2+fDifference) < fTimeMax) {
1801 //we choose to fill the fd2 with all the values
1803 for (Int_t i = 0; i < fTimeMax; i++) {
1805 if(fFillWithZero) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
1807 if(((Float_t) fPHValue[i] > 0.0)) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
1811 if(fFillWithZero) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd2,i,fPHValue[i]);
1813 if(((Float_t) fPHValue[i] > 0.0)) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd2,i,fPHValue[i]);
1820 // Two zones voisines sinon rien!
1822 if ((fd1 - fCalibraMode->GetNfragZ(1)) >= 0) {
1823 if (fd2 == (fd1 - fCalibraMode->GetNfragZ(1))) {
1824 // One of the two fast all the think
1825 if (k2 > (k1 + fDifference)) {
1826 //we choose to fill the fd1 with all the values
1828 for (Int_t i = 0; i < fTimeMax; i++) {
1830 if(fFillWithZero) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1832 if(((Float_t) fPHValue[i] > 0.0)) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1836 if(fFillWithZero) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1838 if(((Float_t) fPHValue[i] > 0.0)) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1843 if ((k2+fDifference) < fTimeMax) {
1844 //we choose to fill the fd2 with all the values
1846 for (Int_t i = 0; i < fTimeMax; i++) {
1848 if(fFillWithZero) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
1850 if(((Float_t) fPHValue[i] > 0.0)) fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
1854 if(fFillWithZero) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd2,i,fPHValue[i]);
1856 if(((Float_t) fPHValue[i] > 0.0)) fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd2,i,fPHValue[i]);
1868 //////////////////////////////////////////////////////////////////////////////////////////
1869 // DAQ process functions
1870 /////////////////////////////////////////////////////////////////////////////////////////
1871 //_____________________________________________________________________
1872 Int_t AliTRDCalibraFillHisto::ProcessEventDAQ(AliRawReader *rawReader)
1875 // Event Processing loop - AliTRDrawStream
1877 // 0 timebin problem
1880 // Same algorithm as TestBeam but different reader
1883 AliTRDrawStream *rawStream = new AliTRDrawStream(rawReader);
1885 AliTRDdigitsManager *digitsManager = new AliTRDdigitsManager(kTRUE);
1886 digitsManager->CreateArrays();
1888 Int_t withInput = 1;
1890 Double_t phvalue[16][144][36];
1891 for(Int_t k = 0; k < 36; k++){
1892 for(Int_t j = 0; j < 16; j++){
1893 for(Int_t c = 0; c < 144; c++){
1894 phvalue[j][c][k] = 0.0;
1899 fDetectorPreviousTrack = -1;
1903 Int_t nbtimebin = 0;
1904 Int_t baseline = 10;
1910 while ((det = rawStream->NextChamber(digitsManager, NULL, NULL)) >= 0) { //idetector
1912 if (digitsManager->GetIndexes(det)->HasEntry()) {//QA
1913 // printf("there is ADC data on this chamber!\n");
1915 AliTRDarrayADC *digits = (AliTRDarrayADC *) digitsManager->GetDigits(det); //mod
1916 if (digits->HasData()) { //array
1918 AliTRDSignalIndex *indexes = digitsManager->GetIndexes(det);
1919 if (indexes->IsAllocated() == kFALSE) {
1920 AliError("Indexes do not exist!");
1925 indexes->ResetCounters();
1927 while (indexes->NextRCIndex(iRow, iCol)) { //column,row
1928 //printf(" det %d \t row %d \t col %d \t digit\n",det,iRow,iCol);
1929 //while (rawStream->Next()) {
1931 Int_t idetector = det; // current detector
1932 //Int_t imcm = rawStream->GetMCM(); // current MCM
1933 //Int_t irob = rawStream->GetROB(); // current ROB
1936 if((fDetectorPreviousTrack != idetector) && (fDetectorPreviousTrack != -1)) {
1938 withInput = TMath::Max(FillDAQ(phvalue),withInput);
1941 for(Int_t k = 0; k < 36; k++){
1942 for(Int_t j = 0; j < 16; j++){
1943 for(Int_t c = 0; c < 144; c++){
1944 phvalue[j][c][k] = 0.0;
1950 fDetectorPreviousTrack = idetector;
1951 //fMCMPrevious = imcm;
1952 //fROBPrevious = irob;
1954 // nbtimebin = rawStream->GetNumberOfTimeBins(); // number of time bins read from data
1955 AliTRDdigitsParam *digitParam = (AliTRDdigitsParam *)digitsManager->GetDigitsParam();
1956 nbtimebin = digitParam->GetNTimeBins(det); // number of time bins read from data
1957 baseline = digitParam->GetADCbaseline(det); // baseline
1959 if(nbtimebin == 0) return 0;
1960 if((fTimeMax != 0) && (nbtimebin != fTimeMax)) return 0;
1961 fTimeMax = nbtimebin;
1963 fNumberClustersf = fTimeMax;
1964 fNumberClusters = (Int_t)(fNumberClustersProcent*fTimeMax);
1967 for(Int_t itime = 0; itime < nbtimebin; itime++) {
1968 // phvalue[row][col][itime] = signal[itime]-baseline;
1969 phvalue[iRow][iCol][itime] = (Short_t)(digits->GetData(iRow,iCol,itime) - baseline);
1970 /*if(phvalue[iRow][iCol][itime] >= 20) {
1971 printf("----------> phvalue[%d][%d][%d] %d baseline %d \n",
1975 (Short_t)(digits->GetData(iRow,iCol,itime)),
1982 // fill the last one
1983 if(fDetectorPreviousTrack != -1){
1986 withInput = TMath::Max(FillDAQ(phvalue),withInput);
1987 // printf("\n ---> withinput %d\n\n",withInput);
1989 for(Int_t k = 0; k < 36; k++){
1990 for(Int_t j = 0; j < 16; j++){
1991 for(Int_t c = 0; c < 144; c++){
1992 phvalue[j][c][k] = 0.0;
2000 digitsManager->ClearArrays(det);
2002 delete digitsManager;
2007 //_____________________________________________________________________
2008 //////////////////////////////////////////////////////////////////////////////
2009 // Routine inside the DAQ process
2010 /////////////////////////////////////////////////////////////////////////////
2011 //_______________________________________________________________________
2012 Int_t AliTRDCalibraFillHisto::FillDAQ(Double_t phvalue[16][144][36]){
2015 // Look for the maximum by collapsing over the time
2016 // Sum over four pad col and two pad row
2022 Int_t idect = fDetectorPreviousTrack;
2023 //printf("Enter Detector %d\n",fDetectorPreviousTrack);
2025 for(Int_t tb = 0; tb < 36; tb++){
2029 //fGoodTracklet = kTRUE;
2030 //fDetectorPreviousTrack = 0;
2033 ///////////////////////////
2035 /////////////////////////
2039 Double_t integralMax = -1;
2041 for (Int_t ir = 1; ir <= 15; ir++)
2043 for (Int_t ic = 2; ic <= 142; ic++)
2045 Double_t integral = 0;
2046 for (Int_t ishiftR = 0; ishiftR < fNumberRowDAQ; ishiftR++)
2048 for (Int_t ishiftC = -fNumberColDAQ; ishiftC < fNumberColDAQ; ishiftC++)
2050 if (ir + ishiftR >= 1 && ir + ishiftR <= 16 &&
2051 ic + ishiftC >= 1 && ic + ishiftC <= 144)
2054 for(Int_t tb = 0; tb< fTimeMax; tb++){
2055 integral += phvalue[ir + ishiftR-1][ic + ishiftC-1][tb];
2060 if (integralMax < integral)
2064 integralMax = integral;
2066 } // check max integral
2070 // printf("imaxRow %d, imaxCol %d, fTimeMax %d, integralMax %f\n",imaxRow,imaxCol,fTimeMax, integralMax);
2071 //if((imaxRow == 0) || (imaxRow >= 15) || (imaxCol <= 3) || (imaxCol >= 140)) {
2076 if(((imaxRow + fNumberRowDAQ) > 16) || (imaxRow == 0) || ((imaxCol - fNumberColDAQ) <= 1) || ((imaxCol + fNumberColDAQ) >= 144)) {
2080 //CheckGoodTrackletV0(fDetectorPreviousTrack,imaxRow,imaxCol);
2081 //if(!fGoodTracklet) used = 1;;
2083 // /////////////////////////////////////////////////////
2084 // sum ober 2 row and 4 pad cols for each time bins
2085 // ////////////////////////////////////////////////////
2089 for (Int_t ishiftR = 0; ishiftR < fNumberRowDAQ; ishiftR++)
2091 for (Int_t ishiftC = -fNumberColDAQ; ishiftC < fNumberColDAQ; ishiftC++)
2093 if (imaxRow + ishiftR >= 1 && imaxRow + ishiftR <= 16 &&
2094 imaxCol + ishiftC >= 1 && imaxCol + ishiftC <= 144)
2096 for(Int_t it = 0; it < fTimeMax; it++){
2097 sum[it] += phvalue[imaxRow + ishiftR-1][imaxCol + ishiftC-1][it];
2104 Double_t sumcharge = 0.0;
2105 for(Int_t it = 0; it < fTimeMax; it++){
2106 sumcharge += sum[it];
2107 if(sum[it] > fThresholdClustersDAQ) nbcl++;
2111 /////////////////////////////////////////////////////////
2113 ////////////////////////////////////////////////////////
2114 if(fDebugLevel > 0){
2115 if ( !fDebugStreamer ) {
2117 TDirectory *backup = gDirectory;
2118 fDebugStreamer = new TTreeSRedirector("TRDdebugCalibraFill.root");
2119 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
2122 Double_t amph0 = sum[0];
2123 Double_t amphlast = sum[fTimeMax-1];
2124 Double_t rms = TMath::RMS(fTimeMax,sum);
2125 Int_t goodtracklet = (Int_t) fGoodTracklet;
2126 for(Int_t it = 0; it < fTimeMax; it++){
2127 Double_t clustera = sum[it];
2129 (* fDebugStreamer) << "FillDAQa"<<
2130 "ampTotal="<<sumcharge<<
2133 "detector="<<idect<<
2135 "amphlast="<<amphlast<<
2136 "goodtracklet="<<goodtracklet<<
2137 "clustera="<<clustera<<
2145 ////////////////////////////////////////////////////////
2147 ///////////////////////////////////////////////////////
2148 //printf("fNumberClusters %d, fNumberClustersf %d\n",fNumberClusters,fNumberClustersf);
2149 if(sum[0] > 100.0) used = 1;
2150 if(nbcl < fNumberClusters) used = 1;
2151 if(nbcl > fNumberClustersf) used = 1;
2153 //if(fDetectorPreviousTrack == 15){
2154 // printf("rms %f and first time bin %f\n",TMath::RMS(fTimeMax,sum),sum[0]);
2156 //if((TMath::RMS(fTimeMax,sum) <= 10.0) && (sum[0] > 200.0)) return 1;
2158 for(Int_t it = 0; it < fTimeMax; it++){
2159 if(fFillWithZero) UpdateDAQ(fDetectorPreviousTrack,0,0,it,sum[it],fTimeMax);
2161 if(sum[it] > 0.0) UpdateDAQ(fDetectorPreviousTrack,0,0,it,sum[it],fTimeMax);
2163 //if(fFillWithZero) UpdateDAQ(0,0,0,it,sum[it],fTimeMax);
2165 // if(sum[it] > 0.0) UpdateDAQ(0,0,0,it,sum[it],fTimeMax);
2170 //((TH2I *)GetCH2d()->Fill(sumcharge/30.0,fDetectorPreviousTrack));
2172 //printf("Pass Detector %d\n",fDetectorPreviousTrack);
2179 //____________Online trackling in AliTRDtrigger________________________________
2180 Bool_t AliTRDCalibraFillHisto::UpdateDAQ(Int_t det, Int_t /*row*/, Int_t /*col*/, Int_t timebin, Float_t signal, Int_t nbtimebins)
2184 // Fill a simple average pulse height
2188 ((TProfile2D *)GetPH2d(nbtimebins,fSf))->Fill((Float_t) timebin/fSf,det+0.5,(Float_t) signal);
2194 //____________Write_____________________________________________________
2195 //_____________________________________________________________________
2196 void AliTRDCalibraFillHisto::Write2d(const Char_t *filename, Bool_t append)
2199 // Write infos to file
2203 if ( fDebugStreamer ) {
2204 delete fDebugStreamer;
2205 fDebugStreamer = 0x0;
2208 AliInfo(Form("Numbertrack: %d Numberusedch[0]: %d, Numberusedch[1]: %d Numberusedph[0]: %d, Numberusedph[1]: %d"
2213 ,fNumberUsedPh[1]));
2215 TDirectory *backup = gDirectory;
2221 option = "recreate";
2223 TFile f(filename,option.Data());
2225 TStopwatch stopwatch;
2228 f.WriteTObject(fCalibraVector);
2233 f.WriteTObject(fCH2d);
2238 f.WriteTObject(fPH2d);
2243 f.WriteTObject(fPRF2d);
2246 if(fLinearFitterOn){
2247 if(fLinearFitterDebugOn) AnalyseLinearFitter();
2248 f.WriteTObject(fLinearVdriftFit);
2253 if ( backup ) backup->cd();
2255 AliInfo(Form("Execution time Write2d: R:%.2fs C:%.2fs"
2256 ,stopwatch.RealTime(),stopwatch.CpuTime()));
2258 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
2260 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
2261 //___________________________________________probe the histos__________________________________________________
2262 Double_t *AliTRDCalibraFillHisto::StatH(TH2 *h, Int_t i)
2265 // Check the number of stats in h, 0 is TH2I 1 is TProfile2D
2266 // debug mode with 2 for TH2I and 3 for TProfile2D
2267 // It gives a pointer to a Double_t[7] with the info following...
2268 // [0] : number of calibration groups with entries
2269 // [1] : minimal number of entries found
2270 // [2] : calibration group number of the min
2271 // [3] : maximal number of entries found
2272 // [4] : calibration group number of the max
2273 // [5] : mean number of entries found
2274 // [6] : mean relative error
2277 Double_t *info = new Double_t[7];
2279 // Number of Xbins (detectors or groups of pads)
2280 Int_t nbins = h->GetNbinsY(); //number of calibration groups
2281 Int_t nxbins = h->GetNbinsX(); //number of bins per histo
2284 Double_t nbwe = 0; //number of calibration groups with entries
2285 Double_t minentries = 0; //minimal number of entries found
2286 Double_t maxentries = 0; //maximal number of entries found
2287 Double_t placemin = 0; //calibration group number of the min
2288 Double_t placemax = -1; //calibration group number of the max
2289 Double_t meanstats = 0.0; //mean number of entries over the calibration group with at least ome entry
2290 Double_t meanrelativerror = 0.0; //mean relativ error in the TProfile2D
2292 Double_t counter = 0;
2295 TH1F *nbEntries = 0x0;//distribution of the number of entries
2296 TH1F *nbEntriesPerGroup = 0x0;//Number of entries per group
2297 TProfile *nbEntriesPerSp = 0x0;//Number of entries for one supermodule
2299 // Beginning of the loop over the calibration groups
2300 for (Int_t idect = 0; idect < nbins; idect++) {
2302 TH1I *projch = (TH1I *) h->ProjectionX("projch",idect+1,idect+1,(Option_t *)"e");
2303 projch->SetDirectory(0);
2305 // Number of entries for this calibration group
2306 Double_t nentries = 0.0;
2308 for (Int_t k = 0; k < nxbins; k++) {
2309 nentries += h->GetBinContent(h->GetBin(k+1,idect+1));
2313 for (Int_t k = 0; k < nxbins; k++) {
2314 nentries += ((TProfile2D *)h)->GetBinEntries(h->GetBin(k+1,idect+1));
2315 if(h->GetBinContent(h->GetBin(k+1,idect+1)) != 0) {
2316 meanrelativerror += (h->GetBinError(h->GetBin(k+1,idect+1))/(TMath::Abs(h->GetBinContent(h->GetBin(k+1,idect+1)))));
2325 if(!((Bool_t)nbEntries)) nbEntries = new TH1F("Number of entries","Number of entries",100,(Int_t)nentries/2,nentries*2);
2326 nbEntries->SetDirectory(0);
2327 nbEntries->Fill(nentries);
2328 if(!((Bool_t)nbEntriesPerGroup)) nbEntriesPerGroup = new TH1F("Number of entries per group","Number of entries per group",nbins,0,nbins);
2329 nbEntriesPerGroup->SetDirectory(0);
2330 nbEntriesPerGroup->Fill(idect+0.5,nentries);
2331 if(!((Bool_t)nbEntriesPerSp)) nbEntriesPerSp = new TProfile("Number of entries per supermodule","Number of entries per supermodule",(Int_t)(nbins/18),0,(Int_t)(nbins/18));
2332 nbEntriesPerSp->SetDirectory(0);
2333 nbEntriesPerSp->Fill((idect%((Int_t)(nbins/18)))+0.5,nentries);
2338 if(nentries > maxentries){
2339 maxentries = nentries;
2343 minentries = nentries;
2345 if(nentries < minentries){
2346 minentries = nentries;
2352 meanstats += nentries;
2354 }//calibration groups loop
2356 if(nbwe > 0) meanstats /= nbwe;
2357 if(counter > 0) meanrelativerror /= counter;
2359 AliInfo(Form("There are %f calibration groups with entries",nbwe));
2360 AliInfo(Form("The minimum number of entries is %f for the group %f",minentries,placemin));
2361 AliInfo(Form("The maximum number of entries is %f for the group %f",maxentries,placemax));
2362 AliInfo(Form("The mean number of entries is %f",meanstats));
2363 if((i%2) == 1) AliInfo(Form("The mean relative error is %f",meanrelativerror));
2366 info[1] = minentries;
2368 info[3] = maxentries;
2370 info[5] = meanstats;
2371 info[6] = meanrelativerror;
2373 if(nbEntries && nbEntriesPerSp && nbEntriesPerGroup){
2374 gStyle->SetPalette(1);
2375 gStyle->SetOptStat(1111);
2376 gStyle->SetPadBorderMode(0);
2377 gStyle->SetCanvasColor(10);
2378 gStyle->SetPadLeftMargin(0.13);
2379 gStyle->SetPadRightMargin(0.01);
2380 TCanvas *stat = new TCanvas("stat","",50,50,600,800);
2383 nbEntries->Draw("");
2385 nbEntriesPerSp->SetStats(0);
2386 nbEntriesPerSp->Draw("");
2387 TCanvas *stat1 = new TCanvas("stat1","",50,50,600,800);
2389 nbEntriesPerGroup->SetStats(0);
2390 nbEntriesPerGroup->Draw("");
2396 //____________________________________________________________________________
2397 Double_t *AliTRDCalibraFillHisto::GetMeanMedianRMSNumberCH()
2400 // Return a Int_t[4] with:
2401 // 0 Mean number of entries
2402 // 1 median of number of entries
2403 // 2 rms of number of entries
2404 // 3 number of group with entries
2407 Double_t *stat = new Double_t[4];
2410 Int_t nbofgroups = CalculateTotalNumberOfBins(0);
2412 Double_t *weight = new Double_t[nbofgroups];
2413 Double_t *nonul = new Double_t[nbofgroups];
2415 for(Int_t k = 0; k < nbofgroups; k++){
2416 if(fEntriesCH[k] > 0) {
2418 nonul[(Int_t)stat[3]] = fEntriesCH[k];
2421 else weight[k] = 0.0;
2423 stat[0] = TMath::Mean(nbofgroups,fEntriesCH,weight);
2424 stat[1] = TMath::Median(nbofgroups,fEntriesCH,weight);
2425 stat[2] = TMath::RMS((Int_t)stat[3],nonul);
2433 //____________________________________________________________________________
2434 Double_t *AliTRDCalibraFillHisto::GetMeanMedianRMSNumberLinearFitter() const
2437 // Return a Int_t[4] with:
2438 // 0 Mean number of entries
2439 // 1 median of number of entries
2440 // 2 rms of number of entries
2441 // 3 number of group with entries
2444 Double_t *stat = new Double_t[4];
2447 Int_t nbofgroups = 540;
2448 Double_t *weight = new Double_t[nbofgroups];
2449 Int_t *nonul = new Int_t[nbofgroups];
2451 for(Int_t k = 0; k < nbofgroups; k++){
2452 if(fEntriesLinearFitter[k] > 0) {
2454 nonul[(Int_t) stat[3]] = fEntriesLinearFitter[k];
2457 else weight[k] = 0.0;
2459 stat[0] = TMath::Mean(nbofgroups,fEntriesLinearFitter,weight);
2460 stat[1] = TMath::Median(nbofgroups,fEntriesLinearFitter,weight);
2461 stat[2] = TMath::RMS((Int_t)stat[3],nonul);
2469 //////////////////////////////////////////////////////////////////////////////////////
2471 //////////////////////////////////////////////////////////////////////////////////////
2472 //_____________________________________________________________________________
2473 void AliTRDCalibraFillHisto::CreatePRF2d(Int_t nn)
2476 // Create the 2D histos: here we have 2*fNgroupprf bins in tnp of 0.2 amplitude each
2477 // If fNgroupprf is zero then no binning in tnp
2481 name += fCalibraMode->GetNz(2);
2483 name += fCalibraMode->GetNrphi(2);
2487 if(fNgroupprf != 0){
2489 fPRF2d = new TProfile2D("PRF2d",(const Char_t *) name
2490 ,2*fNgroupprf*fNumberBinPRF,-3.0*fNgroupprf,3.0*fNgroupprf,nn,0,nn);
2491 fPRF2d->SetYTitle("Det/pad groups");
2492 fPRF2d->SetXTitle("Position x/W [pad width units]");
2493 fPRF2d->SetZTitle("Q_{i}/Q_{total}");
2494 fPRF2d->SetStats(0);
2497 fPRF2d = new TProfile2D("PRF2d",(const Char_t *) name
2498 ,fNumberBinPRF,-1.5,1.5,nn,0,nn);
2499 fPRF2d->SetYTitle("Det/pad groups");
2500 fPRF2d->SetXTitle("Position x/W [pad width units]");
2501 fPRF2d->SetZTitle("Q_{i}/Q_{total}");
2502 fPRF2d->SetStats(0);
2507 //_____________________________________________________________________________
2508 void AliTRDCalibraFillHisto::CreatePH2d(Int_t nn)
2511 // Create the 2D histos
2514 TString name("Ver");
2515 name += fVersionVdriftUsed;
2517 name += fSubVersionVdriftUsed;
2519 name += fFirstRunVdrift;
2521 name += fCalibraMode->GetNz(1);
2523 name += fCalibraMode->GetNrphi(1);
2525 fPH2d = new TProfile2D("PH2d",(const Char_t *) name
2526 ,fTimeMax,-0.5/fSf,(Float_t) (fTimeMax-0.5)/fSf
2528 fPH2d->SetYTitle("Det/pad groups");
2529 fPH2d->SetXTitle("time [#mus]");
2530 fPH2d->SetZTitle("<PH> [a.u.]");
2534 //_____________________________________________________________________________
2535 void AliTRDCalibraFillHisto::CreateCH2d(Int_t nn)
2538 // Create the 2D histos
2541 TString name("Ver");
2542 name += fVersionGainUsed;
2544 name += fSubVersionGainUsed;
2546 name += fFirstRunGain;
2548 name += fCalibraMode->GetNz(0);
2550 name += fCalibraMode->GetNrphi(0);
2552 fCH2d = new TH2I("CH2d",(const Char_t *) name
2553 ,fNumberBinCharge,0,300,nn,0,nn);
2554 fCH2d->SetYTitle("Det/pad groups");
2555 fCH2d->SetXTitle("charge deposit [a.u]");
2556 fCH2d->SetZTitle("counts");
2561 //////////////////////////////////////////////////////////////////////////////////
2562 // Set relative scale
2563 /////////////////////////////////////////////////////////////////////////////////
2564 //_____________________________________________________________________________
2565 void AliTRDCalibraFillHisto::SetRelativeScale(Float_t RelativeScale)
2568 // Set the factor that will divide the deposited charge
2569 // to fit in the histo range [0,300]
2572 if (RelativeScale > 0.0) {
2573 fRelativeScale = RelativeScale;
2576 AliInfo("RelativeScale must be strict positif!");
2580 //////////////////////////////////////////////////////////////////////////////////
2581 // Quick way to fill a histo
2582 //////////////////////////////////////////////////////////////////////////////////
2583 //_____________________________________________________________________
2584 void AliTRDCalibraFillHisto::FillCH2d(Int_t x, Float_t y)
2587 // FillCH2d: Marian style
2590 //skip simply the value out of range
2591 if((y>=300.0) || (y<0.0)) return;
2593 //Calcul the y place
2594 Int_t yplace = (Int_t) (fNumberBinCharge*y/300.0)+1;
2595 Int_t place = (fNumberBinCharge+2)*(x+1)+yplace;
2598 fCH2d->GetArray()[place]++;
2602 //////////////////////////////////////////////////////////////////////////////////
2603 // Geometrical functions
2604 ///////////////////////////////////////////////////////////////////////////////////
2605 //_____________________________________________________________________________
2606 Int_t AliTRDCalibraFillHisto::GetLayer(Int_t d) const
2609 // Reconstruct the layer number from the detector number
2612 return ((Int_t) (d % 6));
2616 //_____________________________________________________________________________
2617 Int_t AliTRDCalibraFillHisto::GetStack(Int_t d) const
2620 // Reconstruct the stack number from the detector number
2622 const Int_t kNlayer = 6;
2624 return ((Int_t) (d % 30) / kNlayer);
2628 //_____________________________________________________________________________
2629 Int_t AliTRDCalibraFillHisto::GetSector(Int_t d) const
2632 // Reconstruct the sector number from the detector number
2636 return ((Int_t) (d / fg));
2639 ///////////////////////////////////////////////////////////////////////////////////
2640 // Getter functions for DAQ of the CH2d and the PH2d
2641 //////////////////////////////////////////////////////////////////////////////////
2642 //_____________________________________________________________________
2643 TProfile2D* AliTRDCalibraFillHisto::GetPH2d(Int_t nbtimebin, Float_t samplefrequency)
2646 // return pointer to fPH2d TProfile2D
2647 // create a new TProfile2D if it doesn't exist allready
2653 fTimeMax = nbtimebin;
2654 fSf = samplefrequency;
2660 //_____________________________________________________________________
2661 TH2I* AliTRDCalibraFillHisto::GetCH2d()
2664 // return pointer to fCH2d TH2I
2665 // create a new TH2I if it doesn't exist allready
2674 ////////////////////////////////////////////////////////////////////////////////////////////
2675 // Drift velocity calibration
2676 ///////////////////////////////////////////////////////////////////////////////////////////
2677 //_____________________________________________________________________
2678 TLinearFitter* AliTRDCalibraFillHisto::GetLinearFitter(Int_t detector, Bool_t force)
2681 // return pointer to TLinearFitter Calibration
2682 // if force is true create a new TLinearFitter if it doesn't exist allready
2685 if ((!force) || (fLinearFitterArray.UncheckedAt(detector))){
2686 return (TLinearFitter*)fLinearFitterArray.UncheckedAt(detector);
2689 // if we are forced and TLinearFitter doesn't yet exist create it
2691 // new TLinearFitter
2692 TLinearFitter *linearfitter = new TLinearFitter(2,"pol1");
2693 fLinearFitterArray.AddAt(linearfitter,detector);
2694 return linearfitter;
2697 //____________________________________________________________________________
2698 void AliTRDCalibraFillHisto::AnalyseLinearFitter()
2701 // Analyse array of linear fitter because can not be written
2702 // Store two arrays: one with the param the other one with the error param + number of entries
2705 for(Int_t k = 0; k < 540; k++){
2706 TLinearFitter *linearfitter = GetLinearFitter(k);
2707 if((linearfitter!=0) && (fEntriesLinearFitter[k]>10)){
2708 TVectorD *par = new TVectorD(2);
2709 TVectorD pare = TVectorD(2);
2710 TVectorD *parE = new TVectorD(3);
2711 if((linearfitter->EvalRobust(0.8)==0)) {
2712 //linearfitter->Eval();
2713 linearfitter->GetParameters(*par);
2714 //linearfitter->GetErrors(pare);
2715 //Float_t ppointError = TMath::Sqrt(TMath::Abs(linearfitter->GetChisquare())/fEntriesLinearFitter[k]);
2716 //(*parE)[0] = pare[0]*ppointError;
2717 //(*parE)[1] = pare[1]*ppointError;
2721 (*parE)[2] = (Double_t) fEntriesLinearFitter[k];
2722 ((TObjArray *)fLinearVdriftFit->GetPArray())->AddAt(par,k);
2723 ((TObjArray *)fLinearVdriftFit->GetEArray())->AddAt(parE,k);