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,
57 Bool_t createAndUseStatusMap)
59 fCalibrationData(calib),
61 fLogger(new AliMUONLogger(1000))
64 if (createAndUseStatusMap)
66 AliMUONPadStatusMaker maker(fCalibrationData);
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)
73 maker.SetHVSt12Limits(1300,1600);
74 maker.SetHVSt345Limits(1500,2000);
75 maker.SetPedMeanLimits(50,200);
76 maker.SetPedSigmaLimits(0.1,3);
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.
83 AliMUONPadStatusMapMaker mapMaker(fCalibrationData);
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 ;-)
91 fStatusMap = mapMaker.MakePadStatusMap(*status,mask);
97 // make a fake (empty) status map
98 fStatusMap = AliMUONPadStatusMapMaker::MakeEmptyPadStatusMap();
102 //_____________________________________________________________________________
103 AliMUONDigitCalibrator::~AliMUONDigitCalibrator()
108 AliInfo("Summary of messages:");
114 //_____________________________________________________________________________
116 AliMUONDigitCalibrator::Calibrate(AliMUONVDigitStore& digitStore)
118 /// Calibrate the digits contained in digitStore
119 TIter next(digitStore.CreateTrackerIterator());
120 AliMUONVDigit* digit;
122 while ( ( digit = static_cast<AliMUONVDigit*>(next() ) ) )
124 CalibrateDigit(*digit);
128 //_____________________________________________________________________________
130 AliMUONDigitCalibrator::CalibrateDigit(AliMUONVDigit& digit)
132 /// Calibrate one digit
134 if ( digit.IsCalibrated() )
136 fLogger->Log("ERROR : trying to calibrate a digit twice");
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 )
147 // pad itself is bad (not testing its neighbours at this stage)
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()));
156 // If the channel is good, go on with the calibration itself.
158 AliMUONVCalibParam* pedestal = static_cast<AliMUONVCalibParam*>
159 (fCalibrationData.Pedestals(digit.DetElemId(),digit.ManuId()));
161 AliMUONVCalibParam* gain = static_cast<AliMUONVCalibParam*>
162 (fCalibrationData.Gains(digit.DetElemId(),digit.ManuId()));
166 AliFatal(Form("Got a null ped object for DE,manu=%d,%d",
167 digit.DetElemId(),digit.ManuId()));
172 AliFatal(Form("Got a null gain object for DE,manu=%d,%d",
173 digit.DetElemId(),digit.ManuId()));
176 Int_t manuChannel = digit.ManuChannel();
177 Float_t adc = digit.ADC();
178 Float_t padc = adc-pedestal->ValueAsFloat(manuChannel,0);
180 if ( padc > 3.0*pedestal->ValueAsFloat(manuChannel,1) )
182 Float_t a0 = gain->ValueAsFloat(manuChannel,0);
183 Float_t a1 = gain->ValueAsFloat(manuChannel,1);
184 Int_t thres = gain->ValueAsInt(manuChannel,2);
191 charge = a0*thres + a0*(padc-thres) + a1*(padc-thres)*(padc-thres);
194 digit.SetCharge(charge);
195 Int_t saturation = gain->ValueAsInt(manuChannel,4);
196 if ( charge >= saturation )
198 digit.Saturated(kTRUE);