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