915dabe1 |
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 | |
2aef44c1 |
27 | ClassImp(TPCData) |
915dabe1 |
28 | |
29 | TPCData::TPCData() : |
30 | fSectors(36), fSectorBlockSize(65536), |
d6433e5d |
31 | fLoadThreshold(0), fLoadPedestal(0), fAutoPedestal(kFALSE) |
915dabe1 |
32 | { |
33 | TPCSectorData::InitStatics(); |
34 | } |
35 | |
36 | TPCData::~TPCData() |
37 | { |
38 | // !!!! delete sectors |
39 | } |
40 | |
41 | /**************************************************************************/ |
42 | |
43 | void TPCData::CreateSector(Int_t sector) |
44 | { |
45 | if(fSectors[sector] == 0) |
46 | fSectors[sector] = new TPCSectorData(sector, fSectorBlockSize); |
47 | } |
48 | |
49 | void TPCData::CreateAllSectors() |
50 | { |
51 | for(Int_t s=0; s<36; ++s) |
52 | CreateSector(s); |
53 | } |
54 | |
55 | /**************************************************************************/ |
56 | |
57 | TPCSectorData* TPCData::GetSectorData(Int_t sector, Bool_t spawnSectors) |
58 | { |
59 | if(sector < 0 || sector > 35) return 0; |
60 | if(fSectors[sector] == 0 && spawnSectors) |
61 | CreateSector(sector); |
62 | return fSectors[sector]; |
63 | } |
64 | |
65 | /**************************************************************************/ |
66 | |
67 | void TPCData::LoadDigits(TTree* tree, Bool_t spawnSectors) |
68 | { |
69 | // Load data from TTree of AliSimDigits. |
70 | // If spawnSectors is false only sectors that have been created previously |
71 | // via CreateSector() are loaded. |
72 | // If spawnSectors is true sectors are created if data for them is encountered. |
73 | |
74 | AliSimDigits digit, *digitPtr = &digit; |
75 | tree->GetBranch("Segment")->SetAddress(&digitPtr); |
76 | |
77 | Int_t sector, row, pad, curPad; |
78 | Short_t time, signal; |
79 | Bool_t inFill = kFALSE; |
80 | TPCSectorData* secData = 0; |
81 | |
82 | Int_t numEnt = (Int_t) tree->GetEntries(); |
83 | for (Int_t ent=0; ent<numEnt; ent++) { |
84 | tree->GetEntry(ent); |
85 | Alieve::TPCSectorData::GetParam().AdjustSectorRow(digit.GetID(), sector, row); |
86 | if(sector >= 36) { |
87 | sector -= 36; |
88 | row += TPCSectorData::GetInnSeg().GetNRows(); |
89 | } |
90 | secData = GetSectorData(sector, spawnSectors); |
91 | if(secData == 0) |
92 | continue; |
93 | |
94 | if(digit.First() == kFALSE) |
95 | continue; |
96 | curPad = -1; |
97 | do { |
98 | pad = digit.CurrentColumn(); |
99 | time = digit.CurrentRow(); |
100 | signal = digit.CurrentDigit(); |
101 | |
102 | if(pad != curPad) { |
103 | if(inFill) |
d6433e5d |
104 | secData->EndPad(fAutoPedestal, fLoadThreshold); |
915dabe1 |
105 | secData->BeginPad(row, pad, kFALSE); |
106 | curPad = pad; |
107 | inFill = kTRUE; |
108 | } |
109 | if(signal > fLoadThreshold) |
b56d8877 |
110 | secData->RegisterData(time, signal - fLoadPedestal); |
915dabe1 |
111 | |
112 | } while (digit.Next()); |
113 | if(inFill) { |
d6433e5d |
114 | secData->EndPad(fAutoPedestal, fLoadThreshold); |
915dabe1 |
115 | inFill = kFALSE; |
116 | } |
117 | } |
118 | } |
119 | |
120 | void TPCData::LoadRaw(AliTPCRawStream& input, Bool_t spawnSectors) |
121 | { |
122 | // Load data from AliTPCRawStream. |
123 | // If spawnSectors is false only sectors that have been created previously |
124 | // via CreateSector() are loaded. |
125 | // If spawnSectors is true sectors are created if data for them is encountered. |
126 | |
d6433e5d |
127 | Int_t sector = -1, row = -1, pad = -1, rowOffset = 0; |
128 | Short_t time, signal; |
129 | Bool_t inFill = kFALSE; |
915dabe1 |
130 | TPCSectorData* secData = 0; |
131 | |
132 | while (input.Next()) { |
133 | if (input.IsNewSector()) { |
134 | if(inFill) { |
d6433e5d |
135 | secData->EndPad(fAutoPedestal, fLoadThreshold); |
915dabe1 |
136 | inFill = kFALSE; |
137 | } |
138 | sector = input.GetSector(); |
139 | if(sector >= 36) { |
140 | sector -= 36; |
141 | rowOffset = TPCSectorData::GetInnSeg().GetNRows(); |
142 | } else { |
143 | rowOffset = 0; |
144 | } |
145 | secData = GetSectorData(sector, spawnSectors); |
146 | } |
147 | if (secData == 0) |
148 | continue; |
149 | |
150 | if (input.IsNewPad()) { |
151 | if(inFill) { |
d6433e5d |
152 | secData->EndPad(fAutoPedestal, fLoadThreshold); |
915dabe1 |
153 | inFill = kFALSE; |
154 | } |
155 | row = input.GetRow() + rowOffset; |
156 | pad = input.GetPad(); |
157 | |
158 | secData->BeginPad(row, pad, kTRUE); |
159 | inFill = kTRUE; |
160 | } |
161 | |
d6433e5d |
162 | time = input.GetTime(); |
163 | signal = input.GetSignal(); |
164 | if(fAutoPedestal) { |
165 | secData->RegisterData(time, signal); |
166 | } else { |
167 | if(signal > fLoadThreshold) |
168 | secData->RegisterData(time, signal - fLoadPedestal); |
169 | } |
915dabe1 |
170 | } |
171 | |
172 | if(inFill) { |
d6433e5d |
173 | secData->EndPad(fAutoPedestal, fLoadThreshold); |
915dabe1 |
174 | inFill = kFALSE; |
175 | } |
176 | } |
177 | |
178 | void TPCData::LoadRaw(AliTPCRawStreamOld& input, Bool_t spawnSectors, Bool_t warn) |
179 | { |
180 | // Load data from AliTPCRawStream. |
181 | // If spawnSectors is false only sectors that have been created previously |
182 | // via CreateSector() are loaded. |
183 | // If spawnSectors is true sectors are created if data for them is encountered. |
184 | |
185 | static const Exc_t eH("TPCData::LoadRaw "); |
186 | |
d6433e5d |
187 | Int_t sector = -1, row = -1, pad = -1, rowOffset = 0; |
188 | Short_t time, signal; |
189 | Bool_t inFill = kFALSE; |
915dabe1 |
190 | TPCSectorData* secData = 0; |
191 | |
192 | while (input.Next()) { |
193 | if (input.IsNewSector()) { |
194 | if(inFill) { |
d6433e5d |
195 | secData->EndPad(fAutoPedestal, fLoadThreshold); |
915dabe1 |
196 | inFill = kFALSE; |
197 | } |
198 | sector = input.GetSector(); |
199 | if(sector >= 36) { |
200 | sector -= 36; |
201 | rowOffset = TPCSectorData::GetInnSeg().GetNRows(); |
202 | } else { |
203 | rowOffset = 0; |
204 | } |
205 | secData = GetSectorData(sector, spawnSectors); |
206 | } |
207 | if (secData == 0) |
208 | continue; |
209 | |
210 | if (input.IsNewPad()) { |
211 | if(inFill) { |
d6433e5d |
212 | secData->EndPad(fAutoPedestal, fLoadThreshold); |
915dabe1 |
213 | inFill = kFALSE; |
214 | } |
215 | row = input.GetRow() + rowOffset; |
216 | pad = input.GetPad(); |
217 | |
218 | if(pad >= TPCSectorData::GetNPadsInRow(row)) { |
219 | if(warn) { |
220 | Warning(eH.Data(), "pad out of range (row=%d, pad=%d, maxpad=%d).", |
221 | row, pad, TPCSectorData::GetNPadsInRow(row)); |
222 | } |
223 | continue; |
224 | } |
225 | |
226 | secData->BeginPad(row, pad, kTRUE); |
227 | inFill = kTRUE; |
228 | } |
229 | |
d6433e5d |
230 | time = input.GetTime(); |
231 | signal = input.GetSignal(); |
232 | if(fAutoPedestal) { |
233 | secData->RegisterData(time, signal); |
234 | } else { |
235 | if(signal > fLoadThreshold) |
236 | secData->RegisterData(time, signal - fLoadPedestal); |
237 | } |
915dabe1 |
238 | } |
239 | |
240 | if(inFill) { |
d6433e5d |
241 | secData->EndPad(fAutoPedestal, fLoadThreshold); |
915dabe1 |
242 | inFill = kFALSE; |
243 | } |
244 | } |