New flat raw-data event format. The details can be found at: http://indico.cern.ch...
[u/mrichter/AliRoot.git] / RAW / AliAltroBuffer.cxx
CommitLineData
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
31ClassImp(AliAltroBuffer)
32
3ea47630 33//_____________________________________________________________________________
573322da 34AliAltroBuffer::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//_____________________________________________________________________________
52AliAltroBuffer::~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//_____________________________________________________________________________
65AliAltroBuffer::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//_____________________________________________________________________________
81AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/)
82{
83//Assigment operator
84
85 Fatal("operator =", "assignment operator not implemented");
86 return *this;
87}
88
3ea47630 89//_____________________________________________________________________________
90void 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//_____________________________________________________________________________
102void 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
133//_____________________________________________________________________________
5802cf2d 134void 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
149//_____________________________________________________________________________
3ea47630 150void 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 168void 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
193//_____________________________________________________________________________
3ea47630 194void 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//_____________________________________________________________________________
206void 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//_____________________________________________________________________________
217Int_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
20daa34d 253//_____________________________________________________________________________
3ea47630 254void 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);
2c7410c2 268 header.fSize = 0xFFFFFFFF; // RCU can't write raw-data size so we always get an 'invalid' size field
269 // header.fSize = currentFilePos-fDataHeaderPos;
3ea47630 270 header.SetAttribute(0); // valid data
271 if (compressed) header.SetAttribute(1);
4c846604 272 fFile->WriteBuffer((char*)(&header), sizeof(header));
273 fFile->Seekp(currentFilePos);
3ea47630 274 }
275}
5e6235b5 276
277//_____________________________________________________________________________
278void AliAltroBuffer::WriteRCUTrailer(Int_t rcuId)
279{
280 // Writes the RCU trailer
281 // rcuId the is serial number of the corresponding
282 // RCU. The basic format of the trailer can be
283 // found in the RCU manual.
284 // This method should be called at the end of
285 // raw data writing.
286
287 UInt_t currentFilePos = fFile->Tellp();
288 UInt_t size = currentFilePos-fDataHeaderPos;
289 size -= sizeof(AliRawDataHeader);
290
291 if ((size % 5) != 0) {
292 AliFatal(Form("The current raw data payload is not a mutiple of 5 (%d) ! Can not write the RCU trailer !",size));
293 return;
294 }
295
296 // Now put the size in unit of number of 40bit words
297 size /= 5;
298 fFile->WriteBuffer((char *)(&size),sizeof(UInt_t));
299
300 // Now several not yet full defined fields
301 // In principle they are supposed to contain
302 // information about the sampling frequency,
303 // L1 phase, list of 'dead' FECs, etc.
304 // UInt_t buffer[n];
305 // fFile->WriteBuffer((char *)(buffer),sizeof(UInt_t)*n);
306
307 // Now the RCU identifier and size of the trailer
308 // FOr the moment the triler size is 2 32-bit words
9a090ccd 309 UInt_t buffer = (2 & 0x7F);
310 buffer |= ((rcuId & 0x1FF) << 7);
311 buffer |= 0xAAAA << 16;
5e6235b5 312 fFile->WriteBuffer((char *)(&buffer),sizeof(UInt_t));
313
314}