Updated for modifs in AliMUONPadStatusMapMaker
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitCalibrator.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
7 * Permission to use, copy, modify and distribute this software and its   *
8 * documentation strictly for non-commercial purposes is hereby granted   *
9 * without fee, provided that the above copyright notice appears in all   *
10 * copies and that both the copyright notice and this permission notice   *
11 * appear in the supporting documentation. The authors make no claims     *
12 * about the suitability of this software for any purpose. It is          *
13 * provided "as is" without express or implied warranty.                  *
14 **************************************************************************/
15
16 // $Id$
17
18 #include "AliMUONDigitCalibrator.h"
19
20 #include "AliLog.h"
21 #include "AliMUONCalibrationData.h"
22 #include "AliMUONConstants.h"
23 #include "AliMUONData.h"
24 #include "AliMUONDigit.h"
25 #include "AliMUONLogger.h"
26 #include "AliMUONPadStatusMaker.h"
27 #include "AliMUONPadStatusMapMaker.h"
28 #include "AliMUONV2DStore.h"
29 #include "AliMUONVCalibParam.h"
30 #include "TClonesArray.h"
31
32 /// \class AliMUONDigitCalibrator
33 /// Class used to calibrate digits (either real or simulated ones).
34 ///
35 /// The calibration consists of subtracting the pedestal
36 /// and multiplying by a gain, so that
37 /// Signal = (ADC-pedestal)*gain
38 ///
39 /// Please note also that for the moment, if a digit lies on a dead channel
40 /// we remove this digit from the list of digits.
41 /// FIXME: this has to be revisited. By using the AliMUONDigit::fFlags we
42 /// should in principle flag a digit as bad w/o removing it, but this 
43 /// then requires some changes in the cluster finder to deal with this extra
44 /// information correctly (e.g. to set a quality for the cluster if it contains
45 /// bad digits).
46 ///
47 /// \author Laurent Aphecetche
48
49
50 /// \cond CLASSIMP
51 ClassImp(AliMUONDigitCalibrator)
52 /// \endcond
53
54 //_____________________________________________________________________________
55 AliMUONDigitCalibrator::AliMUONDigitCalibrator(AliMUONData* muonData,
56                                                AliMUONCalibrationData* calib,
57                                                Bool_t createAndUseStatusMap)
58 : TTask("AliMUONDigitCalibrator","Raw digit calibration"),
59   fData(muonData),
60   fCalibrationData(calib),
61   fStatusMap(0x0),
62   fLogger(new AliMUONLogger(1000))
63 {
64     /// ctor. This class needs the muonData to get access to the digit,
65     /// and the calibrationData to get access to calibration parameters.
66     
67     if (!calib) {
68       AliFatal("No calibration data defined");
69     }   
70     
71     if (createAndUseStatusMap) 
72     {
73       AliMUONPadStatusMaker maker(*calib);
74       
75       // this is here that we decide on our "goodness" policy, i.e.
76       // what do we call an invalid pad (a pad maybe bad because its HV
77       // was too low, or its pedestals too high, etc..)
78       //
79       maker.SetHVSt12Limits(1300,1600);
80       maker.SetHVSt345Limits(1500,2000);
81       maker.SetPedMeanLimits(50,200);
82       maker.SetPedSigmaLimits(0.1,3);
83       
84       // From this set of limits, compute the status of all tracker pads.
85       AliMUONV2DStore* status = maker.MakeStatus();      
86       // we do not check that status is != 0x0, as this is supposed to be
87       // the responsability of the padStatusMaker.
88       
89       AliMUONPadStatusMapMaker mapMaker(*calib);
90       
91       Int_t mask(0x8080); 
92       //FIXME: kind of fake one for the moment, we consider dead only 
93       // if ped and/or hv value missing.
94       //WARNING : getting this mask wrong is a very effective way of getting
95       //no digits at all out of this class ;-)
96       
97       fStatusMap = mapMaker.MakePadStatusMap(*status,mask);
98       
99       delete status;
100     }
101     else
102     {
103       // make a fake (empty) status map
104       fStatusMap = AliMUONPadStatusMapMaker::MakeEmptyPadStatusMap();
105     }
106 }
107
108 //_____________________________________________________________________________
109 AliMUONDigitCalibrator::~AliMUONDigitCalibrator()
110 {
111   /// dtor.
112   delete fStatusMap;
113   
114   AliInfo("Summary of messages:");
115   fLogger->Print();
116
117   delete fLogger;
118 }
119
120 //_____________________________________________________________________________
121 void
122 AliMUONDigitCalibrator::Exec(Option_t*)
123 {
124   /// Main method.
125   /// We loop on tracking chambers (i.e. we do nothing for trigger)
126   /// and for each digit in that chamber, we calibrate it :
127   /// a) we set its status map and if status is bad, set the signal to zero
128   /// b) we then apply pedestal and gain corrections.
129   
130   for ( Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ++ch )
131   {
132     TClonesArray* digitArray = fData->Digits(ch);
133     Int_t nDigits = digitArray->GetEntriesFast();
134     for ( Int_t d = 0; d < nDigits; ++d )
135     {
136       AliMUONDigit* digit = 
137         static_cast<AliMUONDigit*>(digitArray->UncheckedAt(d));
138  
139       AliMUONVCalibParam* deadmap = static_cast<AliMUONVCalibParam*>
140         (fStatusMap->Get(digit->DetElemId(),digit->ManuId()));
141       Int_t statusMap = deadmap->ValueAsInt(digit->ManuChannel());
142       digit->SetStatusMap(statusMap);
143       if ( ( statusMap & AliMUONPadStatusMapMaker::SelfDeadMask() ) != 0 ) // pad itself is bad (not testing its neighbours at this stage)
144       {
145         digit->SetSignal(0);
146         fLogger->Log(Form("%s:%d:Channel detElemId %d manuId %d "
147                         "manuChannel %d is bad %x",__FILE__,__LINE__,
148                           digit->DetElemId(),digit->ManuId(),
149                         digit->ManuChannel(),digit->StatusMap()));
150         continue;
151       }
152           
153       // If the channel is good, go on with the calibration itself.
154       
155       AliMUONVCalibParam* pedestal = static_cast<AliMUONVCalibParam*>
156         (fCalibrationData->Pedestals(digit->DetElemId(),digit->ManuId()));
157       
158       AliMUONVCalibParam* gain = static_cast<AliMUONVCalibParam*>
159         (fCalibrationData->Gains(digit->DetElemId(),digit->ManuId()));
160       
161       if (!pedestal)
162       {
163         AliFatal(Form("Got a null ped object for DE,manu=%d,%d",
164                       digit->DetElemId(),digit->ManuId()));
165         
166       }
167       if (!gain)
168       {
169         AliFatal(Form("Got a null gain object for DE,manu=%d,%d",
170                       digit->DetElemId(),digit->ManuId()));        
171       }
172       
173       Int_t manuChannel = digit->ManuChannel();
174       Float_t adc = digit->Signal();
175       Float_t padc = adc-pedestal->ValueAsFloat(manuChannel,0);
176       if ( padc < 3.0*pedestal->ValueAsFloat(manuChannel,1) ) 
177       {
178         padc = 0.0;
179       }
180       Float_t charge = padc*gain->ValueAsFloat(manuChannel,0);
181       digit->SetSignal(charge);
182       Int_t saturation = gain->ValueAsInt(manuChannel,1);
183       if ( charge >= saturation )
184       {
185         digit->Saturated(kTRUE);
186       }
187     }
188   }
189 }