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