1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 #include "AliMUONDigitCalibrator.h"
21 #include "AliMpConstants.h"
22 #include "AliMUONCalibrationData.h"
23 #include "AliMUONVDigit.h"
24 #include "AliMUONVDigitStore.h"
25 #include "AliMUONLogger.h"
26 #include "AliMUONPadStatusMaker.h"
27 #include "AliMUONPadStatusMapMaker.h"
28 #include "AliMUONVStore.h"
29 #include "AliMUONVCalibParam.h"
31 //-----------------------------------------------------------------------------
32 /// \class AliMUONDigitCalibrator
33 /// Class used to calibrate digits (either real or simulated ones).
35 /// The calibration consists of subtracting the pedestal
36 /// and multiplying by a gain, so that
37 /// Signal = (ADC-pedestal)*gain
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
47 /// \author Laurent Aphecetche
48 //-----------------------------------------------------------------------------
52 ClassImp(AliMUONDigitCalibrator)
55 //_____________________________________________________________________________
56 AliMUONDigitCalibrator::AliMUONDigitCalibrator(const AliMUONCalibrationData& calib)
58 fLogger(new AliMUONLogger(1000)),
65 fStatusMaker = new AliMUONPadStatusMaker(calib);
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)
72 fStatusMaker->SetHVSt12Limits(1300,1600);
73 fStatusMaker->SetHVSt345Limits(1500,2000);
74 fStatusMaker->SetPedMeanLimits(50,200);
75 fStatusMaker->SetPedSigmaLimits(0.1,3);
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 ;-)
83 Bool_t deferredInitialization = kTRUE;
85 fStatusMapMaker = new AliMUONPadStatusMapMaker(*fStatusMaker,mask,deferredInitialization);
87 fPedestals = calib.Pedestals();
88 fGains = calib.Gains();
91 //_____________________________________________________________________________
92 AliMUONDigitCalibrator::~AliMUONDigitCalibrator()
96 delete fStatusMapMaker;
98 AliInfo("Summary of messages:");
104 //_____________________________________________________________________________
106 AliMUONDigitCalibrator::Calibrate(AliMUONVDigitStore& digitStore)
108 /// Calibrate the digits contained in digitStore
109 TIter next(digitStore.CreateTrackerIterator());
110 AliMUONVDigit* digit;
112 while ( ( digit = static_cast<AliMUONVDigit*>(next() ) ) )
114 CalibrateDigit(*digit);
118 //_____________________________________________________________________________
120 AliMUONDigitCalibrator::CalibrateDigit(AliMUONVDigit& digit)
122 /// Calibrate one digit
124 if ( digit.IsCalibrated() )
126 fLogger->Log("ERROR : trying to calibrate a digit twice");
130 Int_t statusMap = fStatusMapMaker->StatusMap(digit.DetElemId(),
132 digit.ManuChannel());
134 digit.SetStatusMap(statusMap);
135 digit.Calibrated(kTRUE);
137 if ( ( statusMap & AliMUONPadStatusMapMaker::SelfDeadMask() ) != 0 )
139 // pad itself is bad (not testing its neighbours at this stage)
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()));
148 // If the channel is good, go on with the calibration itself.
150 AliMUONVCalibParam* pedestal = static_cast<AliMUONVCalibParam*>
151 (fPedestals->FindObject(digit.DetElemId(),digit.ManuId()));
153 AliMUONVCalibParam* gain = static_cast<AliMUONVCalibParam*>
154 (fGains->FindObject(digit.DetElemId(),digit.ManuId()));
158 AliFatal(Form("Got a null ped object for DE,manu=%d,%d",
159 digit.DetElemId(),digit.ManuId()));
164 AliFatal(Form("Got a null gain object for DE,manu=%d,%d",
165 digit.DetElemId(),digit.ManuId()));
168 Int_t manuChannel = digit.ManuChannel();
169 Float_t adc = digit.ADC();
170 Float_t padc = adc-pedestal->ValueAsFloat(manuChannel,0);
172 if ( padc > 3.0*pedestal->ValueAsFloat(manuChannel,1) )
174 Float_t a0 = gain->ValueAsFloat(manuChannel,0);
175 Float_t a1 = gain->ValueAsFloat(manuChannel,1);
176 Int_t thres = gain->ValueAsInt(manuChannel,2);
183 charge = a0*thres + a0*(padc-thres) + a1*(padc-thres)*(padc-thres);
186 digit.SetCharge(charge);
187 Int_t saturation = gain->ValueAsInt(manuChannel,4);
188 if ( charge >= saturation )
190 digit.Saturated(kTRUE);