]>
Commit | Line | Data |
---|---|---|
1 | /************************************************************************** | |
2 | * Copyright(c) 2007-2009, 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 | /* $Id$*/ | |
17 | ||
18 | /////////////////////////////////////////////////////////////////////////////// | |
19 | /// | |
20 | /// This class provides access to ITS SDD digits in raw data. | |
21 | /// | |
22 | /////////////////////////////////////////////////////////////////////////////// | |
23 | ||
24 | #include "AliITSRawStreamSDD.h" | |
25 | #include "AliITSRawStreamSDDCompressed.h" | |
26 | #include "AliRawReader.h" | |
27 | #include "AliLog.h" | |
28 | ||
29 | ClassImp(AliITSRawStreamSDD) | |
30 | ||
31 | const UInt_t AliITSRawStreamSDD::fgkCodeLength[8] = {8, 18, 2, 3, 4, 5, 6, 7}; | |
32 | ||
33 | //______________________________________________________________________ | |
34 | AliITSRawStreamSDD::AliITSRawStreamSDD(AliRawReader* rawReader) : | |
35 | AliITSRawStream(rawReader), | |
36 | fDDLModuleMap(0), | |
37 | fData(0), | |
38 | fResetSkip(kTRUE), | |
39 | fEventId(0), | |
40 | fCarlosId(-1), | |
41 | fChannel(0), | |
42 | fJitter(0), | |
43 | fEightBitSignal(0), | |
44 | fDecompressAmbra(kTRUE) | |
45 | { | |
46 | // create an object to read ITS SDD raw digits | |
47 | Reset(); | |
48 | for(Int_t im=0;im<kSDDModules;im++){ | |
49 | fLowThresholdArray[im][0]=0; | |
50 | fLowThresholdArray[im][1]=0; | |
51 | } | |
52 | for(Int_t i=0;i<kFifoWords;i++) fNfifo[i]=0; | |
53 | fRawReader->Reset(); | |
54 | fRawReader->Select("ITSSDD"); | |
55 | ||
56 | for(Short_t i=0; i<kCarlosWords; i++) fICarlosWord[i]=0x30000000 + i; // 805306368+i; | |
57 | for(Short_t i=0; i<kFifoWords; i++) fIFifoWord[i]=0x30000010 + i; // 805306384+i; | |
58 | } | |
59 | ||
60 | //______________________________________________________________________ | |
61 | AliITSRawStreamSDD::AliITSRawStreamSDD(const AliITSRawStreamSDD& rs) : | |
62 | AliITSRawStream(rs.fRawReader), | |
63 | fDDLModuleMap(rs.fDDLModuleMap), | |
64 | fData(0), | |
65 | fResetSkip(kTRUE), | |
66 | fEventId(0), | |
67 | fCarlosId(-1), | |
68 | fChannel(0), | |
69 | fJitter(0), | |
70 | fEightBitSignal(0), | |
71 | fDecompressAmbra(kTRUE) | |
72 | { | |
73 | // copy constructor | |
74 | AliError("Copy constructor should not be used."); | |
75 | } | |
76 | //__________________________________________________________________________ | |
77 | AliITSRawStreamSDD& AliITSRawStreamSDD::operator=(const AliITSRawStreamSDD& rs) { | |
78 | // assignment operator | |
79 | if (this!=&rs) {} | |
80 | AliError("Assignment opertator should not be used."); | |
81 | return *this; | |
82 | } | |
83 | ||
84 | //______________________________________________________________________ | |
85 | AliITSRawStreamSDD::~AliITSRawStreamSDD(){ | |
86 | if(fDDLModuleMap) delete fDDLModuleMap; | |
87 | } | |
88 | //______________________________________________________________________ | |
89 | UChar_t AliITSRawStreamSDD::ReadBlockAttributes(AliRawReader* rawReader){ | |
90 | // reads block attribuited from CDH | |
91 | UChar_t *data; | |
92 | rawReader->Reset(); | |
93 | rawReader->Select("ITSSDD"); | |
94 | do{ | |
95 | if(!rawReader->ReadNextData(data)) return 0x0; | |
96 | }while(rawReader->GetDataSize()==0); | |
97 | UChar_t attr=rawReader->GetBlockAttributes(); | |
98 | return attr; | |
99 | } | |
100 | //______________________________________________________________________ | |
101 | AliITSRawStream* AliITSRawStreamSDD::CreateRawStreamSDD(AliRawReader* rawReader, UChar_t attributes){ | |
102 | // instantiates the proper raw stream from block attributes value | |
103 | ||
104 | Int_t rawFormat=(attributes&0xE0)>>5; | |
105 | rawReader->Reset(); | |
106 | AliITSRawStream* inputSDD; | |
107 | if(rawFormat==0){ | |
108 | inputSDD=new AliITSRawStreamSDDCompressed(rawReader); | |
109 | inputSDD->SetADCEncoded(kTRUE); | |
110 | }else{ | |
111 | inputSDD=new AliITSRawStreamSDD(rawReader); | |
112 | } | |
113 | return inputSDD; | |
114 | } | |
115 | //______________________________________________________________________ | |
116 | AliITSRawStream* AliITSRawStreamSDD::CreateRawStreamSDD(AliRawReader* rawReader){ | |
117 | // reads the data format from CDH and instantiates the proper raw stream | |
118 | UChar_t attr=ReadBlockAttributes(rawReader); | |
119 | return CreateRawStreamSDD(rawReader,attr); | |
120 | } | |
121 | //______________________________________________________________________ | |
122 | UInt_t AliITSRawStreamSDD::ReadBits() | |
123 | { | |
124 | // read bits from the given channel | |
125 | UInt_t result = (fChannelData[fCarlosId][fChannel] & ((1<<fReadBits[fCarlosId][fChannel]) - 1)); | |
126 | fChannelData[fCarlosId][fChannel] >>= fReadBits[fCarlosId][fChannel]; | |
127 | fLastBit[fCarlosId][fChannel] -= fReadBits[fCarlosId][fChannel]; | |
128 | return result; | |
129 | } | |
130 | ||
131 | //______________________________________________________________________ | |
132 | Int_t AliITSRawStreamSDD::DecompAmbra(Int_t value) const | |
133 | { | |
134 | // AMBRA decompression (from 8 to 10 bit) | |
135 | ||
136 | if ((value & 0x80) == 0) { | |
137 | return value & 0x7f; | |
138 | } else if ((value & 0x40) == 0) { | |
139 | if(value&1) return 0x080 + ((value & 0x3f) << 1); | |
140 | return 0x081 + ((value & 0x3f) << 1); | |
141 | } else if ((value & 0x20) == 0) { | |
142 | if(value&1) return 0x103 + ((value & 0x1f) << 3); | |
143 | return 0x104 + ((value & 0x1f) << 3); | |
144 | } else { | |
145 | if(value&1) return 0x207 + ((value & 0x1f) << 4); | |
146 | return 0x208 + ((value & 0x1f) << 4); | |
147 | } | |
148 | ||
149 | } | |
150 | ||
151 | //______________________________________________________________________ | |
152 | Bool_t AliITSRawStreamSDD::Next() | |
153 | { | |
154 | // read the next raw digit | |
155 | // returns kFALSE if there is no digit left | |
156 | // returns kTRUE and fCompletedModule=kFALSE and fCompletedDDL=kFALSE when a digit is found | |
157 | // returns kTRUE and fCompletedModule=kTRUE and fCompletedDDL=kFALSE when a module is completed (=3x3FFFFFFF footer words) | |
158 | // returns kTRUE and fCompletedModule=kFALSE and fCompletedDDL=kTRUE when a DDL is completed (=jitter word) | |
159 | ||
160 | fPrevModuleID = fModuleID; | |
161 | fCompletedModule=kFALSE; | |
162 | ||
163 | while (kTRUE) { | |
164 | if(fResetSkip){ | |
165 | Reset(); | |
166 | Bool_t kSkip = SkipHeaderWord(); | |
167 | if(!kSkip) return kSkip; | |
168 | fResetSkip=kFALSE; | |
169 | } | |
170 | if ((fChannel < 0) || (fCarlosId < 0) || (fChannel >= 2) || (fCarlosId >= kModulesPerDDL) || (fLastBit[fCarlosId][fChannel] < fReadBits[fCarlosId][fChannel]) ) { | |
171 | if (!fRawReader->ReadNextInt(fData)) return kFALSE; // read next word | |
172 | ||
173 | ||
174 | if((fData >> 16) == 0x7F00){ // jitter word | |
175 | fJitter = fData&0x000000ff; | |
176 | fResetSkip=kTRUE; | |
177 | fCompletedModule=kFALSE; | |
178 | fCompletedDDL=kTRUE; | |
179 | return kTRUE; | |
180 | } | |
181 | ||
182 | UInt_t nData28= fData >> 28; | |
183 | UInt_t nData30= fData >> 30; | |
184 | ||
185 | ||
186 | if (nData28== 0x02) { // header | |
187 | fEventId = (fData >> 3) & 0x07FF; | |
188 | } else if (nData28== 0x03) { // Carlos and FIFO words or Footers | |
189 | if(fData>=fICarlosWord[0]&&fData<=fICarlosWord[11]) { // Carlos Word | |
190 | fCarlosId = fData-fICarlosWord[0]; | |
191 | Int_t iFifoIdx = fCarlosId/3; | |
192 | fNfifo[iFifoIdx] = fCarlosId; | |
193 | } else if (fData>=fIFifoWord[0]&&fData<=fIFifoWord[3]){ // FIFO word | |
194 | fCarlosId = fNfifo[fData-fIFifoWord[0]]; | |
195 | } else if(fData==0x3FFFFFFF && fCarlosId>=0 && fCarlosId<kModulesPerDDL){ // Carlos footer | |
196 | fICountFoot[fCarlosId]++; // stop before the last word (last word=jitter) | |
197 | if(fICountFoot[fCarlosId]==3){ | |
198 | fCompletedModule=kTRUE; | |
199 | fCompletedDDL=kFALSE; | |
200 | return kTRUE; | |
201 | } | |
202 | } else if(fData==0x3F1F1F1F){ // CarlosRX footer | |
203 | // CARLOSRX footer -- do nothing | |
204 | }else{ | |
205 | fRawReader->AddMajorErrorLog(kDataError,"Bad footer"); | |
206 | AliWarning(Form("Invalid data: bad footer %08X\n", fData)); | |
207 | return kFALSE; | |
208 | } | |
209 | } else if (nData30 == 0x02 || nData30 == 0x03) { | |
210 | fChannel = nData30-2; | |
211 | if(fCarlosId>=0 && fCarlosId<kModulesPerDDL){ | |
212 | fChannelData[fCarlosId][fChannel] += | |
213 | (ULong64_t(fData & 0x3FFFFFFF) << fLastBit[fCarlosId][fChannel]); | |
214 | fLastBit[fCarlosId][fChannel] += 30; | |
215 | } | |
216 | } else if (nData28== 0x04) { | |
217 | // JTAG word -- do nothing | |
218 | } else { // unknown data format | |
219 | fRawReader->AddMajorErrorLog(kDataFormatErr,Form("Invalid data %8.8x",fData)); | |
220 | AliWarning(Form("Invalid data: %08X\n", fData)); | |
221 | return kFALSE; | |
222 | } | |
223 | ||
224 | if(fCarlosId>=0 && fCarlosId <kModulesPerDDL){ | |
225 | Int_t nDDL=fRawReader->GetDDLID(); | |
226 | if(nDDL>=0){ | |
227 | fModuleID = GetModuleNumber(nDDL,fCarlosId); | |
228 | } | |
229 | } | |
230 | } else { // decode data | |
231 | if (fReadCode[fCarlosId][fChannel]) {// read the next code word | |
232 | fChannelCode[fCarlosId][fChannel] = ReadBits(); | |
233 | fReadCode[fCarlosId][fChannel] = kFALSE; | |
234 | fReadBits[fCarlosId][fChannel] = fgkCodeLength[fChannelCode[fCarlosId][fChannel]]; | |
235 | } else { // read the next data word | |
236 | UInt_t data = ReadBits(); | |
237 | fReadCode[fCarlosId][fChannel] = kTRUE; | |
238 | fReadBits[fCarlosId][fChannel] = 3; | |
239 | if (fChannelCode[fCarlosId][fChannel] == 0) { // set the time bin | |
240 | fTimeBin[fCarlosId][fChannel] = data; | |
241 | } else if (fChannelCode[fCarlosId][fChannel] == 1) { // next anode | |
242 | fTimeBin[fCarlosId][fChannel] = 0; | |
243 | fAnode[fCarlosId][fChannel]++; | |
244 | } else { // ADC signal data | |
245 | fEightBitSignal=data + (1 << fChannelCode[fCarlosId][fChannel]); | |
246 | if(fDecompressAmbra) fSignal = DecompAmbra(fEightBitSignal + fLowThresholdArray[fModuleID-kSPDModules][fChannel]); | |
247 | fCoord1 = fAnode[fCarlosId][fChannel]; | |
248 | fCoord2 = fTimeBin[fCarlosId][fChannel]; | |
249 | fTimeBin[fCarlosId][fChannel]++; | |
250 | fCompletedModule=kFALSE; | |
251 | fCompletedDDL=kFALSE; | |
252 | return kTRUE; | |
253 | } | |
254 | } | |
255 | } | |
256 | } | |
257 | return kFALSE; | |
258 | } | |
259 | ||
260 | //______________________________________________________________________ | |
261 | void AliITSRawStreamSDD::Reset(){ | |
262 | ||
263 | //reset data member for a new ddl | |
264 | for(Int_t i=0;i<2;i++){ | |
265 | for(Int_t ic=0;ic<kModulesPerDDL;ic++){ | |
266 | fChannelData[ic][i]=0; | |
267 | fLastBit[ic][i]=0; | |
268 | fChannelCode[ic][i]=0; | |
269 | fReadCode[ic][i]=kTRUE; | |
270 | fReadBits[ic][i]=3; | |
271 | fTimeBin[ic][i]=0; | |
272 | fAnode[ic][i]=0; | |
273 | fICountFoot[ic]=0; | |
274 | } | |
275 | } | |
276 | } | |
277 | ||
278 | //______________________________________________________________________ | |
279 | Bool_t AliITSRawStreamSDD::SkipHeaderWord(){ | |
280 | // skip the 1 DDL header word = 0xffffffff | |
281 | while (kTRUE) { | |
282 | if (!fRawReader->ReadNextInt(fData)) return kFALSE; | |
283 | if ((fData >> 30) == 0x01) continue; // JTAG word | |
284 | if(fData==0xFFFFFFFF) return kTRUE; | |
285 | } | |
286 | } | |
287 |