]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/EveDet/AliEveTPCData.cxx
Coverity
[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 <AliTPCRawStreamV3.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(AliTPCRawStreamV3& input, Bool_t spawnSectors, Bool_t warn)
171 {
172   // Load data from AliTPCRawStreamV3.
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.NextDDL()) {
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     while (input.NextChannel()) {
209       if (input.IsNewPad()) {
210         if (inFill) {
211           secData->EndPad(fAutoPedestal, threshold);
212           inFill = kFALSE;
213         }
214         row = input.GetRow() + rowOffset;
215         pad = input.GetPad();
216
217         if (pad >= AliEveTPCSectorData::GetNPadsInRow(row) || pad < 0) {
218           if (warn) {
219             Warning(kEH.Data(), "pad out of range (row=%d, pad=%d, maxpad=%d).",
220                     row, pad, AliEveTPCSectorData::GetNPadsInRow(row));
221           }
222           continue;
223         }
224
225         threshold = fLoadThreshold;
226
227         secData->BeginPad(row, pad, kTRUE);
228         inFill   = kTRUE;
229         pdrwCnt  = 0;     pdrwCntWarn  = kFALSE;
230         lastTime = 1024;  lastTimeWarn = kFALSE;
231       }
232
233       while (input.NextBunch()) {
234         const UShort_t *signalarr = input.GetSignals();
235
236         Int_t starttime = input.GetStartTimeBin();
237         for (Int_t i = 0; i < input.GetBunchLength(); i++) {
238           time   = starttime--;;
239           signal = signalarr[i];
240           ++pdrwCnt;
241           if (pdrwCnt > 1024) {
242             if (pdrwCntWarn == kFALSE) {
243               if (warn)
244                 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.",
245                         row, pad, time);
246               pdrwCntWarn = kTRUE;
247             }
248             continue;
249           }
250           if (time >= lastTime) {
251             if (lastTimeWarn == kFALSE) {
252               if (warn)
253                 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.",
254                         row, pad, time, lastTime);
255               lastTimeWarn = kTRUE;
256             }
257             continue;
258           }
259           lastTime = time;
260           if (fAutoPedestal) {
261             secData->RegisterData(time, signal);
262           } else {
263             signal -= fLoadPedestal;
264             if (signal > threshold)
265               secData->RegisterData(time, signal);
266           }
267         }
268       }
269     }
270   }
271
272   if (inFill) {
273     secData->EndPad(fAutoPedestal, threshold);
274     inFill = kFALSE;
275   }
276 }