d99769c3 |
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 | |
d99769c3 |
20 | #include "AliLog.h" |
42825ed9 |
21 | #include "AliMpConstants.h" |
d99769c3 |
22 | #include "AliMUONCalibrationData.h" |
42825ed9 |
23 | #include "AliMUONVDigit.h" |
24 | #include "AliMUONVDigitStore.h" |
fe6ed686 |
25 | #include "AliMUONLogger.h" |
d1c20d08 |
26 | #include "AliMUONPadStatusMaker.h" |
27 | #include "AliMUONPadStatusMapMaker.h" |
42825ed9 |
28 | #include "AliMUONVStore.h" |
c795d086 |
29 | #include "AliMUONVCalibParam.h" |
d99769c3 |
30 | |
7945aae7 |
31 | /// \class AliMUONDigitCalibrator |
1171bb0a |
32 | /// Class used to calibrate digits (either real or simulated ones). |
33 | /// |
34 | /// The calibration consists of subtracting the pedestal |
35 | /// and multiplying by a gain, so that |
36 | /// Signal = (ADC-pedestal)*gain |
37 | /// |
38 | /// Please note also that for the moment, if a digit lies on a dead channel |
39 | /// we remove this digit from the list of digits. |
40 | /// FIXME: this has to be revisited. By using the AliMUONDigit::fFlags we |
41 | /// should in principle flag a digit as bad w/o removing it, but this |
42 | /// then requires some changes in the cluster finder to deal with this extra |
43 | /// information correctly (e.g. to set a quality for the cluster if it contains |
44 | /// bad digits). |
45 | /// |
7945aae7 |
46 | /// \author Laurent Aphecetche |
47 | |
1171bb0a |
48 | |
7945aae7 |
49 | /// \cond CLASSIMP |
d99769c3 |
50 | ClassImp(AliMUONDigitCalibrator) |
7945aae7 |
51 | /// \endcond |
d99769c3 |
52 | |
53 | //_____________________________________________________________________________ |
42825ed9 |
54 | AliMUONDigitCalibrator::AliMUONDigitCalibrator(const AliMUONCalibrationData& calib, |
20356e33 |
55 | Bool_t createAndUseStatusMap) |
42825ed9 |
56 | : TObject(), |
57 | fCalibrationData(calib), |
58 | fStatusMap(0x0), |
59 | fLogger(new AliMUONLogger(1000)) |
d99769c3 |
60 | { |
42825ed9 |
61 | /// ctor |
62 | if (createAndUseStatusMap) |
63 | { |
64 | AliMUONPadStatusMaker maker(fCalibrationData); |
d1c20d08 |
65 | |
42825ed9 |
66 | // this is here that we decide on our "goodness" policy, i.e. |
67 | // what do we call an invalid pad (a pad maybe bad because its HV |
68 | // was too low, or its pedestals too high, etc..) |
69 | // FIXME: find a way not to hard-code the goodness policy (i.e. the limits) |
70 | // here... |
71 | maker.SetHVSt12Limits(1300,1600); |
72 | maker.SetHVSt345Limits(1500,2000); |
73 | maker.SetPedMeanLimits(50,200); |
74 | maker.SetPedSigmaLimits(0.1,3); |
d1c20d08 |
75 | |
42825ed9 |
76 | // From this set of limits, compute the status of all tracker pads. |
77 | AliMUONVStore* status = maker.MakeStatus(); |
78 | // we do not check that status is != 0x0, as this is supposed to be |
79 | // the responsability of the padStatusMaker. |
80 | |
81 | AliMUONPadStatusMapMaker mapMaker(fCalibrationData); |
82 | |
83 | Int_t mask(0x8080); |
84 | //FIXME: kind of fake one for the moment, we consider dead only |
85 | // if ped and/or hv value missing. |
86 | //WARNING : getting this mask wrong is a very effective way of getting |
87 | //no digits at all out of this class ;-) |
88 | |
89 | fStatusMap = mapMaker.MakePadStatusMap(*status,mask); |
90 | |
91 | delete status; |
20356e33 |
92 | } |
42825ed9 |
93 | else |
94 | { |
95 | // make a fake (empty) status map |
96 | fStatusMap = AliMUONPadStatusMapMaker::MakeEmptyPadStatusMap(); |
97 | } |
d99769c3 |
98 | } |
99 | |
100 | //_____________________________________________________________________________ |
101 | AliMUONDigitCalibrator::~AliMUONDigitCalibrator() |
102 | { |
d1c20d08 |
103 | /// dtor. |
104 | delete fStatusMap; |
fe6ed686 |
105 | |
106 | AliInfo("Summary of messages:"); |
107 | fLogger->Print(); |
108 | |
109 | delete fLogger; |
d99769c3 |
110 | } |
111 | |
112 | //_____________________________________________________________________________ |
113 | void |
42825ed9 |
114 | AliMUONDigitCalibrator::Calibrate(AliMUONVDigitStore& digitStore) |
d99769c3 |
115 | { |
42825ed9 |
116 | /// Calibrate the digits contained in digitStore |
117 | TIter next(digitStore.CreateTrackerIterator()); |
118 | AliMUONVDigit* digit; |
c795d086 |
119 | |
42825ed9 |
120 | while ( ( digit = static_cast<AliMUONVDigit*>(next() ) ) ) |
d99769c3 |
121 | { |
42825ed9 |
122 | CalibrateDigit(*digit); |
123 | } |
124 | } |
125 | |
126 | //_____________________________________________________________________________ |
127 | void |
128 | AliMUONDigitCalibrator::CalibrateDigit(AliMUONVDigit& digit) |
129 | { |
130 | /// Calibrate one digit |
131 | |
cf27231a |
132 | if ( digit.IsCalibrated() ) |
133 | { |
134 | fLogger->Log("ERROR : trying to calibrate a digit twice"); |
135 | return; |
136 | } |
137 | |
42825ed9 |
138 | AliMUONVCalibParam* deadmap = static_cast<AliMUONVCalibParam*> |
139 | (fStatusMap->FindObject(digit.DetElemId(),digit.ManuId())); |
140 | Int_t statusMap = deadmap->ValueAsInt(digit.ManuChannel()); |
141 | digit.SetStatusMap(statusMap); |
142 | digit.Calibrated(kTRUE); |
143 | if ( ( statusMap & AliMUONPadStatusMapMaker::SelfDeadMask() ) != 0 ) |
144 | { |
145 | // pad itself is bad (not testing its neighbours at this stage) |
146 | digit.SetCharge(0); |
147 | fLogger->Log(Form("%s:%d:Channel detElemId %d manuId %d " |
148 | "manuChannel %d is bad %x",__FILE__,__LINE__, |
149 | digit.DetElemId(),digit.ManuId(), |
150 | digit.ManuChannel(),digit.StatusMap())); |
151 | } |
152 | else |
153 | { |
154 | // If the channel is good, go on with the calibration itself. |
155 | |
156 | AliMUONVCalibParam* pedestal = static_cast<AliMUONVCalibParam*> |
157 | (fCalibrationData.Pedestals(digit.DetElemId(),digit.ManuId())); |
158 | |
159 | AliMUONVCalibParam* gain = static_cast<AliMUONVCalibParam*> |
160 | (fCalibrationData.Gains(digit.DetElemId(),digit.ManuId())); |
161 | |
162 | if (!pedestal) |
d99769c3 |
163 | { |
42825ed9 |
164 | AliFatal(Form("Got a null ped object for DE,manu=%d,%d", |
165 | digit.DetElemId(),digit.ManuId())); |
c795d086 |
166 | |
42825ed9 |
167 | } |
168 | if (!gain) |
169 | { |
170 | AliFatal(Form("Got a null gain object for DE,manu=%d,%d", |
171 | digit.DetElemId(),digit.ManuId())); |
172 | } |
173 | |
174 | Int_t manuChannel = digit.ManuChannel(); |
175 | Float_t adc = digit.ADC(); |
176 | Float_t padc = adc-pedestal->ValueAsFloat(manuChannel,0); |
cf27231a |
177 | Float_t charge(0); |
178 | if ( padc > 3.0*pedestal->ValueAsFloat(manuChannel,1) ) |
42825ed9 |
179 | { |
cf27231a |
180 | Float_t a0 = gain->ValueAsFloat(manuChannel,0); |
181 | Float_t a1 = gain->ValueAsFloat(manuChannel,1); |
182 | Int_t thres = gain->ValueAsInt(manuChannel,2); |
183 | if ( padc < thres ) |
184 | { |
185 | charge = a0*padc; |
186 | } |
187 | else |
188 | { |
189 | charge = a0*thres + a0*padc + a1*padc*padc; |
190 | } |
42825ed9 |
191 | } |
42825ed9 |
192 | digit.SetCharge(charge); |
cf27231a |
193 | Int_t saturation = gain->ValueAsInt(manuChannel,4); |
42825ed9 |
194 | if ( charge >= saturation ) |
195 | { |
196 | digit.Saturated(kTRUE); |
d99769c3 |
197 | } |
198 | } |
199 | } |