]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDReconstructor.cxx
Add newlines for fussy compilers
[u/mrichter/AliRoot.git] / FMD / AliFMDReconstructor.cxx
CommitLineData
37c55dc0 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 **************************************************************************/
0d0e6995 15/* $Id$ */
c2fc1258 16/** @file AliFMDReconstructor.cxx
17 @author Christian Holm Christensen <cholm@nbi.dk>
18 @date Mon Mar 27 12:47:09 2006
19 @brief FMD reconstruction
20*/
4347b38f 21//____________________________________________________________________
42403906 22//
02a27b50 23// This is a class that constructs AliFMDRecPoint objects from of Digits
6169f936 24// This class reads either digits from a TClonesArray or raw data from
4347b38f 25// a DDL file (or similar), and stores the read ADC counts in an
6169f936 26// internal cache (fAdcs). The rec-points are made via the naiive
27// method.
4347b38f 28//
37c55dc0 29//-- Authors: Evgeny Karpechev(INR) and Alla Maevsksia
4347b38f 30// Latest changes by Christian Holm Christensen <cholm@nbi.dk>
31//
32//
33//____________________________________________________________________
37c55dc0 34
f95a63c4 35// #include <AliLog.h> // ALILOG_H
6169f936 36// #include <AliRun.h> // ALIRUN_H
f95a63c4 37#include "AliFMDDebug.h"
1a1fdef7 38#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
39#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
5cf05dbb 40#include "AliFMDAltroMapping.h" // ALIFMDALTROMAPPING_H
56b1929b 41#include "AliFMDDigit.h" // ALIFMDDIGIT_H
faf80567 42#include "AliFMDSDigit.h" // ALIFMDDIGIT_H
56b1929b 43#include "AliFMDReconstructor.h" // ALIFMDRECONSTRUCTOR_H
818fff8d 44#include "AliFMDRecoParam.h" // ALIFMDRECOPARAM_H
56b1929b 45#include "AliFMDRawReader.h" // ALIFMDRAWREADER_H
bf000c32 46#include "AliFMDRecPoint.h" // ALIFMDMULTNAIIVE_H
af885e0f 47#include "AliESDEvent.h" // ALIESDEVENT_H
aad72f45 48#include "AliESDVertex.h" // ALIESDVERTEX_H
50b9d194 49#include "AliESDTZERO.h" // ALIESDVERTEX_H
8f6ee336 50#include <AliESDFMD.h> // ALIESDFMD_H
aad72f45 51#include <TMath.h>
9684be2f 52#include <TH1.h>
53#include <TH2.h>
54#include <TFile.h>
68aba90a 55#include <climits>
86878381 56#include "AliFMDESDRevertexer.h"
50b9d194 57
68aba90a 58
02a27b50 59class AliRawReader;
4347b38f 60
61//____________________________________________________________________
925e6570 62ClassImp(AliFMDReconstructor)
1a1fdef7 63#if 0
64 ; // This is here to keep Emacs for indenting the next line
65#endif
37c55dc0 66
4347b38f 67//____________________________________________________________________
68AliFMDReconstructor::AliFMDReconstructor()
69 : AliReconstructor(),
e9fd1e20 70 fMult(0x0),
71 fNMult(0),
72 fTreeR(0x0),
73 fCurrentVertex(0),
74 fESDObj(0x0),
9684be2f 75 fNoiseFactor(0),
76 fAngleCorrect(kTRUE),
77 fVertexType(kNoVertex),
9684be2f 78 fESD(0x0),
68aba90a 79 fDiagnostics(kTRUE),
9684be2f 80 fDiagStep1(0),
81 fDiagStep2(0),
82 fDiagStep3(0),
83 fDiagStep4(0),
84 fDiagAll(0)
4347b38f 85{
8f6ee336 86 // Make a new FMD reconstructor object - default CTOR.
a9579262 87 SetNoiseFactor();
88 SetAngleCorrect();
9b98d361 89 if (AliDebugLevel() > 0) fDiagnostics = kTRUE;
030d93c1 90 for(Int_t det = 1; det<=3; det++) {
91 fZS[det-1] = kFALSE;
92 fZSFactor[det-1] = 0;
93 }
4347b38f 94}
56b1929b 95
96//____________________________________________________________________
97AliFMDReconstructor::~AliFMDReconstructor()
98{
99 // Destructor
8f6ee336 100 if (fMult) fMult->Delete();
101 if (fMult) delete fMult;
102 if (fESDObj) delete fESDObj;
56b1929b 103}
4347b38f 104
105//____________________________________________________________________
106void
d76c31f4 107AliFMDReconstructor::Init()
1a1fdef7 108{
109 // Initialize the reconstructor
f011bd38 110
bf000c32 111 // Initialize the geometry
9b48326f 112 AliFMDGeometry* geom = AliFMDGeometry::Instance();
113 geom->Init();
114 geom->InitTransformations();
115
116 // Initialize the parameters
117 AliFMDParameters* param = AliFMDParameters::Instance();
118 param->Init();
bf000c32 119
8f6ee336 120 // Current vertex position
1a1fdef7 121 fCurrentVertex = 0;
8f6ee336 122 // Create array of reconstructed strip multiplicities
bf000c32 123 fMult = new TClonesArray("AliFMDRecPoint", 51200);
8f6ee336 124 // Create ESD output object
125 fESDObj = new AliESDFMD;
126
9684be2f 127 // Check if we need diagnostics histograms
128 if (!fDiagnostics) return;
9b98d361 129 AliInfo("Making diagnostics histograms");
9684be2f 130 fDiagStep1 = new TH2I("diagStep1", "Read ADC vs. Noise surpressed ADC",
131 1024, -.5, 1023.5, 1024, -.5, 1023.5);
132 fDiagStep1->SetDirectory(0);
133 fDiagStep1->GetXaxis()->SetTitle("ADC (read)");
134 fDiagStep1->GetYaxis()->SetTitle(Form("ADC (noise surpressed %4.f)",
135 fNoiseFactor));
136 fDiagStep2 = new TH2F("diagStep2", "ADC vs Edep deduced",
137 1024, -.5, 1023.5, 100, 0, 2);
138 fDiagStep2->SetDirectory(0);
139 fDiagStep2->GetXaxis()->SetTitle("ADC (noise surpressed)");
140 fDiagStep2->GetYaxis()->SetTitle("#Delta E [GeV]");
141 fDiagStep3 = new TH2F("diagStep3", "Edep vs Edep path corrected",
142 100, 0., 2., 100, 0., 2.);
143 fDiagStep3->SetDirectory(0);
144 fDiagStep3->GetXaxis()->SetTitle("#Delta E [GeV]");
145 fDiagStep3->GetYaxis()->SetTitle("#Delta E/#Delta x #times #delta x [GeV]");
146 fDiagStep4 = new TH2F("diagStep4", "Edep vs Multiplicity deduced",
147 100, 0., 2., 100, -.1, 19.9);
148 fDiagStep4->SetDirectory(0);
149 fDiagStep4->GetXaxis()->SetTitle("#Delta E/#Delta x #times #delta x [GeV]");
150 fDiagStep4->GetYaxis()->SetTitle("Multiplicity");
151 fDiagAll = new TH2F("diagAll", "Read ADC vs Multiplicity deduced",
152 1024, -.5, 1023.5, 100, -.1, 19.9);
153 fDiagAll->SetDirectory(0);
154 fDiagAll->GetXaxis()->SetTitle("ADC (read)");
155 fDiagAll->GetYaxis()->SetTitle("Multiplicity");
4347b38f 156}
dc8af42e 157
4347b38f 158//____________________________________________________________________
159void
1a1fdef7 160AliFMDReconstructor::ConvertDigits(AliRawReader* reader,
161 TTree* digitsTree) const
162{
163 // Convert Raw digits to AliFMDDigit's in a tree
faf80567 164 AliFMDDebug(1, ("Reading raw data into digits tree"));
1a1fdef7 165 AliFMDRawReader rawRead(reader, digitsTree);
166 // rawRead.SetSampleRate(fFMD->GetSampleRate());
167 rawRead.Exec();
5cf05dbb 168 AliFMDAltroMapping* map = AliFMDParameters::Instance()->GetAltroMap();
169 for (size_t i = 1; i <= 3; i++) {
170 fZS[i] = rawRead.IsZeroSuppressed(map->Detector2DDL(i));
171 fZSFactor[i] = rawRead.NoiseFactor(map->Detector2DDL(i));
172 }
4347b38f 173}
174
4347b38f 175//____________________________________________________________________
176void
8983e5ae 177AliFMDReconstructor::GetVertex(AliESDEvent* esd) const
4347b38f 178{
97e94238 179 // Return the vertex to use.
180 // This is obtained from the ESD object.
181 // If not found, a warning is issued.
9684be2f 182 fVertexType = kNoVertex;
183 fCurrentVertex = 0;
8983e5ae 184 if (!esd) return;
185
186 const AliESDVertex* vertex = esd->GetPrimaryVertex();
187 if (!vertex) vertex = esd->GetPrimaryVertexSPD();
188 if (!vertex) vertex = esd->GetPrimaryVertexTPC();
189 if (!vertex) vertex = esd->GetVertex();
190
191 if (vertex) {
192 AliFMDDebug(2, ("Got %s (%s) from ESD: %f",
193 vertex->GetName(), vertex->GetTitle(), vertex->GetZv()));
194 fCurrentVertex = vertex->GetZv();
195 fVertexType = kESDVertex;
196 return;
197 }
198 else if (esd->GetESDTZERO()) {
199 AliFMDDebug(2, ("Got primary vertex from T0: %f", esd->GetT0zVertex()));
200 fCurrentVertex = esd->GetT0zVertex();
201 fVertexType = kESDVertex;
202 return;
a3537838 203 }
9684be2f 204 AliWarning("Didn't get any vertex from ESD or generator");
205}
206
818fff8d 207//____________________________________________________________________
208Int_t
209AliFMDReconstructor::GetIdentifier() const
210{
211 return AliReconstruction::GetDetIndex(GetDetectorName());
212}
213
214//____________________________________________________________________
215const AliFMDRecoParam*
216AliFMDReconstructor::GetParameters() const
217{
218 Int_t iDet = 12; // GetIdentifier();
219 const AliDetectorRecoParam* params = AliReconstructor::GetRecoParam(iDet);
220 if (!params || params->IsA() != AliFMDRecoParam::Class()) return 0;
221 return static_cast<const AliFMDRecoParam*>(params);
222}
223
224//____________________________________________________________________
225void
226AliFMDReconstructor::UseRecoParam(Bool_t set) const
227{
228 static Float_t savedNoiseFactor = fNoiseFactor;
229 static Bool_t savedAngleCorrect = fAngleCorrect;
230 if (set) {
231 const AliFMDRecoParam* params = GetParameters();
232 if (params) {
233 fNoiseFactor = params->NoiseFactor();
234 fAngleCorrect = params->AngleCorrect();
235 }
236 return;
237 }
238 fNoiseFactor = savedNoiseFactor;
239 fAngleCorrect = savedAngleCorrect;
240}
241
242
9684be2f 243
ddaa8027 244//____________________________________________________________________
245void
50b9d194 246AliFMDReconstructor::Reconstruct(AliRawReader* reader, TTree*) const
ddaa8027 247{
248 // Reconstruct directly from raw data (no intermediate output on
249 // digit tree or rec point tree).
50b9d194 250 //
ddaa8027 251 // Parameters:
252 // reader Raw event reader
253 // ctree Not used.
3991ca94 254 AliFMDDebug(1, ("Reconstructing from raw reader"));
50b9d194 255 AliFMDRawReader rawReader(reader, 0);
256
257 UShort_t det, sec, str, fac;
258 Short_t adc, oldDet = -1;
259 Bool_t zs;
260 Char_t rng;
818fff8d 261
262 UseRecoParam(kTRUE);
50b9d194 263 while (rawReader.NextSignal(det, rng, sec, str, adc, zs, fac)) {
264 if (det != oldDet) {
265 fZS[det-1] = zs;
266 fZSFactor[det-1] = fac;
267 oldDet = det;
268 }
269 ProcessSignal(det, rng, sec, str, adc);
270 }
818fff8d 271 UseRecoParam(kFALSE);
272
ddaa8027 273}
274
faf80567 275//____________________________________________________________________
276void
277AliFMDReconstructor::Digitize(AliRawReader* reader, TClonesArray* sdigits) const
278{
279 // Reconstruct directly from raw data (no intermediate output on
280 // digit tree or rec point tree).
281 //
282 // Parameters:
283 // reader Raw event reader
284 // ctree Not used.
285 AliFMDRawReader rawReader(reader, 0);
286
287 UShort_t det, sec, str, sam, rat, fac;
288 Short_t adc, oldDet = -1;
289 Bool_t zs;
290 Char_t rng;
291
818fff8d 292 UseRecoParam(kTRUE);
faf80567 293 while (rawReader.NextSample(det, rng, sec, str, sam, rat, adc, zs, fac)) {
294 if (!rawReader.SelectSample(sam, rat)) continue;
295 if (det != oldDet) {
296 fZS[det-1] = zs;
297 fZSFactor[det-1] = fac;
298 oldDet = det;
299 }
300 DigitizeSignal(sdigits, det, rng, sec, str, sam, adc);
301 }
818fff8d 302 UseRecoParam(kFALSE);
faf80567 303}
304
9684be2f 305//____________________________________________________________________
306void
307AliFMDReconstructor::Reconstruct(TTree* digitsTree,
308 TTree* clusterTree) const
309{
310 // Reconstruct event from digits in tree
311 // Get the FMD branch holding the digits.
312 // FIXME: The vertex may not be known yet, so we may have to move
313 // some of this to FillESD.
50b9d194 314 //
315 // Parameters:
316 // digitsTree Pointer to a tree containing digits
317 // clusterTree Pointer to output tree
318 //
3991ca94 319 AliFMDDebug(1, ("Reconstructing from digits in a tree"));
8983e5ae 320 GetVertex(fESD);
86878381 321
322 static TClonesArray* digits = new TClonesArray("AliFMDDigit");
1a1fdef7 323 TBranch *digitBranch = digitsTree->GetBranch("FMD");
4347b38f 324 if (!digitBranch) {
1a1fdef7 325 Error("Exec", "No digit branch for the FMD found");
326 return;
4347b38f 327 }
86878381 328 // TClonesArray* digits = new TClonesArray("AliFMDDigit");
1a1fdef7 329 digitBranch->SetAddress(&digits);
4347b38f 330
8f6ee336 331 if (fMult) fMult->Clear();
332 if (fESDObj) fESDObj->Clear();
333
334 fNMult = 0;
335 fTreeR = clusterTree;
336 fTreeR->Branch("FMD", &fMult);
337
f95a63c4 338 AliFMDDebug(5, ("Getting entry 0 from digit branch"));
1a1fdef7 339 digitBranch->GetEntry(0);
340
3991ca94 341 AliFMDDebug(5, ("Processing digits"));
818fff8d 342 UseRecoParam(kTRUE);
e802be3e 343 ProcessDigits(digits);
818fff8d 344 UseRecoParam(kFALSE);
e802be3e 345
8f6ee336 346 Int_t written = clusterTree->Fill();
f95a63c4 347 AliFMDDebug(10, ("Filled %d bytes into cluster tree", written));
0abe7182 348 digits->Delete();
86878381 349 // delete digits;
4347b38f 350}
1a1fdef7 351
8f6ee336 352
4347b38f 353//____________________________________________________________________
e802be3e 354void
355AliFMDReconstructor::ProcessDigits(TClonesArray* digits) const
4347b38f 356{
69b696b9 357 // For each digit, find the pseudo rapdity, azimuthal angle, and
358 // number of corrected ADC counts, and pass it on to the algorithms
359 // used.
50b9d194 360 //
361 // Parameters:
362 // digits Array of digits
363 //
e802be3e 364 Int_t nDigits = digits->GetEntries();
3991ca94 365 AliFMDDebug(2, ("Got %d digits", nDigits));
a9579262 366 fESDObj->SetNoiseFactor(fNoiseFactor);
367 fESDObj->SetAngleCorrected(fAngleCorrect);
e802be3e 368 for (Int_t i = 0; i < nDigits; i++) {
369 AliFMDDigit* digit = static_cast<AliFMDDigit*>(digits->At(i));
50b9d194 370 if (!digit) continue;
371 ProcessDigit(digit);
372 }
373}
8f6ee336 374
50b9d194 375//____________________________________________________________________
376void
377AliFMDReconstructor::ProcessDigit(AliFMDDigit* digit) const
378{
379 UShort_t det = digit->Detector();
380 Char_t rng = digit->Ring();
381 UShort_t sec = digit->Sector();
382 UShort_t str = digit->Strip();
383 Short_t adc = digit->Counts();
86878381 384 if (adc < 0)
385 digit->Print();
50b9d194 386 ProcessSignal(det, rng, sec, str, adc);
387}
388
389//____________________________________________________________________
390void
391AliFMDReconstructor::ProcessSignal(UShort_t det,
392 Char_t rng,
393 UShort_t sec,
394 UShort_t str,
395 Short_t adc) const
396{
397 // Process the signal from a single strip
398 //
399 // Parameters:
400 // det Detector ID
401 // rng Ring ID
402 // sec Sector ID
403 // rng Strip ID
404 // adc ADC counts
405 //
406 AliFMDParameters* param = AliFMDParameters::Instance();
407 // Check that the strip is not marked as dead
408 if (param->IsDead(det, rng, sec, str)) {
86878381 409 AliFMDDebug(1, ("FMD%d%c[%2d,%3d] is dead", det, rng, sec, str));
50b9d194 410 return;
411 }
412
413 // digit->Print();
414 // Get eta and phi
415 Float_t eta, phi;
416 PhysicalCoordinates(det, rng, sec, str, eta, phi);
4347b38f 417
50b9d194 418 // Substract pedestal.
419 UShort_t counts = SubtractPedestal(det, rng, sec, str, adc);
420 if(counts == USHRT_MAX) return;
421
8f6ee336 422 // Gain match digits.
50b9d194 423 Double_t edep = Adc2Energy(det, rng, sec, str, eta, counts);
424 // Get rid of nonsense energy
425 if(edep < 0) return;
426
427 // Make rough multiplicity
428 Double_t mult = Energy2Multiplicity(det, rng, sec, str, edep);
429 // Get rid of nonsense mult
86878381 430 if (mult > 20) {
431 AliWarning(Form("The mutliplicity in FMD%d%c[%2d,%3d]=%f > 20 "
432 "(ADC: %d, Energy: %f)", det, rng, sec, str, mult,
433 counts, edep));
434 }
50b9d194 435 if (mult < 0) return;
3991ca94 436 AliFMDDebug(10, ("FMD%d%c[%2d,%3d]: "
50b9d194 437 "ADC: %d, Counts: %d, Energy: %f, Mult: %f",
438 det, rng, sec, str, adc, counts, edep, mult));
439
440 // Create a `RecPoint' on the output branch.
441 if (fMult) {
442 AliFMDRecPoint* m =
443 new ((*fMult)[fNMult]) AliFMDRecPoint(det, rng, sec, str,
444 eta, phi, edep, mult);
445 (void)m; // Suppress warnings about unused variables.
446 fNMult++;
4347b38f 447 }
50b9d194 448
449 fESDObj->SetMultiplicity(det, rng, sec, str, mult);
450 fESDObj->SetEta(det, rng, sec, str, eta);
451
452 if (fDiagAll) fDiagAll->Fill(adc, mult);
453
4347b38f 454}
8f6ee336 455
faf80567 456//____________________________________________________________________
457void
458AliFMDReconstructor::DigitizeSignal(TClonesArray* sdigits,
459 UShort_t det,
460 Char_t rng,
461 UShort_t sec,
462 UShort_t str,
463 UShort_t /* sam */,
464 Short_t adc) const
465{
466 // Process the signal from a single strip
467 //
468 // Parameters:
469 // det Detector ID
470 // rng Ring ID
471 // sec Sector ID
472 // rng Strip ID
473 // adc ADC counts
474 //
475 AliFMDParameters* param = AliFMDParameters::Instance();
476 // Check that the strip is not marked as dead
477 if (param->IsDead(det, rng, sec, str)) {
478 AliFMDDebug(10, ("FMD%d%c[%2d,%3d] is dead", det, rng, sec, str));
479 return;
480 }
481
482 // Substract pedestal.
483 UShort_t counts = SubtractPedestal(det, rng, sec, str, adc);
484 if(counts == USHRT_MAX || counts == 0) return;
485
486 // Gain match digits.
487 Double_t edep = Adc2Energy(det, rng, sec, str, counts);
488 // Get rid of nonsense energy
489 if(edep < 0) return;
490
491 Int_t n = sdigits->GetEntriesFast();
492 // AliFMDSDigit* sdigit =
493 new ((*sdigits)[n])
494 AliFMDSDigit(det, rng, sec, str, edep, counts, counts, counts, counts);
495 // sdigit->SetCount(sam, counts);
496}
497
498//____________________________________________________________________
499UShort_t
500AliFMDReconstructor::SubtractPedestal(UShort_t det,
501 Char_t rng,
502 UShort_t sec,
503 UShort_t str,
504 UShort_t adc,
505 Float_t noiseFactor,
506 Bool_t zsEnabled,
507 UShort_t zsNoiseFactor) const
508{
509 AliFMDParameters* param = AliFMDParameters::Instance();
510 Float_t ped = (zsEnabled ? 0 :
511 param->GetPedestal(det, rng, sec, str));
512 Float_t noise = param->GetPedestalWidth(det, rng, sec, str);
513 if(ped < 0 || noise < 0) {
514 AliWarningClass(Form("Invalid pedestal (%f) or noise (%f) "
515 "for FMD%d%c[%02d,%03d]",
516 ped, noise, det, rng, sec, str));
517 return USHRT_MAX;
518 }
519 AliDebugClass(15, Form("Subtracting pedestal for FMD%d%c[%2d,%3d]=%4d "
520 "(%s w/factor %d, noise factor %f, "
521 "pedestal %8.2f+/-%8.2f)",
522 det, rng, sec, str, adc,
523 (zsEnabled ? "zs'ed" : "straight"),
524 zsNoiseFactor, noiseFactor, ped, noise));
525
526 Int_t counts = adc + Int_t(zsEnabled ? zsNoiseFactor * noise : - ped);
527 counts = TMath::Max(Int_t(counts), 0);
528 // Calculate the noise factor for suppressing remenants of the noise
529 // peak. If we have done on-line zero suppression, we only check
530 // for noise signals that are larger than the suppressed noise. If
531 // the noise factor used on line is larger than the factor used
532 // here, we do not do this check at all.
533 //
534 // For example:
535 // Online factor | Read factor | Result
536 // ---------------+--------------+-------------------------------
537 // 2 | 3 | Check if signal > 1 * noise
538 // 3 | 3 | Check if signal > 0
539 // 3 | 2 | Check if signal > 0
540 //
541 // In this way, we make sure that we do not suppress away too much
542 // data, and that the read-factor is the most stringent cut.
543 Float_t nf = TMath::Max(0.F, noiseFactor - (zsEnabled ? zsNoiseFactor : 0));
544 if (counts < noise * nf) counts = 0;
545 if (counts > 0) AliDebugClass(15, "Got a hit strip");
546
86878381 547 UShort_t ret = counts < 0 ? 0 : counts;
548 return ret;
faf80567 549}
50b9d194 550
551
1a1fdef7 552//____________________________________________________________________
553UShort_t
50b9d194 554AliFMDReconstructor::SubtractPedestal(UShort_t det,
555 Char_t rng,
556 UShort_t sec,
557 UShort_t str,
558 Short_t adc) const
1a1fdef7 559{
560 // Member function to subtract the pedestal from a digit
50b9d194 561 //
562 // Parameters:
563 // det Detector ID
564 // rng Ring ID
565 // sec Sector ID
566 // rng Strip ID
567 // adc # of ADC counts
568 // Return:
569 // Pedestal subtracted signal or USHRT_MAX in case of problems
570 //
faf80567 571 UShort_t counts = SubtractPedestal(det, rng, sec, str, adc,
572 fNoiseFactor, fZS[det-1],
573 fZSFactor[det-1]);
9684be2f 574 if (fDiagStep1) fDiagStep1->Fill(adc, counts);
8f6ee336 575
faf80567 576 return counts;
1a1fdef7 577}
578
8f6ee336 579//____________________________________________________________________
580Float_t
50b9d194 581AliFMDReconstructor::Adc2Energy(UShort_t det,
582 Char_t rng,
583 UShort_t sec,
584 UShort_t str,
50b9d194 585 UShort_t count) const
8f6ee336 586{
587 // Converts number of ADC counts to energy deposited.
588 // Note, that this member function can be overloaded by derived
589 // classes to do strip-specific look-ups in databases or the like,
590 // to find the proper gain for a strip.
591 //
68aba90a 592 // In the first simple version, we calculate the energy deposited as
8f6ee336 593 //
594 // EnergyDeposited = cos(theta) * gain * count
595 //
596 // where
597 //
598 // Pre_amp_MIP_Range
599 // gain = ----------------- * Energy_deposited_per_MIP
600 // ADC_channel_size
601 //
602 // is constant and the same for all strips.
68aba90a 603 //
604 // For the production we use the conversion measured in the NBI lab.
605 // The total conversion is then:
50b9d194 606 //
607 // gain = ADC / DAC
608 //
609 // EdepMip * count
610 // => energy = ----------------
611 // gain * DACPerADC
612 //
613 // Parameters:
614 // det Detector ID
615 // rng Ring ID
616 // sec Sector ID
617 // rng Strip ID
50b9d194 618 // counts Number of ADC counts over pedestal
619 // Return
620 // The energy deposited in a single strip, or -1 in case of problems
68aba90a 621 //
a9579262 622 if (count <= 0) return 0;
8f6ee336 623 AliFMDParameters* param = AliFMDParameters::Instance();
50b9d194 624 Float_t gain = param->GetPulseGain(det, rng, sec, str);
68aba90a 625 // 'Tagging' bad gains as bad energy
626 if (gain < 0) {
50b9d194 627 AliWarning(Form("Invalid gain (%f) for FMD%d%c[%02d,%03d]",
628 gain, det, rng, sec, str));
68aba90a 629 return -1;
630 }
50b9d194 631 AliFMDDebug(5, ("Converting counts %d to energy (factor=%f, DAC2MIP=%f)",
68aba90a 632 count, gain,param->GetDACPerMIP()));
a9579262 633
50b9d194 634 Double_t edep = ((count * param->GetEdepMip())
635 / (gain * param->GetDACPerMIP()));
faf80567 636 return edep;
637}
638
639//____________________________________________________________________
640Float_t
641AliFMDReconstructor::Adc2Energy(UShort_t det,
642 Char_t rng,
643 UShort_t sec,
644 UShort_t str,
645 Float_t eta,
646 UShort_t count) const
647{
648 // Converts number of ADC counts to energy deposited.
649 // Note, that this member function can be overloaded by derived
650 // classes to do strip-specific look-ups in databases or the like,
651 // to find the proper gain for a strip.
652 //
653 // In the first simple version, we calculate the energy deposited as
654 //
655 // EnergyDeposited = cos(theta) * gain * count
656 //
657 // where
658 //
659 // Pre_amp_MIP_Range
660 // gain = ----------------- * Energy_deposited_per_MIP
661 // ADC_channel_size
662 //
663 // is constant and the same for all strips.
664 //
665 // For the production we use the conversion measured in the NBI lab.
666 // The total conversion is then:
667 //
668 // gain = ADC / DAC
669 //
670 // EdepMip * count
671 // => energy = ----------------
672 // gain * DACPerADC
673 //
674 // Parameters:
675 // det Detector ID
676 // rng Ring ID
677 // sec Sector ID
678 // rng Strip ID
679 // eta Psuedo-rapidity
680 // counts Number of ADC counts over pedestal
681 // Return
682 // The energy deposited in a single strip, or -1 in case of problems
683 //
684 Double_t edep = Adc2Energy(det, rng, sec, str, count);
685
9684be2f 686 if (fDiagStep2) fDiagStep2->Fill(count, edep);
a9579262 687 if (fAngleCorrect) {
9684be2f 688 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
689 Double_t corr = TMath::Abs(TMath::Cos(theta));
690 Double_t cedep = corr * edep;
f95a63c4 691 AliFMDDebug(10, ("correcting for path %f * %f = %f (eta=%f, theta=%f)",
9684be2f 692 edep, corr, cedep, eta, theta));
693 if (fDiagStep3) fDiagStep3->Fill(edep, cedep);
694 edep = cedep;
a9579262 695 }
8f6ee336 696 return edep;
697}
698
699//____________________________________________________________________
700Float_t
50b9d194 701AliFMDReconstructor::Energy2Multiplicity(UShort_t /*det*/,
702 Char_t /*rng*/,
703 UShort_t /*sec*/,
704 UShort_t /*str*/,
705 Float_t edep) const
8f6ee336 706{
707 // Converts an energy signal to number of particles.
708 // Note, that this member function can be overloaded by derived
709 // classes to do strip-specific look-ups in databases or the like,
710 // to find the proper gain for a strip.
711 //
712 // In this simple version, we calculate the multiplicity as
713 //
714 // multiplicity = Energy_deposited / Energy_deposited_per_MIP
715 //
716 // where
717 //
718 // Energy_deposited_per_MIP = 1.664 * SI_density * SI_thickness
719 //
720 // is constant and the same for all strips
50b9d194 721 //
722 // Parameters:
723 // det Detector ID
724 // rng Ring ID
725 // sec Sector ID
726 // rng Strip ID
727 // edep Energy deposited in a single strip
728 // Return
729 // The "bare" multiplicity corresponding to the energy deposited
8f6ee336 730 AliFMDParameters* param = AliFMDParameters::Instance();
731 Double_t edepMIP = param->GetEdepMip();
732 Float_t mult = edep / edepMIP;
68aba90a 733#if 0
8f6ee336 734 if (edep > 0)
f95a63c4 735 AliFMDDebug(15, ("Translating energy %f to multiplicity via "
8f6ee336 736 "divider %f->%f", edep, edepMIP, mult));
68aba90a 737#endif
9684be2f 738 if (fDiagStep4) fDiagStep4->Fill(edep, mult);
8f6ee336 739 return mult;
740}
741
742//____________________________________________________________________
743void
50b9d194 744AliFMDReconstructor::PhysicalCoordinates(UShort_t det,
745 Char_t rng,
746 UShort_t sec,
747 UShort_t str,
8f6ee336 748 Float_t& eta,
749 Float_t& phi) const
750{
751 // Get the eta and phi of a digit
752 //
50b9d194 753 // Parameters:
754 // det Detector ID
755 // rng Ring ID
756 // sec Sector ID
757 // rng Strip ID
758 // eta On return, contains the psuedo-rapidity of the strip
759 // phi On return, contains the azimuthal angle of the strip
760 //
9b48326f 761 AliFMDGeometry* geom = AliFMDGeometry::Instance();
bf000c32 762 Double_t x, y, z, r, theta;
50b9d194 763 geom->Detector2XYZ(det, rng, sec, str, x, y, z);
bf000c32 764 // Correct for vertex offset.
8161c5f7 765 z -= fCurrentVertex;
bf000c32 766 phi = TMath::ATan2(y, x);
767 r = TMath::Sqrt(y * y + x * x);
768 theta = TMath::ATan2(r, z);
769 eta = -TMath::Log(TMath::Tan(theta / 2));
8f6ee336 770}
771
772
773
4347b38f 774//____________________________________________________________________
775void
1a1fdef7 776AliFMDReconstructor::FillESD(TTree* /* digitsTree */,
777 TTree* /* clusterTree */,
af885e0f 778 AliESDEvent* esd) const
121a60bd 779{
42403906 780 // nothing to be done
69b696b9 781 // FIXME: The vertex may not be known when Reconstruct is executed,
782 // so we may have to move some of that member function here.
f95a63c4 783 AliFMDDebug(2, ("Calling FillESD with two trees and one ESD"));
8f6ee336 784 // fESDObj->Print();
785
50b9d194 786 Double_t oldVz = fCurrentVertex;
8983e5ae 787 GetVertex(esd);
50b9d194 788 if (fVertexType != kNoVertex) {
789 AliFMDDebug(2, ("Revertexing the ESD data to vz=%f (was %f)",
790 fCurrentVertex, oldVz));
791 AliFMDESDRevertexer revertexer;
792 revertexer.Revertex(fESDObj, fCurrentVertex);
793 }
794
8f6ee336 795 if (esd) {
f95a63c4 796 AliFMDDebug(2, ("Writing FMD data to ESD tree"));
8f6ee336 797 esd->SetFMDData(fESDObj);
a3537838 798 }
9684be2f 799
800 if (!fDiagnostics || !esd) return;
801 static bool first = true;
69893a66 802 // This is most likely NOT the event number you'd like to use. It
803 // has nothing to do with the 'real' event number.
804 // - That's OK. We just use it for the name of the directory -
805 // nothing else. Christian
806 Int_t evno = esd->GetEventNumberInFile();
3991ca94 807 AliFMDDebug(3, ("Writing diagnostics histograms to FMD.Diag.root/%03d",evno));
9684be2f 808 TFile f("FMD.Diag.root", (first ? "RECREATE" : "UPDATE"));
809 first = false;
810 f.cd();
811 TDirectory* d = f.mkdir(Form("%03d", evno),
812 Form("Diagnostics histograms for event # %d", evno));
813 d->cd();
814 if (fDiagStep1) fDiagStep1->Write();
815 if (fDiagStep2) fDiagStep2->Write();
816 if (fDiagStep3) fDiagStep3->Write();
817 if (fDiagStep4) fDiagStep4->Write();
818 if (fDiagAll) fDiagAll->Write();
819 d->Write();
820 f.Write();
821 f.Close();
822
823 if (fDiagStep1) fDiagStep1->Reset();
824 if (fDiagStep2) fDiagStep2->Reset();
825 if (fDiagStep3) fDiagStep3->Reset();
826 if (fDiagStep4) fDiagStep4->Reset();
827 if (fDiagAll) fDiagAll->Reset();
121a60bd 828}
829
ddaa8027 830//____________________________________________________________________
831void
832AliFMDReconstructor::FillESD(AliRawReader*, TTree* clusterTree,
833 AliESDEvent* esd) const
834{
835 TTree* dummy = 0;
836 FillESD(dummy, clusterTree, esd);
837}
42403906 838//____________________________________________________________________
839//
840// EOF
841//