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 | |
3d1463c8 |
31 | //----------------------------------------------------------------------------- |
7945aae7 |
32 | /// \class AliMUONDigitCalibrator |
1171bb0a |
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 | /// |
7945aae7 |
47 | /// \author Laurent Aphecetche |
3d1463c8 |
48 | //----------------------------------------------------------------------------- |
7945aae7 |
49 | |
1171bb0a |
50 | |
7945aae7 |
51 | /// \cond CLASSIMP |
d99769c3 |
52 | ClassImp(AliMUONDigitCalibrator) |
7945aae7 |
53 | /// \endcond |
d99769c3 |
54 | |
55 | //_____________________________________________________________________________ |
49e396d9 |
56 | AliMUONDigitCalibrator::AliMUONDigitCalibrator(const AliMUONCalibrationData& calib) |
42825ed9 |
57 | : TObject(), |
49e396d9 |
58 | fLogger(new AliMUONLogger(1000)), |
59 | fStatusMaker(0x0), |
60 | fStatusMapMaker(0x0), |
61 | fPedestals(0x0), |
62 | fGains(0x0) |
d99769c3 |
63 | { |
42825ed9 |
64 | /// ctor |
49e396d9 |
65 | fStatusMaker = new AliMUONPadStatusMaker(calib); |
66 | |
67 | // this is here that we decide on our "goodness" policy, i.e. |
68 | // what do we call an invalid pad (a pad maybe bad because its HV |
69 | // was too low, or its pedestals too high, etc..) |
70 | // FIXME: find a way not to hard-code the goodness policy (i.e. the limits) |
71 | // here... |
72 | fStatusMaker->SetHVSt12Limits(1300,1600); |
73 | fStatusMaker->SetHVSt345Limits(1500,2000); |
74 | fStatusMaker->SetPedMeanLimits(50,200); |
75 | fStatusMaker->SetPedSigmaLimits(0.1,3); |
76 | |
77 | Int_t mask(0x8080); |
78 | //FIXME: kind of fake one for the moment, we consider dead only |
79 | // if ped and/or hv value missing. |
80 | //WARNING : getting this mask wrong is a very effective way of getting |
81 | //no digits at all out of this class ;-) |
82 | |
83 | Bool_t deferredInitialization = kTRUE; |
84 | |
85 | fStatusMapMaker = new AliMUONPadStatusMapMaker(*fStatusMaker,mask,deferredInitialization); |
86 | |
87 | fPedestals = calib.Pedestals(); |
88 | fGains = calib.Gains(); |
d99769c3 |
89 | } |
90 | |
91 | //_____________________________________________________________________________ |
92 | AliMUONDigitCalibrator::~AliMUONDigitCalibrator() |
93 | { |
d1c20d08 |
94 | /// dtor. |
49e396d9 |
95 | delete fStatusMaker; |
96 | delete fStatusMapMaker; |
fe6ed686 |
97 | |
98 | AliInfo("Summary of messages:"); |
99 | fLogger->Print(); |
100 | |
101 | delete fLogger; |
d99769c3 |
102 | } |
103 | |
104 | //_____________________________________________________________________________ |
105 | void |
42825ed9 |
106 | AliMUONDigitCalibrator::Calibrate(AliMUONVDigitStore& digitStore) |
d99769c3 |
107 | { |
42825ed9 |
108 | /// Calibrate the digits contained in digitStore |
109 | TIter next(digitStore.CreateTrackerIterator()); |
110 | AliMUONVDigit* digit; |
c795d086 |
111 | |
42825ed9 |
112 | while ( ( digit = static_cast<AliMUONVDigit*>(next() ) ) ) |
d99769c3 |
113 | { |
42825ed9 |
114 | CalibrateDigit(*digit); |
115 | } |
116 | } |
117 | |
118 | //_____________________________________________________________________________ |
119 | void |
120 | AliMUONDigitCalibrator::CalibrateDigit(AliMUONVDigit& digit) |
121 | { |
122 | /// Calibrate one digit |
123 | |
cf27231a |
124 | if ( digit.IsCalibrated() ) |
125 | { |
126 | fLogger->Log("ERROR : trying to calibrate a digit twice"); |
127 | return; |
128 | } |
129 | |
49e396d9 |
130 | Int_t statusMap = fStatusMapMaker->StatusMap(digit.DetElemId(), |
131 | digit.ManuId(), |
132 | digit.ManuChannel()); |
133 | |
42825ed9 |
134 | digit.SetStatusMap(statusMap); |
135 | digit.Calibrated(kTRUE); |
49e396d9 |
136 | |
42825ed9 |
137 | if ( ( statusMap & AliMUONPadStatusMapMaker::SelfDeadMask() ) != 0 ) |
138 | { |
139 | // pad itself is bad (not testing its neighbours at this stage) |
140 | digit.SetCharge(0); |
141 | fLogger->Log(Form("%s:%d:Channel detElemId %d manuId %d " |
142 | "manuChannel %d is bad %x",__FILE__,__LINE__, |
143 | digit.DetElemId(),digit.ManuId(), |
144 | digit.ManuChannel(),digit.StatusMap())); |
145 | } |
146 | else |
147 | { |
148 | // If the channel is good, go on with the calibration itself. |
149 | |
150 | AliMUONVCalibParam* pedestal = static_cast<AliMUONVCalibParam*> |
49e396d9 |
151 | (fPedestals->FindObject(digit.DetElemId(),digit.ManuId())); |
42825ed9 |
152 | |
153 | AliMUONVCalibParam* gain = static_cast<AliMUONVCalibParam*> |
49e396d9 |
154 | (fGains->FindObject(digit.DetElemId(),digit.ManuId())); |
42825ed9 |
155 | |
156 | if (!pedestal) |
d99769c3 |
157 | { |
42825ed9 |
158 | AliFatal(Form("Got a null ped object for DE,manu=%d,%d", |
159 | digit.DetElemId(),digit.ManuId())); |
c795d086 |
160 | |
42825ed9 |
161 | } |
162 | if (!gain) |
163 | { |
164 | AliFatal(Form("Got a null gain object for DE,manu=%d,%d", |
165 | digit.DetElemId(),digit.ManuId())); |
166 | } |
167 | |
168 | Int_t manuChannel = digit.ManuChannel(); |
169 | Float_t adc = digit.ADC(); |
170 | Float_t padc = adc-pedestal->ValueAsFloat(manuChannel,0); |
cf27231a |
171 | Float_t charge(0); |
172 | if ( padc > 3.0*pedestal->ValueAsFloat(manuChannel,1) ) |
42825ed9 |
173 | { |
cf27231a |
174 | Float_t a0 = gain->ValueAsFloat(manuChannel,0); |
175 | Float_t a1 = gain->ValueAsFloat(manuChannel,1); |
176 | Int_t thres = gain->ValueAsInt(manuChannel,2); |
177 | if ( padc < thres ) |
178 | { |
179 | charge = a0*padc; |
180 | } |
181 | else |
182 | { |
b7e22562 |
183 | charge = a0*thres + a0*(padc-thres) + a1*(padc-thres)*(padc-thres); |
cf27231a |
184 | } |
42825ed9 |
185 | } |
42825ed9 |
186 | digit.SetCharge(charge); |
cf27231a |
187 | Int_t saturation = gain->ValueAsInt(manuChannel,4); |
42825ed9 |
188 | if ( charge >= saturation ) |
189 | { |
190 | digit.Saturated(kTRUE); |
d99769c3 |
191 | } |
192 | } |
193 | } |