Added class documentation.
[u/mrichter/AliRoot.git] / EVE / EveDet / AliEveTPCData.cxx
1 // $Id$
2 // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3
4 /**************************************************************************
5  * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6  * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
7  * full copyright notice.                                                 *
8  **************************************************************************/
9
10 #include "AliEveTPCData.h"
11
12 #include <EveDet/AliEveTPCSectorData.h>
13
14 #include <AliSimDigits.h>
15 #include <AliTPCParam.h>
16 #include <AliTPCRawStream.h>
17 #include <TTree.h>
18
19
20 //______________________________________________________________________________
21 //
22 // A central manager for TPC data of an event.  Can read digits (from
23 // a tree: LoadDigits()) and raw-data (via AliRawReader: LoadRaw()).
24 //
25 // The sector data is stored in 36 AliEveTPCSectorData objects.
26 // Sectors 0 - 17: +z side, 18 - 35: -z side.
27 // No separation of inner/outer segments, use row numbers for addressing.
28 //
29 // Threshold application and pedestal subtraction can be performed at
30 // load time: use SetLoadThreshold(thresh) and SetLoadPedestal(ped).
31 //
32 // For raw-data (loaded using LoadRaw) pedestals can be calculated
33 // automatically per pad. Use SetAutoPedestal(kTRUE) to activate it.
34 // You might still want to set load threshold (default iz zero).
35 //
36
37 ClassImp(AliEveTPCData)
38
39 AliEveTPCData::AliEveTPCData() :
40   fSectors(36), fSectorBlockSize(65536),
41   fLoadThreshold(0), fLoadPedestal(0), fAutoPedestal(kFALSE)
42 {
43   // Constructor.
44
45   AliEveTPCSectorData::InitStatics();
46 }
47
48 AliEveTPCData::~AliEveTPCData()
49 {
50   // Destructor, deletes all sector-data.
51
52   DeleteAllSectors();
53 }
54
55 /******************************************************************************/
56
57 void AliEveTPCData::CreateSector(Int_t sector)
58 {
59   // Create sector-data for sector if it does not exist already.
60
61   if (fSectors[sector] == 0)
62     fSectors[sector] = new AliEveTPCSectorData(sector, fSectorBlockSize);
63 }
64
65 void AliEveTPCData::CreateAllSectors()
66 {
67   // Create all 36 sectors.
68
69   for (Int_t s=0; s<36; ++s)
70     CreateSector(s);
71 }
72
73 void AliEveTPCData::DropAllSectors()
74 {
75   // Drop data of all existing sectors.
76
77   for (Int_t s=0; s<36; ++s) {
78     if (fSectors[s] != 0)
79       fSectors[s]->DropData();
80   }
81 }
82
83 void AliEveTPCData::DeleteAllSectors()
84 {
85   // Delete all sector-data.
86
87   for (Int_t s=0; s<36; ++s) {
88     delete fSectors[s];
89     fSectors[s] = 0;
90   }
91 }
92
93 /******************************************************************************/
94
95 AliEveTPCSectorData* AliEveTPCData::GetSectorData(Int_t sector, Bool_t spawnSectors)
96 {
97   // Get sector-data for sector. If spawnSectors is true, the
98   // sector-data is created if it does not exist already.
99
100   if (sector < 0 || sector > 35) return 0;
101   if (fSectors[sector] == 0 && spawnSectors)
102     CreateSector(sector);
103   return fSectors[sector];
104 }
105
106 /******************************************************************************/
107
108 void AliEveTPCData::LoadDigits(TTree* tree, Bool_t spawnSectors)
109 {
110   // Load data from TTree of AliSimDigits.
111   // If spawnSectors is false only sectors that have been created previously
112   // via CreateSector() are loaded.
113   // If spawnSectors is true sectors are created if data for them is encountered.
114
115   AliSimDigits digit, *digitPtr = &digit;
116   tree->GetBranch("Segment")->SetAddress(&digitPtr);
117
118   Int_t sector, row, pad, curPad;
119   Short_t time, signal;
120   Bool_t  inFill = kFALSE;
121   AliEveTPCSectorData* secData = 0;
122
123   Int_t numEnt = (Int_t) tree->GetEntries();
124   for (Int_t ent=0; ent<numEnt; ent++) {
125     tree->GetEntry(ent);
126     AliEveTPCSectorData::GetParam().AdjustSectorRow(digit.GetID(), sector, row);
127     if (sector >= 36) {
128       sector -= 36;
129       row    += AliEveTPCSectorData::GetInnSeg().GetNRows();
130     }
131     secData = GetSectorData(sector, spawnSectors);
132     if (secData == 0)
133       continue;
134
135     if (digit.First() == kFALSE)
136       continue;
137     curPad = -1;
138     do {
139       pad    = digit.CurrentColumn();
140       time   = digit.CurrentRow();
141       signal = digit.CurrentDigit();
142
143       if (pad != curPad) {
144         if (inFill)
145           secData->EndPad(fAutoPedestal, fLoadThreshold);
146         secData->BeginPad(row, pad, kFALSE);
147         curPad = pad;
148         inFill = kTRUE;
149       }
150       if (fAutoPedestal) {
151         secData->RegisterData(time, signal);
152       } else {
153         signal -= fLoadPedestal;
154         if (signal >= fLoadThreshold)
155           secData->RegisterData(time, signal);
156       }
157
158     } while (digit.Next());
159     if (inFill) {
160       secData->EndPad(fAutoPedestal, fLoadThreshold);
161       inFill = kFALSE;
162     }
163   }
164 }
165
166 void AliEveTPCData::LoadRaw(AliTPCRawStream& input, Bool_t spawnSectors, Bool_t warn)
167 {
168   // Load data from AliTPCRawStream.
169   // If spawnSectors is false only sectors that have been created previously
170   // via CreateSector() are loaded.
171   // If spawnSectors is true sectors are created if data for them is encountered.
172
173   static const TEveException eH("AliEveTPCData::LoadRaw ");
174
175   Int_t   sector = -1, row = -1, pad = -1, rowOffset = 0;
176   Short_t time,  signal;
177   Bool_t  inFill   = kFALSE;
178   Short_t lastTime = 9999;
179   Bool_t  lastTimeWarn = kFALSE;
180   AliEveTPCSectorData* secData = 0;
181
182   Short_t threshold = fLoadThreshold;
183
184   while (input.Next()) {
185     if (input.IsNewSector()) {
186       if (inFill) {
187         secData->EndPad(fAutoPedestal, threshold);
188         inFill = kFALSE;
189       }
190       sector = input.GetSector();
191       if (sector >= 36) {
192         sector -= 36;
193         rowOffset = AliEveTPCSectorData::GetInnSeg().GetNRows();
194       } else {
195         rowOffset = 0;
196       }
197       secData = GetSectorData(sector, spawnSectors);
198     }
199     if (secData == 0)
200       continue;
201
202     if (input.IsNewPad()) {
203       if (inFill) {
204         secData->EndPad(fAutoPedestal, threshold);
205         inFill = kFALSE;
206       }
207       row = input.GetRow() + rowOffset;
208       pad = input.GetPad();
209
210       if (pad >= AliEveTPCSectorData::GetNPadsInRow(row)) {
211         if (warn) {
212           Warning(eH.Data(), "pad out of range (row=%d, pad=%d, maxpad=%d).",
213                   row, pad, AliEveTPCSectorData::GetNPadsInRow(row));
214         }
215         continue;
216       }
217
218       AliEveTPCSectorData::PadRowHack* prh = secData->GetPadRowHack(row, pad);
219       if (prh != 0) {
220         threshold = prh->fThrExt + Short_t(prh->fThrFac*fLoadThreshold);
221       } else {
222         threshold = fLoadThreshold;
223       }
224
225       secData->BeginPad(row, pad, kTRUE);
226       inFill   = kTRUE;
227       lastTime = 1024;  lastTimeWarn = kFALSE;
228     }
229
230     time   = input.GetTime();
231     signal = input.GetSignal();
232     if (time >= lastTime) {
233       if (lastTimeWarn == kFALSE) {
234         if (warn)
235           Warning(eH.Data(), "time out of order (row=%d, pad=%d, time=%d, lastTime=%d).",
236                   row, pad, time, lastTime);
237         lastTimeWarn = kTRUE;
238       }
239       continue;
240     }
241     lastTime = time;
242     if (fAutoPedestal) {
243       secData->RegisterData(time, signal);
244     } else {
245       signal -= fLoadPedestal;
246       if (signal > threshold)
247         secData->RegisterData(time, signal);
248     }
249   }
250
251   if (inFill) {
252     secData->EndPad(fAutoPedestal, threshold);
253     inFill = kFALSE;
254   }
255 }