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