]>
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; | |
37 | ||
38 | ||
39 | AliTPCRawStream::AliTPCRawStream(AliRawReader* rawReader) | |
40 | { | |
41 | // create an object to read TPC raw digits | |
42 | ||
43 | fRawReader = rawReader; | |
44 | fRawReader->Select(0); | |
42d20574 | 45 | fData = new UShort_t[fgkDataMax]; |
f8aae377 | 46 | fDataSize = fPosition = 0; |
47 | fCount = fBunchLength = 0; | |
48 | ||
49 | if (!fgRootNode) { | |
42d20574 | 50 | fgRootNode = new AliTPCHNode*[fgkNumTables]; |
51 | fCompression.CreateTreesFromFile(fgRootNode, fgkNumTables); | |
f8aae377 | 52 | } |
53 | ||
54 | fSector = fPrevSector = fRow = fPrevRow = fPad = fPrevPad = fTime = fSignal = -1; | |
55 | } | |
56 | ||
42d20574 | 57 | AliTPCRawStream::AliTPCRawStream(const AliTPCRawStream& stream) : |
58 | TObject(stream) | |
59 | { | |
60 | Fatal("AliTPCRawStream", "copy constructor not implemented"); | |
61 | } | |
62 | ||
63 | AliTPCRawStream& AliTPCRawStream::operator = (const AliTPCRawStream& | |
64 | /* stream */) | |
65 | { | |
66 | Fatal("operator =", "assignment operator not implemented"); | |
67 | return *this; | |
68 | } | |
69 | ||
f8aae377 | 70 | AliTPCRawStream::~AliTPCRawStream() |
71 | { | |
72 | // clean up | |
73 | ||
74 | delete[] fData; | |
75 | } | |
76 | ||
a8ffd46b | 77 | void AliTPCRawStream::Reset() |
78 | { | |
79 | // reset tpc raw stream params | |
80 | ||
81 | fDataSize = fPosition = 0; | |
82 | fCount = fBunchLength = 0; | |
83 | ||
84 | fSector = fPrevSector = fRow = fPrevRow = fPad = fPrevPad = fTime = fSignal = -1; | |
85 | } | |
f8aae377 | 86 | |
87 | Bool_t AliTPCRawStream::Next() | |
88 | { | |
89 | // read the next raw digit | |
90 | // returns kFALSE if there is no digit left | |
91 | ||
92 | fPrevSector = fSector; | |
93 | fPrevRow = fRow; | |
94 | fPrevPad = fPad; | |
95 | ||
96 | while (fCount == 0) { // next trailer | |
97 | if (fPosition >= fDataSize) { // next payload | |
98 | UChar_t* data; | |
99 | do { | |
100 | if (!fRawReader->ReadNextData(data)) return kFALSE; | |
101 | } while (fRawReader->GetDataSize() == 0); | |
102 | ||
103 | if (fRawReader->IsCompressed()) { // compressed data | |
0b3c7dfc | 104 | UInt_t size = 0; |
42d20574 | 105 | fCompression.Decompress(fgRootNode, fgkNumTables, |
f8aae377 | 106 | (char*) data, fRawReader->GetDataSize(), |
107 | fData, size); | |
108 | fDataSize = size; | |
109 | ||
110 | } else { // uncompressed data | |
111 | fDataSize = 0; | |
112 | Int_t pos = (fRawReader->GetDataSize() * 8) / 10; | |
113 | while (Get10BitWord(data, pos-1) == 0x2AA) pos--; | |
114 | while (pos > 0) { | |
115 | for (Int_t i = 0; i < 4; i++) { // copy trailer | |
116 | fData[fDataSize++] = Get10BitWord(data, pos-4+i); | |
117 | } | |
118 | pos -= 4; | |
119 | Int_t count = fData[fDataSize-4]; | |
120 | pos -= (4 - (count % 4)) % 4; // skip fill words | |
121 | ||
122 | while (count > 0) { | |
123 | UShort_t bunchLength = Get10BitWord(data, pos-1); | |
124 | fData[fDataSize++] = bunchLength; | |
125 | fData[fDataSize++] = Get10BitWord(data, pos-2); // time bin | |
126 | ||
127 | // copy signal amplitudes in increasing order on time | |
128 | for (Int_t i = 0; i < bunchLength-2; i++) { | |
129 | fData[fDataSize++] = Get10BitWord(data, pos - bunchLength + i); | |
130 | } | |
131 | pos -= bunchLength; | |
132 | count -= bunchLength; | |
133 | } | |
134 | } | |
135 | } | |
136 | ||
137 | fPosition = 0; | |
138 | } | |
139 | if (fPosition + 4 >= fDataSize) { | |
140 | Error("Next", "could not read trailer"); | |
141 | return kFALSE; | |
142 | } | |
143 | fCount = fData[fPosition++]; | |
144 | fPad = fData[fPosition++]; | |
145 | fRow = fData[fPosition++]; | |
146 | fSector = fData[fPosition++]; | |
147 | fBunchLength = 0; | |
148 | } | |
149 | ||
150 | if (fBunchLength == 0) { | |
151 | if (fPosition >= fDataSize) { | |
152 | Error("Next", "could not read bunch length"); | |
153 | return kFALSE; | |
154 | } | |
155 | fBunchLength = fData[fPosition++] - 2; | |
156 | fCount--; | |
157 | ||
158 | if (fPosition >= fDataSize) { | |
159 | Error("Next", "could not read time bin"); | |
160 | return kFALSE; | |
161 | } | |
162 | fTime = fData[fPosition++] - fBunchLength; | |
163 | fCount--; | |
164 | } | |
165 | ||
166 | fTime++; | |
167 | if (fPosition >= fDataSize) { | |
168 | Error("Next", "could not read sample amplitude"); | |
169 | return kFALSE; | |
170 | } | |
42d20574 | 171 | fSignal = fData[fPosition++] + fgkOffset; |
f8aae377 | 172 | fCount--; |
173 | fBunchLength--; | |
174 | ||
175 | return kTRUE; | |
176 | } | |
177 | ||
178 | ||
42d20574 | 179 | UShort_t AliTPCRawStream::Get10BitWord(UChar_t* buffer, Int_t position) const |
f8aae377 | 180 | { |
42d20574 | 181 | // return a word in a 10 bit array as an UShort_t |
182 | ||
f8aae377 | 183 | Int_t iBit = position * 10; |
184 | Int_t iByte = iBit / 8; | |
185 | Int_t shift = iBit % 8; | |
186 | // return ((buffer[iByte+1] * 256 + buffer[iByte]) >> shift) & 0x03FF; | |
187 | ||
188 | // recalculate the byte numbers and the shift because | |
189 | // the raw data is written as integers where the high bits are filled first | |
190 | // -> little endian is assumed here ! | |
191 | Int_t iByteHigh = 4 * (iByte / 4) + 3 - (iByte % 4); | |
192 | iByte++; | |
193 | Int_t iByteLow = 4 * (iByte / 4) + 3 - (iByte % 4); | |
194 | shift = 6 - shift; | |
195 | return ((buffer[iByteHigh] * 256 + buffer[iByteLow]) >> shift) & 0x03FF; | |
196 | } |