Fixing a bug. Cluster should not be deleted, as it is owned by the clusterfinder
[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"
21#include "AliMUONCalibrationData.h"
22#include "AliMUONConstants.h"
23#include "AliMUONData.h"
24#include "AliMUONDigit.h"
d1c20d08 25#include "AliMUONPadStatusMaker.h"
26#include "AliMUONPadStatusMapMaker.h"
27#include "AliMUONV2DStore.h"
c795d086 28#include "AliMUONVCalibParam.h"
d99769c3 29#include "TClonesArray.h"
30
7945aae7 31/// \class AliMUONDigitCalibrator
1171bb0a 32/// Class used to calibrate digits (either real or simulated ones).
33///
34/// The calibration consists of subtracting the pedestal
35/// and multiplying by a gain, so that
36/// Signal = (ADC-pedestal)*gain
37///
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
44/// bad digits).
45///
7945aae7 46/// \author Laurent Aphecetche
47
1171bb0a 48
7945aae7 49/// \cond CLASSIMP
d99769c3 50ClassImp(AliMUONDigitCalibrator)
7945aae7 51/// \endcond
d99769c3 52
53//_____________________________________________________________________________
54AliMUONDigitCalibrator::AliMUONDigitCalibrator(AliMUONData* muonData,
d1c20d08 55 AliMUONCalibrationData* calib)
56: TTask("AliMUONDigitCalibrator","Raw digit calibration"),
d99769c3 57 fData(muonData),
d1c20d08 58 fCalibrationData(calib),
59 fStatusMap(0x0)
d99769c3 60{
d1c20d08 61 /// ctor. This class needs the muonData to get access to the digit,
7945aae7 62 /// and the calibrationData to get access to calibration parameters.
d1c20d08 63
64 if (!calib) throw;
65
66 AliMUONPadStatusMaker maker(*calib);
67
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 it's HV
70 // was too low, or its pedestals too high, etc..)
71 //
72 maker.SetHVSt12Limits(1300,1600);
73 maker.SetHVSt345Limits(1500,2000);
74 maker.SetPedMeanLimits(50,200);
75 maker.SetPedSigmaLimits(0.1,3);
76
77 // From this set of limits, compute the status of all tracker pads.
78 AliMUONV2DStore* status = maker.MakeStatus();
79
80 AliMUONPadStatusMapMaker mapMaker;
81
82 Int_t mask(0x8000000);
83 //FIXME: fake one (consider dead only if ped mean too high or hv switch off)
84
85 fStatusMap = mapMaker.MakePadStatusMap(*status,mask);
86
87 delete status;
d99769c3 88}
89
90//_____________________________________________________________________________
91AliMUONDigitCalibrator::~AliMUONDigitCalibrator()
92{
d1c20d08 93 /// dtor.
94 delete fStatusMap;
d99769c3 95}
96
97//_____________________________________________________________________________
98void
99AliMUONDigitCalibrator::Exec(Option_t*)
100{
7945aae7 101 /// Main method.
102 /// We loop on tracking chambers (i.e. we do nothing for trigger)
103 /// and for each digit in that chamber, we calibrate it :
d1c20d08 104 /// a) we set its status map and if status is bad, set the signal to zero
7945aae7 105 /// b) we then apply pedestal and gain corrections.
c795d086 106
d99769c3 107 for ( Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ++ch )
108 {
109 TClonesArray* digitArray = fData->Digits(ch);
110 Int_t nDigits = digitArray->GetEntriesFast();
111 for ( Int_t d = 0; d < nDigits; ++d )
112 {
113 AliMUONDigit* digit =
114 static_cast<AliMUONDigit*>(digitArray->UncheckedAt(d));
115
d1c20d08 116 AliMUONVCalibParam* deadmap = static_cast<AliMUONVCalibParam*>
117 (fStatusMap->Get(digit->DetElemId(),digit->ManuId()));
118 Int_t statusMap = deadmap->ValueAsInt(digit->ManuChannel());
119 digit->SetStatusMap(statusMap);
120 if ( ( statusMap & AliMUONPadStatusMapMaker::SelfDeadMask() ) != 0 ) // pad itself is bad (not testing its neighbours at this stage)
c795d086 121 {
c795d086 122 digit->SetSignal(0);
d1c20d08 123 AliWarning(Form("Channel detElemId %d manuId %d "
124 "manuChannel %d is bad %x",digit->DetElemId(),digit->ManuId(),
125 digit->ManuChannel(),digit->StatusMap()));
c795d086 126 continue;
127 }
128
129 // If the channel is good, go on with the calibration itself.
130
131 AliMUONVCalibParam* pedestal = static_cast<AliMUONVCalibParam*>
1171bb0a 132 (fCalibrationData->Pedestals(digit->DetElemId(),digit->ManuId()));
c795d086 133
134 AliMUONVCalibParam* gain = static_cast<AliMUONVCalibParam*>
1171bb0a 135 (fCalibrationData->Gains(digit->DetElemId(),digit->ManuId()));
d99769c3 136
d99769c3 137 if (!pedestal)
138 {
c795d086 139 AliFatal(Form("Got a null ped object for DE,manu=%d,%d",
140 digit->DetElemId(),digit->ManuId()));
d99769c3 141
142 }
143 if (!gain)
144 {
c795d086 145 AliFatal(Form("Got a null gain object for DE,manu=%d,%d",
146 digit->DetElemId(),digit->ManuId()));
d99769c3 147 }
148
c795d086 149 Int_t manuChannel = digit->ManuChannel();
45dd3605 150 Float_t adc = digit->Signal();
c795d086 151 Float_t padc = adc-pedestal->ValueAsFloat(manuChannel,0);
152 if ( padc < 3.0*pedestal->ValueAsFloat(manuChannel,1) )
d99769c3 153 {
154 padc = 0.0;
155 }
c795d086 156 Float_t charge = padc*gain->ValueAsFloat(manuChannel,0);
45dd3605 157 digit->SetSignal(charge);
c795d086 158 Int_t saturation = gain->ValueAsInt(manuChannel,1);
45dd3605 159 if ( charge >= saturation )
c795d086 160 {
161 digit->Saturated(kTRUE);
162 }
d99769c3 163 }
164 }
165}