]>
Commit | Line | Data |
---|---|---|
3ea47630 | 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 | /* $Id$ */ | |
17 | ||
18 | // Interface to the Altro format | |
19 | // to read and write digits | |
20 | // To be used in Alice Data Challenges | |
21 | // and in the compression of the RAW data | |
3ea47630 | 22 | |
23 | #include "AliAltroBuffer.h" | |
5802cf2d | 24 | #include "AliAltroMapping.h" |
74b154bd | 25 | #include "AliRawDataHeaderSim.h" |
5802cf2d | 26 | #include "AliLog.h" |
4c846604 | 27 | #include "AliFstream.h" |
28 | //#include <stdlib.h> | |
3ea47630 | 29 | |
30 | ||
31 | ClassImp(AliAltroBuffer) | |
32 | ||
3ea47630 | 33 | //_____________________________________________________________________________ |
573322da | 34 | AliAltroBuffer::AliAltroBuffer(const char* fileName, AliAltroMapping *mapping): |
3ea47630 | 35 | fShift(0), |
36 | fCurrentCell(0), | |
5e6235b5 | 37 | fFreeCellBuffer(16), |
3ea47630 | 38 | fVerbose(0), |
39 | fFile(NULL), | |
3ea47630 | 40 | fDataHeaderPos(0), |
5802cf2d | 41 | fMapping(mapping) |
3ea47630 | 42 | { |
3ea47630 | 43 | //the buffer is cleaned |
44 | for (Int_t i = 0; i < 5; i++) fBuffer[i] = 0; | |
45 | ||
4c846604 | 46 | //open the output file |
47 | fFile = new AliFstream(fileName); | |
5802cf2d | 48 | |
3ea47630 | 49 | } |
50 | ||
51 | //_____________________________________________________________________________ | |
52 | AliAltroBuffer::~AliAltroBuffer() | |
53 | { | |
54 | // destructor | |
55 | ||
4c846604 | 56 | //Flush out the Buffer content at the end only if Buffer wasn't completely filled |
57 | Flush(); | |
58 | if (fVerbose) Info("~AliAltroBuffer", "File Created"); | |
59 | ||
3ea47630 | 60 | delete fFile; |
5802cf2d | 61 | |
3ea47630 | 62 | } |
63 | ||
64 | //_____________________________________________________________________________ | |
65 | AliAltroBuffer::AliAltroBuffer(const AliAltroBuffer& source): | |
66 | TObject(source), | |
67 | fShift(source.fShift), | |
68 | fCurrentCell(source.fCurrentCell), | |
69 | fFreeCellBuffer(source.fFreeCellBuffer), | |
3ea47630 | 70 | fVerbose(source.fVerbose), |
71 | fFile(NULL), | |
3ea47630 | 72 | fDataHeaderPos(source.fDataHeaderPos), |
5802cf2d | 73 | fMapping(source.fMapping) |
3ea47630 | 74 | { |
75 | // Copy Constructor | |
76 | ||
77 | Fatal("AliAltroBuffer", "copy constructor not implemented"); | |
78 | } | |
79 | ||
80 | //_____________________________________________________________________________ | |
81 | AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/) | |
82 | { | |
83 | //Assigment operator | |
84 | ||
85 | Fatal("operator =", "assignment operator not implemented"); | |
86 | return *this; | |
87 | } | |
88 | ||
3ea47630 | 89 | //_____________________________________________________________________________ |
90 | void AliAltroBuffer::Flush() | |
91 | { | |
92 | // Flushes the Buffer content | |
93 | if (fFreeCellBuffer != 16) { | |
94 | Int_t temp = fFreeCellBuffer; | |
95 | for (Int_t i = 0; i < temp; i++){ | |
96 | FillBuffer(0x2AA); | |
97 | }//end for | |
98 | }//end if | |
99 | } | |
100 | ||
101 | //_____________________________________________________________________________ | |
102 | void AliAltroBuffer::FillBuffer(Int_t val) | |
103 | { | |
104 | //Fills the Buffer with 16 ten bits words and write into a file | |
105 | ||
23b19451 | 106 | if ((val > 0x3FF) || (val < 0)) { |
107 | Error("FillBuffer", "Value out of range (10 bits): %d", val); | |
108 | val = 0x3FF; | |
109 | } | |
3ea47630 | 110 | fFreeCellBuffer--; |
5e6235b5 | 111 | |
112 | fBuffer[fCurrentCell] |= (val << fShift); | |
113 | fShift += 10; | |
114 | ||
115 | if (fShift > 32) { | |
3ea47630 | 116 | fCurrentCell++; |
5e6235b5 | 117 | fShift -= 32; |
118 | fBuffer[fCurrentCell] |= (val >> (10 - fShift)); | |
3ea47630 | 119 | } |
5e6235b5 | 120 | |
121 | if (fShift == 32) { | |
3ea47630 | 122 | //Buffer is written into a file |
4c846604 | 123 | fFile->WriteBuffer((char*)fBuffer, sizeof(UInt_t)*5); |
3ea47630 | 124 | //Buffer is empty |
125 | for (Int_t j = 0; j < 5; j++) fBuffer[j] = 0; | |
5e6235b5 | 126 | fShift = 0; |
3ea47630 | 127 | fCurrentCell = 0; |
128 | fFreeCellBuffer = 16; | |
129 | } | |
130 | } | |
131 | ||
132 | ||
5802cf2d | 133 | //_____________________________________________________________________________ |
134 | void AliAltroBuffer::WriteDummyTrailer(Int_t wordsNumber, Int_t padNumber, | |
135 | Int_t rowNumber, Int_t secNumber) | |
136 | { | |
137 | //Writes a trailer of 40 bits | |
138 | ||
139 | Int_t num = fFreeCellBuffer % 4; | |
140 | for(Int_t i = 0; i < num; i++) { | |
141 | FillBuffer(0x2AA); | |
142 | }//end for | |
143 | FillBuffer(wordsNumber); | |
144 | FillBuffer(padNumber); | |
145 | FillBuffer(rowNumber); | |
146 | FillBuffer(secNumber); | |
147 | } | |
148 | ||
3ea47630 | 149 | //_____________________________________________________________________________ |
150 | void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Int_t padNumber, | |
151 | Int_t rowNumber, Int_t secNumber) | |
152 | { | |
153 | //Writes a trailer of 40 bits | |
154 | ||
5802cf2d | 155 | if (!fMapping) { |
156 | AliError("No ALTRO mapping information is loaded! Filling a dummy trailer!"); | |
157 | return WriteDummyTrailer(wordsNumber,padNumber, | |
158 | rowNumber,secNumber); | |
159 | } | |
160 | ||
cc934096 | 161 | Short_t hwAddress = fMapping->GetHWAddress(rowNumber,padNumber,secNumber); |
162 | if (hwAddress == -1) | |
20daa34d | 163 | AliFatal(Form("No hardware (ALTRO) adress found for these pad-row (%d) and pad (%d) indeces !",rowNumber,padNumber)); |
cc934096 | 164 | WriteTrailer(wordsNumber,hwAddress); |
20daa34d | 165 | } |
166 | ||
167 | //_____________________________________________________________________________ | |
cc934096 | 168 | void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Short_t hwAddress) |
20daa34d | 169 | { |
170 | //Writes a trailer of 40 bits using | |
171 | //a given hardware adress | |
3ea47630 | 172 | Int_t num = fFreeCellBuffer % 4; |
173 | for(Int_t i = 0; i < num; i++) { | |
174 | FillBuffer(0x2AA); | |
175 | }//end for | |
5802cf2d | 176 | Int_t temp; |
cc934096 | 177 | temp = hwAddress & 0x3FF; |
5802cf2d | 178 | FillBuffer(temp); |
cc934096 | 179 | |
5802cf2d | 180 | temp = (wordsNumber << 6) & 0x3FF; |
181 | temp |= (0xA << 2); | |
cc934096 | 182 | temp |= ((hwAddress >> 10) & 0x3); |
183 | FillBuffer(temp); | |
5802cf2d | 184 | |
cc934096 | 185 | temp = 0xA << 6; |
186 | temp |= ((wordsNumber & 0x3FF) >> 4); | |
5802cf2d | 187 | FillBuffer(temp); |
cc934096 | 188 | |
189 | temp = 0x2AA; | |
5802cf2d | 190 | FillBuffer(temp); |
3ea47630 | 191 | } |
192 | ||
3ea47630 | 193 | //_____________________________________________________________________________ |
194 | void AliAltroBuffer::WriteChannel(Int_t padNumber, Int_t rowNumber, | |
195 | Int_t secNumber, | |
196 | Int_t nTimeBins, const Int_t* adcValues, | |
197 | Int_t threshold) | |
198 | { | |
cc934096 | 199 | //Write all ADC values and the trailer of a channel |
200 | Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold); | |
201 | // write the trailer | |
bd2e5cec | 202 | if (nWords) WriteTrailer(nWords, padNumber, rowNumber, secNumber); |
cc934096 | 203 | } |
204 | ||
205 | //_____________________________________________________________________________ | |
206 | void AliAltroBuffer::WriteChannel(Short_t hwAddress, | |
207 | Int_t nTimeBins, const Int_t* adcValues, | |
208 | Int_t threshold) | |
209 | { | |
210 | //Write all ADC values and the trailer of a channel | |
211 | Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold); | |
212 | // write the trailer | |
bd2e5cec | 213 | if (nWords) WriteTrailer(nWords, hwAddress); |
cc934096 | 214 | } |
215 | ||
216 | //_____________________________________________________________________________ | |
217 | Int_t AliAltroBuffer::WriteBunch(Int_t nTimeBins, const Int_t* adcValues, | |
218 | Int_t threshold) | |
219 | { | |
220 | //Write all ADC values | |
221 | //Return number of words written | |
3ea47630 | 222 | |
223 | Int_t nWords = 0; | |
224 | Int_t timeBin = -1; | |
225 | Int_t bunchLength = 0; | |
226 | ||
227 | // loop over time bins | |
228 | for (Int_t iTime = 0; iTime < nTimeBins; iTime++) { | |
229 | if (adcValues[iTime] >= threshold) { // ADC value above threshold | |
230 | FillBuffer(adcValues[iTime]); | |
231 | nWords++; | |
232 | timeBin = iTime; | |
233 | bunchLength++; | |
234 | ||
235 | } else if (timeBin >= 0) { // end of bunch | |
236 | FillBuffer(timeBin); | |
237 | FillBuffer(bunchLength + 2); | |
238 | nWords += 2; | |
239 | timeBin = -1; | |
240 | bunchLength = 0; | |
241 | } | |
242 | } | |
243 | ||
244 | if (timeBin >= 0) { // end of bunch | |
245 | FillBuffer(timeBin); | |
246 | FillBuffer(bunchLength + 2); | |
247 | nWords += 2; | |
248 | } | |
249 | ||
cc934096 | 250 | return nWords; |
3ea47630 | 251 | } |
252 | ||
3ea47630 | 253 | //_____________________________________________________________________________ |
254 | void AliAltroBuffer::WriteDataHeader(Bool_t dummy, Bool_t compressed) | |
255 | { | |
256 | //Write a (dummy or real) DDL data header, | |
257 | //set the compression bit if compressed | |
258 | ||
74b154bd | 259 | AliRawDataHeaderSim header; |
3ea47630 | 260 | if (dummy) { |
261 | //if size=0 it means that this data header is a dummy data header | |
4c846604 | 262 | fDataHeaderPos = fFile->Tellp(); |
263 | fFile->WriteBuffer((char*)(&header), sizeof(header)); | |
3ea47630 | 264 | } else { |
5e6235b5 | 265 | WriteRCUTrailer(0); |
4c846604 | 266 | UInt_t currentFilePos = fFile->Tellp(); |
267 | fFile->Seekp(fDataHeaderPos); | |
3ea47630 | 268 | header.fSize = currentFilePos-fDataHeaderPos; |
269 | header.SetAttribute(0); // valid data | |
270 | if (compressed) header.SetAttribute(1); | |
4c846604 | 271 | fFile->WriteBuffer((char*)(&header), sizeof(header)); |
272 | fFile->Seekp(currentFilePos); | |
3ea47630 | 273 | } |
274 | } | |
5e6235b5 | 275 | |
276 | //_____________________________________________________________________________ | |
277 | void AliAltroBuffer::WriteRCUTrailer(Int_t rcuId) | |
278 | { | |
279 | // Writes the RCU trailer | |
280 | // rcuId the is serial number of the corresponding | |
281 | // RCU. The basic format of the trailer can be | |
282 | // found in the RCU manual. | |
283 | // This method should be called at the end of | |
284 | // raw data writing. | |
285 | ||
286 | UInt_t currentFilePos = fFile->Tellp(); | |
287 | UInt_t size = currentFilePos-fDataHeaderPos; | |
288 | size -= sizeof(AliRawDataHeader); | |
289 | ||
290 | if ((size % 5) != 0) { | |
291 | AliFatal(Form("The current raw data payload is not a mutiple of 5 (%d) ! Can not write the RCU trailer !",size)); | |
292 | return; | |
293 | } | |
294 | ||
295 | // Now put the size in unit of number of 40bit words | |
296 | size /= 5; | |
297 | fFile->WriteBuffer((char *)(&size),sizeof(UInt_t)); | |
298 | ||
299 | // Now several not yet full defined fields | |
300 | // In principle they are supposed to contain | |
301 | // information about the sampling frequency, | |
302 | // L1 phase, list of 'dead' FECs, etc. | |
303 | // UInt_t buffer[n]; | |
304 | // fFile->WriteBuffer((char *)(buffer),sizeof(UInt_t)*n); | |
305 | ||
306 | // Now the RCU identifier and size of the trailer | |
307 | // FOr the moment the triler size is 2 32-bit words | |
9a090ccd | 308 | UInt_t buffer = (2 & 0x7F); |
309 | buffer |= ((rcuId & 0x1FF) << 7); | |
310 | buffer |= 0xAAAA << 16; | |
5e6235b5 | 311 | fFile->WriteBuffer((char *)(&buffer),sizeof(UInt_t)); |
312 | ||
313 | } |