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>
57 #include "AliCDBManager.h"
59 #include "AliTRDCalibraFillHisto.h"
60 #include "AliTRDCalibraFit.h"
61 #include "AliTRDCalibraMode.h"
62 #include "AliTRDCalibraVector.h"
63 #include "AliTRDCalibraVdriftLinearFit.h"
64 #include "AliTRDcalibDB.h"
65 #include "AliTRDCommonParam.h"
66 #include "AliTRDmcmTracklet.h"
67 #include "AliTRDpadPlane.h"
68 #include "AliTRDcluster.h"
69 #include "AliTRDtrack.h"
70 #include "AliTRDRawStream.h"
71 #include "AliRawReader.h"
72 #include "AliRawReaderDate.h"
73 #include "AliTRDgeometry.h"
80 ClassImp(AliTRDCalibraFillHisto)
82 AliTRDCalibraFillHisto* AliTRDCalibraFillHisto::fgInstance = 0;
83 Bool_t AliTRDCalibraFillHisto::fgTerminated = kFALSE;
85 //_____________singleton implementation_________________________________________________
86 AliTRDCalibraFillHisto *AliTRDCalibraFillHisto::Instance()
89 // Singleton implementation
92 if (fgTerminated != kFALSE) {
96 if (fgInstance == 0) {
97 fgInstance = new AliTRDCalibraFillHisto();
104 //______________________________________________________________________________________
105 void AliTRDCalibraFillHisto::Terminate()
108 // Singleton implementation
109 // Deletes the instance of this class
112 fgTerminated = kTRUE;
114 if (fgInstance != 0) {
121 //______________________________________________________________________________________
122 AliTRDCalibraFillHisto::AliTRDCalibraFillHisto()
126 ,fMcmTracking(kFALSE)
127 ,fMcmCorrectAngle(kFALSE)
133 ,fLinearFitterOn(kFALSE)
134 ,fLinearFitterDebugOn(kFALSE)
136 ,fThresholdClusterPRF2(15.0)
137 ,fCalibraMode(new AliTRDCalibraMode())
140 ,fDetectorAliTRDtrack(kFALSE)
141 ,fDetectorPreviousTrack(-1)
148 ,fNumberBinCharge(100)
151 ,fListClusters(new TObjArray())
160 ,fGoodTracklet(kTRUE)
163 ,fEntriesLinearFitter(0x0)
168 ,fLinearFitterArray(0)
169 ,fLinearVdriftFit(0x0)
172 // Default constructor
176 // Init some default values
179 fNumberUsedCh[0] = 0;
180 fNumberUsedCh[1] = 0;
181 fNumberUsedPh[0] = 0;
182 fNumberUsedPh[1] = 0;
184 fGeo = new AliTRDgeometry();
188 //______________________________________________________________________________________
189 AliTRDCalibraFillHisto::AliTRDCalibraFillHisto(const AliTRDCalibraFillHisto &c)
192 ,fMITracking(c.fMITracking)
193 ,fMcmTracking(c.fMcmTracking)
194 ,fMcmCorrectAngle(c.fMcmCorrectAngle)
197 ,fPRF2dOn(c.fPRF2dOn)
198 ,fHisto2d(c.fHisto2d)
199 ,fVector2d(c.fVector2d)
200 ,fLinearFitterOn(c.fLinearFitterOn)
201 ,fLinearFitterDebugOn(c.fLinearFitterDebugOn)
202 ,fRelativeScale(c.fRelativeScale)
203 ,fThresholdClusterPRF2(c.fThresholdClusterPRF2)
206 ,fDebugLevel(c.fDebugLevel)
207 ,fDetectorAliTRDtrack(c.fDetectorAliTRDtrack)
208 ,fDetectorPreviousTrack(c.fDetectorPreviousTrack)
209 ,fNumberClusters(c.fNumberClusters)
210 ,fProcent(c.fProcent)
211 ,fDifference(c.fDifference)
212 ,fNumberTrack(c.fNumberTrack)
213 ,fTimeMax(c.fTimeMax)
215 ,fNumberBinCharge(c.fNumberBinCharge)
216 ,fNumberBinPRF(c.fNumberBinPRF)
217 ,fNgroupprf(c.fNgroupprf)
218 ,fListClusters(new TObjArray())
227 ,fGoodTracklet(c.fGoodTracklet)
228 ,fGoodTrack(c.fGoodTrack)
230 ,fEntriesLinearFitter(0x0)
235 ,fLinearFitterArray(0)
236 ,fLinearVdriftFit(0x0)
241 if(c.fCalibraMode) fCalibraMode = new AliTRDCalibraMode(*c.fCalibraMode);
242 if(c.fCalibraVector) fCalibraVector = new AliTRDCalibraVector(*c.fCalibraVector);
244 fPH2d = new TProfile2D(*c.fPH2d);
245 fPH2d->SetDirectory(0);
248 fPRF2d = new TProfile2D(*c.fPRF2d);
249 fPRF2d->SetDirectory(0);
252 fCH2d = new TH2I(*c.fCH2d);
253 fCH2d->SetDirectory(0);
255 if(c.fLinearVdriftFit){
256 fLinearVdriftFit = new AliTRDCalibraVdriftLinearFit(*c.fLinearVdriftFit);
262 fGeo = new AliTRDgeometry();
265 //____________________________________________________________________________________
266 AliTRDCalibraFillHisto::~AliTRDCalibraFillHisto()
269 // AliTRDCalibraFillHisto destructor
273 if ( fDebugStreamer ) delete fDebugStreamer;
281 //_____________________________________________________________________________
282 void AliTRDCalibraFillHisto::Destroy()
295 //_____________________________________________________________________________
296 void AliTRDCalibraFillHisto::ClearHistos()
317 //____________Functions for initialising the AliTRDCalibraFillHisto in the code_________
318 Bool_t AliTRDCalibraFillHisto::Init2Dhistos()
321 // For the offline tracking
322 // This function will be called in the function AliReconstruction::Run()
323 // Init the calibration mode (Nz, Nrphi), the 2D histograms if fHisto2d = kTRUE,
328 AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
330 AliInfo("Could not get calibDB");
333 AliTRDCommonParam *parCom = AliTRDCommonParam::Instance();
335 AliInfo("Could not get CommonParam");
340 fTimeMax = cal->GetNumberOfTimeBins();
341 fSf = parCom->GetSamplingFrequency();
344 //Init the tracklet parameters
345 fPar0 = new Double_t[fTimeMax];
346 fPar1 = new Double_t[fTimeMax];
347 fPar2 = new Double_t[fTimeMax];
348 fPar3 = new Double_t[fTimeMax];
349 fPar4 = new Double_t[fTimeMax];
351 for(Int_t k = 0; k < fTimeMax; k++){
359 // Calcul Xbins Chambd0, Chamb2
360 Int_t Ntotal0 = CalculateTotalNumberOfBins(0);
361 Int_t Ntotal1 = CalculateTotalNumberOfBins(1);
362 Int_t Ntotal2 = CalculateTotalNumberOfBins(2);
364 // If vector method On initialised all the stuff
366 fCalibraVector = new AliTRDCalibraVector();
367 fCalibraVector->SetNumberBinCharge(fNumberBinCharge);
368 fCalibraVector->SetTimeMax(fTimeMax);
369 if(fNgroupprf != 0) {
370 fCalibraVector->SetNumberBinPRF(2*fNgroupprf*fNumberBinPRF);
371 fCalibraVector->SetPRFRange((Float_t)(3.0*fNgroupprf));
374 fCalibraVector->SetNumberBinPRF(fNumberBinPRF);
375 fCalibraVector->SetPRFRange(1.5);
377 for(Int_t k = 0; k < 3; k++){
378 fCalibraVector->SetDetCha0(k,fCalibraMode->GetDetChamb0(k));
379 fCalibraVector->SetDetCha2(k,fCalibraMode->GetDetChamb2(k));
381 TString namech("Nz");
382 namech += fCalibraMode->GetNz(0);
384 namech += fCalibraMode->GetNrphi(0);
385 fCalibraVector->SetNameCH((const char* ) namech);
386 TString nameph("Nz");
387 nameph += fCalibraMode->GetNz(1);
389 nameph += fCalibraMode->GetNrphi(1);
390 fCalibraVector->SetNamePH((const char* ) nameph);
391 TString nameprf("Nz");
392 nameprf += fCalibraMode->GetNz(2);
394 nameprf += fCalibraMode->GetNrphi(2);
396 nameprf += fNgroupprf;
397 fCalibraVector->SetNamePRF((const char* ) nameprf);
400 // Create the 2D histos corresponding to the pad groupCalibration mode
403 AliInfo(Form("The pad calibration mode for the relative gain calibration: Nz %d, and Nrphi %d"
404 ,fCalibraMode->GetNz(0)
405 ,fCalibraMode->GetNrphi(0)));
407 // Create the 2D histo
412 fAmpTotal = new Float_t[TMath::Max(fCalibraMode->GetDetChamb2(0),fCalibraMode->GetDetChamb0(0))];
413 for (Int_t k = 0; k < TMath::Max(fCalibraMode->GetDetChamb2(0),fCalibraMode->GetDetChamb0(0)); k++) {
417 fEntriesCH = new Int_t[Ntotal0];
418 for(Int_t k = 0; k < Ntotal0; k++){
425 AliInfo(Form("The pad calibration mode for the drift velocity calibration: Nz %d, and Nrphi %d"
426 ,fCalibraMode->GetNz(1)
427 ,fCalibraMode->GetNrphi(1)));
429 // Create the 2D histo
434 fPHPlace = new Short_t[fTimeMax];
435 for (Int_t k = 0; k < fTimeMax; k++) {
438 fPHValue = new Float_t[fTimeMax];
439 for (Int_t k = 0; k < fTimeMax; k++) {
443 if (fLinearFitterOn) {
444 fLinearFitterArray.Expand(540);
445 fLinearFitterArray.SetName("ArrayLinearFitters");
446 fEntriesLinearFitter = new Int_t[540];
447 for(Int_t k = 0; k < 540; k++){
448 fEntriesLinearFitter[k] = 0;
450 fLinearVdriftFit = new AliTRDCalibraVdriftLinearFit();
455 AliInfo(Form("The pad calibration mode for the PRF calibration: Nz %d, and Nrphi %d"
456 ,fCalibraMode->GetNz(2)
457 ,fCalibraMode->GetNrphi(2)));
458 // Create the 2D histo
460 CreatePRF2d(Ntotal2);
468 //____________Functions for filling the histos in the code_____________________
470 //____________Offine tracking in the AliTRDtracker_____________________________
471 Bool_t AliTRDCalibraFillHisto::ResetTrack()
474 // For the offline tracking
475 // This function will be called in the function
476 // AliTRDtracker::FollowBackPropagation() at the beginning
477 // Reset the parameter to know we have a new TRD track
480 fDetectorAliTRDtrack = kFALSE;
485 //____________Offine tracking in the AliTRDtracker_____________________________
486 void AliTRDCalibraFillHisto::ResetfVariables()
489 // Reset values per tracklet
492 // Reset the list of clusters
493 fListClusters->Clear();
495 //Reset the tracklet parameters
496 for(Int_t k = 0; k < fTimeMax; k++){
505 //Reset good tracklet
506 fGoodTracklet = kTRUE;
508 // Reset the fPHValue
510 //Reset the fPHValue and fPHPlace
511 for (Int_t k = 0; k < fTimeMax; k++) {
517 // Reset the fAmpTotal where we put value
519 for (Int_t k = 0; k < fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0); k++) {
525 //____________Offline tracking in the AliTRDtracker____________________________
526 Bool_t AliTRDCalibraFillHisto::UpdateHistograms(AliTRDcluster *cl, AliTRDtrack *t)
529 // For the offline tracking
530 // This function will be called in the function
531 // AliTRDtracker::FollowBackPropagation() in the loop over the clusters
533 // Fill the 2D histos or the vectors with the info of the clusters at
534 // the end of a detectors if the track is "good"
537 // Localisation of the detector
538 Int_t detector = cl->GetDetector();
541 // Fill the infos for the previous clusters if not the same
542 // detector anymore or if not the same track
543 if (((detector != fDetectorPreviousTrack) || (!fDetectorAliTRDtrack)) &&
544 (fDetectorPreviousTrack != -1)) {
548 // If the same track, then look if the previous detector is in
549 // the same plane, if yes: not a good track
551 if (fDetectorAliTRDtrack &&
552 (GetPlane(detector) <= GetPlane(fDetectorPreviousTrack))) {
554 //if (fDetectorAliTRDtrack &&
555 // (GetPlane(detector) >= GetPlane(fDetectorPreviousTrack))) {
559 // Fill only if the track doesn't touch a masked pad or doesn't
560 // appear in the middle (fGoodTrack)
561 if (fGoodTrack && fGoodTracklet) {
563 // drift velocity unables to cut bad tracklets
564 Bool_t pass = FindP1TrackPH();
568 FillTheInfoOfTheTrackCH();
573 FillTheInfoOfTheTrackPH();
576 if(pass && fPRF2dOn) HandlePRF();
583 } // Fill at the end the charge
585 // Calcul the position of the detector
586 if (detector != fDetectorPreviousTrack) {
587 LocalisationDetectorXbins(detector);
590 // Reset the detector
591 fDetectorPreviousTrack = detector;
592 fDetectorAliTRDtrack = kTRUE;
594 // Store the infos of the tracklets
595 AliTRDcluster *kcl = new AliTRDcluster(*cl);
596 fListClusters->Add((TObject *)kcl);
597 Int_t time = cl->GetLocalTimeBin();
598 fPar0[time] = t->GetY();
599 fPar1[time] = t->GetZ();
600 fPar2[time] = t->GetSnp();
601 fPar3[time] = t->GetTgl();
602 fPar4[time] = t->Get1Pt();
604 // Store the info bis of the tracklet
605 Int_t *rowcol = CalculateRowCol(cl);
606 CheckGoodTracklet(detector,rowcol);
607 Int_t group[2] = {0,0};
608 if(fCH2dOn) group[0] = CalculateCalibrationGroup(0,rowcol);
609 if(fPH2dOn) group[1] = CalculateCalibrationGroup(1,rowcol);
610 StoreInfoCHPH(cl,t,group);
615 //____________Online trackling in AliTRDtrigger________________________________
616 Bool_t AliTRDCalibraFillHisto::UpdateHistogramcm(AliTRDmcmTracklet *trk)
620 // This function will be called in the function AliTRDtrigger::TestTracklet
621 // before applying the pt cut on the tracklets
622 // Fill the infos for the tracklets fTrkTest if the tracklets is "good"
625 // Localisation of the Xbins involved
626 Int_t idect = trk->GetDetector();
627 fDetectorPreviousTrack = idect;
628 LocalisationDetectorXbins(idect);
630 // Get the parameter object
631 AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
633 AliInfo("Could not get calibDB");
640 // Row of the tracklet and position in the pad groups
641 Int_t *rowcol = new Int_t[2];
642 rowcol[0] = trk->GetRow();
643 Int_t group[3] = {-1,-1,-1};
645 // Eventuelle correction due to track angle in z direction
646 Float_t correction = 1.0;
647 if (fMcmCorrectAngle) {
648 Float_t z = trk->GetRowz();
649 Float_t r = trk->GetTime0();
650 correction = r / TMath::Sqrt((r*r+z*z));
653 // Boucle sur les clusters
654 // Condition on number of cluster: don't come from the middle of the detector
655 if (trk->GetNclusters() >= fNumberClusters) {
657 for (Int_t icl = 0; icl < trk->GetNclusters(); icl++) {
659 Float_t amp[3] = { 0.0, 0.0, 0.0 };
660 Int_t time = trk->GetClusterTime(icl);
661 rowcol[1] = trk->GetClusterCol(icl);
663 amp[0] = trk->GetClusterADC(icl)[0] * correction;
664 amp[1] = trk->GetClusterADC(icl)[1] * correction;
665 amp[2] = trk->GetClusterADC(icl)[2] * correction;
668 if ((amp[0] < 0.0) ||
674 // Col of cluster and position in the pad groups
676 group[0] = CalculateCalibrationGroup(0,rowcol);
677 fAmpTotal[(Int_t) group[0]] += (Float_t) (amp[0]+amp[1]+amp[2]);
680 group[1] = CalculateCalibrationGroup(1,rowcol);
681 fPHPlace[time] = group[1];
682 fPHValue[time] = (Float_t) (amp[0]+amp[1]+amp[2]);
684 if(fPRF2dOn) group[2] = CalculateCalibrationGroup(2,rowcol);
686 // See if we are not near a masked pad fGoodTracklet
687 CheckGoodTracklet(idect,rowcol);
689 // Fill PRF direct without tnp bins...only for monitoring...
690 if (fPRF2dOn && fGoodTracklet) {
692 if ((amp[0] > fThresholdClusterPRF2) &&
693 (amp[1] > fThresholdClusterPRF2) &&
694 (amp[2] > fThresholdClusterPRF2) &&
695 ((amp[0]*amp[2]/(amp[1]*amp[1])) < 0.06)) {
697 // Security of the denomiateur is 0
698 if ((((Float_t) (((Float_t) amp[1]) * ((Float_t) amp[1])))
699 / ((Float_t) (((Float_t) amp[0]) * ((Float_t) amp[2])))) != 1.0) {
700 Float_t xcenter = 0.5 * (TMath::Log(amp[2] / amp[0]))
701 / (TMath::Log((amp[1]*amp[1]) / (amp[0]*amp[2])));
702 Float_t ycenter = amp[1] / (amp[0] + amp[1] + amp[2]);
704 if (TMath::Abs(xcenter) < 0.5) {
705 Float_t yminus = amp[0] / (amp[0]+amp[1]+amp[2]);
706 Float_t ymax = amp[2] / (amp[0]+amp[1]+amp[2]);
707 // Fill only if it is in the drift region!
708 if (((Float_t) time / fSf) > 0.3) {
710 fPRF2d->Fill(xcenter,(fCalibraMode->GetXbins(2)+group[2]+0.5),ycenter);
711 fPRF2d->Fill(-(xcenter+1.0),(fCalibraMode->GetXbins(2)+group[2]+0.5),yminus);
712 fPRF2d->Fill((1.0-xcenter),(fCalibraMode->GetXbins(2)+group[2]+0.5),ymax);
715 fCalibraVector->UpdateVectorPRF(idect,group[2],xcenter,ycenter);
716 fCalibraVector->UpdateVectorPRF(idect,group[2],-(xcenter+1.0),yminus);
717 fCalibraVector->UpdateVectorPRF(idect,group[2],(1.0-xcenter),ymax);
719 }//in the drift region
721 }//denominateur security
722 }//cluster shape and thresholds
729 if (fCH2dOn) FillTheInfoOfTheTrackCH();
730 if (fPH2dOn) FillTheInfoOfTheTrackPH();
735 } // Condition on number of clusters
740 //_____________________________________________________________________________
741 Int_t *AliTRDCalibraFillHisto::CalculateRowCol(AliTRDcluster *cl) const
744 // Calculate the row and col number of the cluster
748 Int_t *rowcol = new Int_t[2];
752 // Localisation of the detector
753 Int_t detector = cl->GetDetector();
754 Int_t chamber = GetChamber(detector);
755 Int_t plane = GetPlane(detector);
757 // Localisation of the cluster
758 Double_t pos[3] = { 0.0, 0.0, 0.0 };
759 pos[0] = ((AliCluster *)cl)->GetX();
763 // Position of the cluster
764 AliTRDpadPlane *padplane = fGeo->GetPadPlane(plane,chamber);
765 Int_t row = padplane->GetPadRowNumber(pos[2]);
766 //Do not take from here because it was corrected from ExB already....
767 //Double_t offsetz = padplane->GetPadRowOffset(row,pos[2]);
768 //Double_t offsettilt = padplane->GetTiltOffset(offsetz);
769 //Int_t col = padplane->GetPadColNumber(pos[1] + offsettilt,offsetz);
770 //Int_t col = padplane->GetPadColNumber(pos[1]+offsettilt);
771 Int_t col = cl->GetPad();
779 //_____________________________________________________________________________
780 void AliTRDCalibraFillHisto::CheckGoodTracklet(Int_t detector, Int_t *rowcol)
783 // See if we are not near a masked pad
786 Int_t row = rowcol[0];
787 Int_t col = rowcol[1];
789 if (!IsPadOn(detector, col, row)) {
790 fGoodTracklet = kFALSE;
794 if (!IsPadOn(detector, col-1, row)) {
795 fGoodTracklet = kFALSE;
800 if (!IsPadOn(detector, col+1, row)) {
801 fGoodTracklet = kFALSE;
806 //_____________________________________________________________________________
807 Bool_t AliTRDCalibraFillHisto::IsPadOn(Int_t detector, Int_t col, Int_t row) const
810 // Look in the choosen database if the pad is On.
811 // If no the track will be "not good"
814 // Get the parameter object
815 AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
817 AliInfo("Could not get calibDB");
821 if (!cal->IsChamberInstalled(detector) ||
822 cal->IsChamberMasked(detector) ||
823 cal->IsPadMasked(detector,col,row)) {
831 //_____________________________________________________________________________
832 Int_t AliTRDCalibraFillHisto::CalculateCalibrationGroup(Int_t i, Int_t *rowcol) const
835 // Calculate the calibration group number for i
838 // Row of the cluster and position in the pad groups
840 if (fCalibraMode->GetNnZ(i) != 0) {
841 posr = (Int_t) rowcol[0] / fCalibraMode->GetNnZ(i);
845 // Col of the cluster and position in the pad groups
847 if (fCalibraMode->GetNnRphi(i) != 0) {
848 posc = (Int_t) rowcol[1] / fCalibraMode->GetNnRphi(i);
851 return posc*fCalibraMode->GetNfragZ(i)+posr;
854 //____________________________________________________________________________________
855 Int_t AliTRDCalibraFillHisto::CalculateTotalNumberOfBins(Int_t i)
858 // Calculate the total number of calibration groups
862 fCalibraMode->ModePadCalibration(2,i);
863 fCalibraMode->ModePadFragmentation(0,2,0,i);
864 fCalibraMode->SetDetChamb2(i);
865 Ntotal += 6 * 18 * fCalibraMode->GetDetChamb2(i);
866 fCalibraMode->ModePadCalibration(0,i);
867 fCalibraMode->ModePadFragmentation(0,0,0,i);
868 fCalibraMode->SetDetChamb0(i);
869 Ntotal += 6 * 4 * 18 * fCalibraMode->GetDetChamb0(i);
870 AliInfo(Form("Total number of Xbins: %d for i %d",Ntotal,i));
874 //____________Set the pad calibration variables for the detector_______________
875 Bool_t AliTRDCalibraFillHisto::LocalisationDetectorXbins(Int_t detector)
878 // For the detector calcul the first Xbins and set the number of row
879 // and col pads per calibration groups, the number of calibration
880 // groups in the detector.
883 // first Xbins of the detector
885 fCalibraMode->CalculXBins(detector,0);
888 fCalibraMode->CalculXBins(detector,1);
891 fCalibraMode->CalculXBins(detector,2);
894 // fragmentation of idect
895 for (Int_t i = 0; i < 3; i++) {
896 fCalibraMode->ModePadCalibration((Int_t) GetChamber(detector),i);
897 fCalibraMode->ModePadFragmentation((Int_t) GetPlane(detector)
898 , (Int_t) GetChamber(detector)
899 , (Int_t) GetSector(detector),i);
905 //_____________________________________________________________________________
906 void AliTRDCalibraFillHisto::StoreInfoCHPH(AliTRDcluster *cl, AliTRDtrack *t, Int_t *group)
909 // Store the infos in fAmpTotal, fPHPlace and fPHValue
912 // Charge in the cluster
913 Float_t q = TMath::Abs(cl->GetQ());
914 Int_t time = cl->GetLocalTimeBin();
916 // Correction due to the track angle
917 Float_t correction = 1.0;
918 Float_t normalisation = 6.67;
919 if ((q >0) && (t->GetNdedx() > 0)) {
920 correction = t->GetClusterdQdl((t->GetNdedx() - 1)) / (normalisation);
923 // Fill the fAmpTotal with the charge
925 fAmpTotal[(Int_t) group[0]] += correction;
928 // Fill the fPHPlace and value
930 fPHPlace[time] = group[1];
931 fPHValue[time] = correction;
935 //_____________________________________________________________________
936 Int_t AliTRDCalibraFillHisto::ProcessEventDAQ(AliTRDRawStream *rawStream, Bool_t nocheck)
939 // Event Processing loop - AliTRDRawStream
950 for(Int_t k = 0; k < 36; k++){
955 fDetectorPreviousTrack = -1;
962 while (rawStream->Next()) {
964 Int_t idetector = rawStream->GetDet(); // current detector
965 if((fDetectorPreviousTrack != idetector) && (fDetectorPreviousTrack != -1)){
966 if(TMath::Mean(fTimeMax,phvalue)>0.0){
968 for(Int_t k = 0; k < fTimeMax; k++){
969 UpdateDAQ(fDetectorPreviousTrack,0,0,k,phvalue[k],fTimeMax);
976 fDetectorPreviousTrack = idetector;
977 nbtimebin = rawStream->GetNumberOfTimeBins(); // number of time bins read from data
978 if(nbtimebin == 0) return 0;
979 if((fTimeMax != 0) && (nbtimebin != fTimeMax)) return 0;
980 fTimeMax = nbtimebin;
981 Int_t iTimeBin = rawStream->GetTimeBin(); // current time bin
982 //row[iTimeBin] = rawStream->GetRow(); // current row
983 //col[iTimeBin] = rawStream->GetCol(); // current col
984 Int_t *signal = rawStream->GetSignals(); // current ADC signal
986 Int_t fin = TMath::Min(fTimeMax,(iTimeBin+3));
988 for(Int_t itime = iTimeBin; itime < fin; itime++){
989 // should extract baseline here!
990 if(signal[n]>5.0) phvalue[itime] = signal[n];
996 if(fDetectorPreviousTrack != -1){
997 if(TMath::Mean(fTimeMax,phvalue)>0.0){
999 for(Int_t k = 0; k < fTimeMax; k++){
1000 UpdateDAQ(fDetectorPreviousTrack,0,0,k,phvalue[k],fTimeMax);
1011 while (rawStream->Next()) {
1013 Int_t idetector = rawStream->GetDet(); // current detector
1014 if((fDetectorPreviousTrack != idetector) && (fDetectorPreviousTrack != -1)){
1015 if(TMath::Mean(nbtimebin,phvalue)>0.0){
1017 for(Int_t k = 0; k < nbtimebin; k++){
1018 UpdateDAQ(fDetectorPreviousTrack,0,0,k,phvalue[k],nbtimebin);
1025 fDetectorPreviousTrack = idetector;
1026 nbtimebin = rawStream->GetNumberOfTimeBins(); // number of time bins read from data
1027 Int_t iTimeBin = rawStream->GetTimeBin(); // current time bin
1028 //row[iTimeBin] = rawStream->GetRow(); // current row
1029 //col[iTimeBin] = rawStream->GetCol(); // current col
1030 Int_t *signal = rawStream->GetSignals(); // current ADC signal
1032 Int_t fin = TMath::Min(nbtimebin,(iTimeBin+3));
1034 for(Int_t itime = iTimeBin; itime < fin; itime++){
1035 // should extract baseline here!
1036 if(signal[n]>5.0) phvalue[itime] = signal[n];
1041 // fill the last one
1042 if(fDetectorPreviousTrack != -1){
1043 if(TMath::Mean(nbtimebin,phvalue)>0.0){
1045 for(Int_t k = 0; k < nbtimebin; k++){
1046 UpdateDAQ(fDetectorPreviousTrack,0,0,k,phvalue[k],nbtimebin);
1058 //_____________________________________________________________________
1059 Int_t AliTRDCalibraFillHisto::ProcessEventDAQ(AliRawReader *rawReader, Bool_t nocheck)
1062 // Event processing loop - AliRawReader
1066 AliTRDRawStream rawStream(rawReader);
1068 rawReader->Select("TRD");
1070 return ProcessEventDAQ(&rawStream, nocheck);
1072 //_________________________________________________________________________
1073 Int_t AliTRDCalibraFillHisto::ProcessEventDAQ(
1075 eventHeaderStruct *event,
1078 eventHeaderStruct* /*event*/,
1085 // process date event
1088 AliRawReader *rawReader = new AliRawReaderDate((void*)event);
1089 Int_t result=ProcessEventDAQ(rawReader, nocheck);
1093 Fatal("AliTRDCalibraFillHisto", "this class was compiled without DATE");
1098 //____________Online trackling in AliTRDtrigger________________________________
1099 Bool_t AliTRDCalibraFillHisto::UpdateDAQ(Int_t det, Int_t /*row*/, Int_t /*col*/, Int_t timebin, Int_t signal, Int_t nbtimebins)
1103 // Fill a simple average pulse height
1106 // Localisation of the Xbins involved
1107 //LocalisationDetectorXbins(det);
1109 // Row and position in the pad groups
1111 //if (fCalibraMode->GetNnZ(1) != 0) {
1112 // posr = (Int_t) row / fCalibraMode->GetNnZ(1);
1115 // Col of cluster and position in the pad groups
1117 //if (fCalibraMode->GetNnRphi(1) != 0) {
1118 // posc = (Int_t) col / fCalibraMode->GetNnRphi(1);
1121 //fPH2d->Fill((Float_t) timebin/fSf,(fCalibraMode->GetXbins(1)+posc*fCalibraMode->GetNfragZ(1)+posr)+0.5,(Float_t) signal);
1123 ((TProfile2D *)GetPH2d(nbtimebins,fSf))->Fill((Float_t) timebin/fSf,det+0.5,(Float_t) signal);
1128 //____________Write_____________________________________________________
1129 //_____________________________________________________________________
1130 void AliTRDCalibraFillHisto::Write2d(const Char_t *filename, Bool_t append)
1133 // Write infos to file
1137 if ( fDebugStreamer ) {
1138 delete fDebugStreamer;
1139 fDebugStreamer = 0x0;
1142 AliInfo(Form("Numbertrack: %d Numberusedch[0]: %d, Numberusedch[1]: %d Numberusedph[0]: %d, Numberusedph[1]: %d"
1147 ,fNumberUsedPh[1]));
1149 TDirectory *backup = gDirectory;
1155 option = "recreate";
1157 TFile f(filename,option.Data());
1159 TStopwatch stopwatch;
1162 f.WriteTObject(fCalibraVector);
1167 f.WriteTObject(fCH2d);
1172 f.WriteTObject(fPH2d);
1177 f.WriteTObject(fPRF2d);
1180 if(fLinearFitterOn){
1181 AnalyseLinearFitter();
1182 f.WriteTObject(fLinearVdriftFit);
1187 if ( backup ) backup->cd();
1189 AliInfo(Form("Execution time Write2d: R:%.2fs C:%.2fs"
1190 ,stopwatch.RealTime(),stopwatch.CpuTime()));
1192 //___________________________________________probe the histos__________________________________________________
1193 Double_t *AliTRDCalibraFillHisto::StatH(TH2 *h, Int_t i)
1196 // Check the number of stats in h, 0 is TH2I 1 is TProfile2D
1197 // debug mode with 2 for TH2I and 3 for TProfile2D
1198 // It gives a pointer to a Double_t[7] with the info following...
1199 // [0] : number of calibration groups with entries
1200 // [1] : minimal number of entries found
1201 // [2] : calibration group number of the min
1202 // [3] : maximal number of entries found
1203 // [4] : calibration group number of the max
1204 // [5] : mean number of entries found
1205 // [6] : mean relative error
1208 Double_t *info = new Double_t[7];
1210 // Number of Xbins (detectors or groups of pads)
1211 Int_t nbins = h->GetNbinsY(); //number of calibration groups
1212 Int_t nxbins = h->GetNbinsX(); //number of bins per histo
1215 Double_t nbwe = 0; //number of calibration groups with entries
1216 Double_t minentries = 0; //minimal number of entries found
1217 Double_t maxentries = 0; //maximal number of entries found
1218 Double_t placemin = 0; //calibration group number of the min
1219 Double_t placemax = -1; //calibration group number of the max
1220 Double_t meanstats = 0.0; //mean number of entries over the calibration group with at least ome entry
1221 Double_t meanrelativerror = 0.0; //mean relativ error in the TProfile2D
1223 Double_t counter = 0;
1226 TH1F *NbEntries = 0x0;//distribution of the number of entries
1227 TH1F *NbEntriesPerGroup = 0x0;//Number of entries per group
1228 TProfile *NbEntriesPerSp = 0x0;//Number of entries for one supermodule
1230 // Beginning of the loop over the calibration groups
1231 for (Int_t idect = 0; idect < nbins; idect++) {
1233 TH1I *projch = (TH1I *) h->ProjectionX("projch",idect+1,idect+1,(Option_t *)"e");
1234 projch->SetDirectory(0);
1236 // Number of entries for this calibration group
1237 Double_t nentries = 0.0;
1239 for (Int_t k = 0; k < nxbins; k++) {
1240 nentries += h->GetBinContent(h->GetBin(k+1,idect+1));
1244 for (Int_t k = 0; k < nxbins; k++) {
1245 nentries += ((TProfile2D *)h)->GetBinEntries(h->GetBin(k+1,idect+1));
1246 if(h->GetBinContent(h->GetBin(k+1,idect+1)) != 0) {
1247 meanrelativerror += (h->GetBinError(h->GetBin(k+1,idect+1))/(TMath::Abs(h->GetBinContent(h->GetBin(k+1,idect+1)))));
1255 if((!((Bool_t)NbEntries)) && (nentries > 0)){
1256 NbEntries = new TH1F("Number of entries","Number of entries"
1257 ,100,(Int_t)nentries/2,nentries*2);
1258 NbEntries->SetDirectory(0);
1259 NbEntriesPerGroup = new TH1F("Number of entries per group","Number of entries per group"
1261 NbEntriesPerGroup->SetDirectory(0);
1262 NbEntriesPerSp = new TProfile("Number of entries per supermodule","Number of entries per supermodule"
1263 ,(Int_t)(nbins/18),0,(Int_t)(nbins/18));
1264 NbEntriesPerSp->SetDirectory(0);
1267 if(nentries > 0) NbEntries->Fill(nentries);
1268 NbEntriesPerGroup->Fill(idect+0.5,nentries);
1269 NbEntriesPerSp->Fill((idect%((Int_t)(nbins/18)))+0.5,nentries);
1274 if(nentries > maxentries){
1275 maxentries = nentries;
1279 minentries = nentries;
1281 if(nentries < minentries){
1282 minentries = nentries;
1288 meanstats += nentries;
1290 }//calibration groups loop
1292 if(nbwe > 0) meanstats /= nbwe;
1293 if(counter > 0) meanrelativerror /= counter;
1295 AliInfo(Form("There are %f calibration groups with entries",nbwe));
1296 AliInfo(Form("The minimum number of entries is %f for the group %f",minentries,placemin));
1297 AliInfo(Form("The maximum number of entries is %f for the group %f",maxentries,placemax));
1298 AliInfo(Form("The mean number of entries is %f",meanstats));
1299 if((i%2) == 1) AliInfo(Form("The mean relative error is %f",meanrelativerror));
1302 info[1] = minentries;
1304 info[3] = maxentries;
1306 info[5] = meanstats;
1307 info[6] = meanrelativerror;
1310 gStyle->SetPalette(1);
1311 gStyle->SetOptStat(1111);
1312 gStyle->SetPadBorderMode(0);
1313 gStyle->SetCanvasColor(10);
1314 gStyle->SetPadLeftMargin(0.13);
1315 gStyle->SetPadRightMargin(0.01);
1316 TCanvas *stat = new TCanvas("stat","",50,50,600,800);
1319 NbEntries->Draw("");
1321 NbEntriesPerSp->SetStats(0);
1322 NbEntriesPerSp->Draw("");
1323 TCanvas *stat1 = new TCanvas("stat1","",50,50,600,800);
1325 NbEntriesPerGroup->SetStats(0);
1326 NbEntriesPerGroup->Draw("");
1332 //____________________________________________________________________________
1333 Double_t *AliTRDCalibraFillHisto::GetMeanMedianRMSNumberCH()
1336 // Return a Int_t[4] with:
1337 // 0 Mean number of entries
1338 // 1 median of number of entries
1339 // 2 rms of number of entries
1340 // 3 number of group with entries
1343 Double_t *stat = new Double_t[4];
1346 Int_t nbofgroups = CalculateTotalNumberOfBins(0);
1347 Double_t *weight = new Double_t[nbofgroups];
1348 Int_t *nonul = new Int_t[nbofgroups];
1350 for(Int_t k = 0; k < nbofgroups; k++){
1351 if(fEntriesCH[k] > 0) {
1353 nonul[(Int_t)stat[3]] = fEntriesCH[k];
1356 else weight[k] = 0.0;
1358 stat[0] = TMath::Mean(nbofgroups,fEntriesCH,weight);
1359 stat[1] = TMath::Median(nbofgroups,fEntriesCH,weight);
1360 stat[2] = TMath::RMS((Int_t)stat[3],nonul);
1365 //____________________________________________________________________________
1366 Double_t *AliTRDCalibraFillHisto::GetMeanMedianRMSNumberLinearFitter() const
1369 // Return a Int_t[4] with:
1370 // 0 Mean number of entries
1371 // 1 median of number of entries
1372 // 2 rms of number of entries
1373 // 3 number of group with entries
1376 Double_t *stat = new Double_t[4];
1379 Int_t nbofgroups = 540;
1380 Double_t *weight = new Double_t[nbofgroups];
1381 Int_t *nonul = new Int_t[nbofgroups];
1383 for(Int_t k = 0; k < nbofgroups; k++){
1384 if(fEntriesLinearFitter[k] > 0) {
1386 nonul[(Int_t) stat[3]] = fEntriesLinearFitter[k];
1389 else weight[k] = 0.0;
1391 stat[0] = TMath::Mean(nbofgroups,fEntriesLinearFitter,weight);
1392 stat[1] = TMath::Median(nbofgroups,fEntriesLinearFitter,weight);
1393 stat[2] = TMath::RMS((Int_t)stat[3],nonul);
1398 //_____________________________________________________________________________
1399 void AliTRDCalibraFillHisto::SetNumberGroupsPRF(Short_t numberGroupsPRF)
1402 // Should be between 0 and 6
1405 if ((numberGroupsPRF < 0) || (numberGroupsPRF > 6)) {
1406 AliInfo("The number of groups must be between 0 and 6!");
1409 fNgroupprf = numberGroupsPRF;
1413 //_____________________________________________________________________________
1414 void AliTRDCalibraFillHisto::SetRelativeScale(Float_t RelativeScale)
1417 // Set the factor that will divide the deposited charge
1418 // to fit in the histo range [0,300]
1421 if (RelativeScale > 0.0) {
1422 fRelativeScale = RelativeScale;
1425 AliInfo("RelativeScale must be strict positif!");
1430 //_____________________________________________________________________________
1431 void AliTRDCalibraFillHisto::SetNz(Int_t i, Short_t Nz)
1434 // Set the mode of calibration group in the z direction for the parameter i
1439 fCalibraMode->SetNz(i, Nz);
1442 AliInfo("You have to choose between 0 and 4");
1447 //_____________________________________________________________________________
1448 void AliTRDCalibraFillHisto::SetNrphi(Int_t i, Short_t Nrphi)
1451 // Set the mode of calibration group in the rphi direction for the parameter i
1456 fCalibraMode->SetNrphi(i ,Nrphi);
1459 AliInfo("You have to choose between 0 and 6");
1463 //____________Protected Functions______________________________________________
1464 //____________Create the 2D histo to be filled online__________________________
1466 //_____________________________________________________________________________
1467 void AliTRDCalibraFillHisto::CreatePRF2d(Int_t nn)
1470 // Create the 2D histos: here we have 2*fNgroupprf bins in tnp of 0.2 amplitude each
1471 // If fNgroupprf is zero then no binning in tnp
1475 name += fCalibraMode->GetNz(2);
1477 name += fCalibraMode->GetNrphi(2);
1481 if(fNgroupprf != 0){
1483 fPRF2d = new TProfile2D("PRF2d",(const Char_t *) name
1484 ,2*fNgroupprf*fNumberBinPRF,-3.0*fNgroupprf,3.0*fNgroupprf,nn,0,nn);
1485 fPRF2d->SetYTitle("Det/pad groups");
1486 fPRF2d->SetXTitle("Position x/W [pad width units]");
1487 fPRF2d->SetZTitle("Q_{i}/Q_{total}");
1488 fPRF2d->SetStats(0);
1491 fPRF2d = new TProfile2D("PRF2d",(const Char_t *) name
1492 ,fNumberBinPRF,-1.5,1.5,nn,0,nn);
1493 fPRF2d->SetYTitle("Det/pad groups");
1494 fPRF2d->SetXTitle("Position x/W [pad width units]");
1495 fPRF2d->SetZTitle("Q_{i}/Q_{total}");
1496 fPRF2d->SetStats(0);
1501 //_____________________________________________________________________________
1502 void AliTRDCalibraFillHisto::CreatePH2d(Int_t nn)
1505 // Create the 2D histos
1509 name += fCalibraMode->GetNz(1);
1511 name += fCalibraMode->GetNrphi(1);
1513 fPH2d = new TProfile2D("PH2d",(const Char_t *) name
1514 ,fTimeMax,-0.5/fSf,(Float_t) (fTimeMax-0.5)/fSf
1516 fPH2d->SetYTitle("Det/pad groups");
1517 fPH2d->SetXTitle("time [#mus]");
1518 fPH2d->SetZTitle("<PH> [a.u.]");
1522 //_____________________________________________________________________________
1523 void AliTRDCalibraFillHisto::CreateCH2d(Int_t nn)
1526 // Create the 2D histos
1530 name += fCalibraMode->GetNz(0);
1532 name += fCalibraMode->GetNrphi(0);
1534 fCH2d = new TH2I("CH2d",(const Char_t *) name
1535 ,fNumberBinCharge,0,300,nn,0,nn);
1536 fCH2d->SetYTitle("Det/pad groups");
1537 fCH2d->SetXTitle("charge deposit [a.u]");
1538 fCH2d->SetZTitle("counts");
1544 //____________Offine tracking in the AliTRDtracker_____________________________
1545 void AliTRDCalibraFillHisto::FillTheInfoOfTheTrackCH()
1548 // For the offline tracking or mcm tracklets
1549 // This function will be called in the functions UpdateHistogram...
1550 // to fill the info of a track for the relativ gain calibration
1553 Int_t nb = 0; // Nombre de zones traversees
1554 Int_t fd = -1; // Premiere zone non nulle
1555 Float_t totalcharge = 0.0; // Total charge for the supermodule histo
1560 // See if the track goes through different zones
1561 for (Int_t k = 0; k < fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0); k++) {
1562 if (fAmpTotal[k] > 0.0) {
1563 totalcharge += fAmpTotal[k];
1576 fEntriesCH[fCalibraMode->GetXbins(0)+fd]++;
1578 FillCH2d(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1579 //fCH2d->Fill(fAmpTotal[fd]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+0.5);
1582 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd,fAmpTotal[fd]/fRelativeScale);
1586 if ((fAmpTotal[fd] > 0.0) &&
1587 (fAmpTotal[fd+1] > 0.0)) {
1588 // One of the two very big
1589 if (fAmpTotal[fd] > fProcent*fAmpTotal[fd+1]) {
1591 FillCH2d(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1592 //fCH2d->Fill(fAmpTotal[fd]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+0.5);
1595 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd,fAmpTotal[fd]/fRelativeScale);
1598 fEntriesCH[fCalibraMode->GetXbins(0)+fd]++;
1600 if (fAmpTotal[fd+1] > fProcent*fAmpTotal[fd]) {
1602 FillCH2d(fCalibraMode->GetXbins(0)+fd+1,fAmpTotal[fd+1]/fRelativeScale);
1603 //fCH2d->Fill(fAmpTotal[fd+1]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+1.5);
1606 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd+1,fAmpTotal[fd+1]/fRelativeScale);
1609 fEntriesCH[fCalibraMode->GetXbins(0)+fd+1]++;
1612 if (fCalibraMode->GetNfragZ(0) > 1) {
1613 if (fAmpTotal[fd] > 0.0) {
1614 if ((fd+fCalibraMode->GetNfragZ(0)) < (fCalibraMode->GetNfragZ(0)*fCalibraMode->GetNfragRphi(0))) {
1615 if (fAmpTotal[fd+fCalibraMode->GetNfragZ(0)] > 0.0) {
1616 // One of the two very big
1617 if (fAmpTotal[fd] > fProcent*fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]) {
1619 FillCH2d(fCalibraMode->GetXbins(0)+fd,fAmpTotal[fd]/fRelativeScale);
1620 //fCH2d->Fill(fAmpTotal[fd]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+0.5);
1623 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd,fAmpTotal[fd]/fRelativeScale);
1626 fEntriesCH[fCalibraMode->GetXbins(0)+fd]++;
1628 if (fAmpTotal[fd+fCalibraMode->GetNfragZ(0)] > fProcent*fAmpTotal[fd]) {
1630 FillCH2d(fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0),fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/fRelativeScale);
1631 //fCH2d->Fill(fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/fRelativeScale,fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0)+0.5);
1634 fEntriesCH[fCalibraMode->GetXbins(0)+fd+fCalibraMode->GetNfragZ(0)]++;
1636 fCalibraVector->UpdateVectorCH(fDetectorPreviousTrack,fd+fCalibraMode->GetNfragZ(0),fAmpTotal[fd+fCalibraMode->GetNfragZ(0)]/fRelativeScale);
1647 //____________Offine tracking in the AliTRDtracker_____________________________
1648 void AliTRDCalibraFillHisto::FillTheInfoOfTheTrackPH()
1651 // For the offline tracking or mcm tracklets
1652 // This function will be called in the functions UpdateHistogram...
1653 // to fill the info of a track for the drift velocity calibration
1656 Int_t nb = 1; // Nombre de zones traversees 1, 2 ou plus de 3
1657 Int_t fd1 = -1; // Premiere zone non nulle
1658 Int_t fd2 = -1; // Deuxieme zone non nulle
1659 Int_t k1 = -1; // Debut de la premiere zone
1660 Int_t k2 = -1; // Debut de la seconde zone
1662 // See if the track goes through different zones
1663 for (Int_t k = 0; k < fTimeMax; k++) {
1664 if (fPHValue[k] > 0.0) {
1669 if (fPHPlace[k] != fd1) {
1675 if (fPHPlace[k] != fd2) {
1687 for (Int_t i = 0; i < fTimeMax; i++) {
1689 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1692 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1697 if ((fd1 == fd2+1) ||
1699 // One of the two fast all the think
1700 if (k2 > (k1+fDifference)) {
1701 //we choose to fill the fd1 with all the values
1703 for (Int_t i = 0; i < fTimeMax; i++) {
1705 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1708 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1712 if ((k2+fDifference) < fTimeMax) {
1713 //we choose to fill the fd2 with all the values
1715 for (Int_t i = 0; i < fTimeMax; i++) {
1717 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
1720 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd2,i,fPHValue[i]);
1725 // Two zones voisines sinon rien!
1726 if (fCalibraMode->GetNfragZ(1) > 1) {
1728 if ((fd1+fCalibraMode->GetNfragZ(1)) < (fCalibraMode->GetNfragZ(1)*fCalibraMode->GetNfragRphi(1))) {
1729 if (fd2 == (fd1+fCalibraMode->GetNfragZ(1))) {
1730 // One of the two fast all the think
1731 if (k2 > (k1+fDifference)) {
1732 //we choose to fill the fd1 with all the values
1734 for (Int_t i = 0; i < fTimeMax; i++) {
1736 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1739 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1743 if ((k2+fDifference) < fTimeMax) {
1744 //we choose to fill the fd2 with all the values
1746 for (Int_t i = 0; i < fTimeMax; i++) {
1748 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
1751 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd2,i,fPHValue[i]);
1757 // Two zones voisines sinon rien!
1759 if ((fd1 - fCalibraMode->GetNfragZ(1)) >= 0) {
1760 if (fd2 == (fd1 - fCalibraMode->GetNfragZ(1))) {
1761 // One of the two fast all the think
1762 if (k2 > (k1 + fDifference)) {
1763 //we choose to fill the fd1 with all the values
1765 for (Int_t i = 0; i < fTimeMax; i++) {
1767 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd1)+0.5,(Float_t) fPHValue[i]);
1770 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd1,i,fPHValue[i]);
1774 if ((k2+fDifference) < fTimeMax) {
1775 //we choose to fill the fd2 with all the values
1777 for (Int_t i = 0; i < fTimeMax; i++) {
1779 fPH2d->Fill((Float_t) i/fSf,(fCalibraMode->GetXbins(1)+fd2)+0.5,(Float_t) fPHValue[i]);
1782 fCalibraVector->UpdateVectorPH(fDetectorPreviousTrack,fd2,i,fPHValue[i]);
1793 //____________Offine tracking in the AliTRDtracker_____________________________
1794 Bool_t AliTRDCalibraFillHisto::FindP1TrackPH()
1797 // For the offline tracking
1798 // This function will be called in the functions UpdateHistogram...
1799 // to fill the find the parameter P1 of a track for the drift velocity calibration
1803 //Number of points: if less than 3 return kFALSE
1804 Int_t Npoints = fListClusters->GetEntriesFast();
1805 if(Npoints <= 2) return kFALSE;
1808 TLinearFitter linearFitterTracklet = TLinearFitter(2,"pol1"); // TLinearFitter per tracklet
1809 Double_t snp = 0.0; // sin angle in the plan yx track
1810 Double_t y = 0.0; // y clusters in the middle of the chamber
1811 Double_t z = 0.0; // z cluster in the middle of the chamber
1812 Double_t dydt = 0.0; // dydt tracklet after straight line fit
1813 Double_t tnp = 0.0; // tan angle in the plan xy track
1814 Double_t tgl = 0.0; // dz/dl and not dz/dx!
1815 Double_t errorpar = 0.0; // error after straight line fit on dy/dt
1816 Double_t pointError = 0.0; // error after straight line fit
1817 Int_t detector = ((AliTRDcluster *) fListClusters->At(0))->GetDetector(); //detector
1818 Int_t snpright = 1; // if we took in the middle snp
1819 Int_t crossrow = 0; // if it crosses a pad row
1820 Double_t tiltingangle = 0; // tiltingangle of the pad
1821 Float_t dzdx = 0; // dz/dx now from dz/dl
1822 Int_t nbli = 0; // number linear fitter points
1823 AliTRDpadPlane *padplane = fGeo->GetPadPlane(GetPlane(detector),GetChamber(detector));
1825 linearFitterTracklet.StoreData(kFALSE);
1826 linearFitterTracklet.ClearPoints();
1828 //if more than one row
1829 Int_t rowp = -1; // if it crosses a pad row
1832 tiltingangle = padplane->GetTiltingAngle();
1833 Float_t tnt = TMath::Tan(tiltingangle/180.*TMath::Pi()); // tan tiltingangle
1836 for(Int_t k = 0; k < Npoints; k++){
1838 AliTRDcluster *cl = (AliTRDcluster *) fListClusters->At(k);
1839 Double_t ycluster = cl->GetY();
1840 Int_t time = cl->GetLocalTimeBin();
1841 Double_t timeis = time/fSf;
1842 //See if cross two pad rows
1843 Int_t row = padplane->GetPadRowNumber(cl->GetZ());
1844 if(k==0) rowp = row;
1845 if(row != rowp) crossrow = 1;
1846 //Take in the middle of the chamber
1848 if(time > (Int_t) 10) {
1850 //if(time < (Int_t) 11) {
1856 linearFitterTracklet.AddPoint(&timeis,ycluster,1);
1860 if(((AliTRDcluster *) fListClusters->At(0))->GetLocalTimeBin() < 10) snpright = 0;
1862 //if(((AliTRDcluster *) fListClusters->At(0))->GetLocalTimeBin() >= 11) snpright = 0;
1863 if(nbli <= 2) return kFALSE;
1865 // Do the straight line fit now
1867 linearFitterTracklet.Eval();
1868 linearFitterTracklet.GetParameters(pars);
1869 pointError = TMath::Sqrt(linearFitterTracklet.GetChisquare()/nbli);
1870 errorpar = linearFitterTracklet.GetParError(1)*pointError;
1873 if( TMath::Abs(snp) < 1.){
1874 tnp = snp / (TMath::Sqrt(1-(snp*snp)));
1876 dzdx = tgl*TMath::Sqrt(1+tnp*tnp);
1878 if(fDebugLevel > 0){
1879 if ( !fDebugStreamer ) {
1881 TDirectory *backup = gDirectory;
1882 fDebugStreamer = new TTreeSRedirector("TRDdebugCalibraFill.root");
1883 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
1886 (* fDebugStreamer) << "VDRIFT0"<<
1887 "Npoints="<<Npoints<<
1891 (* fDebugStreamer) << "VDRIFT"<<
1892 "snpright="<<snpright<<
1893 "Npoints="<<Npoints<<
1895 "detector="<<detector<<
1904 "crossrow="<<crossrow<<
1905 "errorpar="<<errorpar<<
1906 "pointError="<<pointError<<
1911 if(Npoints < fNumberClusters) return kFALSE;
1912 if(snpright == 0) return kFALSE;
1913 if(pointError >= 0.1) return kFALSE;
1914 if(crossrow == 1) return kFALSE;
1916 if(fLinearFitterOn){
1917 //Add to the linear fitter of the detector
1918 if( TMath::Abs(snp) < 1.){
1919 Double_t x = tnp-dzdx*tnt;
1920 (GetLinearFitter(detector,kTRUE))->AddPoint(&x,dydt);
1921 if(fLinearFitterDebugOn) {
1922 fLinearVdriftFit->Update(detector,x,pars[1]);
1924 fEntriesLinearFitter[detector]++;
1927 //AliInfo("End of FindP1TrackPH with success!")
1931 //____________Offine tracking in the AliTRDtracker_____________________________
1932 Bool_t AliTRDCalibraFillHisto::HandlePRF()
1935 // For the offline tracking
1936 // Fit the tracklet with a line and take the position as reference for the PRF
1940 Int_t Npoints = fListClusters->GetEntriesFast(); // number of total points
1941 Int_t Nb3pc = 0; // number of three pads clusters used for fit
1942 Int_t detector = ((AliTRDcluster *) fListClusters->At(0))->GetDetector(); // detector
1945 // To see the difference due to the fit
1946 Double_t *padPositions;
1947 padPositions = new Double_t[Npoints];
1948 for(Int_t k = 0; k < Npoints; k++){
1949 padPositions[k] = 0.0;
1953 //Find the position by a fit
1954 TLinearFitter fitter(2,"pol1");
1955 fitter.StoreData(kFALSE);
1956 fitter.ClearPoints();
1957 for(Int_t k = 0; k < Npoints; k++){
1959 AliTRDcluster *cl = (AliTRDcluster *) fListClusters->At(k);
1960 Short_t *signals = cl->GetSignals();
1961 Double_t time = cl->GetLocalTimeBin();
1962 //Calculate x if possible
1963 Float_t xcenter = 0.0;
1964 Bool_t echec = kTRUE;
1965 if((time<=7) || (time>=21)) continue;
1966 // Center 3 balanced: position with the center of the pad
1967 if ((((Float_t) signals[3]) > 0.0) &&
1968 (((Float_t) signals[2]) > 0.0) &&
1969 (((Float_t) signals[4]) > 0.0)) {
1971 // Security if the denomiateur is 0
1972 if ((((Float_t) (((Float_t) signals[3]) * ((Float_t) signals[3]))) /
1973 ((Float_t) (((Float_t) signals[2]) * ((Float_t) signals[4])))) != 1.0) {
1974 xcenter = 0.5 * (TMath::Log((Float_t) (((Float_t) signals[4]) / ((Float_t) signals[2]))))
1975 / (TMath::Log(((Float_t) (((Float_t) signals[3]) * ((Float_t) signals[3])))
1976 / ((Float_t) (((Float_t) signals[2]) * ((Float_t) signals[4])))));
1982 if(TMath::Abs(xcenter) > 0.5) echec = kTRUE;
1984 //if no echec: calculate with the position of the pad
1985 // Position of the cluster
1986 Double_t padPosition = xcenter + cl->GetPad();
1987 padPositions[k] = padPosition;
1989 fitter.AddPoint(&time, padPosition,1);
1992 //printf("Nb3pc %d, Npoints %d\n",Nb3pc,Npoints);
1993 if(Nb3pc < 3) return kFALSE;
1996 fitter.GetParameters(line);
1997 Float_t pointError = -1.0;
1998 pointError = TMath::Sqrt(fitter.GetChisquare()/Nb3pc);
2002 for(Int_t k = 0; k < Npoints; k++){
2004 AliTRDcluster *cl = (AliTRDcluster *) fListClusters->At(k);
2005 Short_t *signals = cl->GetSignals(); // signal
2006 Double_t time = cl->GetLocalTimeBin(); // time bin
2007 Float_t padPosTracklet = line[0]+line[1]*time; // reconstruct position from fit
2008 Float_t padPos = cl->GetPad(); // middle pad
2009 Double_t dpad = padPosTracklet - padPos; // reconstruct position relative to middle pad from fit
2010 Float_t ycenter = 0.0; // relative center charge
2011 Float_t ymin = 0.0; // relative left charge
2012 Float_t ymax = 0.0; // relative right charge
2013 Double_t tgl = fPar3[(Int_t)time]; // dz/dl and not dz/dx
2014 Double_t pt = fPar4[(Int_t)time]; // pt
2015 Float_t dzdx = 0.0; // dzdx
2018 //Requiere simply two pads clusters at least
2019 if(((((Float_t) signals[3]) > 0.0) && (((Float_t) signals[2]) > 0.0)) ||
2020 ((((Float_t) signals[3]) > 0.0) && (((Float_t) signals[4]) > 0.0))){
2021 Float_t sum = ((Float_t) signals[2]) + ((Float_t) signals[3]) + ((Float_t) signals[4]);
2022 if(sum > 0.0) ycenter = ((Float_t) signals[3])/ sum;
2023 if(sum > 0.0) ymin = ((Float_t) signals[2])/ sum;
2024 if(sum > 0.0) ymax = ((Float_t) signals[4])/ sum;
2028 Int_t *rowcol = CalculateRowCol(cl); // calcul col and row pad of the cluster
2029 Int_t grouplocal = CalculateCalibrationGroup(2,rowcol); // calcul the corresponding group
2030 Int_t caligroup = fCalibraMode->GetXbins(2)+ grouplocal; // calcul the corresponding group
2031 Double_t snp = fPar2[(Int_t)time]; // sin angle in xy plan
2032 Float_t xcl = cl->GetY(); // y cluster
2033 Float_t qcl = cl->GetQ(); // charge cluster
2034 Int_t plane = GetPlane(detector); // plane
2035 Int_t chamber = GetChamber(detector); // chamber
2036 Double_t xdiff = dpad; // reconstructed position constant
2037 Double_t x = dpad; // reconstructed position moved
2038 Float_t Ep = pointError; // error of fit
2039 Float_t signal1 = (Float_t)signals[1]; // signal at the border
2040 Float_t signal3 = (Float_t)signals[3]; // signal
2041 Float_t signal2 = (Float_t)signals[2]; // signal
2042 Float_t signal4 = (Float_t)signals[4]; // signal
2043 Float_t signal5 = (Float_t)signals[5]; // signal at the border
2045 if(TMath::Abs(snp) < 1.0){
2046 tnp = snp / (TMath::Sqrt(1-snp*snp));
2047 dzdx = tgl*TMath::Sqrt(1+tnp*tnp);
2051 if(fDebugLevel > 0){
2052 if ( !fDebugStreamer ) {
2054 TDirectory *backup = gDirectory;
2055 fDebugStreamer = new TTreeSRedirector("TRDdebugCalibraFill.root");
2056 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
2059 (* fDebugStreamer) << "PRF0"<<
2060 "caligroup="<<caligroup<<
2061 "detector="<<detector<<
2063 "chamber="<<chamber<<
2064 "Npoints="<<Npoints<<
2073 "padPosition="<<padPositions[k]<<
2074 "padPosTracklet="<<padPosTracklet<<
2076 "ycenter="<<ycenter<<
2081 "signal1="<<signal1<<
2082 "signal2="<<signal2<<
2083 "signal3="<<signal3<<
2084 "signal4="<<signal4<<
2085 "signal5="<<signal5<<
2090 Float_t y = ycenter;
2091 (* fDebugStreamer) << "PRFALL"<<
2092 "caligroup="<<caligroup<<
2093 "detector="<<detector<<
2095 "chamber="<<chamber<<
2096 "Npoints="<<Npoints<<
2106 "padPosition="<<padPositions[k]<<
2107 "padPosTracklet="<<padPosTracklet<<
2112 "signal1="<<signal1<<
2113 "signal2="<<signal2<<
2114 "signal3="<<signal3<<
2115 "signal4="<<signal4<<
2116 "signal5="<<signal5<<
2122 (* fDebugStreamer) << "PRFALL"<<
2123 "caligroup="<<caligroup<<
2124 "detector="<<detector<<
2126 "chamber="<<chamber<<
2127 "Npoints="<<Npoints<<
2137 "padPosition="<<padPositions[k]<<
2138 "padPosTracklet="<<padPosTracklet<<
2143 "signal1="<<signal1<<
2144 "signal2="<<signal2<<
2145 "signal3="<<signal3<<
2146 "signal4="<<signal4<<
2147 "signal5="<<signal5<<
2154 (* fDebugStreamer) << "PRFALL"<<
2155 "caligroup="<<caligroup<<
2156 "detector="<<detector<<
2158 "chamber="<<chamber<<
2159 "Npoints="<<Npoints<<
2169 "padPosition="<<padPositions[k]<<
2170 "padPosTracklet="<<padPosTracklet<<
2175 "signal1="<<signal1<<
2176 "signal2="<<signal2<<
2177 "signal3="<<signal3<<
2178 "signal4="<<signal4<<
2179 "signal5="<<signal5<<
2186 if(Npoints < fNumberClusters) continue;
2187 if(Nb3pc <= 5) continue;
2188 if((time >= 21) || (time < 7)) continue;
2189 if(TMath::Abs(snp) >= 1.0) continue;
2190 if(qcl < 80) continue;
2192 Bool_t echec = kFALSE;
2193 Double_t shift = 0.0;
2194 //Calculate the shift in x coresponding to this tnp
2195 if(fNgroupprf != 0.0){
2196 shift = -3.0*(fNgroupprf-1)-1.5;
2197 Double_t limithigh = -0.2*(fNgroupprf-1);
2198 if((tnp < (-0.2*fNgroupprf)) || (tnp > (0.2*fNgroupprf))) echec = kTRUE;
2200 while(tnp > limithigh){
2206 if (fHisto2d && !echec) {
2207 if(TMath::Abs(dpad) < 1.5) {
2208 fPRF2d->Fill(shift+dpad,(caligroup+0.5),ycenter);
2209 fPRF2d->Fill(shift-dpad,(caligroup+0.5),ycenter);
2211 if((ymin > 0.0) && (TMath::Abs(dpad+1.0) < 1.5)) {
2212 fPRF2d->Fill(shift-(dpad+1.0),(caligroup+0.5),ymin);
2213 fPRF2d->Fill(shift+(dpad+1.0),(caligroup+0.5),ymin);
2215 if((ymax > 0.0) && (TMath::Abs(dpad-1.0) < 1.5)) {
2216 fPRF2d->Fill(shift+1.0-dpad,(caligroup+0.5),ymax);
2217 fPRF2d->Fill(shift-1.0+dpad,(caligroup+0.5),ymax);
2220 //Not equivalent anymore here!
2221 if (fVector2d && !echec) {
2222 if(TMath::Abs(dpad) < 1.5) {
2223 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift+dpad,ycenter);
2224 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift-dpad,ycenter);
2226 if((ymin > 0.0) && (TMath::Abs(dpad+1.0) < 1.5)) {
2227 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift-(dpad+1.0),ymin);
2228 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift+(dpad+1.0),ymin);
2230 if((ymax > 0.0) && (TMath::Abs(dpad-1.0) < 1.5)) {
2231 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift+1.0-dpad,ymax);
2232 fCalibraVector->UpdateVectorPRF(fDetectorPreviousTrack,grouplocal,shift-1.0+dpad,ymax);
2240 //____________Some basic geometry function_____________________________________
2242 //_____________________________________________________________________________
2243 Int_t AliTRDCalibraFillHisto::GetPlane(Int_t d) const
2246 // Reconstruct the plane number from the detector number
2249 return ((Int_t) (d % 6));
2253 //_____________________________________________________________________________
2254 Int_t AliTRDCalibraFillHisto::GetChamber(Int_t d) const
2257 // Reconstruct the chamber number from the detector number
2261 return ((Int_t) (d % 30) / fgkNplan);
2265 //_____________________________________________________________________________
2266 Int_t AliTRDCalibraFillHisto::GetSector(Int_t d) const
2269 // Reconstruct the sector number from the detector number
2273 return ((Int_t) (d / fg));
2276 //_____________________________________________________________________
2277 TProfile2D* AliTRDCalibraFillHisto::GetPH2d(Int_t nbtimebin, Float_t samplefrequency)
2280 // return pointer to fPH2d TProfile2D
2281 // create a new TProfile2D if it doesn't exist allready
2287 fTimeMax = nbtimebin;
2288 fSf = samplefrequency;
2291 AliInfo(Form("The pad calibration mode for the drift velocity calibration: Nz %d, and Nrphi %d"
2292 ,fCalibraMode->GetNz(1)
2293 ,fCalibraMode->GetNrphi(1)));
2295 // Calcul the number of Xbins
2297 fCalibraMode->ModePadCalibration(2,1);
2298 fCalibraMode->ModePadFragmentation(0,2,0,1);
2299 fCalibraMode->SetDetChamb2(1);
2300 Ntotal1 += 6 * 18 * fCalibraMode->GetDetChamb2(1);
2301 fCalibraMode->ModePadCalibration(0,1);
2302 fCalibraMode->ModePadFragmentation(0,0,0,1);
2303 fCalibraMode->SetDetChamb0(1);
2304 Ntotal1 += 6 * 4 * 18 * fCalibraMode->GetDetChamb0(1);
2305 AliInfo(Form("Total number of Xbins: %d",Ntotal1));
2307 CreatePH2d(Ntotal1);
2314 //_____________________________________________________________________
2315 TLinearFitter* AliTRDCalibraFillHisto::GetLinearFitter(Int_t detector, Bool_t force)
2318 // return pointer to TLinearFitter Calibration
2319 // if force is true create a new TLinearFitter if it doesn't exist allready
2321 if ( !force || fLinearFitterArray.UncheckedAt(detector) )
2322 return (TLinearFitter*)fLinearFitterArray.UncheckedAt(detector);
2324 // if we are forced and TLinearFitter doesn't yet exist create it
2326 // new TLinearFitter
2327 TLinearFitter *linearfitter = new TLinearFitter(2,"pol1");
2328 fLinearFitterArray.AddAt(linearfitter,detector);
2329 return linearfitter;
2332 //_____________________________________________________________________
2333 void AliTRDCalibraFillHisto::FillCH2d(Int_t x, Float_t y)
2336 // FillCH2d: Marian style
2339 //skip simply the value out of range
2340 if((y>=300.0) || (y<0.0)) return;
2342 //Calcul the y place
2343 Int_t yplace = (Int_t) (fNumberBinCharge*y/300.0)+1;
2344 Int_t place = (fNumberBinCharge+2)*(x+1)+yplace;
2347 fCH2d->GetArray()[place]++;
2351 //____________________________________________________________________________
2352 void AliTRDCalibraFillHisto::AnalyseLinearFitter()
2355 // Analyse array of linear fitter because can not be written
2356 // Store two arrays: one with the param the other one with the error param + number of entries
2359 for(Int_t k = 0; k < 540; k++){
2360 TLinearFitter *linearfitter = GetLinearFitter(k);
2361 if((linearfitter!=0) && (fEntriesLinearFitter[k]>10)){
2362 TVectorD *par = new TVectorD(2);
2363 TVectorD pare = TVectorD(2);
2364 TVectorD *parE = new TVectorD(3);
2365 linearfitter->Eval();
2366 linearfitter->GetParameters(*par);
2367 linearfitter->GetErrors(pare);
2368 Float_t ppointError = TMath::Sqrt(TMath::Abs(linearfitter->GetChisquare())/fEntriesLinearFitter[k]);
2369 (*parE)[0] = pare[0]*ppointError;
2370 (*parE)[1] = pare[1]*ppointError;
2371 (*parE)[2] = (Double_t) fEntriesLinearFitter[k];
2372 ((TObjArray *)fLinearVdriftFit->GetPArray())->AddAt(par,k);
2373 ((TObjArray *)fLinearVdriftFit->GetEArray())->AddAt(parE,k);