]>
Commit | Line | Data |
---|---|---|
f8aae377 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
42d20574 | 16 | /* $Id$ */ |
17 | ||
f8aae377 | 18 | /////////////////////////////////////////////////////////////////////////////// |
bea6b2a4 | 19 | /// |
20 | /// This class provides access to TPC digits in raw data. | |
21 | /// | |
22 | /// It loops over all TPC digits in the raw data given by the AliRawReader. | |
23 | /// The Next method goes to the next digit. If there are no digits left | |
24 | /// it returns kFALSE. | |
25 | /// Several getters provide information about the current digit. | |
26 | /// | |
f8aae377 | 27 | /////////////////////////////////////////////////////////////////////////////// |
28 | ||
29 | #include "AliTPCRawStream.h" | |
bea6b2a4 | 30 | #include "AliTPCHNode.h" |
42d20574 | 31 | #include "AliRawReader.h" |
f8aae377 | 32 | |
33 | ClassImp(AliTPCRawStream) | |
34 | ||
35 | ||
36 | AliTPCHNode** AliTPCRawStream::fgRootNode = NULL; | |
95e50ecd | 37 | UInt_t** AliTPCRawStream::fgLUTDimension = NULL; |
38 | AliTPCHNode***AliTPCRawStream::fgLUTNode = NULL; | |
f8aae377 | 39 | |
40 | ||
41 | AliTPCRawStream::AliTPCRawStream(AliRawReader* rawReader) | |
42 | { | |
43 | // create an object to read TPC raw digits | |
44 | ||
45 | fRawReader = rawReader; | |
46 | fRawReader->Select(0); | |
42d20574 | 47 | fData = new UShort_t[fgkDataMax]; |
f8aae377 | 48 | fDataSize = fPosition = 0; |
49 | fCount = fBunchLength = 0; | |
50 | ||
51 | if (!fgRootNode) { | |
42d20574 | 52 | fgRootNode = new AliTPCHNode*[fgkNumTables]; |
95e50ecd | 53 | fgLUTDimension = new UInt_t*[fgkNumTables]; |
54 | fgLUTNode = new AliTPCHNode**[fgkNumTables]; | |
42d20574 | 55 | fCompression.CreateTreesFromFile(fgRootNode, fgkNumTables); |
95e50ecd | 56 | fCompression.CreateLUTsFromTrees(fgRootNode, fgkNumTables, fgLUTDimension, fgLUTNode); |
f8aae377 | 57 | } |
58 | ||
59 | fSector = fPrevSector = fRow = fPrevRow = fPad = fPrevPad = fTime = fSignal = -1; | |
60 | } | |
61 | ||
42d20574 | 62 | AliTPCRawStream::AliTPCRawStream(const AliTPCRawStream& stream) : |
63 | TObject(stream) | |
64 | { | |
65 | Fatal("AliTPCRawStream", "copy constructor not implemented"); | |
66 | } | |
67 | ||
68 | AliTPCRawStream& AliTPCRawStream::operator = (const AliTPCRawStream& | |
69 | /* stream */) | |
70 | { | |
71 | Fatal("operator =", "assignment operator not implemented"); | |
72 | return *this; | |
73 | } | |
74 | ||
f8aae377 | 75 | AliTPCRawStream::~AliTPCRawStream() |
76 | { | |
77 | // clean up | |
78 | ||
79 | delete[] fData; | |
80 | } | |
81 | ||
a8ffd46b | 82 | void AliTPCRawStream::Reset() |
83 | { | |
84 | // reset tpc raw stream params | |
85 | ||
86 | fDataSize = fPosition = 0; | |
87 | fCount = fBunchLength = 0; | |
88 | ||
89 | fSector = fPrevSector = fRow = fPrevRow = fPad = fPrevPad = fTime = fSignal = -1; | |
90 | } | |
f8aae377 | 91 | |
92 | Bool_t AliTPCRawStream::Next() | |
93 | { | |
94 | // read the next raw digit | |
95 | // returns kFALSE if there is no digit left | |
96 | ||
97 | fPrevSector = fSector; | |
98 | fPrevRow = fRow; | |
99 | fPrevPad = fPad; | |
100 | ||
101 | while (fCount == 0) { // next trailer | |
102 | if (fPosition >= fDataSize) { // next payload | |
103 | UChar_t* data; | |
104 | do { | |
105 | if (!fRawReader->ReadNextData(data)) return kFALSE; | |
106 | } while (fRawReader->GetDataSize() == 0); | |
107 | ||
108 | if (fRawReader->IsCompressed()) { // compressed data | |
0b3c7dfc | 109 | UInt_t size = 0; |
95e50ecd | 110 | // fCompression.Decompress(fgRootNode, fgkNumTables, |
111 | // (char*) data, fRawReader->GetDataSize(), | |
112 | // fData, size); | |
113 | fCompression.DecompressWithLUTs(fgRootNode, fgLUTDimension, fgLUTNode, fgkNumTables, | |
114 | (char*) data, fRawReader->GetDataSize(), | |
115 | fData, size); | |
f8aae377 | 116 | fDataSize = size; |
117 | ||
118 | } else { // uncompressed data | |
119 | fDataSize = 0; | |
120 | Int_t pos = (fRawReader->GetDataSize() * 8) / 10; | |
121 | while (Get10BitWord(data, pos-1) == 0x2AA) pos--; | |
122 | while (pos > 0) { | |
123 | for (Int_t i = 0; i < 4; i++) { // copy trailer | |
124 | fData[fDataSize++] = Get10BitWord(data, pos-4+i); | |
125 | } | |
126 | pos -= 4; | |
127 | Int_t count = fData[fDataSize-4]; | |
128 | pos -= (4 - (count % 4)) % 4; // skip fill words | |
129 | ||
130 | while (count > 0) { | |
131 | UShort_t bunchLength = Get10BitWord(data, pos-1); | |
132 | fData[fDataSize++] = bunchLength; | |
133 | fData[fDataSize++] = Get10BitWord(data, pos-2); // time bin | |
134 | ||
135 | // copy signal amplitudes in increasing order on time | |
136 | for (Int_t i = 0; i < bunchLength-2; i++) { | |
137 | fData[fDataSize++] = Get10BitWord(data, pos - bunchLength + i); | |
138 | } | |
139 | pos -= bunchLength; | |
140 | count -= bunchLength; | |
141 | } | |
142 | } | |
143 | } | |
144 | ||
145 | fPosition = 0; | |
146 | } | |
147 | if (fPosition + 4 >= fDataSize) { | |
148 | Error("Next", "could not read trailer"); | |
149 | return kFALSE; | |
150 | } | |
151 | fCount = fData[fPosition++]; | |
152 | fPad = fData[fPosition++]; | |
153 | fRow = fData[fPosition++]; | |
154 | fSector = fData[fPosition++]; | |
155 | fBunchLength = 0; | |
156 | } | |
157 | ||
158 | if (fBunchLength == 0) { | |
159 | if (fPosition >= fDataSize) { | |
160 | Error("Next", "could not read bunch length"); | |
161 | return kFALSE; | |
162 | } | |
163 | fBunchLength = fData[fPosition++] - 2; | |
164 | fCount--; | |
165 | ||
166 | if (fPosition >= fDataSize) { | |
167 | Error("Next", "could not read time bin"); | |
168 | return kFALSE; | |
169 | } | |
170 | fTime = fData[fPosition++] - fBunchLength; | |
171 | fCount--; | |
172 | } | |
173 | ||
174 | fTime++; | |
175 | if (fPosition >= fDataSize) { | |
176 | Error("Next", "could not read sample amplitude"); | |
177 | return kFALSE; | |
178 | } | |
42d20574 | 179 | fSignal = fData[fPosition++] + fgkOffset; |
f8aae377 | 180 | fCount--; |
181 | fBunchLength--; | |
182 | ||
183 | return kTRUE; | |
184 | } | |
185 | ||
186 | ||
42d20574 | 187 | UShort_t AliTPCRawStream::Get10BitWord(UChar_t* buffer, Int_t position) const |
f8aae377 | 188 | { |
42d20574 | 189 | // return a word in a 10 bit array as an UShort_t |
190 | ||
f8aae377 | 191 | Int_t iBit = position * 10; |
192 | Int_t iByte = iBit / 8; | |
193 | Int_t shift = iBit % 8; | |
194 | // return ((buffer[iByte+1] * 256 + buffer[iByte]) >> shift) & 0x03FF; | |
195 | ||
196 | // recalculate the byte numbers and the shift because | |
197 | // the raw data is written as integers where the high bits are filled first | |
198 | // -> little endian is assumed here ! | |
199 | Int_t iByteHigh = 4 * (iByte / 4) + 3 - (iByte % 4); | |
200 | iByte++; | |
201 | Int_t iByteLow = 4 * (iByte / 4) + 3 - (iByte % 4); | |
202 | shift = 6 - shift; | |
203 | return ((buffer[iByteHigh] * 256 + buffer[iByteLow]) >> shift) & 0x03FF; | |
204 | } |