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