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>
48 #include <TStopwatch.h>
50 #include <TDirectory.h>
52 #include <TTreeStream.h>
56 #include "AliCDBManager.h"
57 #include "AliRawReader.h"
58 #include "AliRawReaderDate.h"
60 #include "AliTRDCalibraFillHisto.h"
61 #include "AliTRDCalibraMode.h"
62 #include "AliTRDCalibraVector.h"
63 #include "AliTRDcalibDB.h"
64 #include "AliTRDCommonParam.h"
65 #include "AliTRDmcmTracklet.h"
66 #include "AliTRDpadPlane.h"
67 #include "AliTRDcluster.h"
68 #include "AliTRDtrack.h"
69 #include "AliTRDRawStream.h"
70 #include "AliTRDgeometry.h"
76 ClassImp(AliTRDCalibraFillHisto)
78 AliTRDCalibraFillHisto* AliTRDCalibraFillHisto::fgInstance = 0;
79 Bool_t AliTRDCalibraFillHisto::fgTerminated = kFALSE;
81 //_____________singleton implementation_________________________________________________
82 AliTRDCalibraFillHisto *AliTRDCalibraFillHisto::Instance()
85 // Singleton implementation
88 if (fgTerminated != kFALSE) {
92 if (fgInstance == 0) {
93 fgInstance = new AliTRDCalibraFillHisto();
100 //______________________________________________________________________________________
101 void AliTRDCalibraFillHisto::Terminate()
104 // Singleton implementation
105 // Deletes the instance of this class
108 fgTerminated = kTRUE;
110 if (fgInstance != 0) {
116 //______________________________________________________________________________________
117 AliTRDCalibraFillHisto::AliTRDCalibraFillHisto()
121 ,fMcmTracking(kFALSE)
122 ,fMcmCorrectAngle(kFALSE)
128 ,fLinearFitterOn(kFALSE)
129 ,fLinearFitterDebugOn(kFALSE)
131 ,fThresholdClusterPRF2(15.0)
132 ,fCalibraMode(new AliTRDCalibraMode())
135 ,fDetectorAliTRDtrack(kFALSE)
136 ,fDetectorPreviousTrack(-1)
143 ,fNumberBinCharge(100)
146 ,fListClusters(new TObjArray())
155 ,fGoodTracklet(kTRUE)
158 ,fEntriesLinearFitter(0x0)
163 ,fLinearFitterArray(0)
164 ,fLinearFitterHistoArray(0)
167 // Default constructor
171 // Init some default values
174 fNumberUsedCh[0] = 0;
175 fNumberUsedCh[1] = 0;
176 fNumberUsedPh[0] = 0;
177 fNumberUsedPh[1] = 0;
179 fGeo = new AliTRDgeometry();
183 //______________________________________________________________________________________
184 AliTRDCalibraFillHisto::AliTRDCalibraFillHisto(const AliTRDCalibraFillHisto &c)
187 ,fMITracking(c.fMITracking)
188 ,fMcmTracking(c.fMcmTracking)
189 ,fMcmCorrectAngle(c.fMcmCorrectAngle)
192 ,fPRF2dOn(c.fPRF2dOn)
193 ,fHisto2d(c.fHisto2d)
194 ,fVector2d(c.fVector2d)
195 ,fLinearFitterOn(c.fLinearFitterOn)
196 ,fLinearFitterDebugOn(c.fLinearFitterDebugOn)
197 ,fRelativeScale(c.fRelativeScale)
198 ,fThresholdClusterPRF2(c.fThresholdClusterPRF2)
201 ,fDebugLevel(c.fDebugLevel)
202 ,fDetectorAliTRDtrack(c.fDetectorAliTRDtrack)
203 ,fDetectorPreviousTrack(c.fDetectorPreviousTrack)
204 ,fNumberClusters(c.fNumberClusters)
205 ,fProcent(c.fProcent)
206 ,fDifference(c.fDifference)
207 ,fNumberTrack(c.fNumberTrack)
208 ,fTimeMax(c.fTimeMax)
210 ,fNumberBinCharge(c.fNumberBinCharge)
211 ,fNumberBinPRF(c.fNumberBinPRF)
212 ,fNgroupprf(c.fNgroupprf)
213 ,fListClusters(new TObjArray())
219 ,fAmpTotal(c.fAmpTotal)
220 ,fPHPlace(c.fPHPlace)
221 ,fPHValue(c.fPHValue)
222 ,fGoodTracklet(c.fGoodTracklet)
223 ,fGoodTrack(c.fGoodTrack)
224 ,fEntriesCH(c.fEntriesCH)
225 ,fEntriesLinearFitter(fEntriesLinearFitter)
230 ,fLinearFitterArray(0)
231 ,fLinearFitterHistoArray(0)
236 if(c.fCalibraMode) fCalibraMode = new AliTRDCalibraMode(*c.fCalibraMode);
237 if(c.fCalibraVector) fCalibraVector = new AliTRDCalibraVector(*c.fCalibraVector);
239 fPH2d = new TProfile2D(*c.fPH2d);
240 fPH2d->SetDirectory(0);
243 fPRF2d = new TProfile2D(*c.fPRF2d);
244 fPRF2d->SetDirectory(0);
247 fCH2d = new TH2I(*c.fCH2d);
248 fCH2d->SetDirectory(0);
250 if(c.fLinearFitterOn){
251 fLinearFitterArray.Expand(540);
252 for (Int_t cb = 0; cb < 540; cb++){
253 const TLinearFitter *linearFitter = (TLinearFitter*)c.fLinearFitterArray.UncheckedAt(cb);
254 if ( linearFitter != 0x0 ) fLinearFitterArray.AddAt(new TLinearFitter(*linearFitter), cb);
257 if(c.fLinearFitterDebugOn){
258 fLinearFitterHistoArray.Expand(540);
259 for (Int_t cb = 0; cb < 540; cb++){
260 const TH2F *linearfitterhisto = (TH2F*)c.fLinearFitterHistoArray.UncheckedAt(cb);
261 if ( linearfitterhisto != 0x0 ){
262 TH2F *hNew = new TH2F(*linearfitterhisto);
263 hNew->SetDirectory(0);
264 fLinearFitterHistoArray.AddAt(hNew,cb);
271 fGeo = new AliTRDgeometry();
275 //____________________________________________________________________________________
276 AliTRDCalibraFillHisto::~AliTRDCalibraFillHisto()
279 // AliTRDCalibraFillHisto destructor
283 if ( fDebugStreamer ) delete fDebugStreamer;
291 //_____________________________________________________________________________
292 void AliTRDCalibraFillHisto::Destroy()
305 //_____________________________________________________________________________
306 void AliTRDCalibraFillHisto::ClearHistos()
326 //____________Functions for initialising the AliTRDCalibraFillHisto in the code_________
327 Bool_t AliTRDCalibraFillHisto::Init2Dhistos()
330 // For the offline tracking
331 // This function will be called in the function AliReconstruction::Run()
332 // Init the calibration mode (Nz, Nrphi), the 2D histograms if fHisto2d = kTRUE,
337 AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
339 AliInfo("Could not get calibDB");
342 AliTRDCommonParam *parCom = AliTRDCommonParam::Instance();
344 AliInfo("Could not get CommonParam");
349 fTimeMax = cal->GetNumberOfTimeBins();
350 fSf = parCom->GetSamplingFrequency();
353 //Init the tracklet parameters
354 fPar0 = new Double_t[fTimeMax];
355 fPar1 = new Double_t[fTimeMax];
356 fPar2 = new Double_t[fTimeMax];
357 fPar3 = new Double_t[fTimeMax];
358 fPar4 = new Double_t[fTimeMax];
360 for(Int_t k = 0; k < fTimeMax; k++){
368 //If vector method On initialised all the stuff
370 fCalibraVector = new AliTRDCalibraVector();
371 fCalibraVector->SetNumberBinCharge(fNumberBinCharge);
372 fCalibraVector->SetTimeMax(fTimeMax);
373 if(fNgroupprf != 0) {
374 fCalibraVector->SetNumberBinPRF(2*fNgroupprf*fNumberBinPRF);
375 fCalibraVector->SetPRFRange((Float_t)(3.0*fNgroupprf));
378 fCalibraVector->SetNumberBinPRF(fNumberBinPRF);
379 fCalibraVector->SetPRFRange(1.5);
383 // Create the 2D histos corresponding to the pad groupCalibration mode
386 AliInfo(Form("The pad calibration mode for the relative gain calibration: Nz %d, and Nrphi %d"
387 ,fCalibraMode->GetNz(0)
388 ,fCalibraMode->GetNrphi(0)));
390 // Calcul the number of Xbins
391 Int_t Ntotal0 = CalculateTotalNumberOfBins(0);
392 // Create the 2D histo
397 fAmpTotal = new Float_t[TMath::Max(fCalibraMode->GetDetChamb2(0),fCalibraMode->GetDetChamb0(0))];
398 for (Int_t k = 0; k < TMath::Max(fCalibraMode->GetDetChamb2(0),fCalibraMode->GetDetChamb0(0)); k++) {
402 fEntriesCH = new Int_t[Ntotal0];
403 for(Int_t k = 0; k < Ntotal0; k++){
409 AliInfo(Form("The pad calibration mode for the drift velocity calibration: Nz %d, and Nrphi %d"
410 ,fCalibraMode->GetNz(1)
411 ,fCalibraMode->GetNrphi(1)));
413 // Calcul the number of Xbins
414 Int_t Ntotal1 = CalculateTotalNumberOfBins(1);
415 // Create the 2D histo
420 fPHPlace = new Short_t[fTimeMax];
421 for (Int_t k = 0; k < fTimeMax; k++) {
424 fPHValue = new Float_t[fTimeMax];
425 for (Int_t k = 0; k < fTimeMax; k++) {
429 if (fLinearFitterOn) {
430 fLinearFitterArray.Expand(540);
431 fLinearFitterArray.SetName("ArrayLinearFitters");
432 fEntriesLinearFitter = new Int_t[540];
433 for(Int_t k = 0; k < 540; k++){
434 fEntriesLinearFitter[k] = 0;
436 if(fLinearFitterDebugOn) {
437 fLinearFitterHistoArray.Expand(540);
438 fLinearFitterHistoArray.SetName("ArrayHistos");
444 AliInfo(Form("The pad calibration mode for the PRF calibration: Nz %d, and Nrphi %d"
445 ,fCalibraMode->GetNz(2)
446 ,fCalibraMode->GetNrphi(2)));
448 // Calcul the number of Xbins
449 Int_t Ntotal2 = CalculateTotalNumberOfBins(2);
450 // Create the 2D histo
452 CreatePRF2d(Ntotal2);
460 //____________Functions for filling the histos in the code_____________________
462 //____________Offine tracking in the AliTRDtracker_____________________________
463 Bool_t AliTRDCalibraFillHisto::ResetTrack()
466 // For the offline tracking
467 // This function will be called in the function
468 // AliTRDtracker::FollowBackPropagation() at the beginning
469 // Reset the parameter to know we have a new TRD track
472 fDetectorAliTRDtrack = kFALSE;
477 //____________Offine tracking in the AliTRDtracker_____________________________
478 void AliTRDCalibraFillHisto::ResetfVariables()
481 // Reset values per tracklet
484 // Reset the list of clusters
485 fListClusters->Clear();
487 //Reset the tracklet parameters
488 for(Int_t k = 0; k < fTimeMax; k++){
497 //Reset good tracklet
498 fGoodTracklet = kTRUE;
500 // Reset the fPHValue
502 //Reset the fPHValue and fPHPlace
503 for (Int_t k = 0; k < fTimeMax; k++) {
509 // Reset the fAmpTotal where we put value
511 for (Int_t k = 0; k < fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0); k++) {
517 //____________Offline tracking in the AliTRDtracker____________________________
518 Bool_t AliTRDCalibraFillHisto::UpdateHistograms(AliTRDcluster *cl, AliTRDtrack *t)
521 // For the offline tracking
522 // This function will be called in the function
523 // AliTRDtracker::FollowBackPropagation() in the loop over the clusters
525 // Fill the 2D histos or the vectors with the info of the clusters at
526 // the end of a detectors if the track is "good"
529 // Localisation of the detector
530 Int_t detector = cl->GetDetector();
532 // Fill the infos for the previous clusters if not the same
533 // detector anymore or if not the same track
534 if (((detector != fDetectorPreviousTrack) || (!fDetectorAliTRDtrack)) &&
535 (fDetectorPreviousTrack != -1)) {
539 // If the same track, then look if the previous detector is in
540 // the same plane, if yes: not a good track
541 if (fDetectorAliTRDtrack &&
542 (GetPlane(detector) <= GetPlane(fDetectorPreviousTrack))) {
546 // Fill only if the track doesn't touch a masked pad or doesn't
547 // appear in the middle (fGoodTrack)
548 if (fGoodTrack && fGoodTracklet) {
550 // drift velocity unables to cut bad tracklets
551 Bool_t pass = FindP1TrackPH();
555 FillTheInfoOfTheTrackCH();
560 FillTheInfoOfTheTrackPH();
563 if(pass && fPRF2dOn) HandlePRF();
570 } // Fill at the end the charge
572 // Calcul the position of the detector
573 if (detector != fDetectorPreviousTrack) {
574 LocalisationDetectorXbins(detector);
577 // Reset the detector
578 fDetectorPreviousTrack = detector;
579 fDetectorAliTRDtrack = kTRUE;
581 // Store the infos of the tracklets
582 AliTRDcluster *kcl = new AliTRDcluster(*cl);
583 fListClusters->Add((TObject *)kcl);
584 Int_t time = cl->GetLocalTimeBin();
585 fPar0[time] = t->GetY();
586 fPar1[time] = t->GetZ();
587 fPar2[time] = t->GetSnp();
588 fPar3[time] = t->GetTgl();
589 fPar4[time] = t->Get1Pt();
591 // Store the info bis of the tracklet
592 Int_t *rowcol = CalculateRowCol(cl);
593 CheckGoodTracklet(detector,rowcol);
594 Int_t group[2] = {0,0};
595 if(fCH2dOn) group[0] = CalculateCalibrationGroup(0,rowcol);
596 if(fPH2dOn) group[1] = CalculateCalibrationGroup(1,rowcol);
597 StoreInfoCHPH(cl,t,group);
602 //____________Online trackling in AliTRDtrigger________________________________
603 Bool_t AliTRDCalibraFillHisto::UpdateHistogramcm(AliTRDmcmTracklet *trk)
607 // This function will be called in the function AliTRDtrigger::TestTracklet
608 // before applying the pt cut on the tracklets
609 // Fill the infos for the tracklets fTrkTest if the tracklets is "good"
612 // Localisation of the Xbins involved
613 Int_t idect = trk->GetDetector();
614 LocalisationDetectorXbins(idect);
616 // Get the parameter object
617 AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
619 AliInfo("Could not get calibDB");
626 // Row of the tracklet and position in the pad groups
627 Int_t *rowcol = new Int_t[2];
628 rowcol[0] = trk->GetRow();
629 Int_t group[3] = {-1,-1,-1};
631 // Eventuelle correction due to track angle in z direction
632 Float_t correction = 1.0;
633 if (fMcmCorrectAngle) {
634 Float_t z = trk->GetRowz();
635 Float_t r = trk->GetTime0();
636 correction = r / TMath::Sqrt((r*r+z*z));
639 // Boucle sur les clusters
640 // Condition on number of cluster: don't come from the middle of the detector
641 if (trk->GetNclusters() >= fNumberClusters) {
643 for (Int_t icl = 0; icl < trk->GetNclusters(); icl++) {
645 Float_t amp[3] = { 0.0, 0.0, 0.0 };
646 Int_t time = trk->GetClusterTime(icl);
647 rowcol[1] = trk->GetClusterCol(icl);
649 amp[0] = trk->GetClusterADC(icl)[0] * correction;
650 amp[1] = trk->GetClusterADC(icl)[1] * correction;
651 amp[2] = trk->GetClusterADC(icl)[2] * correction;
654 if ((amp[0] < 0.0) ||
660 // Col of cluster and position in the pad groups
662 group[0] = CalculateCalibrationGroup(0,rowcol);
663 fAmpTotal[(Int_t) group[0]] += (Float_t) (amp[0]+amp[1]+amp[2]);
666 group[1] = CalculateCalibrationGroup(1,rowcol);
667 fPHPlace[time] = group[1];
668 fPHValue[time] = (Float_t) (amp[0]+amp[1]+amp[2]);
670 if(fPRF2dOn) group[2] = CalculateCalibrationGroup(2,rowcol);
672 // See if we are not near a masked pad fGoodTracklet
673 CheckGoodTracklet(idect,rowcol);
675 // Fill PRF direct without tnp bins...only for monitoring...
676 if (fPRF2dOn && fGoodTracklet) {
678 if ((amp[0] > fThresholdClusterPRF2) &&
679 (amp[1] > fThresholdClusterPRF2) &&
680 (amp[2] > fThresholdClusterPRF2) &&
681 ((amp[0]*amp[2]/(amp[1]*amp[1])) < 0.06)) {
683 // Security of the denomiateur is 0
684 if ((((Float_t) (((Float_t) amp[1]) * ((Float_t) amp[1])))
685 / ((Float_t) (((Float_t) amp[0]) * ((Float_t) amp[2])))) != 1.0) {
686 Float_t xcenter = 0.5 * (TMath::Log(amp[2] / amp[0]))
687 / (TMath::Log((amp[1]*amp[1]) / (amp[0]*amp[2])));
688 Float_t ycenter = amp[1] / (amp[0] + amp[1] + amp[2]);
690 if (TMath::Abs(xcenter) < 0.5) {
691 Float_t yminus = amp[0] / (amp[0]+amp[1]+amp[2]);
692 Float_t ymax = amp[2] / (amp[0]+amp[1]+amp[2]);
693 // Fill only if it is in the drift region!
694 if (((Float_t) time / fSf) > 0.3) {
696 fPRF2d->Fill(xcenter,(fCalibraMode->GetXbins(2)+group[2]+0.5),ycenter);
697 fPRF2d->Fill(-(xcenter+1.0),(fCalibraMode->GetXbins(2)+group[2]+0.5),yminus);
698 fPRF2d->Fill((1.0-xcenter),(fCalibraMode->GetXbins(2)+group[2]+0.5),ymax);
701 fCalibraVector->UpdateVectorPRF(fCalibraMode->GetXbins(2)+group[2],xcenter,ycenter);
702 fCalibraVector->UpdateVectorPRF(fCalibraMode->GetXbins(2)+group[2],-(xcenter+1.0),yminus);
703 fCalibraVector->UpdateVectorPRF(fCalibraMode->GetXbins(2)+group[2],(1.0-xcenter),ymax);
705 }//in the drift region
707 }//denominateur security
708 }//cluster shape and thresholds
715 if (fCH2dOn) FillTheInfoOfTheTrackCH();
716 if (fPH2dOn) FillTheInfoOfTheTrackPH();
721 } // Condition on number of clusters
726 //_____________________________________________________________________________
727 Int_t *AliTRDCalibraFillHisto::CalculateRowCol(AliTRDcluster *cl) const
730 // Calculate the row and col number of the cluster
734 Int_t *rowcol = new Int_t[2];
738 // Localisation of the detector
739 Int_t detector = cl->GetDetector();
740 Int_t chamber = GetChamber(detector);
741 Int_t plane = GetPlane(detector);
743 // Localisation of the cluster
744 Double_t pos[3] = { 0.0, 0.0, 0.0 };
745 pos[0] = ((AliCluster *)cl)->GetX();
749 // Position of the cluster
750 AliTRDpadPlane *padplane = fGeo->GetPadPlane(plane,chamber);
751 Int_t row = padplane->GetPadRowNumber(pos[2]);
752 //Do not take from here because it was corrected from ExB already....
753 //Double_t offsetz = padplane->GetPadRowOffset(row,pos[2]);
754 //Double_t offsettilt = padplane->GetTiltOffset(offsetz);
755 //Int_t col = padplane->GetPadColNumber(pos[1] + offsettilt,offsetz);
756 //Int_t col = padplane->GetPadColNumber(pos[1]+offsettilt);
757 Int_t col = cl->GetPad();
765 //_____________________________________________________________________________
766 void AliTRDCalibraFillHisto::CheckGoodTracklet(Int_t detector, Int_t *rowcol)
769 // See if we are not near a masked pad
772 Int_t row = rowcol[0];
773 Int_t col = rowcol[1];
775 if (!IsPadOn(detector, col, row)) {
776 fGoodTracklet = kFALSE;
780 if (!IsPadOn(detector, col-1, row)) {
781 fGoodTracklet = kFALSE;
786 if (!IsPadOn(detector, col+1, row)) {
787 fGoodTracklet = kFALSE;
792 //_____________________________________________________________________________
793 Bool_t AliTRDCalibraFillHisto::IsPadOn(Int_t detector, Int_t col, Int_t row) const
796 // Look in the choosen database if the pad is On.
797 // If no the track will be "not good"
800 // Get the parameter object
801 AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
803 AliInfo("Could not get calibDB");
807 if (!cal->IsChamberInstalled(detector) ||
808 cal->IsChamberMasked(detector) ||
809 cal->IsPadMasked(detector,col,row)) {
817 //_____________________________________________________________________________
818 Int_t AliTRDCalibraFillHisto::CalculateCalibrationGroup(Int_t i, Int_t *rowcol) const
821 // Calculate the calibration group number for i
824 // Row of the cluster and position in the pad groups
826 if (fCalibraMode->GetNnZ(i) != 0) {
827 posr = (Int_t) rowcol[0] / fCalibraMode->GetNnZ(i);
831 // Col of the cluster and position in the pad groups
833 if (fCalibraMode->GetNnRphi(i) != 0) {
834 posc = (Int_t) rowcol[1] / fCalibraMode->GetNnRphi(i);
837 return posc*fCalibraMode->GetNfragZ(i)+posr;
840 //____________________________________________________________________________________
841 Int_t AliTRDCalibraFillHisto::CalculateTotalNumberOfBins(Int_t i)
844 // Calculate the total number of calibration groups
848 fCalibraMode->ModePadCalibration(2,i);
849 fCalibraMode->ModePadFragmentation(0,2,0,i);
850 fCalibraMode->SetDetChamb2(i);
851 Ntotal += 6 * 18 * fCalibraMode->GetDetChamb2(i);
852 fCalibraMode->ModePadCalibration(0,i);
853 fCalibraMode->ModePadFragmentation(0,0,0,i);
854 fCalibraMode->SetDetChamb0(i);
855 Ntotal += 6 * 4 * 18 * fCalibraMode->GetDetChamb0(i);
856 AliInfo(Form("Total number of Xbins: %d",Ntotal));
860 //____________Set the pad calibration variables for the detector_______________
861 Bool_t AliTRDCalibraFillHisto::LocalisationDetectorXbins(Int_t detector)
864 // For the detector calcul the first Xbins and set the number of row
865 // and col pads per calibration groups, the number of calibration
866 // groups in the detector.
869 // first Xbins of the detector
871 fCalibraMode->CalculXBins(detector,0);
874 fCalibraMode->CalculXBins(detector,1);
877 fCalibraMode->CalculXBins(detector,2);
880 // fragmentation of idect
881 for (Int_t i = 0; i < 3; i++) {
882 fCalibraMode->ModePadCalibration((Int_t) GetChamber(detector),i);
883 fCalibraMode->ModePadFragmentation((Int_t) GetPlane(detector)
884 , (Int_t) GetChamber(detector)
885 , (Int_t) GetSector(detector),i);
891 //_____________________________________________________________________________
892 void AliTRDCalibraFillHisto::StoreInfoCHPH(AliTRDcluster *cl, AliTRDtrack *t, Int_t *group)
895 // Store the infos in fAmpTotal, fPHPlace and fPHValue
898 // Charge in the cluster
899 Float_t q = TMath::Abs(cl->GetQ());
900 Int_t time = cl->GetLocalTimeBin();
902 // Correction due to the track angle
903 Float_t correction = 1.0;
904 Float_t normalisation = 6.67;
905 if ((q >0) && (t->GetNdedx() > 0)) {
906 correction = t->GetClusterdQdl((t->GetNdedx() - 1)) / (normalisation);
909 // Fill the fAmpTotal with the charge
911 fAmpTotal[(Int_t) group[0]] += correction;
914 // Fill the fPHPlace and value
916 fPHPlace[time] = group[1];
917 fPHValue[time] = correction;
921 //_____________________________________________________________________
922 Bool_t AliTRDCalibraFillHisto::ProcessEventDAQ(AliTRDRawStream *rawStream)
925 // Event Processing loop - AliTRDRawStream
928 Bool_t withInput = kFALSE;
933 for(Int_t k = 0; k < 36; k++){
938 fDetectorPreviousTrack = -1;
941 while (rawStream->Next()) {
943 Int_t idetector = rawStream->GetDet(); // current detector
944 if((fDetectorPreviousTrack != idetector) && (fDetectorPreviousTrack != -1)){
945 if(TMath::Mean(nbtimebin,phvalue)>0.0){
947 for(Int_t k = 0; k < nbtimebin; k++){
948 UpdateDAQ(fDetectorPreviousTrack,0,0,k,phvalue[k],nbtimebin);
955 fDetectorPreviousTrack = idetector;
956 nbtimebin = rawStream->GetNumberOfTimeBins(); // number of time bins read from data
957 Int_t iTimeBin = rawStream->GetTimeBin(); // current time bin
958 //row[iTimeBin] = rawStream->GetRow(); // current row
959 //col[iTimeBin] = rawStream->GetCol(); // current col
960 Int_t *signal = rawStream->GetSignals(); // current ADC signal
962 Int_t fin = TMath::Min(nbtimebin,(iTimeBin+3));
964 for(Int_t itime = iTimeBin; itime < fin; itime++){
965 // should extract baseline here!
966 if(signal[n]>5.0) phvalue[itime] = signal[n];
972 if(fDetectorPreviousTrack != -1){
973 if(TMath::Mean(nbtimebin,phvalue)>0.0){
975 for(Int_t k = 0; k < nbtimebin; k++){
976 UpdateDAQ(fDetectorPreviousTrack,0,0,k,phvalue[k],nbtimebin);
987 //_____________________________________________________________________
988 Bool_t AliTRDCalibraFillHisto::ProcessEventDAQ(AliRawReader *rawReader)
991 // Event processing loop - AliRawReader
995 AliTRDRawStream rawStream(rawReader);
997 rawReader->Select("TRD");
999 return ProcessEventDAQ(&rawStream);
1001 //_________________________________________________________________________
1002 Bool_t AliTRDCalibraFillHisto::ProcessEventDAQ(
1004 eventHeaderStruct *event
1006 eventHeaderStruct* /*event*/
1012 // process date event
1015 AliRawReader *rawReader = new AliRawReaderDate((void*)event);
1016 Bool_t result=ProcessEventDAQ(rawReader);
1020 Fatal("AliTRDCalibraFillHisto", "this class was compiled without DATE");
1025 //____________Online trackling in AliTRDtrigger________________________________
1026 Bool_t AliTRDCalibraFillHisto::UpdateDAQ(Int_t det, Int_t /*row*/, Int_t /*col*/, Int_t timebin, Int_t signal, Int_t nbtimebins)
1030 // Fill a simple average pulse height
1033 // Localisation of the Xbins involved
1034 //LocalisationDetectorXbins(det);
1036 // Row and position in the pad groups
1038 //if (fCalibraMode->GetNnZ(1) != 0) {
1039 // posr = (Int_t) row / fCalibraMode->GetNnZ(1);
1042 // Col of cluster and position in the pad groups
1044 //if (fCalibraMode->GetNnRphi(1) != 0) {
1045 // posc = (Int_t) col / fCalibraMode->GetNnRphi(1);
1048 //fPH2d->Fill((Float_t) timebin/fSf,(fCalibraMode->GetXbins(1)+posc*fCalibraMode->GetNfragZ(1)+posr)+0.5,(Float_t) signal);
1050 ((TProfile2D *)GetPH2d(nbtimebins,fSf,kTRUE))->Fill((Float_t) timebin/fSf,det+0.5,(Float_t) signal);
1055 //____________Functions for plotting the 2D____________________________________
1057 //_____________________________________________________________________________
1058 void AliTRDCalibraFillHisto::Plot2d()
1061 // Plot the 2D histos
1065 TCanvas *cph2d = new TCanvas("cph2d","",50,50,600,800);
1067 fPH2d->Draw("LEGO");
1070 TCanvas *cch2d = new TCanvas("cch2d","",50,50,600,800);
1072 fCH2d->Draw("LEGO");
1075 TCanvas *cPRF2d = new TCanvas("cPRF2d","",50,50,600,800);
1077 fPRF2d->Draw("LEGO");
1081 //_____________________Reset____________________________________________________
1082 //_______________________________________________________________________________
1083 void AliTRDCalibraFillHisto::ResetLinearFitter()
1085 fLinearFitterArray.SetOwner();
1086 fLinearFitterArray.Clear();
1087 fLinearFitterHistoArray.SetOwner();
1088 fLinearFitterHistoArray.Clear();
1090 //____________Write_____________________________________________________
1091 //_____________________________________________________________________
1092 void AliTRDCalibraFillHisto::Write2d(const Char_t *filename, Bool_t append)
1095 // Write infos to file
1099 if ( fDebugStreamer ) {
1100 delete fDebugStreamer;
1101 fDebugStreamer = 0x0;
1104 AliInfo(Form("Numbertrack: %d Numberusedch[0]: %d, Numberusedch[1]: %d Numberusedph[0]: %d, Numberusedph[1]: %d"
1109 ,fNumberUsedPh[1]));
1111 TDirectory *backup = gDirectory;
1117 option = "recreate";
1119 TFile f(filename,option.Data());
1121 TStopwatch stopwatch;
1126 f.WriteTObject(fCH2d);
1130 name += fCalibraMode->GetNz(0);
1132 name += fCalibraMode->GetNrphi(0);
1133 TTree *treeCH2d = fCalibraVector->ConvertVectorCTTreeHisto(fCalibraVector->GetVectorCH(),fCalibraVector->GetPlaCH(),"treeCH2d",(const char *) name);
1134 f.WriteTObject(treeCH2d);
1139 f.WriteTObject(fPH2d);
1143 name += fCalibraMode->GetNz(1);
1145 name += fCalibraMode->GetNrphi(1);
1146 TTree *treePH2d = fCalibraVector->ConvertVectorPTreeHisto(fCalibraVector->GetVectorPH(),fCalibraVector->GetPlaPH(),"treePH2d",(const char *) name);
1147 f.WriteTObject(treePH2d);
1152 f.WriteTObject(fPRF2d);
1156 name += fCalibraMode->GetNz(2);
1158 name += fCalibraMode->GetNrphi(2);
1161 TTree *treePRF2d = fCalibraVector->ConvertVectorPTreeHisto(fCalibraVector->GetVectorPRF(),fCalibraVector->GetPlaPRF(),"treePRF2d",(const char *) name);
1162 f.WriteTObject(treePRF2d);
1165 if(fLinearFitterOn && fLinearFitterDebugOn){
1166 f.WriteTObject(&fLinearFitterHistoArray);
1171 if ( backup ) backup->cd();
1173 AliInfo(Form("Execution time Write2d: R:%.2fs C:%.2fs"
1174 ,stopwatch.RealTime(),stopwatch.CpuTime()));
1176 //___________________________________________probe the histos__________________________________________________
1177 Double_t *AliTRDCalibraFillHisto::StatH(TH2 *h, Int_t i)
1180 // Check the number of stats in h, 0 is TH2I 1 is TProfile2D
1181 // debug mode with 2 for TH2I and 3 for TProfile2D
1182 // It gives a pointer to a Double_t[7] with the info following...
1183 // [0] : number of calibration groups with entries
1184 // [1] : minimal number of entries found
1185 // [2] : calibration group number of the min
1186 // [3] : maximal number of entries found
1187 // [4] : calibration group number of the max
1188 // [5] : mean number of entries found
1189 // [6] : mean relativ error
1192 Double_t *info = new Double_t[7];
1194 // Number of Xbins (detectors or groups of pads)
1195 Int_t nbins = h->GetNbinsY(); //number of calibration groups
1196 Int_t nxbins = h->GetNbinsX(); //number of bins per histo
1199 Double_t nbwe = 0; //number of calibration groups with entries
1200 Double_t minentries = 0; //minimal number of entries found
1201 Double_t maxentries = 0; //maximal number of entries found
1202 Double_t placemin = 0; //calibration group number of the min
1203 Double_t placemax = -1; //calibration group number of the max
1204 Double_t meanstats = 0.0; //mean number of entries over the calibration group with at least ome entry
1205 Double_t meanrelativerror = 0.0; //mean relativ error in the TProfile2D
1207 Double_t counter = 0;
1210 TH1F *NbEntries = 0x0;//distribution of the number of entries
1211 TH1F *NbEntriesPerGroup = 0x0;//Number of entries per group
1212 TProfile *NbEntriesPerSp = 0x0;//Number of entries for one supermodule
1214 // Beginning of the loop over the calibration groups
1215 for (Int_t idect = 0; idect < nbins; idect++) {
1217 TH1I *projch = (TH1I *) h->ProjectionX("projch",idect+1,idect+1,(Option_t *)"e");
1218 projch->SetDirectory(0);
1220 // Number of entries for this calibration group
1221 Double_t nentries = 0.0;
1223 for (Int_t k = 0; k < nxbins; k++) {
1224 nentries += h->GetBinContent(h->GetBin(k+1,idect+1));
1228 for (Int_t k = 0; k < nxbins; k++) {
1229 nentries += ((TProfile2D *)h)->GetBinEntries(h->GetBin(k+1,idect+1));
1230 if(h->GetBinContent(h->GetBin(k+1,idect+1)) != 0) {
1231 meanrelativerror += (h->GetBinError(h->GetBin(k+1,idect+1))/(TMath::Abs(h->GetBinContent(h->GetBin(k+1,idect+1)))));
1239 if((!((Bool_t)NbEntries)) && (nentries > 0)){
1240 NbEntries = new TH1F("Number of entries","Number of entries"
1241 ,100,(Int_t)nentries/2,nentries*2);
1242 NbEntries->SetDirectory(0);
1243 NbEntriesPerGroup = new TH1F("Number of entries per group","Number of entries per group"
1245 NbEntriesPerGroup->SetDirectory(0);
1246 NbEntriesPerSp = new TProfile("Number of entries per supermodule","Number of entries per supermodule"
1247 ,(Int_t)(nbins/18),0,(Int_t)(nbins/18));
1248 NbEntriesPerSp->SetDirectory(0);
1251 if(nentries > 0) NbEntries->Fill(nentries);
1252 NbEntriesPerGroup->Fill(idect+0.5,nentries);
1253 NbEntriesPerSp->Fill((idect%((Int_t)(nbins/18)))+0.5,nentries);
1258 if(nentries > maxentries){
1259 maxentries = nentries;
1263 minentries = nentries;
1265 if(nentries < minentries){
1266 minentries = nentries;
1272 meanstats += nentries;
1274 }//calibration groups loop
1276 if(nbwe > 0) meanstats /= nbwe;
1277 if(counter > 0) meanrelativerror /= counter;
1279 AliInfo(Form("There are %f calibration groups with entries",nbwe));
1280 AliInfo(Form("The minimum number of entries is %f for the group %f",minentries,placemin));
1281 AliInfo(Form("The maximum number of entries is %f for the group %f",maxentries,placemax));
1282 AliInfo(Form("The mean number of entries is %f",meanstats));
1283 if((i%2) == 1) AliInfo(Form("The mean relative error is %f",meanrelativerror));
1286 info[1] = minentries;
1288 info[3] = maxentries;
1290 info[5] = meanstats;
1291 info[6] = meanrelativerror;
1294 gStyle->SetPalette(1);
1295 gStyle->SetOptStat(1111);
1296 gStyle->SetPadBorderMode(0);
1297 gStyle->SetCanvasColor(10);
1298 gStyle->SetPadLeftMargin(0.13);
1299 gStyle->SetPadRightMargin(0.01);
1300 TCanvas *stat = new TCanvas("stat","",50,50,600,800);
1303 NbEntries->Draw("");
1305 NbEntriesPerSp->SetStats(0);
1306 NbEntriesPerSp->Draw("");
1307 TCanvas *stat1 = new TCanvas("stat1","",50,50,600,800);
1309 NbEntriesPerGroup->SetStats(0);
1310 NbEntriesPerGroup->Draw("");
1316 //____________________________________________________________________________
1317 Double_t *AliTRDCalibraFillHisto::GetMeanMedianRMSNumberCH()
1320 // Return a Int_t[4] with:
1321 // 0 Mean number of entries
1322 // 1 median of number of entries
1323 // 2 rms of number of entries
1324 // 3 number of group with entries
1327 Double_t *stat = new Double_t[4];
1330 Int_t nbofgroups = CalculateTotalNumberOfBins(0);
1331 Double_t *weight = new Double_t[nbofgroups];
1332 Int_t *nonul = new Int_t[nbofgroups];
1334 for(Int_t k = 0; k < nbofgroups; k++){
1335 if(fEntriesCH[k] > 0) {
1337 nonul[(Int_t)stat[3]] = fEntriesCH[k];
1340 else weight[k] = 0.0;
1342 stat[0] = TMath::Mean(nbofgroups,fEntriesCH,weight);
1343 stat[1] = TMath::Median(nbofgroups,fEntriesCH,weight);
1344 stat[2] = TMath::RMS((Int_t)stat[3],nonul);
1349 //____________________________________________________________________________
1350 Double_t *AliTRDCalibraFillHisto::GetMeanMedianRMSNumberLinearFitter() const
1353 // Return a Int_t[4] with:
1354 // 0 Mean number of entries
1355 // 1 median of number of entries
1356 // 2 rms of number of entries
1357 // 3 number of group with entries
1360 Double_t *stat = new Double_t[4];
1363 Int_t nbofgroups = 540;
1364 Double_t *weight = new Double_t[nbofgroups];
1365 Int_t *nonul = new Int_t[nbofgroups];
1367 for(Int_t k = 0; k < nbofgroups; k++){
1368 if(fEntriesLinearFitter[k] > 0) {
1370 nonul[(Int_t) stat[3]] = fEntriesLinearFitter[k];
1373 else weight[k] = 0.0;
1375 stat[0] = TMath::Mean(nbofgroups,fEntriesLinearFitter,weight);
1376 stat[1] = TMath::Median(nbofgroups,fEntriesLinearFitter,weight);
1377 stat[2] = TMath::RMS((Int_t)stat[3],nonul);
1382 //_____________________________________________________________________________
1383 void AliTRDCalibraFillHisto::SetNumberGroupsPRF(Short_t numberGroupsPRF)
1386 // Should be between 0 and 6
1389 if ((numberGroupsPRF < 0) || (numberGroupsPRF > 6)) {
1390 AliInfo("The number of groups must be between 0 and 6!");
1393 fNgroupprf = numberGroupsPRF;
1397 //_____________________________________________________________________________
1398 void AliTRDCalibraFillHisto::SetRelativeScale(Float_t RelativeScale)
1401 // Set the factor that will divide the deposited charge
1402 // to fit in the histo range [0,300]
1405 if (RelativeScale > 0.0) {
1406 fRelativeScale = RelativeScale;
1409 AliInfo("RelativeScale must be strict positif!");
1414 //_____________________________________________________________________________
1415 void AliTRDCalibraFillHisto::SetNz(Int_t i, Short_t Nz)
1418 // Set the mode of calibration group in the z direction for the parameter i
1423 fCalibraMode->SetNz(i, Nz);
1426 AliInfo("You have to choose between 0 and 4");
1431 //_____________________________________________________________________________
1432 void AliTRDCalibraFillHisto::SetNrphi(Int_t i, Short_t Nrphi)
1435 // Set the mode of calibration group in the rphi direction for the parameter i
1440 fCalibraMode->SetNrphi(i ,Nrphi);
1443 AliInfo("You have to choose between 0 and 6");
1447 //____________Protected Functions______________________________________________
1448 //____________Create the 2D histo to be filled online__________________________
1450 //_____________________________________________________________________________
1451 void AliTRDCalibraFillHisto::CreatePRF2d(Int_t nn)
1454 // Create the 2D histos: here we have 2*fNgroupprf bins in tnp of 0.2 amplitude each
1455 // If fNgroupprf is zero then no binning in tnp
1459 name += fCalibraMode->GetNz(2);
1461 name += fCalibraMode->GetNrphi(2);
1465 if(fNgroupprf != 0){
1467 fPRF2d = new TProfile2D("PRF2d",(const Char_t *) name
1468 ,2*fNgroupprf*fNumberBinPRF,-3.0*fNgroupprf,3.0*fNgroupprf,nn,0,nn);
1469 fPRF2d->SetYTitle("Det/pad groups");
1470 fPRF2d->SetXTitle("Position x/W [pad width units]");
1471 fPRF2d->SetZTitle("Q_{i}/Q_{total}");
1472 fPRF2d->SetStats(0);
1475 fPRF2d = new TProfile2D("PRF2d",(const Char_t *) name
1476 ,fNumberBinPRF,-1.5,1.5,nn,0,nn);
1477 fPRF2d->SetYTitle("Det/pad groups");
1478 fPRF2d->SetXTitle("Position x/W [pad width units]");
1479 fPRF2d->SetZTitle("Q_{i}/Q_{total}");
1480 fPRF2d->SetStats(0);
1485 //_____________________________________________________________________________
1486 void AliTRDCalibraFillHisto::CreatePH2d(Int_t nn)
1489 // Create the 2D histos
1493 name += fCalibraMode->GetNz(1);
1495 name += fCalibraMode->GetNrphi(1);
1497 fPH2d = new TProfile2D("PH2d",(const Char_t *) name
1498 ,fTimeMax,-0.5/fSf,(Float_t) (fTimeMax-0.5)/fSf
1500 fPH2d->SetYTitle("Det/pad groups");
1501 fPH2d->SetXTitle("time [#mus]");
1502 fPH2d->SetZTitle("<PH> [a.u.]");
1507 //_____________________________________________________________________________
1508 void AliTRDCalibraFillHisto::CreateCH2d(Int_t nn)
1511 // Create the 2D histos
1515 name += fCalibraMode->GetNz(0);
1517 name += fCalibraMode->GetNrphi(0);
1519 fCH2d = new TH2I("CH2d",(const Char_t *) name
1520 ,fNumberBinCharge,0,300,nn,0,nn);
1521 fCH2d->SetYTitle("Det/pad groups");
1522 fCH2d->SetXTitle("charge deposit [a.u]");
1523 fCH2d->SetZTitle("counts");
1528 //____________Offine tracking in the AliTRDtracker_____________________________
1529 void AliTRDCalibraFillHisto::FillTheInfoOfTheTrackCH()
1532 // For the offline tracking or mcm tracklets
1533 // This function will be called in the functions UpdateHistogram...
1534 // to fill the info of a track for the relativ gain calibration
1537 Int_t nb = 0; // Nombre de zones traversees
1538 Int_t fd = -1; // Premiere zone non nulle
1539 Float_t totalcharge = 0.0; // Total charge for the supermodule histo
1542 // See if the track goes through different zones
1543 for (Int_t k = 0; k < fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0); k++) {
1544 if (fAmpTotal[k] > 0.0) {
1545 totalcharge += fAmpTotal[k];
1558 fEntriesCH[fCalibraMode->GetXbins(0)+fd]++;
1560 FillCH2d(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1561 //fCH2d->Fill(fAmpTotal[fd]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+0.5);
1564 fCalibraVector->UpdateVectorCH(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1568 if ((fAmpTotal[fd] > 0.0) &&
1569 (fAmpTotal[fd+1] > 0.0)) {
1570 // One of the two very big
1571 if (fAmpTotal[fd] > fProcent*fAmpTotal[fd+1]) {
1573 FillCH2d(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1574 //fCH2d->Fill(fAmpTotal[fd]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+0.5);
1577 fCalibraVector->UpdateVectorCH(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1580 fEntriesCH[fCalibraMode->GetXbins(0)+fd]++;
1582 if (fAmpTotal[fd+1] > fProcent*fAmpTotal[fd]) {
1584 FillCH2d(fCalibraMode->GetXbins(0)+fd+1,fAmpTotal[fd+1]/fRelativeScale);
1585 //fCH2d->Fill(fAmpTotal[fd+1]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+1.5);
1588 fCalibraVector->UpdateVectorCH(fCalibraMode->GetXbins(0)+fd+1,fAmpTotal[fd+1]/fRelativeScale);
1591 fEntriesCH[fCalibraMode->GetXbins(0)+fd+1]++;
1594 if (fCalibraMode->GetNfragZ(0) > 1) {
1595 if (fAmpTotal[fd] > 0.0) {
1596 if ((fd+fCalibraMode->GetNfragZ(0)) < (fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0))) {
1597 if (fAmpTotal[fd+fCalibraMode->GetNfragZ(0)] > 0.0) {
1598 // One of the two very big
1599 if (fAmpTotal[fd] > fProcent*fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]) {
1601 FillCH2d(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1602 //fCH2d->Fill(fAmpTotal[fd]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+0.5);
1605 fCalibraVector->UpdateVectorCH(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1608 fEntriesCH[fCalibraMode->GetXbins(0)+fd]++;
1610 if (fAmpTotal[fd+fCalibraMode->GetNfragZ(0)] > fProcent*fAmpTotal[fd]) {
1612 FillCH2d(fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0),fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/fRelativeScale);
1613 //fCH2d->Fill(fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0)+0.5);
1616 fEntriesCH[fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0)]++;
1618 fCalibraVector->UpdateVectorCH(fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0),fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/fRelativeScale);
1629 //____________Offine tracking in the AliTRDtracker_____________________________
1630 void AliTRDCalibraFillHisto::FillTheInfoOfTheTrackPH()
1633 // For the offline tracking or mcm tracklets
1634 // This function will be called in the functions UpdateHistogram...
1635 // to fill the info of a track for the drift velocity calibration
1638 Int_t nb = 1; // Nombre de zones traversees 1, 2 ou plus de 3
1639 Int_t fd1 = -1; // Premiere zone non nulle
1640 Int_t fd2 = -1; // Deuxieme zone non nulle
1641 Int_t k1 = -1; // Debut de la premiere zone
1642 Int_t k2 = -1; // Debut de la seconde zone
1644 // See if the track goes through different zones
1645 for (Int_t k = 0; k < fTimeMax; k++) {
1646 if (fPHValue[k] > 0.0) {
1651 if (fPHPlace[k] != fd1) {
1657 if (fPHPlace[k] != fd2) {
1668 for (Int_t i = 0; i < fTimeMax; i++) {
1670 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1673 fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd1),i,fPHValue[i]);
1678 if ((fd1 == fd2+1) ||
1680 // One of the two fast all the think
1681 if (k2 > (k1+fDifference)) {
1682 //we choose to fill the fd1 with all the values
1684 for (Int_t i = 0; i < fTimeMax; i++) {
1686 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1689 fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd1),i,fPHValue[i]);
1693 if ((k2+fDifference) < fTimeMax) {
1694 //we choose to fill the fd2 with all the values
1696 for (Int_t i = 0; i < fTimeMax; i++) {
1698 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
1701 fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd2),i,fPHValue[i]);
1706 // Two zones voisines sinon rien!
1707 if (fCalibraMode->GetNfragZ(1) > 1) {
1709 if ((fd1+fCalibraMode->GetNfragZ(1)) < (fCalibraMode->GetNfragZ(1)*fCalibraMode->GetNfragRphi(1))) {
1710 if (fd2 == (fd1+fCalibraMode->GetNfragZ(1))) {
1711 // One of the two fast all the think
1712 if (k2 > (k1+fDifference)) {
1713 //we choose to fill the fd1 with all the values
1715 for (Int_t i = 0; i < fTimeMax; i++) {
1717 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1720 fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd1),i,fPHValue[i]);
1724 if ((k2+fDifference) < fTimeMax) {
1725 //we choose to fill the fd2 with all the values
1727 for (Int_t i = 0; i < fTimeMax; i++) {
1729 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
1732 fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd2),i,fPHValue[i]);
1738 // Two zones voisines sinon rien!
1740 if ((fd1 - fCalibraMode->GetNfragZ(1)) >= 0) {
1741 if (fd2 == (fd1 - fCalibraMode->GetNfragZ(1))) {
1742 // One of the two fast all the think
1743 if (k2 > (k1 + fDifference)) {
1744 //we choose to fill the fd1 with all the values
1746 for (Int_t i = 0; i < fTimeMax; i++) {
1748 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1751 fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd1),i,fPHValue[i]);
1755 if ((k2+fDifference) < fTimeMax) {
1756 //we choose to fill the fd2 with all the values
1758 for (Int_t i = 0; i < fTimeMax; i++) {
1760 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
1763 fCalibraVector->UpdateVectorPH((fCalibraMode->GetXbins(1)+fd2),i,fPHValue[i]);
1774 //____________Offine tracking in the AliTRDtracker_____________________________
1775 Bool_t AliTRDCalibraFillHisto::FindP1TrackPH()
1778 // For the offline tracking
1779 // This function will be called in the functions UpdateHistogram...
1780 // to fill the find the parameter P1 of a track for the drift velocity calibration
1783 //Number of points: if less than 3 return kFALSE
1784 Int_t Npoints = fListClusters->GetEntriesFast();
1785 if(Npoints <= 2) return kFALSE;
1788 TLinearFitter linearFitterTracklet = TLinearFitter(2,"pol1"); // TLinearFitter per tracklet
1789 Double_t snp = 0.0; // sin angle in the plan yx track
1790 Double_t y = 0.0; // y clusters in the middle of the chamber
1791 Double_t z = 0.0; // z cluster in the middle of the chamber
1792 Double_t dydt = 0.0; // dydt tracklet after straight line fit
1793 Double_t tnp = 0.0; // tan angle in the plan xy track
1794 Double_t tgl = 0.0; // dz/dl and not dz/dx!
1795 Double_t errorpar = 0.0; // error after straight line fit on dy/dt
1796 Double_t pointError = 0.0; // error after straight line fit
1797 Int_t detector = ((AliTRDcluster *) fListClusters->At(0))->GetDetector(); //detector
1798 Int_t snpright = 1; // if we took in the middle snp
1799 Int_t crossrow = 0; // if it crosses a pad row
1800 Double_t tiltingangle = 0; // tiltingangle of the pad
1801 Float_t dzdx = 0; // dz/dx now from dz/dl
1802 Int_t nbli = 0; // number linear fitter points
1803 AliTRDpadPlane *padplane = fGeo->GetPadPlane(GetPlane(detector),GetChamber(detector));
1805 linearFitterTracklet.StoreData(kFALSE);
1806 linearFitterTracklet.ClearPoints();
1808 //if more than one row
1809 Int_t rowp = -1; // if it crosses a pad row
1812 tiltingangle = padplane->GetTiltingAngle();
1813 Float_t tnt = TMath::Tan(tiltingangle/180.*TMath::Pi()); // tan tiltingangle
1816 for(Int_t k = 0; k < Npoints; k++){
1818 AliTRDcluster *cl = (AliTRDcluster *) fListClusters->At(k);
1819 Double_t ycluster = cl->GetY();
1820 Int_t time = cl->GetLocalTimeBin();
1821 Double_t timeis = time/fSf;
1822 //See if cross two pad rows
1823 Int_t row = padplane->GetPadRowNumber(cl->GetZ());
1824 if(k==0) rowp = row;
1825 if(row != rowp) crossrow = 1;
1826 //Take in the middle of the chamber
1827 if(time > (Int_t) 10) {
1833 linearFitterTracklet.AddPoint(&timeis,ycluster,1);
1836 if(((AliTRDcluster *) fListClusters->At(0))->GetLocalTimeBin() <= 10) snpright = 0;
1837 if(nbli <= 2) return kFALSE;
1839 // Do the straight line fit now
1841 linearFitterTracklet.Eval();
1842 linearFitterTracklet.GetParameters(pars);
1843 pointError = TMath::Sqrt(linearFitterTracklet.GetChisquare()/nbli);
1844 errorpar = linearFitterTracklet.GetParError(1)*pointError;
1847 if( TMath::Abs(snp) < 1.){
1848 tnp = snp / (TMath::Sqrt(1-(snp*snp)));
1850 dzdx = tgl*TMath::Sqrt(1+tnp*tnp);
1852 if(fDebugLevel > 0){
1853 if ( !fDebugStreamer ) {
1855 TDirectory *backup = gDirectory;
1856 fDebugStreamer = new TTreeSRedirector("TRDdebugCalibra.root");
1857 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
1860 (* fDebugStreamer) << "VDRIFT0"<<
1861 "Npoints="<<Npoints<<
1865 (* fDebugStreamer) << "VDRIFT"<<
1866 "snpright="<<snpright<<
1867 "Npoints="<<Npoints<<
1869 "detector="<<detector<<
1878 "crossrow="<<crossrow<<
1879 "errorpar="<<errorpar<<
1880 "pointError="<<pointError<<
1885 if(Npoints < fNumberClusters) return kFALSE;
1886 if(snpright == 0) return kFALSE;
1887 if(pointError >= 0.1) return kFALSE;
1888 if(crossrow == 1) return kFALSE;
1890 if(fLinearFitterOn){
1891 //Add to the linear fitter of the detector
1892 if( TMath::Abs(snp) < 1.){
1893 Double_t x = tnp-dzdx*tnt;
1894 (GetLinearFitter(detector,kTRUE))->AddPoint(&x,dydt);
1895 if(fLinearFitterDebugOn) {
1896 ((TH2F *) GetLinearFitterHisto(detector,kTRUE))->Fill(tnp,pars[1]);
1898 fEntriesLinearFitter[detector]++;
1901 //AliInfo("End of FindP1TrackPH with success!")
1905 //____________Offine tracking in the AliTRDtracker_____________________________
1906 Bool_t AliTRDCalibraFillHisto::HandlePRF()
1909 // For the offline tracking
1910 // Fit the tracklet with a line and take the position as reference for the PRF
1914 Int_t Npoints = fListClusters->GetEntriesFast(); // number of total points
1915 Int_t Nb3pc = 0; // number of three pads clusters used for fit
1916 Int_t detector = ((AliTRDcluster *) fListClusters->At(0))->GetDetector(); // detector
1919 // To see the difference due to the fit
1920 Double_t *padPositions;
1921 padPositions = new Double_t[Npoints];
1922 for(Int_t k = 0; k < Npoints; k++){
1923 padPositions[k] = 0.0;
1927 //Find the position by a fit
1928 TLinearFitter fitter(2,"pol1");
1929 fitter.StoreData(kFALSE);
1930 fitter.ClearPoints();
1931 for(Int_t k = 0; k < Npoints; k++){
1933 AliTRDcluster *cl = (AliTRDcluster *) fListClusters->At(k);
1934 Short_t *signals = cl->GetSignals();
1935 Double_t time = cl->GetLocalTimeBin();
1936 //Calculate x if possible
1937 Float_t xcenter = 0.0;
1938 Bool_t echec = kTRUE;
1939 if((time<=7) || (time>=21)) continue;
1940 // Center 3 balanced: position with the center of the pad
1941 if ((((Float_t) signals[3]) > 0.0) &&
1942 (((Float_t) signals[2]) > 0.0) &&
1943 (((Float_t) signals[4]) > 0.0)) {
1945 // Security if the denomiateur is 0
1946 if ((((Float_t) (((Float_t) signals[3]) * ((Float_t) signals[3]))) /
1947 ((Float_t) (((Float_t) signals[2]) * ((Float_t) signals[4])))) != 1.0) {
1948 xcenter = 0.5 * (TMath::Log((Float_t) (((Float_t) signals[4]) / ((Float_t) signals[2]))))
1949 / (TMath::Log(((Float_t) (((Float_t) signals[3]) * ((Float_t) signals[3])))
1950 / ((Float_t) (((Float_t) signals[2]) * ((Float_t) signals[4])))));
1956 if(TMath::Abs(xcenter) > 0.5) echec = kTRUE;
1958 //if no echec: calculate with the position of the pad
1959 // Position of the cluster
1960 Double_t padPosition = xcenter + cl->GetPad();
1961 padPositions[k] = padPosition;
1963 fitter.AddPoint(&time, padPosition,1);
1966 //printf("Nb3pc %d, Npoints %d\n",Nb3pc,Npoints);
1967 if(Nb3pc < 3) return kFALSE;
1970 fitter.GetParameters(line);
1971 Float_t pointError = -1.0;
1972 pointError = TMath::Sqrt(fitter.GetChisquare()/Nb3pc);
1976 for(Int_t k = 0; k < Npoints; k++){
1978 AliTRDcluster *cl = (AliTRDcluster *) fListClusters->At(k);
1979 Short_t *signals = cl->GetSignals(); // signal
1980 Double_t time = cl->GetLocalTimeBin(); // time bin
1981 Float_t padPosTracklet = line[0]+line[1]*time; // reconstruct position from fit
1982 Float_t padPos = cl->GetPad(); // middle pad
1983 Double_t dpad = padPosTracklet - padPos; // reconstruct position relative to middle pad from fit
1984 Float_t ycenter = 0.0; // relative center charge
1985 Float_t ymin = 0.0; // relative left charge
1986 Float_t ymax = 0.0; // relative right charge
1987 Double_t tgl = fPar3[(Int_t)time]; // dz/dl and not dz/dx
1988 Double_t pt = fPar4[(Int_t)time]; // pt
1989 Float_t dzdx = 0.0; // dzdx
1992 //Requiere simply two pads clusters at least
1993 if(((((Float_t) signals[3]) > 0.0) && (((Float_t) signals[2]) > 0.0)) ||
1994 ((((Float_t) signals[3]) > 0.0) && (((Float_t) signals[4]) > 0.0))){
1995 Float_t sum = ((Float_t) signals[2]) + ((Float_t) signals[3]) + ((Float_t) signals[4]);
1996 if(sum > 0.0) ycenter = ((Float_t) signals[3])/ sum;
1997 if(sum > 0.0) ymin = ((Float_t) signals[2])/ sum;
1998 if(sum > 0.0) ymax = ((Float_t) signals[4])/ sum;
2002 Int_t *rowcol = CalculateRowCol(cl); // calcul col and row pad of the cluster
2003 Int_t grouplocal = CalculateCalibrationGroup(2,rowcol); // calcul the corresponding group
2004 Int_t caligroup = fCalibraMode->GetXbins(2)+ grouplocal; // calcul the corresponidng group
2005 Double_t snp = fPar2[(Int_t)time]; // sin angle in xy plan
2006 Float_t xcl = cl->GetY(); // y cluster
2007 Float_t qcl = cl->GetQ(); // charge cluster
2008 Int_t plane = GetPlane(detector); // plane
2009 Int_t chamber = GetChamber(detector); // chamber
2010 Double_t xdiff = dpad; // reconstructed position constant
2011 Double_t x = dpad; // reconstructed position moved
2012 Float_t Ep = pointError; // error of fit
2013 Float_t signal1 = (Float_t)signals[1]; // signal at the border
2014 Float_t signal3 = (Float_t)signals[3]; // signal
2015 Float_t signal2 = (Float_t)signals[2]; // signal
2016 Float_t signal4 = (Float_t)signals[4]; // signal
2017 Float_t signal5 = (Float_t)signals[5]; // signal at the border
2019 if(TMath::Abs(snp) < 1.0){
2020 tnp = snp / (TMath::Sqrt(1-snp*snp));
2021 dzdx = tgl*TMath::Sqrt(1+tnp*tnp);
2025 if(fDebugLevel > 0){
2026 if ( !fDebugStreamer ) {
2028 TDirectory *backup = gDirectory;
2029 fDebugStreamer = new TTreeSRedirector("TRDdebugCalibra.root");
2030 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
2033 (* fDebugStreamer) << "PRF0"<<
2034 "caligroup="<<caligroup<<
2035 "detector="<<detector<<
2037 "chamber="<<chamber<<
2038 "Npoints="<<Npoints<<
2047 "padPosition="<<padPositions[k]<<
2048 "padPosTracklet="<<padPosTracklet<<
2050 "ycenter="<<ycenter<<
2055 "signal1="<<signal1<<
2056 "signal2="<<signal2<<
2057 "signal3="<<signal3<<
2058 "signal4="<<signal4<<
2059 "signal5="<<signal5<<
2064 Float_t y = ycenter;
2065 (* fDebugStreamer) << "PRFALL"<<
2066 "caligroup="<<caligroup<<
2067 "detector="<<detector<<
2069 "chamber="<<chamber<<
2070 "Npoints="<<Npoints<<
2080 "padPosition="<<padPositions[k]<<
2081 "padPosTracklet="<<padPosTracklet<<
2086 "signal1="<<signal1<<
2087 "signal2="<<signal2<<
2088 "signal3="<<signal3<<
2089 "signal4="<<signal4<<
2090 "signal5="<<signal5<<
2096 (* fDebugStreamer) << "PRFALL"<<
2097 "caligroup="<<caligroup<<
2098 "detector="<<detector<<
2100 "chamber="<<chamber<<
2101 "Npoints="<<Npoints<<
2111 "padPosition="<<padPositions[k]<<
2112 "padPosTracklet="<<padPosTracklet<<
2117 "signal1="<<signal1<<
2118 "signal2="<<signal2<<
2119 "signal3="<<signal3<<
2120 "signal4="<<signal4<<
2121 "signal5="<<signal5<<
2128 (* fDebugStreamer) << "PRFALL"<<
2129 "caligroup="<<caligroup<<
2130 "detector="<<detector<<
2132 "chamber="<<chamber<<
2133 "Npoints="<<Npoints<<
2143 "padPosition="<<padPositions[k]<<
2144 "padPosTracklet="<<padPosTracklet<<
2149 "signal1="<<signal1<<
2150 "signal2="<<signal2<<
2151 "signal3="<<signal3<<
2152 "signal4="<<signal4<<
2153 "signal5="<<signal5<<
2160 if(Npoints < fNumberClusters) continue;
2161 if(Nb3pc <= 5) continue;
2162 if((time >= 21) || (time < 7)) continue;
2163 if(TMath::Abs(snp) >= 1.0) continue;
2164 if(qcl < 80) continue;
2166 Bool_t echec = kFALSE;
2167 Double_t shift = 0.0;
2168 //Calculate the shift in x coresponding to this tnp
2169 if(fNgroupprf != 0.0){
2170 shift = -3.0*(fNgroupprf-1)-1.5;
2171 Double_t limithigh = -0.2*(fNgroupprf-1);
2172 if((tnp < (-0.2*fNgroupprf)) || (tnp > (0.2*fNgroupprf))) echec = kTRUE;
2174 while(tnp > limithigh){
2180 if (fHisto2d && !echec) {
2181 fPRF2d->Fill(shift+dpad,(caligroup+0.5),ycenter);
2183 fPRF2d->Fill(shift-(dpad+1.0),(caligroup+0.5),ymin);
2184 fPRF2d->Fill(shift+(dpad+1.0),(caligroup+0.5),ymin);
2187 fPRF2d->Fill(shift+1.0-dpad,(caligroup+0.5),ymax);
2188 fPRF2d->Fill(shift-1.0+dpad,(caligroup+0.5),ymax);
2191 //Not equivalent anymore here!
2192 if (fVector2d && !echec) {
2193 fCalibraVector->UpdateVectorPRF(caligroup,shift+dpad,ycenter);
2195 fCalibraVector->UpdateVectorPRF(caligroup,shift-(dpad+1.0),ymin);
2196 fCalibraVector->UpdateVectorPRF(caligroup,shift+(dpad+1.0),ymin);
2199 fCalibraVector->UpdateVectorPRF(caligroup,shift+1.0-dpad,ymax);
2200 fCalibraVector->UpdateVectorPRF(caligroup,shift-1.0+dpad,ymax);
2208 //____________Some basic geometry function_____________________________________
2210 //_____________________________________________________________________________
2211 Int_t AliTRDCalibraFillHisto::GetPlane(Int_t d) const
2214 // Reconstruct the plane number from the detector number
2217 return ((Int_t) (d % 6));
2221 //_____________________________________________________________________________
2222 Int_t AliTRDCalibraFillHisto::GetChamber(Int_t d) const
2225 // Reconstruct the chamber number from the detector number
2229 return ((Int_t) (d % 30) / fgkNplan);
2233 //_____________________________________________________________________________
2234 Int_t AliTRDCalibraFillHisto::GetSector(Int_t d) const
2237 // Reconstruct the sector number from the detector number
2241 return ((Int_t) (d / fg));
2244 //_____________________________________________________________________
2245 TProfile2D* AliTRDCalibraFillHisto::GetPH2d(Int_t nbtimebin, Float_t samplefrequency, Bool_t force)
2248 // return pointer to fPH2d TProfile2D
2249 // if force is true create a new TProfile2D if it doesn't exist allready
2251 if ( !force || fPH2d )
2255 fTimeMax = nbtimebin;
2256 fSf = samplefrequency;
2259 AliInfo(Form("The pad calibration mode for the drift velocity calibration: Nz %d, and Nrphi %d"
2260 ,fCalibraMode->GetNz(1)
2261 ,fCalibraMode->GetNrphi(1)));
2263 // Calcul the number of Xbins
2265 fCalibraMode->ModePadCalibration(2,1);
2266 fCalibraMode->ModePadFragmentation(0,2,0,1);
2267 fCalibraMode->SetDetChamb2(1);
2268 Ntotal1 += 6 * 18 * fCalibraMode->GetDetChamb2(1);
2269 fCalibraMode->ModePadCalibration(0,1);
2270 fCalibraMode->ModePadFragmentation(0,0,0,1);
2271 fCalibraMode->SetDetChamb0(1);
2272 Ntotal1 += 6 * 4 * 18 * fCalibraMode->GetDetChamb0(1);
2273 AliInfo(Form("Total number of Xbins: %d",Ntotal1));
2275 CreatePH2d(Ntotal1);
2282 //_____________________________________________________________________
2283 TLinearFitter* AliTRDCalibraFillHisto::GetLinearFitter(Int_t detector, Bool_t force)
2286 // return pointer to TLinearFitter Calibration
2287 // if force is true create a new TLinearFitter if it doesn't exist allready
2289 if ( !force || fLinearFitterArray.UncheckedAt(detector) )
2290 return (TLinearFitter*)fLinearFitterArray.UncheckedAt(detector);
2292 // if we are forced and TLinearFitter doesn't yet exist create it
2294 // new TLinearFitter
2295 TLinearFitter *linearfitter = new TLinearFitter(2,"pol1");
2296 fLinearFitterArray.AddAt(linearfitter,detector);
2297 return linearfitter;
2299 //_____________________________________________________________________
2300 TH2F* AliTRDCalibraFillHisto::GetLinearFitterHisto(Int_t detector, Bool_t force)
2303 // return pointer to TH2F histo
2304 // if force is true create a new histo if it doesn't exist allready
2306 if ( !force || fLinearFitterHistoArray.UncheckedAt(detector) )
2307 return (TH2F*)fLinearFitterHistoArray.UncheckedAt(detector);
2309 // if we are forced and TLinearFitter doesn't yes exist create it
2312 TString name("LFDV");
2315 TH2F *lfdv = new TH2F((const Char_t *)name,(const Char_t *) name
2318 lfdv->SetXTitle("tan(phi_{track})");
2319 lfdv->SetYTitle("dy/dt");
2320 lfdv->SetZTitle("Number of clusters");
2322 lfdv->SetDirectory(0);
2324 fLinearFitterHistoArray.AddAt(lfdv,detector);
2327 //_____________________________________________________________________
2328 void AliTRDCalibraFillHisto::FillCH2d(Int_t x, Float_t y)
2331 // FillCH2d: Marian style
2334 //skip simply the value out of range
2335 if((y>=300.0) || (y<0.0)) return;
2337 //Calcul the y place
2338 Int_t yplace = (Int_t) (fNumberBinCharge*y/300.0)+1;
2339 Int_t place = (fNumberBinCharge+2)*(x+1)+yplace;
2342 fCH2d->GetArray()[place]++;