1 /**************************************************************************
2 * Copyright(c) 2004, 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 **************************************************************************/
16 /** @file AliFMDDigitizer.cxx
17 @author Christian Holm Christensen <cholm@nbi.dk>
18 @date Mon Mar 27 12:38:26 2006
19 @brief FMD Digitizers implementation
22 //////////////////////////////////////////////////////////////////////////////
24 // This class contains the procedures simulation ADC signal for the
25 // Forward Multiplicity detector : SDigits->Digits
32 // - ADC count in this channel
39 // - Total energy deposited in the strip
40 // - ADC count in this channel
42 // As the Digits and SDigits have so much in common, the classes
43 // AliFMDDigitizer and AliFMDSDigitizer are implemented via a base
44 // class AliFMDBaseDigitizer.
46 // +---------------------+
47 // | AliFMDBaseDigitizer |
48 // +---------------------+
51 // +----------+---------+
53 // +-----------------+ +------------------+
54 // | AliFMDDigitizer | | AliFMDSDigitizer |
55 // +-----------------+ +------------------+
57 // +-------------------+
58 // | AliFMDSSDigitizer |
59 // +-------------------+
61 // These classes has several paramters:
65 // (Only AliFMDDigitizer)
66 // Mean and width of the pedestal. The pedestal is simulated
67 // by a Guassian, but derived classes my override MakePedestal
68 // to simulate it differently (or pick it up from a database).
71 // The dymamic MIP range of the VA1_ALICE pre-amplifier chip
74 // The largest number plus one that can be stored in one
75 // channel in one time step in the ALTRO ADC chip.
78 // How many times the ALTRO ADC chip samples the VA1_ALICE
79 // pre-amplifier signal. The VA1_ALICE chip is read-out at
80 // 10MHz, while it's possible to drive the ALTRO chip at
81 // 25MHz. That means, that the ALTRO chip can have time to
82 // sample each VA1_ALICE signal up to 2 times. Although it's
83 // not certain this feature will be used in the production,
84 // we'd like have the option, and so it should be reflected in
88 // The shaping function of the VA1_ALICE is generally given by
90 // f(x) = A(1 - exp(-Bx))
92 // where A is the total charge collected in the pre-amp., and B is a
93 // paramter that depends on the shaping time of the VA1_ALICE circut.
95 // When simulating the shaping function of the VA1_ALICe
96 // pre-amp. chip, we have to take into account, that the shaping
97 // function depends on the previous value of read from the pre-amp.
99 // That results in the following algorithm:
102 // FOR charge IN pre-amp. charge train DO
103 // IF last < charge THEN
104 // f(t) = (charge - last) * (1 - exp(-B * t)) + last
106 // f(t) = (last - charge) * exp(-B * t) + charge)
108 // FOR i IN # samples DO
109 // adc_i = f(i / (# samples))
116 // pre-amp. charge train
117 // is a series of 128 charges read from the VA1_ALICE chip
120 // is the number of times the ALTRO ADC samples each of the 128
121 // charges from the pre-amp.
123 // Where Q is the total charge collected by the VA1_ALICE
124 // pre-amplifier. Q is then given by
130 // where E is the total energy deposited in a silicon strip, R is the
131 // dynamic range of the VA1_ALICE pre-amp (fVA1MipRange), e is the
132 // energy deposited by a single MIP, and S ALTRO channel size in each
133 // time step (fAltroChannelSize).
135 // The energy deposited per MIP is given by
139 // where M is the universal number 1.664, rho is the density of
140 // silicon, and w is the depth of the silicon sensor.
142 // The final ADC count is given by
146 // where P is the (randomized) pedestal (see MakePedestal)
148 // This class uses the class template AliFMDMap<Type> to make an
149 // internal cache of the energy deposted of the hits. The class
150 // template is instantasized as
152 // typedef AliFMDMap<std::pair<Float_t, UShort_t> > AliFMDEdepMap;
154 // The first member of the values is the summed energy deposition in a
155 // given strip, while the second member of the values is the number of
156 // hits in a given strip. Using the second member, it's possible to
157 // do some checks on just how many times a strip got hit, and what
158 // kind of error we get in our reconstructed hits. Note, that this
159 // information is currently not written to the digits tree. I think a
160 // QA (Quality Assurance) digit tree is better suited for that task.
161 // However, the information is there to be used in the future.
164 // Latest changes by Christian Holm Christensen
166 //////////////////////////////////////////////////////////////////////////////
169 // | A(-1 + B + exp(-B))
170 // | f(x) dx = ------------------- = 1
174 // and B is the a parameter defined by the shaping time (fShapingTime).
176 // Solving the above equation, for A gives
179 // A = ----------------
182 // So, if we define the function g: [0,1] -> [0:1] by
185 // | Bu + exp(-Bu) - Bv - exp(-Bv)
186 // g(u,v) = | f(x) dx = -A -----------------------------
190 // we can evaluate the ALTRO sample of the VA1_ALICE pre-amp between
191 // any two times (u, v), by
194 // B Bu + exp(-Bu) - Bv - exp(-Bv)
195 // C = Q g(u,v) = - Q ---------------- -----------------------------
196 // -1 + B + exp(-B) B
198 // Bu + exp(-Bu) - Bv - exp(-Bv)
199 // = - Q -----------------------------
203 #include <TTree.h> // ROOT_TTree
205 #include "AliFMDDebug.h" // Better debug macros
206 #include "AliFMDDigitizer.h" // ALIFMDSSDIGITIZER_H
207 #include "AliFMD.h" // ALIFMD_H
208 #include "AliFMDSDigit.h" // ALIFMDDIGIT_H
209 #include "AliFMDDigit.h" // ALIFMDDIGIT_H
210 #include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
211 #include <AliRunDigitizer.h> // ALIRUNDIGITIZER_H
212 #include <AliRun.h> // ALIRUN_H
213 #include <AliLoader.h> // ALILOADER_H
214 #include <AliRunLoader.h> // ALIRUNLOADER_H
216 //====================================================================
217 ClassImp(AliFMDDigitizer)
222 //____________________________________________________________________
224 AliFMDDigitizer::Init()
227 if (!AliFMDBaseDigitizer::Init()) return kFALSE;
230 // Get the AliRun object
231 AliRun* run = fRunLoader->GetAliRun();
233 AliWarning("Loading gAlice");
234 fRunLoader->LoadgAlice();
236 AliError("Can not get Run from Run Loader");
241 // Get the AliFMD object
242 fFMD = static_cast<AliFMD*>(run->GetDetector("FMD"));
244 AliError("Can not get FMD from gAlice");
252 //____________________________________________________________________
254 AliFMDDigitizer::Exec(Option_t*)
257 AliError("No digitisation manager defined");
261 // Clear array of deposited energies
264 AliRunLoader* runLoader = 0;
266 TString folderName(fManager->GetInputFolderName(0));
267 runLoader = AliRunLoader::GetRunLoader(folderName.Data());
269 AliError(Form("Failed at getting run loader from %s",
273 if (!runLoader->GetAliRun()) runLoader->LoadgAlice();
274 runLoader->GetAliRun();
277 AliError("Can not get Run from Run Loader");
281 // Get the AliFMD object
282 fFMD = static_cast<AliFMD*>(gAlice->GetDetector("FMD"));
284 AliError("Can not get FMD from gAlice");
289 // Loop over input files
290 Int_t nFiles= fManager->GetNinputs();
291 AliFMDDebug(1, (" Digitizing event number %d, got %d inputs",
292 fManager->GetOutputEventNr(), nFiles));
293 for (Int_t inputFile = 0; inputFile < nFiles; inputFile++) {
294 AliFMDDebug(5, ("Now reading input # %d", inputFile));
295 // Get the current loader
296 AliRunLoader* currentLoader =
297 AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
298 if (!currentLoader) {
299 Error("Exec", Form("no run loader for input file # %d", inputFile));
303 // Cache contriutions
304 AliFMDDebug(5, ("Now summing the contributions from input # %d",inputFile));
306 // Get the FMD loader
307 AliLoader* inFMD = currentLoader->GetLoader("FMDLoader");
308 // And load the summable digits
309 inFMD->LoadSDigits("READ");
311 // Get the tree of summable digits
312 TTree* sdigitsTree = inFMD->TreeS();
314 AliError("No sdigit tree from manager");
317 if (AliLog::GetDebugLevel("FMD","") >= 10) {
318 TFile* file = sdigitsTree->GetCurrentFile();
320 AliWarning("Input tree has no file!");
323 AliFMDDebug(10, ("Input tree file %s content:", file->GetName()));
326 // AliFMDDebug(5, ("Input tree %s file structure:",
327 // sdigitsTree->GetName()));
328 // sdigitsTree->Print();
331 // Get the FMD branch
332 TBranch* sdigitsBranch = sdigitsTree->GetBranch("FMD");
333 if (!sdigitsBranch) {
334 AliError("Failed to get sdigit branch");
338 // Set the branch addresses
339 fFMD->SetTreeAddress();
341 // Sum contributions from the sdigits
342 AliFMDDebug(3, ("Will now sum contributions from SDigits"));
343 SumContributions(sdigitsBranch);
345 // Unload the sdigits
346 inFMD->UnloadSDigits();
349 TString outFolder(fManager->GetOutputFolderName());
350 AliRunLoader* out = AliRunLoader::GetRunLoader(outFolder.Data());
351 AliLoader* outFMD = out->GetLoader("FMDLoader");
353 AliError("Cannot get the FMDLoader output folder");
356 TTree* outTree = MakeOutputTree(outFMD);
358 AliError("Failed to get output tree");
361 // Set the branch address
362 fFMD->SetTreeAddress();
364 // And digitize the cached data
368 Int_t write = outTree->Fill();
369 AliFMDDebug(5, ("Wrote %d bytes to digit tree", write));
375 //____________________________________________________________________
377 AliFMDDigitizer::SumContributions(TBranch* sdigitsBranch)
379 // Sum energy deposited contributions from each sdigits in a cache
381 AliFMDDebug(3, ("Runnin our version of SumContributions"));
383 // Get a list of hits from the FMD manager
384 TClonesArray *fmdSDigits = fFMD->SDigits();
386 // Get number of entries in the tree
387 Int_t nevents = Int_t(sdigitsBranch->GetEntries());
390 // Loop over the events in the
391 for (Int_t event = 0; event < nevents; event++) {
392 // Read in entry number `event'
393 read += sdigitsBranch->GetEntry(event);
395 // Get the number of sdigits
396 Int_t nsdigits = fmdSDigits->GetEntries ();
397 AliFMDDebug(3, ("Got %5d SDigits", nsdigits));
398 for (Int_t sdigit = 0; sdigit < nsdigits; sdigit++) {
399 // Get the sdigit number `sdigit'
400 AliFMDSDigit* fmdSDigit =
401 static_cast<AliFMDSDigit*>(fmdSDigits->UncheckedAt(sdigit));
403 AliFMDDebug(5, ("Adding contribution of %d tracks",
404 fmdSDigit->GetNTrack()));
405 AliFMDDebug(15, ("Contrib from FMD%d%c[%2d,%3d] (%s) from track %d",
406 fmdSDigit->Detector(),
410 fmdSDigit->GetName(),
411 fmdSDigit->GetTrack(0)));
413 // Extract parameters
414 AddContribution(fmdSDigit->Detector(),
420 fmdSDigit->GetNTrack(),
421 fmdSDigit->GetTracks());
426 AliFMDDebug(3, ("Size of cache: %d bytes, read %d bytes",
427 sizeof(fEdep), read));
430 //____________________________________________________________________