4442e48446518691abfb7be8a43f469363f743c4
[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 lastTime = 9999;
183   Bool_t  lastTimeWarn = kFALSE;
184   AliEveTPCSectorData* secData = 0;
185
186   Short_t threshold = fLoadThreshold;
187
188   while (input.Next()) {
189     if (input.IsNewSector()) {
190       if (inFill) {
191         secData->EndPad(fAutoPedestal, threshold);
192         inFill = kFALSE;
193       }
194       sector = input.GetSector();
195       if (sector >= 36) {
196         sector -= 36;
197         rowOffset = AliEveTPCSectorData::GetInnSeg().GetNRows();
198       } else {
199         rowOffset = 0;
200       }
201       secData = GetSectorData(sector, spawnSectors);
202     }
203     if (secData == 0)
204       continue;
205
206     if (input.IsNewPad()) {
207       if (inFill) {
208         secData->EndPad(fAutoPedestal, threshold);
209         inFill = kFALSE;
210       }
211       row = input.GetRow() + rowOffset;
212       pad = input.GetPad();
213
214       if (pad >= AliEveTPCSectorData::GetNPadsInRow(row)) {
215         if (warn) {
216           Warning(kEH.Data(), "pad out of range (row=%d, pad=%d, maxpad=%d).",
217                   row, pad, AliEveTPCSectorData::GetNPadsInRow(row));
218         }
219         continue;
220       }
221
222       AliEveTPCSectorData::PadRowHack* prh = secData->GetPadRowHack(row, pad);
223       if (prh != 0) {
224         threshold = prh->fThrExt + Short_t(prh->fThrFac*fLoadThreshold);
225       } else {
226         threshold = fLoadThreshold;
227       }
228
229       secData->BeginPad(row, pad, kTRUE);
230       inFill   = kTRUE;
231       lastTime = 1024;  lastTimeWarn = kFALSE;
232     }
233
234     time   = input.GetTime();
235     signal = input.GetSignal();
236     if (time >= lastTime) {
237       if (lastTimeWarn == kFALSE) {
238         if (warn)
239           Warning(kEH.Data(), "time out of order (row=%d, pad=%d, time=%d, lastTime=%d).",
240                   row, pad, time, lastTime);
241         lastTimeWarn = kTRUE;
242       }
243       continue;
244     }
245     lastTime = time;
246     if (fAutoPedestal) {
247       secData->RegisterData(time, signal);
248     } else {
249       signal -= fLoadPedestal;
250       if (signal > threshold)
251         secData->RegisterData(time, signal);
252     }
253   }
254
255   if (inFill) {
256     secData->EndPad(fAutoPedestal, threshold);
257     inFill = kFALSE;
258   }
259 }