]>
Commit | Line | Data |
---|---|---|
d810d0de | 1 | // $Id$ |
2 | // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 | |
915dabe1 | 3 | |
d810d0de | 4 | /************************************************************************** |
5 | * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. * | |
6 | * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for * | |
51346b82 | 7 | * full copyright notice. * |
d810d0de | 8 | **************************************************************************/ |
915dabe1 | 9 | |
d810d0de | 10 | #include "AliEveTPCData.h" |
11 | ||
cb4245bb | 12 | #include <EveDet/AliEveTPCSectorData.h> |
915dabe1 | 13 | |
14 | #include <AliSimDigits.h> | |
15 | #include <AliTPCParam.h> | |
375fd576 | 16 | #include <AliTPCRawStreamV3.h> |
915dabe1 | 17 | #include <TTree.h> |
d810d0de | 18 | |
a15e6d7d | 19 | //============================================================================== |
20 | //============================================================================== | |
21 | // AliEveTPCData | |
22 | //============================================================================== | |
915dabe1 | 23 | |
57ffa5fb | 24 | //______________________________________________________________________________ |
915dabe1 | 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 | // | |
d810d0de | 29 | // The sector data is stored in 36 AliEveTPCSectorData objects. |
915dabe1 | 30 | // Sectors 0 - 17: +z side, 18 - 35: -z side. |
31 | // No separation of inner/outer segments, use row numbers for addressing. | |
32 | // | |
092578a7 | 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 | |
51346b82 | 37 | // automatically per pad. Use SetAutoPedestal(kTRUE) to activate it. |
092578a7 | 38 | // You might still want to set load threshold (default iz zero). |
39 | // | |
915dabe1 | 40 | |
d810d0de | 41 | ClassImp(AliEveTPCData) |
915dabe1 | 42 | |
d810d0de | 43 | AliEveTPCData::AliEveTPCData() : |
915dabe1 | 44 | fSectors(36), fSectorBlockSize(65536), |
d6433e5d | 45 | fLoadThreshold(0), fLoadPedestal(0), fAutoPedestal(kFALSE) |
915dabe1 | 46 | { |
a97abca8 | 47 | // Constructor. |
48 | ||
d810d0de | 49 | AliEveTPCSectorData::InitStatics(); |
915dabe1 | 50 | } |
51 | ||
d810d0de | 52 | AliEveTPCData::~AliEveTPCData() |
915dabe1 | 53 | { |
a97abca8 | 54 | // Destructor, deletes all sector-data. |
55 | ||
092578a7 | 56 | DeleteAllSectors(); |
915dabe1 | 57 | } |
58 | ||
57ffa5fb | 59 | /******************************************************************************/ |
915dabe1 | 60 | |
d810d0de | 61 | void AliEveTPCData::CreateSector(Int_t sector) |
915dabe1 | 62 | { |
a97abca8 | 63 | // Create sector-data for sector if it does not exist already. |
64 | ||
65 | if (fSectors[sector] == 0) | |
d810d0de | 66 | fSectors[sector] = new AliEveTPCSectorData(sector, fSectorBlockSize); |
915dabe1 | 67 | } |
68 | ||
d810d0de | 69 | void AliEveTPCData::CreateAllSectors() |
915dabe1 | 70 | { |
a97abca8 | 71 | // Create all 36 sectors. |
72 | ||
73 | for (Int_t s=0; s<36; ++s) | |
915dabe1 | 74 | CreateSector(s); |
75 | } | |
76 | ||
d810d0de | 77 | void AliEveTPCData::DropAllSectors() |
092578a7 | 78 | { |
a97abca8 | 79 | // Drop data of all existing sectors. |
80 | ||
81 | for (Int_t s=0; s<36; ++s) { | |
82 | if (fSectors[s] != 0) | |
092578a7 | 83 | fSectors[s]->DropData(); |
84 | } | |
85 | } | |
86 | ||
d810d0de | 87 | void AliEveTPCData::DeleteAllSectors() |
092578a7 | 88 | { |
a97abca8 | 89 | // Delete all sector-data. |
90 | ||
91 | for (Int_t s=0; s<36; ++s) { | |
092578a7 | 92 | delete fSectors[s]; |
93 | fSectors[s] = 0; | |
94 | } | |
95 | } | |
96 | ||
57ffa5fb | 97 | /******************************************************************************/ |
915dabe1 | 98 | |
d810d0de | 99 | AliEveTPCSectorData* AliEveTPCData::GetSectorData(Int_t sector, Bool_t spawnSectors) |
915dabe1 | 100 | { |
a97abca8 | 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) | |
915dabe1 | 106 | CreateSector(sector); |
107 | return fSectors[sector]; | |
108 | } | |
109 | ||
57ffa5fb | 110 | /******************************************************************************/ |
915dabe1 | 111 | |
d810d0de | 112 | void AliEveTPCData::LoadDigits(TTree* tree, Bool_t spawnSectors) |
915dabe1 | 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); | |
51346b82 | 121 | |
915dabe1 | 122 | Int_t sector, row, pad, curPad; |
123 | Short_t time, signal; | |
124 | Bool_t inFill = kFALSE; | |
d810d0de | 125 | AliEveTPCSectorData* secData = 0; |
915dabe1 | 126 | |
127 | Int_t numEnt = (Int_t) tree->GetEntries(); | |
128 | for (Int_t ent=0; ent<numEnt; ent++) { | |
129 | tree->GetEntry(ent); | |
d810d0de | 130 | AliEveTPCSectorData::GetParam().AdjustSectorRow(digit.GetID(), sector, row); |
a97abca8 | 131 | if (sector >= 36) { |
915dabe1 | 132 | sector -= 36; |
d810d0de | 133 | row += AliEveTPCSectorData::GetInnSeg().GetNRows(); |
915dabe1 | 134 | } |
135 | secData = GetSectorData(sector, spawnSectors); | |
a97abca8 | 136 | if (secData == 0) |
915dabe1 | 137 | continue; |
138 | ||
a97abca8 | 139 | if (digit.First() == kFALSE) |
915dabe1 | 140 | continue; |
141 | curPad = -1; | |
142 | do { | |
143 | pad = digit.CurrentColumn(); | |
144 | time = digit.CurrentRow(); | |
145 | signal = digit.CurrentDigit(); | |
146 | ||
a97abca8 | 147 | if (pad != curPad) { |
148 | if (inFill) | |
d6433e5d | 149 | secData->EndPad(fAutoPedestal, fLoadThreshold); |
915dabe1 | 150 | secData->BeginPad(row, pad, kFALSE); |
151 | curPad = pad; | |
152 | inFill = kTRUE; | |
153 | } | |
a97abca8 | 154 | if (fAutoPedestal) { |
8bb2a8e9 | 155 | secData->RegisterData(time, signal); |
156 | } else { | |
157 | signal -= fLoadPedestal; | |
a97abca8 | 158 | if (signal >= fLoadThreshold) |
8bb2a8e9 | 159 | secData->RegisterData(time, signal); |
160 | } | |
915dabe1 | 161 | |
162 | } while (digit.Next()); | |
a97abca8 | 163 | if (inFill) { |
d6433e5d | 164 | secData->EndPad(fAutoPedestal, fLoadThreshold); |
915dabe1 | 165 | inFill = kFALSE; |
166 | } | |
167 | } | |
168 | } | |
169 | ||
375fd576 | 170 | void AliEveTPCData::LoadRaw(AliTPCRawStreamV3& input, Bool_t spawnSectors, Bool_t warn) |
915dabe1 | 171 | { |
375fd576 | 172 | // Load data from AliTPCRawStreamV3. |
915dabe1 | 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 | ||
a15e6d7d | 177 | static const TEveException kEH("AliEveTPCData::LoadRaw "); |
915dabe1 | 178 | |
d6433e5d | 179 | Int_t sector = -1, row = -1, pad = -1, rowOffset = 0; |
092578a7 | 180 | Short_t time, signal; |
2148ac41 | 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; | |
092578a7 | 185 | Bool_t lastTimeWarn = kFALSE; |
d810d0de | 186 | AliEveTPCSectorData* secData = 0; |
915dabe1 | 187 | |
75a20dc1 | 188 | Short_t threshold = fLoadThreshold; |
189 | ||
375fd576 | 190 | while (input.NextDDL()) { |
915dabe1 | 191 | if (input.IsNewSector()) { |
a97abca8 | 192 | if (inFill) { |
75a20dc1 | 193 | secData->EndPad(fAutoPedestal, threshold); |
915dabe1 | 194 | inFill = kFALSE; |
195 | } | |
196 | sector = input.GetSector(); | |
a97abca8 | 197 | if (sector >= 36) { |
915dabe1 | 198 | sector -= 36; |
d810d0de | 199 | rowOffset = AliEveTPCSectorData::GetInnSeg().GetNRows(); |
915dabe1 | 200 | } else { |
201 | rowOffset = 0; | |
202 | } | |
203 | secData = GetSectorData(sector, spawnSectors); | |
204 | } | |
205 | if (secData == 0) | |
206 | continue; | |
207 | ||
375fd576 | 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; | |
915dabe1 | 223 | } |
75a20dc1 | 224 | |
375fd576 | 225 | threshold = fLoadThreshold; |
915dabe1 | 226 | |
375fd576 | 227 | secData->BeginPad(row, pad, kTRUE); |
228 | inFill = kTRUE; | |
229 | pdrwCnt = 0; pdrwCntWarn = kFALSE; | |
230 | lastTime = 1024; lastTimeWarn = kFALSE; | |
2148ac41 | 231 | } |
375fd576 | 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 | } | |
092578a7 | 268 | } |
d6433e5d | 269 | } |
915dabe1 | 270 | } |
271 | ||
a97abca8 | 272 | if (inFill) { |
75a20dc1 | 273 | secData->EndPad(fAutoPedestal, threshold); |
915dabe1 | 274 | inFill = kFALSE; |
275 | } | |
276 | } |