b0c2ae4330e8a662abf89f7ad1fc7f0e76dc170f
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitCalibrator.cxx
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
20 #include "AliLog.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"
30
31 /// \class AliMUONDigitCalibrator
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 ///
46 /// \author Laurent Aphecetche
47
48
49 /// \cond CLASSIMP
50 ClassImp(AliMUONDigitCalibrator)
51 /// \endcond
52
53 //_____________________________________________________________________________
54 AliMUONDigitCalibrator::AliMUONDigitCalibrator(const AliMUONCalibrationData& calib,
55                                                Bool_t createAndUseStatusMap)
56 : TObject(),
57 fCalibrationData(calib),
58 fStatusMap(0x0),
59 fLogger(new AliMUONLogger(1000))
60 {
61   /// ctor
62   if (createAndUseStatusMap) 
63   {
64     AliMUONPadStatusMaker maker(fCalibrationData);
65     
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)
70     // here...
71     maker.SetHVSt12Limits(1300,1600);
72     maker.SetHVSt345Limits(1500,2000);
73     maker.SetPedMeanLimits(50,200);
74     maker.SetPedSigmaLimits(0.1,3);
75     
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.
80     
81     AliMUONPadStatusMapMaker mapMaker(fCalibrationData);
82     
83     Int_t mask(0x8080); 
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 ;-)
88     
89     fStatusMap = mapMaker.MakePadStatusMap(*status,mask);
90     
91     delete status;
92     }
93   else
94   {
95     // make a fake (empty) status map
96     fStatusMap = AliMUONPadStatusMapMaker::MakeEmptyPadStatusMap();
97   }
98 }
99
100 //_____________________________________________________________________________
101 AliMUONDigitCalibrator::~AliMUONDigitCalibrator()
102 {
103   /// dtor.
104   delete fStatusMap;
105   
106   AliInfo("Summary of messages:");
107   fLogger->Print();
108
109   delete fLogger;
110 }
111
112 //_____________________________________________________________________________
113 void
114 AliMUONDigitCalibrator::Calibrate(AliMUONVDigitStore& digitStore)
115 {
116   /// Calibrate the digits contained in digitStore  
117   TIter next(digitStore.CreateTrackerIterator());
118   AliMUONVDigit* digit;
119   
120   while ( ( digit = static_cast<AliMUONVDigit*>(next() ) ) )
121   {
122     CalibrateDigit(*digit);
123   }
124 }
125
126 //_____________________________________________________________________________
127 void
128 AliMUONDigitCalibrator::CalibrateDigit(AliMUONVDigit& digit)
129 {
130   /// Calibrate one digit
131   
132   AliMUONVCalibParam* deadmap = static_cast<AliMUONVCalibParam*>
133   (fStatusMap->FindObject(digit.DetElemId(),digit.ManuId()));
134   Int_t statusMap = deadmap->ValueAsInt(digit.ManuChannel());
135   digit.SetStatusMap(statusMap);
136   digit.Calibrated(kTRUE);
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*>
151     (fCalibrationData.Pedestals(digit.DetElemId(),digit.ManuId()));
152     
153     AliMUONVCalibParam* gain = static_cast<AliMUONVCalibParam*>
154       (fCalibrationData.Gains(digit.DetElemId(),digit.ManuId()));
155     
156     if (!pedestal)
157     {
158       AliFatal(Form("Got a null ped object for DE,manu=%d,%d",
159                     digit.DetElemId(),digit.ManuId()));
160       
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);
171     if ( padc < 3.0*pedestal->ValueAsFloat(manuChannel,1) ) 
172     {
173       padc = 0.0;
174     }
175     Float_t charge = padc*gain->ValueAsFloat(manuChannel,0);
176     digit.SetCharge(charge);
177     Int_t saturation = gain->ValueAsInt(manuChannel,1);
178     if ( charge >= saturation )
179     {
180       digit.Saturated(kTRUE);
181     }
182   }
183 }