]>
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 | ||
77 | ||
78 | Bool_t AliTPCRawStream::Next() | |
79 | { | |
80 | // read the next raw digit | |
81 | // returns kFALSE if there is no digit left | |
82 | ||
83 | fPrevSector = fSector; | |
84 | fPrevRow = fRow; | |
85 | fPrevPad = fPad; | |
86 | ||
87 | while (fCount == 0) { // next trailer | |
88 | if (fPosition >= fDataSize) { // next payload | |
89 | UChar_t* data; | |
90 | do { | |
91 | if (!fRawReader->ReadNextData(data)) return kFALSE; | |
92 | } while (fRawReader->GetDataSize() == 0); | |
93 | ||
94 | if (fRawReader->IsCompressed()) { // compressed data | |
0b3c7dfc | 95 | UInt_t size = 0; |
42d20574 | 96 | fCompression.Decompress(fgRootNode, fgkNumTables, |
f8aae377 | 97 | (char*) data, fRawReader->GetDataSize(), |
98 | fData, size); | |
99 | fDataSize = size; | |
100 | ||
101 | } else { // uncompressed data | |
102 | fDataSize = 0; | |
103 | Int_t pos = (fRawReader->GetDataSize() * 8) / 10; | |
104 | while (Get10BitWord(data, pos-1) == 0x2AA) pos--; | |
105 | while (pos > 0) { | |
106 | for (Int_t i = 0; i < 4; i++) { // copy trailer | |
107 | fData[fDataSize++] = Get10BitWord(data, pos-4+i); | |
108 | } | |
109 | pos -= 4; | |
110 | Int_t count = fData[fDataSize-4]; | |
111 | pos -= (4 - (count % 4)) % 4; // skip fill words | |
112 | ||
113 | while (count > 0) { | |
114 | UShort_t bunchLength = Get10BitWord(data, pos-1); | |
115 | fData[fDataSize++] = bunchLength; | |
116 | fData[fDataSize++] = Get10BitWord(data, pos-2); // time bin | |
117 | ||
118 | // copy signal amplitudes in increasing order on time | |
119 | for (Int_t i = 0; i < bunchLength-2; i++) { | |
120 | fData[fDataSize++] = Get10BitWord(data, pos - bunchLength + i); | |
121 | } | |
122 | pos -= bunchLength; | |
123 | count -= bunchLength; | |
124 | } | |
125 | } | |
126 | } | |
127 | ||
128 | fPosition = 0; | |
129 | } | |
130 | if (fPosition + 4 >= fDataSize) { | |
131 | Error("Next", "could not read trailer"); | |
132 | return kFALSE; | |
133 | } | |
134 | fCount = fData[fPosition++]; | |
135 | fPad = fData[fPosition++]; | |
136 | fRow = fData[fPosition++]; | |
137 | fSector = fData[fPosition++]; | |
138 | fBunchLength = 0; | |
139 | } | |
140 | ||
141 | if (fBunchLength == 0) { | |
142 | if (fPosition >= fDataSize) { | |
143 | Error("Next", "could not read bunch length"); | |
144 | return kFALSE; | |
145 | } | |
146 | fBunchLength = fData[fPosition++] - 2; | |
147 | fCount--; | |
148 | ||
149 | if (fPosition >= fDataSize) { | |
150 | Error("Next", "could not read time bin"); | |
151 | return kFALSE; | |
152 | } | |
153 | fTime = fData[fPosition++] - fBunchLength; | |
154 | fCount--; | |
155 | } | |
156 | ||
157 | fTime++; | |
158 | if (fPosition >= fDataSize) { | |
159 | Error("Next", "could not read sample amplitude"); | |
160 | return kFALSE; | |
161 | } | |
42d20574 | 162 | fSignal = fData[fPosition++] + fgkOffset; |
f8aae377 | 163 | fCount--; |
164 | fBunchLength--; | |
165 | ||
166 | return kTRUE; | |
167 | } | |
168 | ||
169 | ||
42d20574 | 170 | UShort_t AliTPCRawStream::Get10BitWord(UChar_t* buffer, Int_t position) const |
f8aae377 | 171 | { |
42d20574 | 172 | // return a word in a 10 bit array as an UShort_t |
173 | ||
f8aae377 | 174 | Int_t iBit = position * 10; |
175 | Int_t iByte = iBit / 8; | |
176 | Int_t shift = iBit % 8; | |
177 | // return ((buffer[iByte+1] * 256 + buffer[iByte]) >> shift) & 0x03FF; | |
178 | ||
179 | // recalculate the byte numbers and the shift because | |
180 | // the raw data is written as integers where the high bits are filled first | |
181 | // -> little endian is assumed here ! | |
182 | Int_t iByteHigh = 4 * (iByte / 4) + 3 - (iByte % 4); | |
183 | iByte++; | |
184 | Int_t iByteLow = 4 * (iByte / 4) + 3 - (iByte % 4); | |
185 | shift = 6 - shift; | |
186 | return ((buffer[iByteHigh] * 256 + buffer[iByteLow]) >> shift) & 0x03FF; | |
187 | } |