Adding main class for the mchview program
[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//_____________________________________________________________________________
49e396d9 56AliMUONDigitCalibrator::AliMUONDigitCalibrator(const AliMUONCalibrationData& calib)
42825ed9 57: TObject(),
49e396d9 58fLogger(new AliMUONLogger(1000)),
59fStatusMaker(0x0),
60fStatusMapMaker(0x0),
61fPedestals(0x0),
62fGains(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
1171bb0a 91//_____________________________________________________________________________
d99769c3 92AliMUONDigitCalibrator::~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//_____________________________________________________________________________
105void
42825ed9 106AliMUONDigitCalibrator::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//_____________________________________________________________________________
119void
120AliMUONDigitCalibrator::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}