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 /// \class AliMUONDigitCalibrator
32 /// Class used to calibrate digits (either real or simulated ones).
34 /// The calibration consists of subtracting the pedestal
35 /// and multiplying by a gain, so that
36 /// Signal = (ADC-pedestal)*gain
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
46 /// \author Laurent Aphecetche
50 ClassImp(AliMUONDigitCalibrator)
53 //_____________________________________________________________________________
54 AliMUONDigitCalibrator::AliMUONDigitCalibrator(const AliMUONCalibrationData& calib,
55 Bool_t createAndUseStatusMap)
57 fCalibrationData(calib),
59 fLogger(new AliMUONLogger(1000))
62 if (createAndUseStatusMap)
64 AliMUONPadStatusMaker maker(fCalibrationData);
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)
71 maker.SetHVSt12Limits(1300,1600);
72 maker.SetHVSt345Limits(1500,2000);
73 maker.SetPedMeanLimits(50,200);
74 maker.SetPedSigmaLimits(0.1,3);
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.
81 AliMUONPadStatusMapMaker mapMaker(fCalibrationData);
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 ;-)
89 fStatusMap = mapMaker.MakePadStatusMap(*status,mask);
95 // make a fake (empty) status map
96 fStatusMap = AliMUONPadStatusMapMaker::MakeEmptyPadStatusMap();
100 //_____________________________________________________________________________
101 AliMUONDigitCalibrator::~AliMUONDigitCalibrator()
106 AliInfo("Summary of messages:");
112 //_____________________________________________________________________________
114 AliMUONDigitCalibrator::Calibrate(AliMUONVDigitStore& digitStore)
116 /// Calibrate the digits contained in digitStore
117 TIter next(digitStore.CreateTrackerIterator());
118 AliMUONVDigit* digit;
120 while ( ( digit = static_cast<AliMUONVDigit*>(next() ) ) )
122 CalibrateDigit(*digit);
126 //_____________________________________________________________________________
128 AliMUONDigitCalibrator::CalibrateDigit(AliMUONVDigit& digit)
130 /// Calibrate one digit
132 if ( digit.IsCalibrated() )
134 fLogger->Log("ERROR : trying to calibrate a digit twice");
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 )
145 // pad itself is bad (not testing its neighbours at this stage)
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()));
154 // If the channel is good, go on with the calibration itself.
156 AliMUONVCalibParam* pedestal = static_cast<AliMUONVCalibParam*>
157 (fCalibrationData.Pedestals(digit.DetElemId(),digit.ManuId()));
159 AliMUONVCalibParam* gain = static_cast<AliMUONVCalibParam*>
160 (fCalibrationData.Gains(digit.DetElemId(),digit.ManuId()));
164 AliFatal(Form("Got a null ped object for DE,manu=%d,%d",
165 digit.DetElemId(),digit.ManuId()));
170 AliFatal(Form("Got a null gain object for DE,manu=%d,%d",
171 digit.DetElemId(),digit.ManuId()));
174 Int_t manuChannel = digit.ManuChannel();
175 Float_t adc = digit.ADC();
176 Float_t padc = adc-pedestal->ValueAsFloat(manuChannel,0);
178 if ( padc > 3.0*pedestal->ValueAsFloat(manuChannel,1) )
180 Float_t a0 = gain->ValueAsFloat(manuChannel,0);
181 Float_t a1 = gain->ValueAsFloat(manuChannel,1);
182 Int_t thres = gain->ValueAsInt(manuChannel,2);
189 charge = a0*thres + a0*(padc-thres) + a1*(padc-thres)*(padc-thres);
192 digit.SetCharge(charge);
193 Int_t saturation = gain->ValueAsInt(manuChannel,4);
194 if ( charge >= saturation )
196 digit.Saturated(kTRUE);