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)
34 //////////////////////////////////////////////////////////////////////////////////////
37 #include <TProfile2D.h>
43 #include <TGraphErrors.h>
44 #include <TObjArray.h>
49 #include <TStopwatch.h>
51 #include <TDirectory.h>
53 #include <TTreeStream.h>
58 #include "AliCDBManager.h"
60 #include "AliTRDCalibraFillHisto.h"
61 #include "AliTRDCalibraFit.h"
62 #include "AliTRDCalibraMode.h"
63 #include "AliTRDCalibraVector.h"
64 #include "AliTRDCalibraVdriftLinearFit.h"
65 #include "AliTRDcalibDB.h"
66 #include "AliTRDCommonParam.h"
67 #include "AliTRDmcmTracklet.h"
68 #include "AliTRDpadPlane.h"
69 #include "AliTRDcluster.h"
70 #include "AliTRDtrack.h"
71 #include "AliTRDRawStreamV2.h"
72 #include "AliRawReader.h"
73 #include "AliRawReaderDate.h"
74 #include "AliTRDgeometry.h"
75 #include "./Cal/AliTRDCalROC.h"
76 #include "./Cal/AliTRDCalDet.h"
83 ClassImp(AliTRDCalibraFillHisto)
85 AliTRDCalibraFillHisto* AliTRDCalibraFillHisto::fgInstance = 0;
86 Bool_t AliTRDCalibraFillHisto::fgTerminated = kFALSE;
88 //_____________singleton implementation_________________________________________________
89 AliTRDCalibraFillHisto *AliTRDCalibraFillHisto::Instance()
92 // Singleton implementation
95 if (fgTerminated != kFALSE) {
99 if (fgInstance == 0) {
100 fgInstance = new AliTRDCalibraFillHisto();
107 //______________________________________________________________________________________
108 void AliTRDCalibraFillHisto::Terminate()
111 // Singleton implementation
112 // Deletes the instance of this class
115 fgTerminated = kTRUE;
117 if (fgInstance != 0) {
124 //______________________________________________________________________________________
125 AliTRDCalibraFillHisto::AliTRDCalibraFillHisto()
129 ,fMcmTracking(kFALSE)
130 ,fMcmCorrectAngle(kFALSE)
136 ,fLinearFitterOn(kFALSE)
137 ,fLinearFitterDebugOn(kFALSE)
139 ,fThresholdClusterPRF2(15.0)
140 ,fCalibraMode(new AliTRDCalibraMode())
143 ,fDetectorAliTRDtrack(kFALSE)
144 ,fDetectorPreviousTrack(-1)
151 ,fNumberBinCharge(100)
154 ,fListClusters(new TObjArray())
163 ,fGoodTracklet(kTRUE)
166 ,fEntriesLinearFitter(0x0)
171 ,fLinearFitterArray(540)
172 ,fLinearVdriftFit(0x0)
179 // Default constructor
183 // Init some default values
186 fNumberUsedCh[0] = 0;
187 fNumberUsedCh[1] = 0;
188 fNumberUsedPh[0] = 0;
189 fNumberUsedPh[1] = 0;
191 fGeo = new AliTRDgeometry();
195 //______________________________________________________________________________________
196 AliTRDCalibraFillHisto::AliTRDCalibraFillHisto(const AliTRDCalibraFillHisto &c)
199 ,fMITracking(c.fMITracking)
200 ,fMcmTracking(c.fMcmTracking)
201 ,fMcmCorrectAngle(c.fMcmCorrectAngle)
204 ,fPRF2dOn(c.fPRF2dOn)
205 ,fHisto2d(c.fHisto2d)
206 ,fVector2d(c.fVector2d)
207 ,fLinearFitterOn(c.fLinearFitterOn)
208 ,fLinearFitterDebugOn(c.fLinearFitterDebugOn)
209 ,fRelativeScale(c.fRelativeScale)
210 ,fThresholdClusterPRF2(c.fThresholdClusterPRF2)
213 ,fDebugLevel(c.fDebugLevel)
214 ,fDetectorAliTRDtrack(c.fDetectorAliTRDtrack)
215 ,fDetectorPreviousTrack(c.fDetectorPreviousTrack)
216 ,fNumberClusters(c.fNumberClusters)
217 ,fProcent(c.fProcent)
218 ,fDifference(c.fDifference)
219 ,fNumberTrack(c.fNumberTrack)
220 ,fTimeMax(c.fTimeMax)
222 ,fNumberBinCharge(c.fNumberBinCharge)
223 ,fNumberBinPRF(c.fNumberBinPRF)
224 ,fNgroupprf(c.fNgroupprf)
225 ,fListClusters(new TObjArray())
234 ,fGoodTracklet(c.fGoodTracklet)
235 ,fGoodTrack(c.fGoodTrack)
237 ,fEntriesLinearFitter(0x0)
242 ,fLinearFitterArray(540)
243 ,fLinearVdriftFit(0x0)
252 if(c.fCalibraMode) fCalibraMode = new AliTRDCalibraMode(*c.fCalibraMode);
253 if(c.fCalibraVector) fCalibraVector = new AliTRDCalibraVector(*c.fCalibraVector);
255 fPH2d = new TProfile2D(*c.fPH2d);
256 fPH2d->SetDirectory(0);
259 fPRF2d = new TProfile2D(*c.fPRF2d);
260 fPRF2d->SetDirectory(0);
263 fCH2d = new TH2I(*c.fCH2d);
264 fCH2d->SetDirectory(0);
266 if(c.fLinearVdriftFit){
267 fLinearVdriftFit = new AliTRDCalibraVdriftLinearFit(*c.fLinearVdriftFit);
270 if(c.fCalDetGain) fCalDetGain = new AliTRDCalDet(*c.fCalDetGain);
271 if(c.fCalDetT0) fCalDetT0 = new AliTRDCalDet(*c.fCalDetT0);
272 if(c.fCalROCGain) fCalROCGain = new AliTRDCalROC(*c.fCalROCGain);
273 if(c.fCalROCT0) fCalROCT0 = new AliTRDCalROC(*c.fCalROCT0);
278 fGeo = new AliTRDgeometry();
281 //____________________________________________________________________________________
282 AliTRDCalibraFillHisto::~AliTRDCalibraFillHisto()
285 // AliTRDCalibraFillHisto destructor
289 if ( fDebugStreamer ) delete fDebugStreamer;
291 if ( fCalDetGain ) delete fCalDetGain;
292 if ( fCalDetT0 ) delete fCalDetT0;
293 if ( fCalROCGain ) delete fCalROCGain;
294 if ( fCalROCT0 ) delete fCalROCT0;
302 //_____________________________________________________________________________
303 void AliTRDCalibraFillHisto::Destroy()
316 //_____________________________________________________________________________
317 void AliTRDCalibraFillHisto::ClearHistos()
338 //____________Functions for initialising the AliTRDCalibraFillHisto in the code_________
339 Bool_t AliTRDCalibraFillHisto::Init2Dhistos()
342 // For the offline tracking
343 // This function will be called in the function AliReconstruction::Run()
344 // Init the calibration mode (Nz, Nrphi), the 2D histograms if fHisto2d = kTRUE,
349 //Init the tracklet parameters
350 fPar0 = new Double_t[fTimeMax];
351 fPar1 = new Double_t[fTimeMax];
352 fPar2 = new Double_t[fTimeMax];
353 fPar3 = new Double_t[fTimeMax];
354 fPar4 = new Double_t[fTimeMax];
356 for(Int_t k = 0; k < fTimeMax; k++){
366 //____________Functions for initialising the AliTRDCalibraFillHisto in the code_________
367 Bool_t AliTRDCalibraFillHisto::Init2Dhistostrack()
370 // For the offline tracking
371 // This function will be called in the function AliReconstruction::Run()
372 // Init the calibration mode (Nz, Nrphi), the 2D histograms if fHisto2d = kTRUE,
377 AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
379 AliInfo("Could not get calibDB");
382 AliTRDCommonParam *parCom = AliTRDCommonParam::Instance();
384 AliInfo("Could not get CommonParam");
389 fTimeMax = cal->GetNumberOfTimeBins();
390 fSf = parCom->GetSamplingFrequency();
393 //calib object from database used for reconstruction
394 if(fCalDetGain) delete fCalDetGain;
395 fCalDetGain = new AliTRDCalDet(*(cal->GetGainFactorDet()));
396 if(fCalDetT0) delete fCalDetT0;
397 fCalDetT0 = new AliTRDCalDet(*(cal->GetT0Det()));
399 // Calcul Xbins Chambd0, Chamb2
400 Int_t Ntotal0 = CalculateTotalNumberOfBins(0);
401 Int_t Ntotal1 = CalculateTotalNumberOfBins(1);
402 Int_t Ntotal2 = CalculateTotalNumberOfBins(2);
404 // If vector method On initialised all the stuff
406 fCalibraVector = new AliTRDCalibraVector();
407 fCalibraVector->SetNumberBinCharge(fNumberBinCharge);
408 fCalibraVector->SetTimeMax(fTimeMax);
409 if(fNgroupprf != 0) {
410 fCalibraVector->SetNumberBinPRF(2*fNgroupprf*fNumberBinPRF);
411 fCalibraVector->SetPRFRange((Float_t)(3.0*fNgroupprf));
414 fCalibraVector->SetNumberBinPRF(fNumberBinPRF);
415 fCalibraVector->SetPRFRange(1.5);
417 for(Int_t k = 0; k < 3; k++){
418 fCalibraVector->SetDetCha0(k,fCalibraMode->GetDetChamb0(k));
419 fCalibraVector->SetDetCha2(k,fCalibraMode->GetDetChamb2(k));
421 TString namech("Nz");
422 namech += fCalibraMode->GetNz(0);
424 namech += fCalibraMode->GetNrphi(0);
425 fCalibraVector->SetNameCH((const char* ) namech);
426 TString nameph("Nz");
427 nameph += fCalibraMode->GetNz(1);
429 nameph += fCalibraMode->GetNrphi(1);
430 fCalibraVector->SetNamePH((const char* ) nameph);
431 TString nameprf("Nz");
432 nameprf += fCalibraMode->GetNz(2);
434 nameprf += fCalibraMode->GetNrphi(2);
436 nameprf += fNgroupprf;
437 fCalibraVector->SetNamePRF((const char* ) nameprf);
440 // Create the 2D histos corresponding to the pad groupCalibration mode
443 AliInfo(Form("The pad calibration mode for the relative gain calibration: Nz %d, and Nrphi %d"
444 ,fCalibraMode->GetNz(0)
445 ,fCalibraMode->GetNrphi(0)));
447 // Create the 2D histo
452 fAmpTotal = new Float_t[TMath::Max(fCalibraMode->GetDetChamb2(0),fCalibraMode->GetDetChamb0(0))];
453 for (Int_t k = 0; k < TMath::Max(fCalibraMode->GetDetChamb2(0),fCalibraMode->GetDetChamb0(0)); k++) {
457 fEntriesCH = new Int_t[Ntotal0];
458 for(Int_t k = 0; k < Ntotal0; k++){
465 AliInfo(Form("The pad calibration mode for the drift velocity calibration: Nz %d, and Nrphi %d"
466 ,fCalibraMode->GetNz(1)
467 ,fCalibraMode->GetNrphi(1)));
469 // Create the 2D histo
474 fPHPlace = new Short_t[fTimeMax];
475 for (Int_t k = 0; k < fTimeMax; k++) {
478 fPHValue = new Float_t[fTimeMax];
479 for (Int_t k = 0; k < fTimeMax; k++) {
483 if (fLinearFitterOn) {
484 //fLinearFitterArray.Expand(540);
485 fLinearFitterArray.SetName("ArrayLinearFitters");
486 fEntriesLinearFitter = new Int_t[540];
487 for(Int_t k = 0; k < 540; k++){
488 fEntriesLinearFitter[k] = 0;
490 fLinearVdriftFit = new AliTRDCalibraVdriftLinearFit();
495 AliInfo(Form("The pad calibration mode for the PRF calibration: Nz %d, and Nrphi %d"
496 ,fCalibraMode->GetNz(2)
497 ,fCalibraMode->GetNrphi(2)));
498 // Create the 2D histo
500 CreatePRF2d(Ntotal2);
508 //____________Functions for filling the histos in the code_____________________
510 //____________Offine tracking in the AliTRDtracker_____________________________
511 Bool_t AliTRDCalibraFillHisto::ResetTrack()
514 // For the offline tracking
515 // This function will be called in the function
516 // AliTRDtracker::FollowBackPropagation() at the beginning
517 // Reset the parameter to know we have a new TRD track
520 fDetectorAliTRDtrack = kFALSE;
521 //fGoodTrack = kTRUE;
525 //____________Offine tracking in the AliTRDtracker_____________________________
526 void AliTRDCalibraFillHisto::ResetfVariables()
529 // Reset values per tracklet
532 // Reset the list of clusters
533 fListClusters->Clear();
535 //Reset the tracklet parameters
536 for(Int_t k = 0; k < fTimeMax; k++){
544 ResetfVariablestrack();
547 //____________Offine tracking in the AliTRDtracker_____________________________
548 void AliTRDCalibraFillHisto::ResetfVariablestrack()
551 // Reset values per tracklet
554 //Reset good tracklet
555 fGoodTracklet = kTRUE;
557 // Reset the fPHValue
559 //Reset the fPHValue and fPHPlace
560 for (Int_t k = 0; k < fTimeMax; k++) {
566 // Reset the fAmpTotal where we put value
568 for (Int_t k = 0; k < fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0); k++) {
573 //____________Offline tracking in the AliTRDtracker____________________________
574 Bool_t AliTRDCalibraFillHisto::UpdateHistograms(AliTRDtrack *t)
577 // For the offline tracking
578 // This function will be called in the function
579 // AliTRDtracker::FollowBackPropagation() in the loop over the clusters
581 // Fill the 2D histos or the vectors with the info of the clusters at
582 // the end of a detectors if the track is "good"
587 AliTRDcluster *cl = 0x0;
591 // reset if good track
595 // loop over the clusters
596 while((cl = t->GetCluster(index1))){
598 // Localisation of the detector
599 Int_t detector = cl->GetDetector();
602 // Fill the infos for the previous clusters if not the same
603 // detector anymore but this time it should be the same track
604 if ((detector != fDetectorPreviousTrack) &&
605 (index0 != index1)) {
609 //printf("detector %d, fPreviousdetector %d, plane %d, planeprevious %d, index0 %d, index1 %d la\n",detector,fDetectorPreviousTrack,GetPlane(detector),GetPlane(fDetectorPreviousTrack),index0,index1);
611 //If the same track, then look if the previous detector is in
612 //the same plane, if yes: not a good track
614 //if (fDetectorAliTRDtrack &&
615 // (GetPlane(detector) <= GetPlane(fDetectorPreviousTrack))) {
617 if ((GetPlane(detector) >= GetPlane(fDetectorPreviousTrack))) {
621 // Fill only if the track doesn't touch a masked pad or doesn't
622 // appear in the middle (fGoodTrack)
623 if (fGoodTrack && fGoodTracklet) {
625 // drift velocity unables to cut bad tracklets
626 Bool_t pass = FindP1TrackPHtrack(t,index0,index1);
630 FillTheInfoOfTheTrackCH();
635 FillTheInfoOfTheTrackPH();
638 if(pass && fPRF2dOn) HandlePRFtrack(t,index0,index1);
644 ResetfVariablestrack();
647 } // Fill at the end the charge
649 // Calcul the position of the detector and take the calib objects
650 if (detector != fDetectorPreviousTrack) {
652 //Localise the detector
653 LocalisationDetectorXbins(detector);
656 AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
658 AliInfo("Could not get calibDB");
663 if( fCalROCGain ) delete fCalROCGain;
664 fCalROCGain = new AliTRDCalROC(*(cal->GetGainFactorROC(detector)));
665 if( fCalROCT0 ) delete fCalROCT0;
666 fCalROCT0 = new AliTRDCalROC(*(cal->GetT0ROC(detector)));
670 // Reset the detectbjobsor
671 fDetectorPreviousTrack = detector;
673 // Store the info bis of the tracklet
674 Int_t *rowcol = CalculateRowCol(cl);
675 CheckGoodTracklet(detector,rowcol);
676 Int_t group[2] = {0,0};
677 if(fCH2dOn) group[0] = CalculateCalibrationGroup(0,rowcol);
678 if(fPH2dOn) group[1] = CalculateCalibrationGroup(1,rowcol);
679 StoreInfoCHPHtrack(cl,t,index1,group,rowcol);
683 } // while on clusters
685 // Fill the last plane
686 if( index0 != index1 ){
688 //printf("fPreviousdetector %d, planeprevious %d, index0 %d, index1 %d li\n",fDetectorPreviousTrack,GetPlane(fDetectorPreviousTrack),index0,index1);
692 if (fGoodTrack && fGoodTracklet) {
694 // drift velocity unables to cut bad tracklets
695 Bool_t pass = FindP1TrackPHtrack(t,index0,index1);
699 FillTheInfoOfTheTrackCH();
704 FillTheInfoOfTheTrackPH();
707 if(pass && fPRF2dOn) HandlePRFtrack(t,index0,index1);
714 ResetfVariablestrack();
719 //____________Offline tracking in the AliTRDtracker____________________________
720 Bool_t AliTRDCalibraFillHisto::UpdateHistograms(AliTRDcluster *cl, AliTRDtrack *t)
723 // For the offline tracking
724 // This function will be called in the function
725 // AliTRDtracker::FollowBackPropagation() in the loop over the clusters
727 // Fill the 2D histos or the vectors with the info of the clusters at
728 // the end of a detectors if the track is "good"
731 // Localisation of the detector
732 Int_t detector = cl->GetDetector();
734 // Fill the infos for the previous clusters if not the same
735 // detector anymore or if not the same track
736 if (((detector != fDetectorPreviousTrack) || (!fDetectorAliTRDtrack)) &&
737 (fDetectorPreviousTrack != -1)) {
741 // If the same track, then look if the previous detector is in
742 // the same plane, if yes: not a good track
744 if (fDetectorAliTRDtrack &&
745 (GetPlane(detector) <= GetPlane(fDetectorPreviousTrack))) {
747 //if (fDetectorAliTRDtrack &&
748 // (GetPlane(detector) >= GetPlane(fDetectorPreviousTrack))) {
752 // Fill only if the track doesn't touch a masked pad or doesn't
753 // appear in the middle (fGoodTrack)
754 if (fGoodTrack && fGoodTracklet) {
756 // drift velocity unables to cut bad tracklets
757 Bool_t pass = FindP1TrackPH();
761 FillTheInfoOfTheTrackCH();
766 FillTheInfoOfTheTrackPH();
769 if(pass && fPRF2dOn) HandlePRF();
775 if(!fDetectorAliTRDtrack) fGoodTrack = kTRUE;
777 } // Fill at the end the charge
779 // Calcul the position of the detector and take the calib objects
780 if (detector != fDetectorPreviousTrack) {
781 //Localise the detector
782 LocalisationDetectorXbins(detector);
785 AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
787 AliInfo("Could not get calibDB");
792 if( fCalROCGain ) delete fCalROCGain;
793 fCalROCGain = new AliTRDCalROC(*(cal->GetGainFactorROC(detector)));
794 if( fCalROCT0 ) delete fCalROCT0;
795 fCalROCT0 = new AliTRDCalROC(*(cal->GetT0ROC(detector)));
798 // Reset the detector
799 fDetectorPreviousTrack = detector;
800 fDetectorAliTRDtrack = kTRUE;
802 // Store the infos of the tracklets
803 AliTRDcluster *kcl = new AliTRDcluster(*cl);
804 fListClusters->Add((TObject *)kcl);
805 Int_t time = cl->GetLocalTimeBin();
806 fPar0[time] = t->GetY();
807 fPar1[time] = t->GetZ();
808 fPar2[time] = t->GetSnp();
809 fPar3[time] = t->GetTgl();
810 fPar4[time] = t->GetSigned1Pt();
812 // Store the info bis of the tracklet
813 Int_t *rowcol = CalculateRowCol(cl);
814 CheckGoodTracklet(detector,rowcol);
815 Int_t group[2] = {0,0};
816 if(fCH2dOn) group[0] = CalculateCalibrationGroup(0,rowcol);
817 if(fPH2dOn) group[1] = CalculateCalibrationGroup(1,rowcol);
818 StoreInfoCHPH(cl,t,group,rowcol);
823 //____________Online trackling in AliTRDtrigger________________________________
824 Bool_t AliTRDCalibraFillHisto::UpdateHistogramcm(AliTRDmcmTracklet *trk)
828 // This function will be called in the function AliTRDtrigger::TestTracklet
829 // before applying the pt cut on the tracklets
830 // Fill the infos for the tracklets fTrkTest if the tracklets is "good"
833 // Localisation of the Xbins involved
834 Int_t idect = trk->GetDetector();
835 fDetectorPreviousTrack = idect;
836 LocalisationDetectorXbins(idect);
838 // Get the parameter object
839 AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
841 AliInfo("Could not get calibDB");
849 if( fCalROCGain ) delete fCalROCGain;
850 fCalROCGain = new AliTRDCalROC(*(cal->GetGainFactorROC(idect)));
851 if( fCalROCT0 ) delete fCalROCT0;
852 fCalROCT0 = new AliTRDCalROC(*(cal->GetT0ROC(idect)));
854 // Row of the tracklet and position in the pad groups
855 Int_t *rowcol = new Int_t[2];
856 rowcol[0] = trk->GetRow();
857 Int_t group[3] = {-1,-1,-1};
859 // Eventuelle correction due to track angle in z direction
860 Float_t correction = 1.0;
861 if (fMcmCorrectAngle) {
862 Float_t z = trk->GetRowz();
863 Float_t r = trk->GetTime0();
864 correction = r / TMath::Sqrt((r*r+z*z));
867 // Boucle sur les clusters
868 // Condition on number of cluster: don't come from the middle of the detector
869 if (trk->GetNclusters() >= fNumberClusters) {
871 for (Int_t icl = 0; icl < trk->GetNclusters(); icl++) {
873 Float_t amp[3] = { 0.0, 0.0, 0.0 };
874 Int_t time = trk->GetClusterTime(icl);
875 rowcol[1] = trk->GetClusterCol(icl);
877 amp[0] = trk->GetClusterADC(icl)[0] * correction;
878 amp[1] = trk->GetClusterADC(icl)[1] * correction;
879 amp[2] = trk->GetClusterADC(icl)[2] * correction;
882 if ((amp[0] < 0.0) ||
888 // Col of cluster and position in the pad groups
890 group[0] = CalculateCalibrationGroup(0,rowcol);
891 fAmpTotal[(Int_t) group[0]] += (Float_t) (amp[0]+amp[1]+amp[2]);
894 group[1] = CalculateCalibrationGroup(1,rowcol);
895 fPHPlace[time] = group[1];
896 fPHValue[time] = (Float_t) (amp[0]+amp[1]+amp[2]);
898 if(fPRF2dOn) group[2] = CalculateCalibrationGroup(2,rowcol);
900 // See if we are not near a masked pad fGoodTracklet
901 CheckGoodTracklet(idect,rowcol);
903 // Fill PRF direct without tnp bins...only for monitoring...
904 if (fPRF2dOn && fGoodTracklet) {
906 if ((amp[0] > fThresholdClusterPRF2) &&
907 (amp[1] > fThresholdClusterPRF2) &&
908 (amp[2] > fThresholdClusterPRF2) &&
909 ((amp[0]*amp[2]/(amp[1]*amp[1])) < 0.06)) {
911 // Security of the denomiateur is 0
912 if ((((Float_t) (((Float_t) amp[1]) * ((Float_t) amp[1])))
913 / ((Float_t) (((Float_t) amp[0]) * ((Float_t) amp[2])))) != 1.0) {
914 Float_t xcenter = 0.5 * (TMath::Log(amp[2] / amp[0]))
915 / (TMath::Log((amp[1]*amp[1]) / (amp[0]*amp[2])));
916 Float_t ycenter = amp[1] / (amp[0] + amp[1] + amp[2]);
918 if (TMath::Abs(xcenter) < 0.5) {
919 Float_t yminus = amp[0] / (amp[0]+amp[1]+amp[2]);
920 Float_t ymax = amp[2] / (amp[0]+amp[1]+amp[2]);
921 // Fill only if it is in the drift region!
922 if (((Float_t) time / fSf) > 0.3) {
924 fPRF2d->Fill(xcenter,(fCalibraMode->GetXbins(2)+group[2]+0.5),ycenter);
925 fPRF2d->Fill(-(xcenter+1.0),(fCalibraMode->GetXbins(2)+group[2]+0.5),yminus);
926 fPRF2d->Fill((1.0-xcenter),(fCalibraMode->GetXbins(2)+group[2]+0.5),ymax);
929 fCalibraVector->UpdateVectorPRF(idect,group[2],xcenter,ycenter);
930 fCalibraVector->UpdateVectorPRF(idect,group[2],-(xcenter+1.0),yminus);
931 fCalibraVector->UpdateVectorPRF(idect,group[2],(1.0-xcenter),ymax);
933 }//in the drift region
935 }//denominateur security
936 }//cluster shape and thresholds
943 if (fCH2dOn) FillTheInfoOfTheTrackCH();
944 if (fPH2dOn) FillTheInfoOfTheTrackPH();
949 } // Condition on number of clusters
954 //_____________________________________________________________________________
955 Int_t *AliTRDCalibraFillHisto::CalculateRowCol(AliTRDcluster *cl) const
958 // Calculate the row and col number of the cluster
962 Int_t *rowcol = new Int_t[2];
966 // Localisation of the detector
967 Int_t detector = cl->GetDetector();
968 Int_t chamber = GetChamber(detector);
969 Int_t plane = GetPlane(detector);
971 // Localisation of the cluster
972 Double_t pos[3] = { 0.0, 0.0, 0.0 };
973 pos[0] = ((AliCluster *)cl)->GetX();
977 // Position of the cluster
978 AliTRDpadPlane *padplane = fGeo->GetPadPlane(plane,chamber);
979 Int_t row = padplane->GetPadRowNumber(pos[2]);
980 //Do not take from here because it was corrected from ExB already....
981 //Double_t offsetz = padplane->GetPadRowOffset(row,pos[2]);
982 //Double_t offsettilt = padplane->GetTiltOffset(offsetz);
983 //Int_t col = padplane->GetPadColNumber(pos[1] + offsettilt,offsetz);
984 //Int_t col = padplane->GetPadColNumber(pos[1]+offsettilt);
985 Int_t col = cl->GetPadCol();
993 //_____________________________________________________________________________
994 void AliTRDCalibraFillHisto::CheckGoodTracklet(Int_t detector, Int_t *rowcol)
997 // See if we are not near a masked pad
1000 Int_t row = rowcol[0];
1001 Int_t col = rowcol[1];
1003 if (!IsPadOn(detector, col, row)) {
1004 fGoodTracklet = kFALSE;
1008 if (!IsPadOn(detector, col-1, row)) {
1009 fGoodTracklet = kFALSE;
1014 if (!IsPadOn(detector, col+1, row)) {
1015 fGoodTracklet = kFALSE;
1020 //_____________________________________________________________________________
1021 Bool_t AliTRDCalibraFillHisto::IsPadOn(Int_t detector, Int_t col, Int_t row) const
1024 // Look in the choosen database if the pad is On.
1025 // If no the track will be "not good"
1028 // Get the parameter object
1029 AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
1031 AliInfo("Could not get calibDB");
1035 if (!cal->IsChamberInstalled(detector) ||
1036 cal->IsChamberMasked(detector) ||
1037 cal->IsPadMasked(detector,col,row)) {
1045 //_____________________________________________________________________________
1046 Int_t AliTRDCalibraFillHisto::CalculateCalibrationGroup(Int_t i, Int_t *rowcol) const
1049 // Calculate the calibration group number for i
1052 // Row of the cluster and position in the pad groups
1054 if (fCalibraMode->GetNnZ(i) != 0) {
1055 posr = (Int_t) rowcol[0] / fCalibraMode->GetNnZ(i);
1059 // Col of the cluster and position in the pad groups
1061 if (fCalibraMode->GetNnRphi(i) != 0) {
1062 posc = (Int_t) rowcol[1] / fCalibraMode->GetNnRphi(i);
1065 return posc*fCalibraMode->GetNfragZ(i)+posr;
1068 //____________________________________________________________________________________
1069 Int_t AliTRDCalibraFillHisto::CalculateTotalNumberOfBins(Int_t i)
1072 // Calculate the total number of calibration groups
1076 fCalibraMode->ModePadCalibration(2,i);
1077 fCalibraMode->ModePadFragmentation(0,2,0,i);
1078 fCalibraMode->SetDetChamb2(i);
1079 Ntotal += 6 * 18 * fCalibraMode->GetDetChamb2(i);
1080 fCalibraMode->ModePadCalibration(0,i);
1081 fCalibraMode->ModePadFragmentation(0,0,0,i);
1082 fCalibraMode->SetDetChamb0(i);
1083 Ntotal += 6 * 4 * 18 * fCalibraMode->GetDetChamb0(i);
1084 AliInfo(Form("Total number of Xbins: %d for i %d",Ntotal,i));
1088 //____________Set the pad calibration variables for the detector_______________
1089 Bool_t AliTRDCalibraFillHisto::LocalisationDetectorXbins(Int_t detector)
1092 // For the detector calcul the first Xbins and set the number of row
1093 // and col pads per calibration groups, the number of calibration
1094 // groups in the detector.
1097 // first Xbins of the detector
1099 fCalibraMode->CalculXBins(detector,0);
1102 fCalibraMode->CalculXBins(detector,1);
1105 fCalibraMode->CalculXBins(detector,2);
1108 // fragmentation of idect
1109 for (Int_t i = 0; i < 3; i++) {
1110 fCalibraMode->ModePadCalibration((Int_t) GetChamber(detector),i);
1111 fCalibraMode->ModePadFragmentation((Int_t) GetPlane(detector)
1112 , (Int_t) GetChamber(detector)
1113 , (Int_t) GetSector(detector),i);
1119 //_____________________________________________________________________________
1120 void AliTRDCalibraFillHisto::StoreInfoCHPH(AliTRDcluster *cl, AliTRDtrack *t, Int_t *group, Int_t *rowcol)
1123 // Store the infos in fAmpTotal, fPHPlace and fPHValue
1126 // Charge in the cluster
1127 Float_t q = TMath::Abs(cl->GetQ());
1128 Int_t time = cl->GetLocalTimeBin();
1130 //Correct for the gain coefficient used in the database for reconstruction
1131 Float_t correctthegain = fCalDetGain->GetValue(fDetectorPreviousTrack)*fCalROCGain->GetValue(rowcol[1],rowcol[0]);
1132 Float_t correcttheT0 = fCalDetT0->GetValue(fDetectorPreviousTrack)+fCalROCT0->GetValue(rowcol[1],rowcol[0]);
1134 // we substract correcttheT0 in AliTRDclusterizerV1::MakeClusters (line 458)
1135 Int_t timec = Arrondi((Double_t)(time+correcttheT0));
1136 if((correcttheT0+0.5)==(int(correcttheT0+0.5))) {
1139 if( timec < 0 ) return;
1142 // Correction due to the track angle
1143 Float_t correction = 1.0;
1144 Float_t normalisation = 6.67;
1145 // we divide with gain in AliTRDclusterizerV1::Transform...
1146 if( correctthegain > 0 ) normalisation /= correctthegain;
1147 if ((q >0) && (t->GetNdedx() > 0)) {
1148 correction = t->GetClusterdQdl((t->GetNdedx() - 1)) / (normalisation);
1151 // Fill the fAmpTotal with the charge
1153 fAmpTotal[(Int_t) group[0]] += correction;
1156 // Fill the fPHPlace and value
1158 fPHPlace[timec] = group[1];
1159 fPHValue[timec] = correction;
1163 //_____________________________________________________________________________
1164 void AliTRDCalibraFillHisto::StoreInfoCHPHtrack(AliTRDcluster *cl, AliTRDtrack *t, Int_t index, Int_t *group, Int_t *rowcol)
1167 // Store the infos in fAmpTotal, fPHPlace and fPHValue
1170 // Charge in the cluster
1171 Float_t q = TMath::Abs(cl->GetQ());
1172 Int_t time = cl->GetLocalTimeBin();
1174 //Correct for the gain coefficient used in the database for reconstruction
1175 Float_t correctthegain = fCalDetGain->GetValue(fDetectorPreviousTrack)*fCalROCGain->GetValue(rowcol[1],rowcol[0]);
1176 Float_t correcttheT0 = fCalDetT0->GetValue(fDetectorPreviousTrack)+fCalROCT0->GetValue(rowcol[1],rowcol[0]);
1178 // we substract correcttheT0 in AliTRDclusterizerV1::MakeClusters (line 458)
1179 Int_t timec = Arrondi((Double_t)(time+correcttheT0));
1180 if((correcttheT0+0.5)==(int(correcttheT0+0.5))) {
1183 if( timec < 0 ) return;
1185 // Correction due to the track angle
1186 Float_t correction = 1.0;
1187 Float_t normalisation = 6.67;
1188 // we divide with gain in AliTRDclusterizerV1::Transform...
1189 if( correctthegain > 0 ) normalisation /= correctthegain;
1191 correction = t->GetClusterdQdl(index) / (normalisation);
1194 // Fill the fAmpTotal with the charge
1196 fAmpTotal[(Int_t) group[0]] += correction;
1199 // Fill the fPHPlace and value
1201 fPHPlace[timec] = group[1];
1202 fPHValue[timec] = correction;
1206 //_____________________________________________________________________
1207 Int_t AliTRDCalibraFillHisto::ProcessEventDAQ(AliTRDRawStreamV2 *rawStream, Bool_t nocheck)
1210 // Event Processing loop - AliTRDRawStreamV2
1211 // 0 timebin problem
1216 Int_t withInput = 1;
1221 for(Int_t k = 0; k < 36; k++){
1226 fDetectorPreviousTrack = -1;
1227 Int_t nbtimebin = 0;
1233 while (rawStream->Next()) {
1235 Int_t idetector = rawStream->GetDet(); // current detector
1236 if((fDetectorPreviousTrack != idetector) && (fDetectorPreviousTrack != -1)){
1237 if(TMath::Mean(fTimeMax,phvalue)>20.0){
1239 for(Int_t k = 0; k < fTimeMax; k++){
1240 UpdateDAQ(fDetectorPreviousTrack,0,0,k,phvalue[k],fTimeMax);
1247 fDetectorPreviousTrack = idetector;
1248 nbtimebin = rawStream->GetNumberOfTimeBins(); // number of time bins read from data
1249 if(nbtimebin == 0) return 0;
1250 if((fTimeMax != 0) && (nbtimebin != fTimeMax)) return 0;
1251 fTimeMax = nbtimebin;
1252 Int_t iTimeBin = rawStream->GetTimeBin(); // current time bin
1253 //row[iTimeBin] = rawStream->GetRow(); // current row
1254 //col[iTimeBin] = rawStream->GetCol(); // current col
1255 Int_t *signal = rawStream->GetSignals(); // current ADC signal
1256 //printf("detector %d, nbtimebin %d, iTimeBin %d\n",fDetectorPreviousTrack,nbtimebin,iTimeBin);
1258 Int_t fin = TMath::Min(fTimeMax,(iTimeBin+3));
1260 for(Int_t itime = iTimeBin; itime < fin; itime++){
1261 // should extract baseline here!
1262 if(signal[n]>13) phvalue[itime] = signal[n];
1263 //printf("signal is %d for %d\n",signal[n],n);
1268 // fill the last one
1269 if(fDetectorPreviousTrack != -1){
1270 if(TMath::Mean(fTimeMax,phvalue)>20.0){
1272 for(Int_t k = 0; k < fTimeMax; k++){
1273 UpdateDAQ(fDetectorPreviousTrack,0,0,k,phvalue[k],fTimeMax);
1284 while (rawStream->Next()) {
1286 Int_t idetector = rawStream->GetDet(); // current detector
1287 if((fDetectorPreviousTrack != idetector) && (fDetectorPreviousTrack != -1)){
1288 if(TMath::Mean(nbtimebin,phvalue)>20.0){
1290 for(Int_t k = 0; k < nbtimebin; k++){
1291 UpdateDAQ(fDetectorPreviousTrack,0,0,k,phvalue[k],nbtimebin);
1298 fDetectorPreviousTrack = idetector;
1299 nbtimebin = rawStream->GetNumberOfTimeBins(); // number of time bins read from data
1300 Int_t iTimeBin = rawStream->GetTimeBin(); // current time bin
1301 //row[iTimeBin] = rawStream->GetRow(); // current row
1302 //col[iTimeBin] = rawStream->GetCol(); // current col
1303 Int_t *signal = rawStream->GetSignals(); // current ADC signal
1304 //printf("detector %d, nbtimebin %d, iTimeBin %d\n",fDetectorPreviousTrack,nbtimebin,iTimeBin);
1306 Int_t fin = TMath::Min(nbtimebin,(iTimeBin+3));
1308 for(Int_t itime = iTimeBin; itime < fin; itime++){
1309 // should extract baseline here!
1310 if(signal[n]>13) phvalue[itime] = signal[n];
1311 //printf("signal is %d for %d\n",signal[n],n);
1316 // fill the last one
1317 if(fDetectorPreviousTrack != -1){
1318 if(TMath::Mean(nbtimebin,phvalue)>20.0){
1320 for(Int_t k = 0; k < nbtimebin; k++){
1321 UpdateDAQ(fDetectorPreviousTrack,0,0,k,phvalue[k],nbtimebin);
1333 //_____________________________________________________________________
1334 Int_t AliTRDCalibraFillHisto::ProcessEventDAQ(AliRawReader *rawReader, Bool_t nocheck)
1337 // Event processing loop - AliRawReader
1341 AliTRDRawStreamV2 rawStream(rawReader);
1343 rawReader->Select("TRD");
1345 return ProcessEventDAQ(&rawStream, nocheck);
1347 //_________________________________________________________________________
1348 Int_t AliTRDCalibraFillHisto::ProcessEventDAQ(
1350 eventHeaderStruct *event,
1353 eventHeaderStruct* /*event*/,
1360 // process date event
1363 AliRawReader *rawReader = new AliRawReaderDate((void*)event);
1364 Int_t result=ProcessEventDAQ(rawReader, nocheck);
1368 Fatal("AliTRDCalibraFillHisto", "this class was compiled without DATE");
1373 //____________Online trackling in AliTRDtrigger________________________________
1374 Bool_t AliTRDCalibraFillHisto::UpdateDAQ(Int_t det, Int_t /*row*/, Int_t /*col*/, Int_t timebin, Int_t signal, Int_t nbtimebins)
1378 // Fill a simple average pulse height
1381 // Localisation of the Xbins involved
1382 //LocalisationDetectorXbins(det);
1384 // Row and position in the pad groups
1386 //if (fCalibraMode->GetNnZ(1) != 0) {
1387 // posr = (Int_t) row / fCalibraMode->GetNnZ(1);
1390 // Col of cluster and position in the pad groups
1392 //if (fCalibraMode->GetNnRphi(1) != 0) {
1393 // posc = (Int_t) col / fCalibraMode->GetNnRphi(1);
1396 //fPH2d->Fill((Float_t) timebin/fSf,(fCalibraMode->GetXbins(1)+posc*fCalibraMode->GetNfragZ(1)+posr)+0.5,(Float_t) signal);
1398 ((TProfile2D *)GetPH2d(nbtimebins,fSf))->Fill((Float_t) timebin/fSf,det+0.5,(Float_t) signal);
1403 //____________Write_____________________________________________________
1404 //_____________________________________________________________________
1405 void AliTRDCalibraFillHisto::Write2d(const Char_t *filename, Bool_t append)
1408 // Write infos to file
1412 if ( fDebugStreamer ) {
1413 delete fDebugStreamer;
1414 fDebugStreamer = 0x0;
1417 AliInfo(Form("Numbertrack: %d Numberusedch[0]: %d, Numberusedch[1]: %d Numberusedph[0]: %d, Numberusedph[1]: %d"
1422 ,fNumberUsedPh[1]));
1424 TDirectory *backup = gDirectory;
1430 option = "recreate";
1432 TFile f(filename,option.Data());
1434 TStopwatch stopwatch;
1437 f.WriteTObject(fCalibraVector);
1442 f.WriteTObject(fCH2d);
1447 f.WriteTObject(fPH2d);
1452 f.WriteTObject(fPRF2d);
1455 if(fLinearFitterOn){
1456 AnalyseLinearFitter();
1457 f.WriteTObject(fLinearVdriftFit);
1462 if ( backup ) backup->cd();
1464 AliInfo(Form("Execution time Write2d: R:%.2fs C:%.2fs"
1465 ,stopwatch.RealTime(),stopwatch.CpuTime()));
1467 //___________________________________________probe the histos__________________________________________________
1468 Double_t *AliTRDCalibraFillHisto::StatH(TH2 *h, Int_t i)
1471 // Check the number of stats in h, 0 is TH2I 1 is TProfile2D
1472 // debug mode with 2 for TH2I and 3 for TProfile2D
1473 // It gives a pointer to a Double_t[7] with the info following...
1474 // [0] : number of calibration groups with entries
1475 // [1] : minimal number of entries found
1476 // [2] : calibration group number of the min
1477 // [3] : maximal number of entries found
1478 // [4] : calibration group number of the max
1479 // [5] : mean number of entries found
1480 // [6] : mean relative error
1483 Double_t *info = new Double_t[7];
1485 // Number of Xbins (detectors or groups of pads)
1486 Int_t nbins = h->GetNbinsY(); //number of calibration groups
1487 Int_t nxbins = h->GetNbinsX(); //number of bins per histo
1490 Double_t nbwe = 0; //number of calibration groups with entries
1491 Double_t minentries = 0; //minimal number of entries found
1492 Double_t maxentries = 0; //maximal number of entries found
1493 Double_t placemin = 0; //calibration group number of the min
1494 Double_t placemax = -1; //calibration group number of the max
1495 Double_t meanstats = 0.0; //mean number of entries over the calibration group with at least ome entry
1496 Double_t meanrelativerror = 0.0; //mean relativ error in the TProfile2D
1498 Double_t counter = 0;
1501 TH1F *NbEntries = 0x0;//distribution of the number of entries
1502 TH1F *NbEntriesPerGroup = 0x0;//Number of entries per group
1503 TProfile *NbEntriesPerSp = 0x0;//Number of entries for one supermodule
1505 // Beginning of the loop over the calibration groups
1506 for (Int_t idect = 0; idect < nbins; idect++) {
1508 TH1I *projch = (TH1I *) h->ProjectionX("projch",idect+1,idect+1,(Option_t *)"e");
1509 projch->SetDirectory(0);
1511 // Number of entries for this calibration group
1512 Double_t nentries = 0.0;
1514 for (Int_t k = 0; k < nxbins; k++) {
1515 nentries += h->GetBinContent(h->GetBin(k+1,idect+1));
1519 for (Int_t k = 0; k < nxbins; k++) {
1520 nentries += ((TProfile2D *)h)->GetBinEntries(h->GetBin(k+1,idect+1));
1521 if(h->GetBinContent(h->GetBin(k+1,idect+1)) != 0) {
1522 meanrelativerror += (h->GetBinError(h->GetBin(k+1,idect+1))/(TMath::Abs(h->GetBinContent(h->GetBin(k+1,idect+1)))));
1530 if((!((Bool_t)NbEntries)) && (nentries > 0)){
1531 NbEntries = new TH1F("Number of entries","Number of entries"
1532 ,100,(Int_t)nentries/2,nentries*2);
1533 NbEntries->SetDirectory(0);
1534 NbEntriesPerGroup = new TH1F("Number of entries per group","Number of entries per group"
1536 NbEntriesPerGroup->SetDirectory(0);
1537 NbEntriesPerSp = new TProfile("Number of entries per supermodule","Number of entries per supermodule"
1538 ,(Int_t)(nbins/18),0,(Int_t)(nbins/18));
1539 NbEntriesPerSp->SetDirectory(0);
1542 if(nentries > 0) NbEntries->Fill(nentries);
1543 NbEntriesPerGroup->Fill(idect+0.5,nentries);
1544 NbEntriesPerSp->Fill((idect%((Int_t)(nbins/18)))+0.5,nentries);
1549 if(nentries > maxentries){
1550 maxentries = nentries;
1554 minentries = nentries;
1556 if(nentries < minentries){
1557 minentries = nentries;
1563 meanstats += nentries;
1565 }//calibration groups loop
1567 if(nbwe > 0) meanstats /= nbwe;
1568 if(counter > 0) meanrelativerror /= counter;
1570 AliInfo(Form("There are %f calibration groups with entries",nbwe));
1571 AliInfo(Form("The minimum number of entries is %f for the group %f",minentries,placemin));
1572 AliInfo(Form("The maximum number of entries is %f for the group %f",maxentries,placemax));
1573 AliInfo(Form("The mean number of entries is %f",meanstats));
1574 if((i%2) == 1) AliInfo(Form("The mean relative error is %f",meanrelativerror));
1577 info[1] = minentries;
1579 info[3] = maxentries;
1581 info[5] = meanstats;
1582 info[6] = meanrelativerror;
1585 gStyle->SetPalette(1);
1586 gStyle->SetOptStat(1111);
1587 gStyle->SetPadBorderMode(0);
1588 gStyle->SetCanvasColor(10);
1589 gStyle->SetPadLeftMargin(0.13);
1590 gStyle->SetPadRightMargin(0.01);
1591 TCanvas *stat = new TCanvas("stat","",50,50,600,800);
1594 NbEntries->Draw("");
1596 NbEntriesPerSp->SetStats(0);
1597 NbEntriesPerSp->Draw("");
1598 TCanvas *stat1 = new TCanvas("stat1","",50,50,600,800);
1600 NbEntriesPerGroup->SetStats(0);
1601 NbEntriesPerGroup->Draw("");
1607 //____________________________________________________________________________
1608 Double_t *AliTRDCalibraFillHisto::GetMeanMedianRMSNumberCH()
1611 // Return a Int_t[4] with:
1612 // 0 Mean number of entries
1613 // 1 median of number of entries
1614 // 2 rms of number of entries
1615 // 3 number of group with entries
1618 Double_t *stat = new Double_t[4];
1621 Int_t nbofgroups = CalculateTotalNumberOfBins(0);
1622 Double_t *weight = new Double_t[nbofgroups];
1623 Int_t *nonul = new Int_t[nbofgroups];
1625 for(Int_t k = 0; k < nbofgroups; k++){
1626 if(fEntriesCH[k] > 0) {
1628 nonul[(Int_t)stat[3]] = fEntriesCH[k];
1631 else weight[k] = 0.0;
1633 stat[0] = TMath::Mean(nbofgroups,fEntriesCH,weight);
1634 stat[1] = TMath::Median(nbofgroups,fEntriesCH,weight);
1635 stat[2] = TMath::RMS((Int_t)stat[3],nonul);
1640 //____________________________________________________________________________
1641 Double_t *AliTRDCalibraFillHisto::GetMeanMedianRMSNumberLinearFitter() const
1644 // Return a Int_t[4] with:
1645 // 0 Mean number of entries
1646 // 1 median of number of entries
1647 // 2 rms of number of entries
1648 // 3 number of group with entries
1651 Double_t *stat = new Double_t[4];
1654 Int_t nbofgroups = 540;
1655 Double_t *weight = new Double_t[nbofgroups];
1656 Int_t *nonul = new Int_t[nbofgroups];
1658 for(Int_t k = 0; k < nbofgroups; k++){
1659 if(fEntriesLinearFitter[k] > 0) {
1661 nonul[(Int_t) stat[3]] = fEntriesLinearFitter[k];
1664 else weight[k] = 0.0;
1666 stat[0] = TMath::Mean(nbofgroups,fEntriesLinearFitter,weight);
1667 stat[1] = TMath::Median(nbofgroups,fEntriesLinearFitter,weight);
1668 stat[2] = TMath::RMS((Int_t)stat[3],nonul);
1673 //_____________________________________________________________________________
1674 void AliTRDCalibraFillHisto::SetNumberGroupsPRF(Short_t numberGroupsPRF)
1677 // Should be between 0 and 6
1680 if ((numberGroupsPRF < 0) || (numberGroupsPRF > 6)) {
1681 AliInfo("The number of groups must be between 0 and 6!");
1684 fNgroupprf = numberGroupsPRF;
1688 //_____________________________________________________________________________
1689 void AliTRDCalibraFillHisto::SetRelativeScale(Float_t RelativeScale)
1692 // Set the factor that will divide the deposited charge
1693 // to fit in the histo range [0,300]
1696 if (RelativeScale > 0.0) {
1697 fRelativeScale = RelativeScale;
1700 AliInfo("RelativeScale must be strict positif!");
1705 //_____________________________________________________________________________
1706 void AliTRDCalibraFillHisto::SetNz(Int_t i, Short_t Nz)
1709 // Set the mode of calibration group in the z direction for the parameter i
1714 fCalibraMode->SetNz(i, Nz);
1717 AliInfo("You have to choose between 0 and 4");
1722 //_____________________________________________________________________________
1723 void AliTRDCalibraFillHisto::SetNrphi(Int_t i, Short_t Nrphi)
1726 // Set the mode of calibration group in the rphi direction for the parameter i
1731 fCalibraMode->SetNrphi(i ,Nrphi);
1734 AliInfo("You have to choose between 0 and 6");
1738 //____________Protected Functions______________________________________________
1739 //____________Create the 2D histo to be filled online__________________________
1741 //_____________________________________________________________________________
1742 void AliTRDCalibraFillHisto::CreatePRF2d(Int_t nn)
1745 // Create the 2D histos: here we have 2*fNgroupprf bins in tnp of 0.2 amplitude each
1746 // If fNgroupprf is zero then no binning in tnp
1750 name += fCalibraMode->GetNz(2);
1752 name += fCalibraMode->GetNrphi(2);
1756 if(fNgroupprf != 0){
1758 fPRF2d = new TProfile2D("PRF2d",(const Char_t *) name
1759 ,2*fNgroupprf*fNumberBinPRF,-3.0*fNgroupprf,3.0*fNgroupprf,nn,0,nn);
1760 fPRF2d->SetYTitle("Det/pad groups");
1761 fPRF2d->SetXTitle("Position x/W [pad width units]");
1762 fPRF2d->SetZTitle("Q_{i}/Q_{total}");
1763 fPRF2d->SetStats(0);
1766 fPRF2d = new TProfile2D("PRF2d",(const Char_t *) name
1767 ,fNumberBinPRF,-1.5,1.5,nn,0,nn);
1768 fPRF2d->SetYTitle("Det/pad groups");
1769 fPRF2d->SetXTitle("Position x/W [pad width units]");
1770 fPRF2d->SetZTitle("Q_{i}/Q_{total}");
1771 fPRF2d->SetStats(0);
1776 //_____________________________________________________________________________
1777 void AliTRDCalibraFillHisto::CreatePH2d(Int_t nn)
1780 // Create the 2D histos
1784 name += fCalibraMode->GetNz(1);
1786 name += fCalibraMode->GetNrphi(1);
1788 fPH2d = new TProfile2D("PH2d",(const Char_t *) name
1789 ,fTimeMax,-0.5/fSf,(Float_t) (fTimeMax-0.5)/fSf
1791 fPH2d->SetYTitle("Det/pad groups");
1792 fPH2d->SetXTitle("time [#mus]");
1793 fPH2d->SetZTitle("<PH> [a.u.]");
1797 //_____________________________________________________________________________
1798 void AliTRDCalibraFillHisto::CreateCH2d(Int_t nn)
1801 // Create the 2D histos
1805 name += fCalibraMode->GetNz(0);
1807 name += fCalibraMode->GetNrphi(0);
1809 fCH2d = new TH2I("CH2d",(const Char_t *) name
1810 ,fNumberBinCharge,0,300,nn,0,nn);
1811 fCH2d->SetYTitle("Det/pad groups");
1812 fCH2d->SetXTitle("charge deposit [a.u]");
1813 fCH2d->SetZTitle("counts");
1819 //____________Offine tracking in the AliTRDtracker_____________________________
1820 void AliTRDCalibraFillHisto::FillTheInfoOfTheTrackCH()
1823 // For the offline tracking or mcm tracklets
1824 // This function will be called in the functions UpdateHistogram...
1825 // to fill the info of a track for the relativ gain calibration
1828 Int_t nb = 0; // Nombre de zones traversees
1829 Int_t fd = -1; // Premiere zone non nulle
1830 Float_t totalcharge = 0.0; // Total charge for the supermodule histo
1835 // See if the track goes through different zones
1836 for (Int_t k = 0; k < fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0); k++) {
1837 if (fAmpTotal[k] > 0.0) {
1838 totalcharge += fAmpTotal[k];
1851 fEntriesCH[fCalibraMode->GetXbins(0)+fd]++;
1853 FillCH2d(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1854 //fCH2d->Fill(fAmpTotal[fd]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+0.5);
1857 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd,fAmpTotal[fd]/fRelativeScale);
1861 if ((fAmpTotal[fd] > 0.0) &&
1862 (fAmpTotal[fd+1] > 0.0)) {
1863 // One of the two very big
1864 if (fAmpTotal[fd] > fProcent*fAmpTotal[fd+1]) {
1866 FillCH2d(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1867 //fCH2d->Fill(fAmpTotal[fd]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+0.5);
1870 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd,fAmpTotal[fd]/fRelativeScale);
1873 fEntriesCH[fCalibraMode->GetXbins(0)+fd]++;
1875 if (fAmpTotal[fd+1] > fProcent*fAmpTotal[fd]) {
1877 FillCH2d(fCalibraMode->GetXbins(0)+fd+1,fAmpTotal[fd+1]/fRelativeScale);
1878 //fCH2d->Fill(fAmpTotal[fd+1]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+1.5);
1881 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd+1,fAmpTotal[fd+1]/fRelativeScale);
1884 fEntriesCH[fCalibraMode->GetXbins(0)+fd+1]++;
1887 if (fCalibraMode->GetNfragZ(0) > 1) {
1888 if (fAmpTotal[fd] > 0.0) {
1889 if ((fd+fCalibraMode->GetNfragZ(0)) < (fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0))) {
1890 if (fAmpTotal[fd+fCalibraMode->GetNfragZ(0)] > 0.0) {
1891 // One of the two very big
1892 if (fAmpTotal[fd] > fProcent*fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]) {
1894 FillCH2d(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1895 //fCH2d->Fill(fAmpTotal[fd]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+0.5);
1898 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd,fAmpTotal[fd]/fRelativeScale);
1901 fEntriesCH[fCalibraMode->GetXbins(0)+fd]++;
1903 if (fAmpTotal[fd+fCalibraMode->GetNfragZ(0)] > fProcent*fAmpTotal[fd]) {
1905 FillCH2d(fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0),fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/fRelativeScale);
1906 //fCH2d->Fill(fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0)+0.5);
1909 fEntriesCH[fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0)]++;
1911 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd+fCalibraMode->GetNfragZ(0),fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/fRelativeScale);
1922 //____________Offine tracking in the AliTRDtracker_____________________________
1923 void AliTRDCalibraFillHisto::FillTheInfoOfTheTrackPH()
1926 // For the offline tracking or mcm tracklets
1927 // This function will be called in the functions UpdateHistogram...
1928 // to fill the info of a track for the drift velocity calibration
1931 Int_t nb = 1; // Nombre de zones traversees 1, 2 ou plus de 3
1932 Int_t fd1 = -1; // Premiere zone non nulle
1933 Int_t fd2 = -1; // Deuxieme zone non nulle
1934 Int_t k1 = -1; // Debut de la premiere zone
1935 Int_t k2 = -1; // Debut de la seconde zone
1937 // See if the track goes through different zones
1938 for (Int_t k = 0; k < fTimeMax; k++) {
1939 if (fPHValue[k] > 0.0) {
1944 if (fPHPlace[k] != fd1) {
1950 if (fPHPlace[k] != fd2) {
1962 for (Int_t i = 0; i < fTimeMax; i++) {
1964 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1967 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1972 if ((fd1 == fd2+1) ||
1974 // One of the two fast all the think
1975 if (k2 > (k1+fDifference)) {
1976 //we choose to fill the fd1 with all the values
1978 for (Int_t i = 0; i < fTimeMax; i++) {
1980 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1983 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1987 if ((k2+fDifference) < fTimeMax) {
1988 //we choose to fill the fd2 with all the values
1990 for (Int_t i = 0; i < fTimeMax; i++) {
1992 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
1995 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd2,i,fPHValue[i]);
2000 // Two zones voisines sinon rien!
2001 if (fCalibraMode->GetNfragZ(1) > 1) {
2003 if ((fd1+fCalibraMode->GetNfragZ(1)) < (fCalibraMode->GetNfragZ(1)*fCalibraMode->GetNfragRphi(1))) {
2004 if (fd2 == (fd1+fCalibraMode->GetNfragZ(1))) {
2005 // One of the two fast all the think
2006 if (k2 > (k1+fDifference)) {
2007 //we choose to fill the fd1 with all the values
2009 for (Int_t i = 0; i < fTimeMax; i++) {
2011 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
2014 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
2018 if ((k2+fDifference) < fTimeMax) {
2019 //we choose to fill the fd2 with all the values
2021 for (Int_t i = 0; i < fTimeMax; i++) {
2023 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
2026 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd2,i,fPHValue[i]);
2032 // Two zones voisines sinon rien!
2034 if ((fd1 - fCalibraMode->GetNfragZ(1)) >= 0) {
2035 if (fd2 == (fd1 - fCalibraMode->GetNfragZ(1))) {
2036 // One of the two fast all the think
2037 if (k2 > (k1 + fDifference)) {
2038 //we choose to fill the fd1 with all the values
2040 for (Int_t i = 0; i < fTimeMax; i++) {
2042 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
2045 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
2049 if ((k2+fDifference) < fTimeMax) {
2050 //we choose to fill the fd2 with all the values
2052 for (Int_t i = 0; i < fTimeMax; i++) {
2054 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
2057 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd2,i,fPHValue[i]);
2068 //____________Offine tracking in the AliTRDtracker_____________________________
2069 Bool_t AliTRDCalibraFillHisto::FindP1TrackPH()
2072 // For the offline tracking
2073 // This function will be called in the functions UpdateHistogram...
2074 // to fill the find the parameter P1 of a track for the drift velocity calibration
2078 //Number of points: if less than 3 return kFALSE
2079 Int_t Npoints = fListClusters->GetEntriesFast();
2080 if(Npoints <= 2) return kFALSE;
2083 TLinearFitter linearFitterTracklet = TLinearFitter(2,"pol1"); // TLinearFitter per tracklet
2084 Double_t snp = 0.0; // sin angle in the plan yx track
2085 Double_t y = 0.0; // y clusters in the middle of the chamber
2086 Double_t z = 0.0; // z cluster in the middle of the chamber
2087 Double_t dydt = 0.0; // dydt tracklet after straight line fit
2088 Double_t tnp = 0.0; // tan angle in the plan xy track
2089 Double_t tgl = 0.0; // dz/dl and not dz/dx!
2090 Double_t errorpar = 0.0; // error after straight line fit on dy/dt
2091 Double_t pointError = 0.0; // error after straight line fit
2092 Int_t detector = ((AliTRDcluster *) fListClusters->At(0))->GetDetector(); //detector
2093 Int_t snpright = 1; // if we took in the middle snp
2094 Int_t crossrow = 0; // if it crosses a pad row
2095 Double_t tiltingangle = 0; // tiltingangle of the pad
2096 Float_t dzdx = 0; // dz/dx now from dz/dl
2097 Int_t nbli = 0; // number linear fitter points
2098 AliTRDpadPlane *padplane = fGeo->GetPadPlane(GetPlane(detector),GetChamber(detector));
2100 linearFitterTracklet.StoreData(kFALSE);
2101 linearFitterTracklet.ClearPoints();
2103 //if more than one row
2104 Int_t rowp = -1; // if it crosses a pad row
2107 tiltingangle = padplane->GetTiltingAngle();
2108 Float_t tnt = TMath::Tan(tiltingangle/180.*TMath::Pi()); // tan tiltingangle
2111 for(Int_t k = 0; k < Npoints; k++){
2113 AliTRDcluster *cl = (AliTRDcluster *) fListClusters->At(k);
2114 Double_t ycluster = cl->GetY();
2115 Int_t time = cl->GetLocalTimeBin();
2116 Double_t timeis = time/fSf;
2117 //See if cross two pad rows
2118 Int_t row = padplane->GetPadRowNumber(cl->GetZ());
2119 if(k==0) rowp = row;
2120 if(row != rowp) crossrow = 1;
2121 //Take in the middle of the chamber
2123 if(time > (Int_t) 10) {
2125 //if(time < (Int_t) 11) {
2131 linearFitterTracklet.AddPoint(&timeis,ycluster,1);
2135 if(((AliTRDcluster *) fListClusters->At(0))->GetLocalTimeBin() < 10) snpright = 0;
2137 //if(((AliTRDcluster *) fListClusters->At(0))->GetLocalTimeBin() >= 11) snpright = 0;
2138 if(nbli <= 2) return kFALSE;
2140 // Do the straight line fit now
2142 linearFitterTracklet.Eval();
2143 linearFitterTracklet.GetParameters(pars);
2144 pointError = TMath::Sqrt(linearFitterTracklet.GetChisquare()/nbli);
2145 errorpar = linearFitterTracklet.GetParError(1)*pointError;
2148 if( TMath::Abs(snp) < 1.){
2149 tnp = snp / (TMath::Sqrt(1-(snp*snp)));
2151 dzdx = tgl*TMath::Sqrt(1+tnp*tnp);
2153 if(fDebugLevel > 0){
2154 if ( !fDebugStreamer ) {
2156 TDirectory *backup = gDirectory;
2157 fDebugStreamer = new TTreeSRedirector("TRDdebugCalibraFill.root");
2158 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
2161 (* fDebugStreamer) << "VDRIFT0"<<
2162 "Npoints="<<Npoints<<
2166 (* fDebugStreamer) << "VDRIFT"<<
2167 "snpright="<<snpright<<
2168 "Npoints="<<Npoints<<
2170 "detector="<<detector<<
2179 "crossrow="<<crossrow<<
2180 "errorpar="<<errorpar<<
2181 "pointError="<<pointError<<
2186 if(Npoints < fNumberClusters) return kFALSE;
2187 if(snpright == 0) return kFALSE;
2188 if(pointError >= 0.1) return kFALSE;
2189 if(crossrow == 1) return kFALSE;
2191 if(fLinearFitterOn){
2192 //Add to the linear fitter of the detector
2193 if( TMath::Abs(snp) < 1.){
2194 Double_t x = tnp-dzdx*tnt;
2195 (GetLinearFitter(detector,kTRUE))->AddPoint(&x,dydt);
2196 if(fLinearFitterDebugOn) {
2197 fLinearVdriftFit->Update(detector,x,pars[1]);
2199 fEntriesLinearFitter[detector]++;
2202 //AliInfo("End of FindP1TrackPH with success!")
2206 //____________Offine tracking in the AliTRDtracker_____________________________
2207 Bool_t AliTRDCalibraFillHisto::HandlePRF()
2210 // For the offline tracking
2211 // Fit the tracklet with a line and take the position as reference for the PRF
2215 Int_t Npoints = fListClusters->GetEntriesFast(); // number of total points
2216 Int_t Nb3pc = 0; // number of three pads clusters used for fit
2217 Int_t detector = ((AliTRDcluster *) fListClusters->At(0))->GetDetector(); // detector
2220 // To see the difference due to the fit
2221 Double_t *padPositions;
2222 padPositions = new Double_t[Npoints];
2223 for(Int_t k = 0; k < Npoints; k++){
2224 padPositions[k] = 0.0;
2228 //Find the position by a fit
2229 TLinearFitter fitter(2,"pol1");
2230 fitter.StoreData(kFALSE);
2231 fitter.ClearPoints();
2232 for(Int_t k = 0; k < Npoints; k++){
2234 AliTRDcluster *cl = (AliTRDcluster *) fListClusters->At(k);
2235 Short_t *signals = cl->GetSignals();
2236 Double_t time = cl->GetLocalTimeBin();
2237 //Calculate x if possible
2238 Float_t xcenter = 0.0;
2239 Bool_t echec = kTRUE;
2240 if((time<=7) || (time>=21)) continue;
2241 // Center 3 balanced: position with the center of the pad
2242 if ((((Float_t) signals[3]) > 0.0) &&
2243 (((Float_t) signals[2]) > 0.0) &&
2244 (((Float_t) signals[4]) > 0.0)) {
2246 // Security if the denomiateur is 0
2247 if ((((Float_t) (((Float_t) signals[3]) * ((Float_t) signals[3]))) /
2248 ((Float_t) (((Float_t) signals[2]) * ((Float_t) signals[4])))) != 1.0) {
2249 xcenter = 0.5 * (TMath::Log((Float_t) (((Float_t) signals[4]) / ((Float_t) signals[2]))))
2250 / (TMath::Log(((Float_t) (((Float_t) signals[3]) * ((Float_t) signals[3])))
2251 / ((Float_t) (((Float_t) signals[2]) * ((Float_t) signals[4])))));
2257 if(TMath::Abs(xcenter) > 0.5) echec = kTRUE;
2259 //if no echec: calculate with the position of the pad
2260 // Position of the cluster
2261 Double_t padPosition = xcenter + cl->GetPadCol();
2262 padPositions[k] = padPosition;
2264 fitter.AddPoint(&time, padPosition,1);
2267 //printf("Nb3pc %d, Npoints %d\n",Nb3pc,Npoints);
2268 if(Nb3pc < 3) return kFALSE;
2271 fitter.GetParameters(line);
2272 Float_t pointError = -1.0;
2273 pointError = TMath::Sqrt(fitter.GetChisquare()/Nb3pc);
2277 for(Int_t k = 0; k < Npoints; k++){
2279 AliTRDcluster *cl = (AliTRDcluster *) fListClusters->At(k);
2280 Short_t *signals = cl->GetSignals(); // signal
2281 Double_t time = cl->GetLocalTimeBin(); // time bin
2282 Float_t padPosTracklet = line[0]+line[1]*time; // reconstruct position from fit
2283 Float_t padPos = cl->GetPadCol(); // middle pad
2284 Double_t dpad = padPosTracklet - padPos; // reconstruct position relative to middle pad from fit
2285 Float_t ycenter = 0.0; // relative center charge
2286 Float_t ymin = 0.0; // relative left charge
2287 Float_t ymax = 0.0; // relative right charge
2288 Double_t tgl = fPar3[(Int_t)time]; // dz/dl and not dz/dx
2289 Double_t pt = fPar4[(Int_t)time]; // pt
2290 Float_t dzdx = 0.0; // dzdx
2293 //Requiere simply two pads clusters at least
2294 if(((((Float_t) signals[3]) > 0.0) && (((Float_t) signals[2]) > 0.0)) ||
2295 ((((Float_t) signals[3]) > 0.0) && (((Float_t) signals[4]) > 0.0))){
2296 Float_t sum = ((Float_t) signals[2]) + ((Float_t) signals[3]) + ((Float_t) signals[4]);
2297 if(sum > 0.0) ycenter = ((Float_t) signals[3])/ sum;
2298 if(sum > 0.0) ymin = ((Float_t) signals[2])/ sum;
2299 if(sum > 0.0) ymax = ((Float_t) signals[4])/ sum;
2303 Int_t *rowcol = CalculateRowCol(cl); // calcul col and row pad of the cluster
2304 Int_t grouplocal = CalculateCalibrationGroup(2,rowcol); // calcul the corresponding group
2305 Int_t caligroup = fCalibraMode->GetXbins(2)+ grouplocal; // calcul the corresponding group
2306 Double_t snp = fPar2[(Int_t)time]; // sin angle in xy plan
2307 Float_t xcl = cl->GetY(); // y cluster
2308 Float_t qcl = cl->GetQ(); // charge cluster
2309 Int_t plane = GetPlane(detector); // plane
2310 Int_t chamber = GetChamber(detector); // chamber
2311 Double_t xdiff = dpad; // reconstructed position constant
2312 Double_t x = dpad; // reconstructed position moved
2313 Float_t Ep = pointError; // error of fit
2314 Float_t signal1 = (Float_t)signals[1]; // signal at the border
2315 Float_t signal3 = (Float_t)signals[3]; // signal
2316 Float_t signal2 = (Float_t)signals[2]; // signal
2317 Float_t signal4 = (Float_t)signals[4]; // signal
2318 Float_t signal5 = (Float_t)signals[5]; // signal at the border
2320 if(TMath::Abs(snp) < 1.0){
2321 tnp = snp / (TMath::Sqrt(1-snp*snp));
2322 dzdx = tgl*TMath::Sqrt(1+tnp*tnp);
2326 if(fDebugLevel > 0){
2327 if ( !fDebugStreamer ) {
2329 TDirectory *backup = gDirectory;
2330 fDebugStreamer = new TTreeSRedirector("TRDdebugCalibraFill.root");
2331 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
2334 (* fDebugStreamer) << "PRF0"<<
2335 "caligroup="<<caligroup<<
2336 "detector="<<detector<<
2338 "chamber="<<chamber<<
2339 "Npoints="<<Npoints<<
2348 "padPosition="<<padPositions[k]<<
2349 "padPosTracklet="<<padPosTracklet<<
2351 "ycenter="<<ycenter<<
2356 "signal1="<<signal1<<
2357 "signal2="<<signal2<<
2358 "signal3="<<signal3<<
2359 "signal4="<<signal4<<
2360 "signal5="<<signal5<<
2365 Float_t y = ycenter;
2366 (* fDebugStreamer) << "PRFALL"<<
2367 "caligroup="<<caligroup<<
2368 "detector="<<detector<<
2370 "chamber="<<chamber<<
2371 "Npoints="<<Npoints<<
2381 "padPosition="<<padPositions[k]<<
2382 "padPosTracklet="<<padPosTracklet<<
2387 "signal1="<<signal1<<
2388 "signal2="<<signal2<<
2389 "signal3="<<signal3<<
2390 "signal4="<<signal4<<
2391 "signal5="<<signal5<<
2397 (* fDebugStreamer) << "PRFALL"<<
2398 "caligroup="<<caligroup<<
2399 "detector="<<detector<<
2401 "chamber="<<chamber<<
2402 "Npoints="<<Npoints<<
2412 "padPosition="<<padPositions[k]<<
2413 "padPosTracklet="<<padPosTracklet<<
2418 "signal1="<<signal1<<
2419 "signal2="<<signal2<<
2420 "signal3="<<signal3<<
2421 "signal4="<<signal4<<
2422 "signal5="<<signal5<<
2429 (* fDebugStreamer) << "PRFALL"<<
2430 "caligroup="<<caligroup<<
2431 "detector="<<detector<<
2433 "chamber="<<chamber<<
2434 "Npoints="<<Npoints<<
2444 "padPosition="<<padPositions[k]<<
2445 "padPosTracklet="<<padPosTracklet<<
2450 "signal1="<<signal1<<
2451 "signal2="<<signal2<<
2452 "signal3="<<signal3<<
2453 "signal4="<<signal4<<
2454 "signal5="<<signal5<<
2461 if(Npoints < fNumberClusters) continue;
2462 if(Nb3pc <= 5) continue;
2463 if((time >= 21) || (time < 7)) continue;
2464 if(TMath::Abs(snp) >= 1.0) continue;
2465 if(qcl < 80) continue;
2467 Bool_t echec = kFALSE;
2468 Double_t shift = 0.0;
2469 //Calculate the shift in x coresponding to this tnp
2470 if(fNgroupprf != 0.0){
2471 shift = -3.0*(fNgroupprf-1)-1.5;
2472 Double_t limithigh = -0.2*(fNgroupprf-1);
2473 if((tnp < (-0.2*fNgroupprf)) || (tnp > (0.2*fNgroupprf))) echec = kTRUE;
2475 while(tnp > limithigh){
2481 if (fHisto2d && !echec) {
2482 if(TMath::Abs(dpad) < 1.5) {
2483 fPRF2d->Fill(shift+dpad,(caligroup+0.5),ycenter);
2484 fPRF2d->Fill(shift-dpad,(caligroup+0.5),ycenter);
2486 if((ymin > 0.0) && (TMath::Abs(dpad+1.0) < 1.5)) {
2487 fPRF2d->Fill(shift-(dpad+1.0),(caligroup+0.5),ymin);
2488 fPRF2d->Fill(shift+(dpad+1.0),(caligroup+0.5),ymin);
2490 if((ymax > 0.0) && (TMath::Abs(dpad-1.0) < 1.5)) {
2491 fPRF2d->Fill(shift+1.0-dpad,(caligroup+0.5),ymax);
2492 fPRF2d->Fill(shift-1.0+dpad,(caligroup+0.5),ymax);
2495 //Not equivalent anymore here!
2496 if (fVector2d && !echec) {
2497 if(TMath::Abs(dpad) < 1.5) {
2498 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift+dpad,ycenter);
2499 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift-dpad,ycenter);
2501 if((ymin > 0.0) && (TMath::Abs(dpad+1.0) < 1.5)) {
2502 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift-(dpad+1.0),ymin);
2503 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift+(dpad+1.0),ymin);
2505 if((ymax > 0.0) && (TMath::Abs(dpad-1.0) < 1.5)) {
2506 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift+1.0-dpad,ymax);
2507 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift-1.0+dpad,ymax);
2514 //____________Offine tracking in the AliTRDtracker_____________________________
2515 Bool_t AliTRDCalibraFillHisto::FindP1TrackPHtrack(AliTRDtrack *t, Int_t index0, Int_t index1)
2518 // For the offline tracking
2519 // This function will be called in the functions UpdateHistogram...
2520 // to fill the find the parameter P1 of a track for the drift velocity calibration
2524 //Number of points: if less than 3 return kFALSE
2525 Int_t Npoints = index1-index0;
2526 if(Npoints <= 2) return kFALSE;
2529 TLinearFitter linearFitterTracklet = TLinearFitter(2,"pol1"); // TLinearFitter per tracklet
2530 Double_t snp = 0.0; // sin angle in the plan yx track
2531 Double_t y = 0.0; // y clusters in the middle of the chamber
2532 Double_t z = 0.0; // z cluster in the middle of the chamber
2533 Double_t dydt = 0.0; // dydt tracklet after straight line fit
2534 Double_t tnp = 0.0; // tan angle in the plan xy track
2535 Double_t tgl = 0.0; // dz/dl and not dz/dx!
2536 Double_t errorpar = 0.0; // error after straight line fit on dy/dt
2537 Double_t pointError = 0.0; // error after straight line fit
2538 Int_t detector = ((AliTRDcluster *) t->GetCluster(index0))->GetDetector(); //detector
2539 //Int_t snpright = 1; // if we took in the middle snp
2540 Int_t crossrow = 0; // if it crosses a pad row
2541 Double_t tiltingangle = 0; // tiltingangle of the pad
2542 Float_t dzdx = 0; // dz/dx now from dz/dl
2543 Int_t nbli = 0; // number linear fitter points
2544 AliTRDpadPlane *padplane = fGeo->GetPadPlane(GetPlane(detector),GetChamber(detector));
2546 linearFitterTracklet.StoreData(kFALSE);
2547 linearFitterTracklet.ClearPoints();
2549 //if more than one row
2550 Int_t rowp = -1; // if it crosses a pad row
2553 tiltingangle = padplane->GetTiltingAngle();
2554 Float_t tnt = TMath::Tan(tiltingangle/180.*TMath::Pi()); // tan tiltingangle
2557 for(Int_t k = 0; k < Npoints; k++){
2559 AliTRDcluster *cl = (AliTRDcluster *) t->GetCluster(k+index0);
2560 Double_t ycluster = cl->GetY();
2561 Int_t time = cl->GetLocalTimeBin();
2562 Double_t timeis = time/fSf;
2563 //See if cross two pad rows
2564 Int_t row = padplane->GetPadRowNumber(cl->GetZ());
2565 if(k==0) rowp = row;
2566 if(row != rowp) crossrow = 1;
2567 //Take in the middle of the chamber
2569 //if(time > (Int_t) 10) {
2571 if(time < (Int_t) 11) {
2575 linearFitterTracklet.AddPoint(&timeis,ycluster,1);
2579 // take now the snp, tnp and tgl from the track
2580 snp = t->GetSnpPlane(GetPlane(detector));
2581 tgl = t->GetTglPlane(GetPlane(detector));
2584 //if(((AliTRDcluster *) t->GetCluster(index0))->GetLocalTimeBin() < 10) snpright = 0;
2586 //if(((AliTRDcluster *) t->GetCluster(index0))->GetLocalTimeBin() >= 11) snpright = 0;
2587 if(nbli <= 2) return kFALSE;
2589 // Do the straight line fit now
2591 linearFitterTracklet.Eval();
2592 linearFitterTracklet.GetParameters(pars);
2593 pointError = TMath::Sqrt(linearFitterTracklet.GetChisquare()/nbli);
2594 errorpar = linearFitterTracklet.GetParError(1)*pointError;
2597 if( TMath::Abs(snp) < 1.){
2598 tnp = snp / (TMath::Sqrt(1-(snp*snp)));
2600 dzdx = tgl*TMath::Sqrt(1+tnp*tnp);
2602 if(fDebugLevel > 0){
2603 if ( !fDebugStreamer ) {
2605 TDirectory *backup = gDirectory;
2606 fDebugStreamer = new TTreeSRedirector("TRDdebugCalibraFill.root");
2607 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
2611 (* fDebugStreamer) << "VDRIFT"<<
2612 //"snpright="<<snpright<<
2613 "Npoints="<<Npoints<<
2615 "detector="<<detector<<
2624 "crossrow="<<crossrow<<
2625 "errorpar="<<errorpar<<
2626 "pointError="<<pointError<<
2631 if(Npoints < fNumberClusters) return kFALSE;
2632 //if(snpright == 0) return kFALSE;
2633 if(pointError >= 0.1) return kFALSE;
2634 if(crossrow == 1) return kFALSE;
2636 if(fLinearFitterOn){
2637 //Add to the linear fitter of the detector
2638 if( TMath::Abs(snp) < 1.){
2639 Double_t x = tnp-dzdx*tnt;
2640 (GetLinearFitter(detector,kTRUE))->AddPoint(&x,dydt);
2641 if(fLinearFitterDebugOn) {
2642 fLinearVdriftFit->Update(detector,x,pars[1]);
2644 fEntriesLinearFitter[detector]++;
2647 //AliInfo("End of FindP1TrackPH with success!")
2651 //____________Offine tracking in the AliTRDtracker_____________________________
2652 Bool_t AliTRDCalibraFillHisto::HandlePRFtrack(AliTRDtrack *t, Int_t index0, Int_t index1)
2655 // For the offline tracking
2656 // Fit the tracklet with a line and take the position as reference for the PRF
2660 Int_t Npoints = index1-index0; // number of total points
2661 Int_t Nb3pc = 0; // number of three pads clusters used for fit
2662 Int_t detector = ((AliTRDcluster *) t->GetCluster(index0))->GetDetector(); // detector
2665 // To see the difference due to the fit
2666 Double_t *padPositions;
2667 padPositions = new Double_t[Npoints];
2668 for(Int_t k = 0; k < Npoints; k++){
2669 padPositions[k] = 0.0;
2673 //Find the position by a fit
2674 TLinearFitter fitter(2,"pol1");
2675 fitter.StoreData(kFALSE);
2676 fitter.ClearPoints();
2677 for(Int_t k = 0; k < Npoints; k++){
2679 AliTRDcluster *cl = (AliTRDcluster *) t->GetCluster(k+index0);
2680 Short_t *signals = cl->GetSignals();
2681 Double_t time = cl->GetLocalTimeBin();
2682 //Calculate x if possible
2683 Float_t xcenter = 0.0;
2684 Bool_t echec = kTRUE;
2685 if((time<=7) || (time>=21)) continue;
2686 // Center 3 balanced: position with the center of the pad
2687 if ((((Float_t) signals[3]) > 0.0) &&
2688 (((Float_t) signals[2]) > 0.0) &&
2689 (((Float_t) signals[4]) > 0.0)) {
2691 // Security if the denomiateur is 0
2692 if ((((Float_t) (((Float_t) signals[3]) * ((Float_t) signals[3]))) /
2693 ((Float_t) (((Float_t) signals[2]) * ((Float_t) signals[4])))) != 1.0) {
2694 xcenter = 0.5 * (TMath::Log((Float_t) (((Float_t) signals[4]) / ((Float_t) signals[2]))))
2695 / (TMath::Log(((Float_t) (((Float_t) signals[3]) * ((Float_t) signals[3])))
2696 / ((Float_t) (((Float_t) signals[2]) * ((Float_t) signals[4])))));
2702 if(TMath::Abs(xcenter) > 0.5) echec = kTRUE;
2704 //if no echec: calculate with the position of the pad
2705 // Position of the cluster
2706 Double_t padPosition = xcenter + cl->GetPadCol();
2707 padPositions[k] = padPosition;
2709 fitter.AddPoint(&time, padPosition,1);
2712 //printf("Nb3pc %d, Npoints %d\n",Nb3pc,Npoints);
2713 if(Nb3pc < 3) return kFALSE;
2716 fitter.GetParameters(line);
2717 Float_t pointError = -1.0;
2718 pointError = TMath::Sqrt(fitter.GetChisquare()/Nb3pc);
2720 // Take the tgl and snp with the track t now
2721 Double_t tgl = t->GetTglPlane(GetPlane(detector)); //dz/dl and not dz/dx
2722 Double_t snp = t->GetSnpPlane(GetPlane(detector)); // sin angle in xy plan
2723 Float_t dzdx = 0.0; // dzdx
2725 if(TMath::Abs(snp) < 1.0){
2726 tnp = snp / (TMath::Sqrt(1-snp*snp));
2727 dzdx = tgl*TMath::Sqrt(1+tnp*tnp);
2732 for(Int_t k = 0; k < Npoints; k++){
2734 AliTRDcluster *cl = (AliTRDcluster *) t->GetCluster(k+index0);
2735 Short_t *signals = cl->GetSignals(); // signal
2736 Double_t time = cl->GetLocalTimeBin(); // time bin
2737 Float_t padPosTracklet = line[0]+line[1]*time; // reconstruct position from fit
2738 Float_t padPos = cl->GetPadCol(); // middle pad
2739 Double_t dpad = padPosTracklet - padPos; // reconstruct position relative to middle pad from fit
2740 Float_t ycenter = 0.0; // relative center charge
2741 Float_t ymin = 0.0; // relative left charge
2742 Float_t ymax = 0.0; // relative right charge
2746 //Requiere simply two pads clusters at least
2747 if(((((Float_t) signals[3]) > 0.0) && (((Float_t) signals[2]) > 0.0)) ||
2748 ((((Float_t) signals[3]) > 0.0) && (((Float_t) signals[4]) > 0.0))){
2749 Float_t sum = ((Float_t) signals[2]) + ((Float_t) signals[3]) + ((Float_t) signals[4]);
2750 if(sum > 0.0) ycenter = ((Float_t) signals[3])/ sum;
2751 if(sum > 0.0) ymin = ((Float_t) signals[2])/ sum;
2752 if(sum > 0.0) ymax = ((Float_t) signals[4])/ sum;
2756 Int_t *rowcol = CalculateRowCol(cl); // calcul col and row pad of the cluster
2757 Int_t grouplocal = CalculateCalibrationGroup(2,rowcol); // calcul the corresponding group
2758 Int_t caligroup = fCalibraMode->GetXbins(2)+ grouplocal; // calcul the corresponding group
2759 Float_t xcl = cl->GetY(); // y cluster
2760 Float_t qcl = cl->GetQ(); // charge cluster
2761 Int_t plane = GetPlane(detector); // plane
2762 Int_t chamber = GetChamber(detector); // chamber
2763 Double_t xdiff = dpad; // reconstructed position constant
2764 Double_t x = dpad; // reconstructed position moved
2765 Float_t Ep = pointError; // error of fit
2766 Float_t signal1 = (Float_t)signals[1]; // signal at the border
2767 Float_t signal3 = (Float_t)signals[3]; // signal
2768 Float_t signal2 = (Float_t)signals[2]; // signal
2769 Float_t signal4 = (Float_t)signals[4]; // signal
2770 Float_t signal5 = (Float_t)signals[5]; // signal at the border
2774 if(fDebugLevel > 0){
2775 if ( !fDebugStreamer ) {
2777 TDirectory *backup = gDirectory;
2778 fDebugStreamer = new TTreeSRedirector("TRDdebugCalibraFill.root");
2779 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
2782 (* fDebugStreamer) << "PRF0"<<
2783 "caligroup="<<caligroup<<
2784 "detector="<<detector<<
2786 "chamber="<<chamber<<
2787 "Npoints="<<Npoints<<
2795 "padPosition="<<padPositions[k]<<
2796 "padPosTracklet="<<padPosTracklet<<
2798 "ycenter="<<ycenter<<
2803 "signal1="<<signal1<<
2804 "signal2="<<signal2<<
2805 "signal3="<<signal3<<
2806 "signal4="<<signal4<<
2807 "signal5="<<signal5<<
2812 Float_t y = ycenter;
2813 (* fDebugStreamer) << "PRFALL"<<
2814 "caligroup="<<caligroup<<
2815 "detector="<<detector<<
2817 "chamber="<<chamber<<
2818 "Npoints="<<Npoints<<
2827 "padPosition="<<padPositions[k]<<
2828 "padPosTracklet="<<padPosTracklet<<
2833 "signal1="<<signal1<<
2834 "signal2="<<signal2<<
2835 "signal3="<<signal3<<
2836 "signal4="<<signal4<<
2837 "signal5="<<signal5<<
2843 (* fDebugStreamer) << "PRFALL"<<
2844 "caligroup="<<caligroup<<
2845 "detector="<<detector<<
2847 "chamber="<<chamber<<
2848 "Npoints="<<Npoints<<
2857 "padPosition="<<padPositions[k]<<
2858 "padPosTracklet="<<padPosTracklet<<
2863 "signal1="<<signal1<<
2864 "signal2="<<signal2<<
2865 "signal3="<<signal3<<
2866 "signal4="<<signal4<<
2867 "signal5="<<signal5<<
2874 (* fDebugStreamer) << "PRFALL"<<
2875 "caligroup="<<caligroup<<
2876 "detector="<<detector<<
2878 "chamber="<<chamber<<
2879 "Npoints="<<Npoints<<
2888 "padPosition="<<padPositions[k]<<
2889 "padPosTracklet="<<padPosTracklet<<
2894 "signal1="<<signal1<<
2895 "signal2="<<signal2<<
2896 "signal3="<<signal3<<
2897 "signal4="<<signal4<<
2898 "signal5="<<signal5<<
2905 if(Npoints < fNumberClusters) continue;
2906 if(Nb3pc <= 5) continue;
2907 if((time >= 21) || (time < 7)) continue;
2908 if(TMath::Abs(snp) >= 1.0) continue;
2909 if(qcl < 80) continue;
2911 Bool_t echec = kFALSE;
2912 Double_t shift = 0.0;
2913 //Calculate the shift in x coresponding to this tnp
2914 if(fNgroupprf != 0.0){
2915 shift = -3.0*(fNgroupprf-1)-1.5;
2916 Double_t limithigh = -0.2*(fNgroupprf-1);
2917 if((tnp < (-0.2*fNgroupprf)) || (tnp > (0.2*fNgroupprf))) echec = kTRUE;
2919 while(tnp > limithigh){
2925 if (fHisto2d && !echec) {
2926 if(TMath::Abs(dpad) < 1.5) {
2927 fPRF2d->Fill(shift+dpad,(caligroup+0.5),ycenter);
2928 fPRF2d->Fill(shift-dpad,(caligroup+0.5),ycenter);
2930 if((ymin > 0.0) && (TMath::Abs(dpad+1.0) < 1.5)) {
2931 fPRF2d->Fill(shift-(dpad+1.0),(caligroup+0.5),ymin);
2932 fPRF2d->Fill(shift+(dpad+1.0),(caligroup+0.5),ymin);
2934 if((ymax > 0.0) && (TMath::Abs(dpad-1.0) < 1.5)) {
2935 fPRF2d->Fill(shift+1.0-dpad,(caligroup+0.5),ymax);
2936 fPRF2d->Fill(shift-1.0+dpad,(caligroup+0.5),ymax);
2939 //Not equivalent anymore here!
2940 if (fVector2d && !echec) {
2941 if(TMath::Abs(dpad) < 1.5) {
2942 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift+dpad,ycenter);
2943 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift-dpad,ycenter);
2945 if((ymin > 0.0) && (TMath::Abs(dpad+1.0) < 1.5)) {
2946 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift-(dpad+1.0),ymin);
2947 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift+(dpad+1.0),ymin);
2949 if((ymax > 0.0) && (TMath::Abs(dpad-1.0) < 1.5)) {
2950 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift+1.0-dpad,ymax);
2951 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift-1.0+dpad,ymax);
2959 //____________Some basic geometry function_____________________________________
2961 //_____________________________________________________________________________
2962 Int_t AliTRDCalibraFillHisto::GetPlane(Int_t d) const
2965 // Reconstruct the plane number from the detector number
2968 return ((Int_t) (d % 6));
2972 //_____________________________________________________________________________
2973 Int_t AliTRDCalibraFillHisto::GetChamber(Int_t d) const
2976 // Reconstruct the chamber number from the detector number
2980 return ((Int_t) (d % 30) / fgkNplan);
2984 //_____________________________________________________________________________
2985 Int_t AliTRDCalibraFillHisto::GetSector(Int_t d) const
2988 // Reconstruct the sector number from the detector number
2992 return ((Int_t) (d / fg));
2995 //_____________________________________________________________________
2996 TProfile2D* AliTRDCalibraFillHisto::GetPH2d(Int_t nbtimebin, Float_t samplefrequency)
2999 // return pointer to fPH2d TProfile2D
3000 // create a new TProfile2D if it doesn't exist allready
3006 fTimeMax = nbtimebin;
3007 fSf = samplefrequency;
3010 AliInfo(Form("The pad calibration mode for the drift velocity calibration: Nz %d, and Nrphi %d"
3011 ,fCalibraMode->GetNz(1)
3012 ,fCalibraMode->GetNrphi(1)));
3014 // Calcul the number of Xbins
3016 fCalibraMode->ModePadCalibration(2,1);
3017 fCalibraMode->ModePadFragmentation(0,2,0,1);
3018 fCalibraMode->SetDetChamb2(1);
3019 Ntotal1 += 6 * 18 * fCalibraMode->GetDetChamb2(1);
3020 fCalibraMode->ModePadCalibration(0,1);
3021 fCalibraMode->ModePadFragmentation(0,0,0,1);
3022 fCalibraMode->SetDetChamb0(1);
3023 Ntotal1 += 6 * 4 * 18 * fCalibraMode->GetDetChamb0(1);
3024 AliInfo(Form("Total number of Xbins: %d",Ntotal1));
3026 CreatePH2d(Ntotal1);
3033 //_____________________________________________________________________
3034 TLinearFitter* AliTRDCalibraFillHisto::GetLinearFitter(Int_t detector, Bool_t force)
3037 // return pointer to TLinearFitter Calibration
3038 // if force is true create a new TLinearFitter if it doesn't exist allready
3041 if ((!force) || (fLinearFitterArray.UncheckedAt(detector))){
3042 return (TLinearFitter*)fLinearFitterArray.UncheckedAt(detector);
3045 // if we are forced and TLinearFitter doesn't yet exist create it
3047 // new TLinearFitter
3048 TLinearFitter *linearfitter = new TLinearFitter(2,"pol1");
3049 fLinearFitterArray.AddAt(linearfitter,detector);
3050 return linearfitter;
3053 //_____________________________________________________________________
3054 void AliTRDCalibraFillHisto::FillCH2d(Int_t x, Float_t y)
3057 // FillCH2d: Marian style
3060 //skip simply the value out of range
3061 if((y>=300.0) || (y<0.0)) return;
3063 //Calcul the y place
3064 Int_t yplace = (Int_t) (fNumberBinCharge*y/300.0)+1;
3065 Int_t place = (fNumberBinCharge+2)*(x+1)+yplace;
3068 fCH2d->GetArray()[place]++;
3072 //____________________________________________________________________________
3073 void AliTRDCalibraFillHisto::AnalyseLinearFitter()
3076 // Analyse array of linear fitter because can not be written
3077 // Store two arrays: one with the param the other one with the error param + number of entries
3080 for(Int_t k = 0; k < 540; k++){
3081 TLinearFitter *linearfitter = GetLinearFitter(k);
3082 if((linearfitter!=0) && (fEntriesLinearFitter[k]>10)){
3083 TVectorD *par = new TVectorD(2);
3084 TVectorD pare = TVectorD(2);
3085 TVectorD *parE = new TVectorD(3);
3086 linearfitter->Eval();
3087 linearfitter->GetParameters(*par);
3088 linearfitter->GetErrors(pare);
3089 Float_t ppointError = TMath::Sqrt(TMath::Abs(linearfitter->GetChisquare())/fEntriesLinearFitter[k]);
3090 (*parE)[0] = pare[0]*ppointError;
3091 (*parE)[1] = pare[1]*ppointError;
3092 (*parE)[2] = (Double_t) fEntriesLinearFitter[k];
3093 ((TObjArray *)fLinearVdriftFit->GetPArray())->AddAt(par,k);
3094 ((TObjArray *)fLinearVdriftFit->GetEArray())->AddAt(parE,k);
3098 //________________________________________________________________________________
3099 Int_t AliTRDCalibraFillHisto::Arrondi(Double_t x) const
3101 // Partie entiere of the (x+0.5)
3106 //if (x + 0.5 == Float_t(i) && i & 1) i--;
3109 //if (x - 0.5 == Float_t(i) && i & 1) i++;