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