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