1 #include "AliFMDESDFixer.h"
3 #include "AliFMDStripIndex.h"
4 #include "AliForwardUtil.h"
5 #include "AliForwardCorrectionManager.h"
6 #include "AliFMDCorrNoiseGain.h"
16 //____________________________________________________________________
17 AliFMDESDFixer::AliFMDESDFixer()
21 fRecalculateEta(true),
24 fInvalidIsEmpty(false),
30 //____________________________________________________________________
31 AliFMDESDFixer::AliFMDESDFixer(const char*)
35 fRecalculateEta(false),
36 fXtraDead(AliFMDStripIndex::Pack(3,'O',19,511)+1),
38 fInvalidIsEmpty(false),
45 //____________________________________________________________________
46 AliFMDESDFixer::AliFMDESDFixer(const AliFMDESDFixer& o)
48 fRecoFactor(o.fRecoFactor),
49 fMaxNoiseCorr(o.fMaxNoiseCorr),
50 fRecalculateEta(o.fRecalculateEta),
51 fXtraDead(o.fXtraDead),
52 fHasXtraDead(o.fHasXtraDead),
53 fInvalidIsEmpty(o.fInvalidIsEmpty),
59 //____________________________________________________________________
61 AliFMDESDFixer::operator=(const AliFMDESDFixer& o)
63 if (&o == this) return *this;
65 fRecoFactor = o.fRecoFactor;
66 fMaxNoiseCorr = o.fMaxNoiseCorr;
67 fRecalculateEta = o.fRecalculateEta;
68 fXtraDead = o.fXtraDead;
69 fHasXtraDead = o.fHasXtraDead;
70 fInvalidIsEmpty = o.fInvalidIsEmpty;
78 //____________________________________________________________________
80 AliFMDESDFixer::CreateOutputObjects(TList* l)
83 d->SetName(GetName());
86 d->Add(AliForwardUtil::MakeParameter("recoFactor", fRecoFactor));
87 d->Add(AliForwardUtil::MakeParameter("recalcEta", fRecalculateEta));
88 d->Add(AliForwardUtil::MakeParameter("invalidIsEmpty", fInvalidIsEmpty));
90 fNoiseChange = new TH1D("noiseChange", "#delta#Delta due to noise",30,0,.3);
91 fNoiseChange->SetDirectory(0);
92 fNoiseChange->SetFillColor(kYellow+1);
93 fNoiseChange->SetFillStyle(3001);
96 fEtaChange = new TH1D("etaChange", "#delta#eta",40,-1,1);
97 fEtaChange->SetDirectory(0);
98 fEtaChange->SetFillColor(kCyan+1);
99 fEtaChange->SetFillStyle(3001);
102 fDeadChange = new TH1D("deadChange", "#deltaN_{dead}",100,0,51200);
103 fDeadChange->SetDirectory(0);
104 fDeadChange->SetFillColor(kMagenta+1);
105 fDeadChange->SetFillStyle(3001);
108 TObjArray* extraDead = new TObjArray;
109 extraDead->SetOwner();
110 extraDead->SetName("extraDead");
112 UInt_t firstBit = fXtraDead.FirstSetBit();
113 UInt_t nBits = fXtraDead.GetNbits();
114 for (UInt_t i = firstBit; i < nBits; i++) {
115 if (!fXtraDead.TestBitNumber(i)) continue;
118 AliFMDStripIndex::Unpack(i, dd, r, s, t);
119 extraDead->Add(AliForwardUtil::MakeParameter(Form("FMD%d%c[%02d,%03d]",
124 fHasXtraDead = nBits > 0;
128 //____________________________________________________________________
130 AliFMDESDFixer::AddDead(UShort_t d, Char_t r, UShort_t s, UShort_t t)
132 if (d < 1 || d > 3) {
133 Warning("AddDead", "Invalid detector FMD%d", d);
136 Bool_t inner = (r == 'I' || r == 'i');
137 if (d == 1 && !inner) {
138 Warning("AddDead", "Invalid ring FMD%d%c", d, r);
141 if ((inner && s >= 20) || (!inner && s >= 40)) {
142 Warning("AddDead", "Invalid sector FMD%d%c[%02d]", d, r, s);
145 if ((inner && t >= 512) || (!inner && t >= 256)) {
146 Warning("AddDead", "Invalid strip FMD%d%c[%02d,%03d]", d, r, s, t);
150 Int_t id = AliFMDStripIndex::Pack(d, r, s, t);
152 fXtraDead.SetBitNumber(id, true);
154 //____________________________________________________________________
156 AliFMDESDFixer::AddDeadRegion(UShort_t d, Char_t r,
157 UShort_t s1, UShort_t s2,
158 UShort_t t1, UShort_t t2)
160 // Add a dead region spanning from FMD<d><r>[<s1>,<t1>] to
161 // FMD<d><r>[<s2>,<t2>] (both inclusive)
162 for (Int_t s = s1; s <= s2; s++)
163 for (Int_t t = t1; t <= t2; t++)
166 //____________________________________________________________________
168 AliFMDESDFixer::AddDead(const Char_t* script)
170 if (!script || script[0] == '\0') return;
172 gROOT->Macro(Form("%s((AliFMDESDFixer*)%p);", script, this));
175 //____________________________________________________________________
177 AliFMDESDFixer::IsDead(UShort_t d, Char_t r, UShort_t s, UShort_t t) const
179 Int_t id = AliFMDStripIndex::Pack(d, r, s, t);
180 return fXtraDead.TestBitNumber(id);
183 //____________________________________________________________________
185 AliFMDESDFixer::FindTargetNoiseFactor(const AliESDFMD& esd, Bool_t check) const
187 if (!IsUseNoiseCorrection())
188 // If the reconstruction factor was high (4 or more), do nothing
192 if (AliESDFMD::Class_Version() < 4) {
193 // IF we running with older STEER - we fix it here
197 if (!esd.TestBit(1 << 14)) {
198 // If the bit isn't set, do nothing
202 // Uncommented until Peter commits patch to STEER/ESD
203 if (!esd.NeedNoiseFix()) {
204 // If the bit isn't set, do nothing
208 target = Int_t(esd.GetNoiseFactor());
210 // Get the target factor - even thought the method below returns a
211 // floating point value, we know that the noise factor is always
212 // integer, so we coerce it to be the same here.
213 target -= fRecoFactor;
215 // If the target factor is the same or smaller than the assumed
216 // factor, we have nothing to do here, and we return immediately
217 if (target <= 0) return 0;
219 // Get the scaled noise from the correction mananger
220 if (check && !AliForwardCorrectionManager::Instance().GetNoiseGain())
226 //____________________________________________________________________
227 #define ETA2COS(ETA) \
228 TMath::Cos(2*TMath::ATan(TMath::Exp(-TMath::Abs(ETA))))
230 //____________________________________________________________________
232 AliFMDESDFixer::Fix(AliESDFMD& esd, Double_t zvtx)
235 const AliFMDCorrNoiseGain* ng = 0;
236 Int_t tgtFactor = FindTargetNoiseFactor(esd, false);
238 ng = AliForwardCorrectionManager::Instance().GetNoiseGain();
240 if (!ng && !fHasXtraDead && !fRecalculateEta && !fInvalidIsEmpty)
241 // We have nothing to do!
245 for (UShort_t d = 1; d <= 3; d++) {
246 UShort_t nQ = d == 1 ? 1 : 2;
248 for (UShort_t q = 0; q < nQ; q++) {
249 Char_t r = (q == 0 ? 'I' : 'O');
250 UShort_t nS = (q == 0 ? 20 : 40);
251 UShort_t nT = (q == 0 ? 512 : 256);
253 for (UShort_t s = 0; s < nS; s++) {
254 for (UShort_t t = 0; t < nT; t++) {
255 Double_t mult = esd.Multiplicity(d,r,s,t);
256 Double_t eta = esd.Eta(d,r,s,t);
257 Double_t cosTheta = 0;
259 if (CheckDead(d,r,s,t,mult)) nDead++;
261 // Possibly re-calculate eta
262 if (fRecalculateEta) RecalculateEta(d,r,s,t,zvtx,eta,mult,cosTheta);
264 // Possibly correct for poor treatment of ZS in reconstruction.
265 if (ng && mult != AliESDFMD::kInvalidMult) {
266 if (cosTheta <= 0) cosTheta = ETA2COS(eta);
267 if (!NoiseCorrect(tgtFactor,ng->Get(d,r,s,t), cosTheta, mult))
271 // Write out final values to object
272 if (mult >= AliESDFMD::kInvalidMult) mult = AliESDFMD::kInvalidMult;
273 esd.SetMultiplicity(d,r,s,t,mult);
274 esd.SetEta(d,r,s,t,eta);
279 fDeadChange->Fill(nDead);
282 //____________________________________________________________________
284 AliFMDESDFixer::CheckDead(UShort_t d, Char_t r, UShort_t s, UShort_t t,
287 // Correct for zero's being flagged as invalid
288 if (mult == AliESDFMD::kInvalidMult && fInvalidIsEmpty) mult = 0;
290 // Take into account what we're defined as dead
291 if (IsDead(d,r,s,t)) {
292 mult = AliESDFMD::kInvalidMult;
298 //____________________________________________________________________
300 AliFMDESDFixer::RecalculateEta(UShort_t d, Char_t r, UShort_t s, UShort_t t,
301 Double_t zvtx, Double_t& eta, Double_t& mult,
304 Double_t oldEta = eta;
305 Double_t newEta = AliForwardUtil::GetEtaFromStrip(d,r,s,t, zvtx);
308 fEtaChange->Fill(newEta-oldEta);
310 if (mult == AliESDFMD::kInvalidMult) return;
312 Double_t newCos = ETA2COS(newEta);
313 Double_t oldCos = ETA2COS(oldEta);
314 Double_t corr = newCos / oldCos;
318 //____________________________________________________________________
320 AliFMDESDFixer::NoiseCorrect(Int_t target, Double_t corr, Double_t cosTheta,
323 if (corr > fMaxNoiseCorr || corr <= 0) {
324 mult = AliESDFMD::kInvalidMult;
327 Double_t add = corr * target * cosTheta;
328 fNoiseChange->Fill(add);
334 #define PF(N,V,...) \
335 AliForwardUtil::PrintField(N,V, ## __VA_ARGS__)
336 #define PFB(N,FLAG) \
338 AliForwardUtil::PrintName(N); \
339 std::cout << std::boolalpha << (FLAG) << std::noboolalpha << std::endl; \
341 #define PFV(N,VALUE) \
343 AliForwardUtil::PrintName(N); \
344 std::cout << (VALUE) << std::endl; } while(false)
346 //____________________________________________________________________
348 AliFMDESDFixer::Print(Option_t*) const
350 AliForwardUtil::PrintTask(*this);
351 gROOT->IncreaseDirLevel();
352 PFB("Consider invalid null", fInvalidIsEmpty);
353 PFB("Has extra dead", fHasXtraDead || fXtraDead.GetNbits() > 0);
354 PFV("Reco noise factor", fRecoFactor);
355 PFV("Max noise corr", fMaxNoiseCorr);
356 PFB("Recalc. eta", fRecalculateEta);
357 gROOT->DecreaseDirLevel();
360 //____________________________________________________________________