]>
Commit | Line | Data |
---|---|---|
2906f4c2 | 1 | /************************************************************************** |
27639c72 | 2 | * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. * |
2906f4c2 | 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 | ||
ceb607d0 | 16 | /* $Id$*/ |
2906f4c2 | 17 | |
18 | /////////////////////////////////////////////////////////////////////////////// | |
19 | /// | |
20 | /// This class provides access to ITS SDD digits in raw data. | |
21 | /// | |
22 | /////////////////////////////////////////////////////////////////////////////// | |
23 | ||
24 | #include "AliITSRawStreamSDD.h" | |
25 | #include "AliRawReader.h" | |
39a7c5cc | 26 | #include "AliLog.h" |
2906f4c2 | 27 | |
28 | ClassImp(AliITSRawStreamSDD) | |
1ba0280f | 29 | |
30 | const UInt_t AliITSRawStreamSDD::fgkCodeLength[8] = {8, 18, 2, 3, 4, 5, 6, 7}; | |
2906f4c2 | 31 | |
979b5a5f | 32 | //______________________________________________________________________ |
2906f4c2 | 33 | AliITSRawStreamSDD::AliITSRawStreamSDD(AliRawReader* rawReader) : |
e56160b8 | 34 | AliITSRawStream(rawReader), |
979b5a5f | 35 | fDDLModuleMap(0), |
e56160b8 | 36 | fData(0), |
a97b3678 | 37 | fEventId(0), |
14dceddf | 38 | fCarlosId(-1), |
e56160b8 | 39 | fChannel(0), |
a97b3678 | 40 | fJitter(0), |
41 | fNCarlos(kModulesPerDDL), | |
27639c72 | 42 | fDDL(0), |
9c8e7d50 | 43 | fEndWords(0), |
44 | fResetSkip(0) | |
45 | { | |
2906f4c2 | 46 | // create an object to read ITS SDD raw digits |
979b5a5f | 47 | fDDLModuleMap=new AliITSDDLModuleMapSDD(); |
48 | fDDLModuleMap->SetDefaultMap(); | |
27639c72 | 49 | Reset(); |
765a9f95 | 50 | for(Int_t i=0;i<kFifoWords;i++) fNfifo[i]=0; |
a97b3678 | 51 | for(Int_t i=0;i<kDDLsNumber;i++) fSkip[i]=0; |
52 | fRawReader->Reset(); | |
362c9d61 | 53 | fRawReader->Select("ITSSDD"); |
1ba0280f | 54 | |
27639c72 | 55 | for(Short_t i=0; i<kCarlosWords; i++) fICarlosWord[i]=0x30000000 + i; // 805306368+i; |
56 | for(Short_t i=0; i<kFifoWords; i++) fIFifoWord[i]=0x30000010 + i; // 805306384+i; | |
1ba0280f | 57 | } |
58 | ||
979b5a5f | 59 | //______________________________________________________________________ |
60 | AliITSRawStreamSDD::AliITSRawStreamSDD(const AliITSRawStreamSDD& rs) : | |
61 | AliITSRawStream(rs.fRawReader), | |
62 | fDDLModuleMap(rs.fDDLModuleMap), | |
63 | fData(0), | |
64 | fEventId(0), | |
65 | fCarlosId(-1), | |
66 | fChannel(0), | |
67 | fJitter(0), | |
68 | fNCarlos(kModulesPerDDL), | |
69 | fDDL(0), | |
70 | fEndWords(0), | |
71 | fResetSkip(0) | |
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 | //______________________________________________________________________ | |
1ba0280f | 89 | UInt_t AliITSRawStreamSDD::ReadBits() |
90 | { | |
91 | // read bits from the given channel | |
a97b3678 | 92 | UInt_t result = (fChannelData[fCarlosId][fChannel] & ((1<<fReadBits[fCarlosId][fChannel]) - 1)); |
93 | fChannelData[fCarlosId][fChannel] >>= fReadBits[fCarlosId][fChannel]; | |
94 | fLastBit[fCarlosId][fChannel] -= fReadBits[fCarlosId][fChannel]; | |
1ba0280f | 95 | return result; |
2906f4c2 | 96 | } |
97 | ||
979b5a5f | 98 | //______________________________________________________________________ |
1ba0280f | 99 | Int_t AliITSRawStreamSDD::DecompAmbra(Int_t value) const |
100 | { | |
a97b3678 | 101 | // AMBRA decompression (from 8 to 10 bit) |
102 | ||
1ba0280f | 103 | if ((value & 0x80) == 0) { |
104 | return value & 0x7f; | |
105 | } else if ((value & 0x40) == 0) { | |
106 | return 0x081 + ((value & 0x3f) << 1); | |
107 | } else if ((value & 0x20) == 0) { | |
108 | return 0x104 + ((value & 0x1f) << 3); | |
109 | } else { | |
110 | return 0x208 + ((value & 0x1f) << 4); | |
111 | } | |
a97b3678 | 112 | |
1ba0280f | 113 | } |
2906f4c2 | 114 | |
979b5a5f | 115 | //______________________________________________________________________ |
2906f4c2 | 116 | Bool_t AliITSRawStreamSDD::Next() |
117 | { | |
118 | // read the next raw digit | |
119 | // returns kFALSE if there is no digit left | |
5dfa68c5 | 120 | // returns kTRUE and fCompletedModule=kFALSE when a digit is found |
121 | // returns kTRUE and fCompletedModule=kTRUE when a module is completed (=3x3FFFFFFF footer words) | |
122 | ||
2906f4c2 | 123 | fPrevModuleID = fModuleID; |
a97b3678 | 124 | fDDL=fRawReader->GetDDLID(); |
125 | Int_t ddln = fRawReader->GetDDLID(); | |
126 | if(ddln <0) ddln=0; | |
5dfa68c5 | 127 | fCompletedModule=kFALSE; |
a97b3678 | 128 | |
a97b3678 | 129 | while (kTRUE) { |
5dfa68c5 | 130 | if(fResetSkip==0){ |
131 | Bool_t kSkip = ResetSkip(ddln); | |
132 | fResetSkip=1; | |
133 | if(!kSkip) return kSkip; | |
134 | } | |
27639c72 | 135 | |
8345a1cf | 136 | if ((fChannel < 0) || (fCarlosId < 0) || (fChannel >= 2) || (fCarlosId >= kModulesPerDDL) || (fLastBit[fCarlosId][fChannel] < fReadBits[fCarlosId][fChannel]) ) { |
14dceddf | 137 | if (!fRawReader->ReadNextInt(fData)) return kFALSE; // read next word |
a97b3678 | 138 | ddln = fRawReader->GetDDLID(); |
27639c72 | 139 | if(ddln!=fDDL) { |
9c8e7d50 | 140 | Reset(); |
9c8e7d50 | 141 | fDDL=fRawReader->GetDDLID(); |
142 | } | |
a97b3678 | 143 | if(ddln < 0 || ddln > (kDDLsNumber-1)) ddln = 0; |
5dfa68c5 | 144 | |
a97b3678 | 145 | fChannel = -1; |
c3ad350c | 146 | if((fData >> 16) == 0x7F00){ // jitter word |
9c8e7d50 | 147 | for(Int_t i=0;i<kDDLsNumber;i++){fSkip[i]=0;} |
148 | fResetSkip=0; | |
149 | fEndWords=0; | |
5dfa68c5 | 150 | continue; |
9c8e7d50 | 151 | } |
5dfa68c5 | 152 | |
14dceddf | 153 | UInt_t nData28= fData >> 28; |
154 | UInt_t nData30= fData >> 30; | |
155 | ||
156 | ||
157 | if (nData28== 0x02) { // header | |
158 | fEventId = (fData >> 3) & 0x07FF; | |
c3ad350c | 159 | } else if (nData28== 0x04) { |
160 | // JTAG word -- do nothing | |
14dceddf | 161 | } else if (nData28== 0x03) { // Carlos and FIFO words or Footers |
162 | if(fData>=fICarlosWord[0]&&fData<=fICarlosWord[11]) { // Carlos Word | |
163 | if(fEndWords==12) continue; // out of event | |
164 | fCarlosId = fData-fICarlosWord[0]; | |
165 | Int_t iFifoIdx = fCarlosId/3; | |
166 | if(fNCarlos == 8) iFifoIdx=fCarlosId/2; | |
167 | fNfifo[iFifoIdx] = fCarlosId; | |
168 | } else if (fData>=fIFifoWord[0]&&fData<=fIFifoWord[3]){ // FIFO word | |
169 | if(fEndWords==12) continue; // out of event | |
170 | fCarlosId = fNfifo[fData-fIFifoWord[0]]; | |
171 | } else if(fData==0x3FFFFFFF){ // Carlos footer | |
8345a1cf | 172 | if(fCarlosId>=0 && fCarlosId<kModulesPerDDL){ |
173 | fICountFoot[fCarlosId]++; // stop before the last word (last word=jitter) | |
174 | if(fICountFoot[fCarlosId]==3){ | |
175 | fCompletedModule=kTRUE; | |
176 | // printf("Completed module %d DDL %d\n",fCarlosId,ddln); | |
177 | return kTRUE; | |
178 | } | |
9c8e7d50 | 179 | } |
14dceddf | 180 | } else if(fData==0x3F1F1F1F){ // CarlosRX footer |
181 | fEndWords++; | |
182 | if(fEndWords<=12) continue; | |
183 | }else{ | |
184 | fRawReader->AddMajorErrorLog(kDataError,"Too many footers"); | |
185 | AliWarning(Form("invalid data: too many footers\n", fData)); | |
186 | return kFALSE; | |
9c8e7d50 | 187 | } |
14dceddf | 188 | } else if (nData30 == 0x02 || nData30 == 0x03) { |
189 | fChannel = nData30-2; | |
8345a1cf | 190 | if(fCarlosId>=0 && fChannel>=0 && fCarlosId <kModulesPerDDL && fChannel<2){ |
191 | fChannelData[fCarlosId][fChannel] += | |
192 | (ULong64_t(fData & 0x3FFFFFFF) << fLastBit[fCarlosId][fChannel]); | |
193 | fLastBit[fCarlosId][fChannel] += 30; | |
194 | } | |
a97b3678 | 195 | } else { // unknown data format |
9c8e7d50 | 196 | fRawReader->AddMajorErrorLog(kDataFormatErr,Form("Invalid data %8.8x",fData)); |
197 | AliWarning(Form("invalid data: %8.8x\n", fData)); | |
198 | return kFALSE; | |
a97b3678 | 199 | } |
200 | ||
14dceddf | 201 | if (fNCarlos == 8 && fCarlosId >= 8) continue; // old data, fNCarlos = 8; |
8345a1cf | 202 | if(fCarlosId>=0 && fCarlosId <kModulesPerDDL){ |
979b5a5f | 203 | fModuleID = GetModuleNumber(ddln,fCarlosId); |
8345a1cf | 204 | } |
a97b3678 | 205 | } else { // decode data |
a97b3678 | 206 | if (fReadCode[fCarlosId][fChannel]) {// read the next code word |
9c8e7d50 | 207 | fChannelCode[fCarlosId][fChannel] = ReadBits(); |
208 | fReadCode[fCarlosId][fChannel] = kFALSE; | |
209 | fReadBits[fCarlosId][fChannel] = fgkCodeLength[fChannelCode[fCarlosId][fChannel]]; | |
a97b3678 | 210 | } else { // read the next data word |
9c8e7d50 | 211 | UInt_t data = ReadBits(); |
212 | fReadCode[fCarlosId][fChannel] = kTRUE; | |
213 | fReadBits[fCarlosId][fChannel] = 3; | |
214 | if (fChannelCode[fCarlosId][fChannel] == 0) { // set the time bin | |
215 | fTimeBin[fCarlosId][fChannel] = data; | |
216 | } else if (fChannelCode[fCarlosId][fChannel] == 1) { // next anode | |
217 | fTimeBin[fCarlosId][fChannel] = 0; | |
218 | fAnode[fCarlosId][fChannel]++; | |
219 | } else { // ADC signal data | |
220 | fSignal = DecompAmbra(data + (1 << fChannelCode[fCarlosId][fChannel]) + fLowThreshold[fChannel]); | |
221 | fCoord1 = fAnode[fCarlosId][fChannel]; | |
222 | fCoord2 = fTimeBin[fCarlosId][fChannel]; | |
223 | fTimeBin[fCarlosId][fChannel]++; | |
14dceddf | 224 | //printf("Data read, Module=%d , Anode=%d , Time=%d , Charge=%d\n",fModuleID,fCoord1,fCoord2,fSignal); |
9c8e7d50 | 225 | return kTRUE; |
226 | } | |
a97b3678 | 227 | } |
228 | } | |
229 | } | |
14dceddf | 230 | return kFALSE; |
2906f4c2 | 231 | } |
1ba0280f | 232 | |
979b5a5f | 233 | //______________________________________________________________________ |
a97b3678 | 234 | void AliITSRawStreamSDD::Reset(){ |
765a9f95 | 235 | |
a97b3678 | 236 | //reset data member for a new ddl |
a97b3678 | 237 | for(Int_t i=0;i<2;i++){ |
238 | for(Int_t ic=0;ic<kModulesPerDDL;ic++){ | |
239 | fChannelData[ic][i]=0; | |
240 | fLastBit[ic][i]=0; | |
241 | fChannelCode[ic][i]=0; | |
14dceddf | 242 | fReadCode[ic][i]=kTRUE; |
243 | fReadBits[ic][i]=3; | |
a97b3678 | 244 | fTimeBin[ic][i]=0; |
245 | fAnode[ic][i]=0; | |
246 | } | |
247 | fLowThreshold[i]=0; | |
248 | } | |
27639c72 | 249 | for(Int_t i=0;i<kModulesPerDDL;i++) fICountFoot[i]=0; |
a97b3678 | 250 | } |
765a9f95 | 251 | |
979b5a5f | 252 | //______________________________________________________________________ |
765a9f95 | 253 | Bool_t AliITSRawStreamSDD::ResetSkip(Int_t ddln){ |
8345a1cf | 254 | // skip the 1 DDL header word = 0xffffffff |
5dfa68c5 | 255 | Bool_t startCount=kFALSE; |
8345a1cf | 256 | while (fSkip[ddln] < 1) { |
27639c72 | 257 | if (!fRawReader->ReadNextInt(fData)) { |
9c8e7d50 | 258 | return kFALSE; |
259 | } | |
5dfa68c5 | 260 | if(fData==0xFFFFFFFF) startCount=kTRUE; |
9c8e7d50 | 261 | //printf("%x\n",fData); |
765a9f95 | 262 | if ((fData >> 30) == 0x01) continue; // JTAG word |
5dfa68c5 | 263 | if(startCount) fSkip[ddln]++; |
765a9f95 | 264 | } |
265 | return kTRUE; | |
266 | } | |
267 |