1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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
23 #include "AliAltroBuffer.h"
24 #include "AliAltroMapping.h"
25 #include "AliRawDataHeaderSim.h"
27 #include "AliFstream.h"
31 ClassImp(AliAltroBuffer)
33 //_____________________________________________________________________________
34 AliAltroBuffer::AliAltroBuffer(const char* fileName, AliAltroMapping *mapping):
43 //the buffer is cleaned
44 for (Int_t i = 0; i < 5; i++) fBuffer[i] = 0;
46 //open the output file
47 fFile = new AliFstream(fileName);
51 //_____________________________________________________________________________
52 AliAltroBuffer::~AliAltroBuffer()
56 //Flush out the Buffer content at the end only if Buffer wasn't completely filled
58 if (fVerbose) Info("~AliAltroBuffer", "File Created");
64 //_____________________________________________________________________________
65 AliAltroBuffer::AliAltroBuffer(const AliAltroBuffer& source):
67 fShift(source.fShift),
68 fCurrentCell(source.fCurrentCell),
69 fFreeCellBuffer(source.fFreeCellBuffer),
70 fVerbose(source.fVerbose),
72 fDataHeaderPos(source.fDataHeaderPos),
73 fMapping(source.fMapping)
77 Fatal("AliAltroBuffer", "copy constructor not implemented");
80 //_____________________________________________________________________________
81 AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/)
85 Fatal("operator =", "assignment operator not implemented");
89 //_____________________________________________________________________________
90 void AliAltroBuffer::Flush()
92 // Flushes the Buffer content
93 if (fFreeCellBuffer != 16) {
94 Int_t temp = fFreeCellBuffer;
95 for (Int_t i = 0; i < temp; i++){
101 //_____________________________________________________________________________
102 void AliAltroBuffer::FillBuffer(Int_t val)
104 //Fills the Buffer with 16 ten bits words and write into a file
106 if ((val > 0x3FF) || (val < 0)) {
107 Error("FillBuffer", "Value out of range (10 bits): %d", val);
112 fBuffer[fCurrentCell] |= (val << fShift);
118 fBuffer[fCurrentCell] |= (val >> (10 - fShift));
122 //Buffer is written into a file
123 fFile->WriteBuffer((char*)fBuffer, sizeof(UInt_t)*5);
125 for (Int_t j = 0; j < 5; j++) fBuffer[j] = 0;
128 fFreeCellBuffer = 16;
133 //_____________________________________________________________________________
134 void AliAltroBuffer::WriteDummyTrailer(Int_t wordsNumber, Int_t padNumber,
135 Int_t rowNumber, Int_t secNumber)
137 //Writes a trailer of 40 bits
139 Int_t num = fFreeCellBuffer % 4;
140 for(Int_t i = 0; i < num; i++) {
143 FillBuffer(wordsNumber);
144 FillBuffer(padNumber);
145 FillBuffer(rowNumber);
146 FillBuffer(secNumber);
149 //_____________________________________________________________________________
150 void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Int_t padNumber,
151 Int_t rowNumber, Int_t secNumber)
153 //Writes a trailer of 40 bits
156 AliError("No ALTRO mapping information is loaded! Filling a dummy trailer!");
157 return WriteDummyTrailer(wordsNumber,padNumber,
158 rowNumber,secNumber);
161 Short_t hwAddress = fMapping->GetHWAddress(rowNumber,padNumber,secNumber);
163 AliFatal(Form("No hardware (ALTRO) adress found for these pad-row (%d) and pad (%d) indeces !",rowNumber,padNumber));
164 WriteTrailer(wordsNumber,hwAddress);
167 //_____________________________________________________________________________
168 void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Short_t hwAddress)
170 //Writes a trailer of 40 bits using
171 //a given hardware adress
172 Int_t num = fFreeCellBuffer % 4;
173 for(Int_t i = 0; i < num; i++) {
177 temp = hwAddress & 0x3FF;
180 temp = (wordsNumber << 6) & 0x3FF;
182 temp |= ((hwAddress >> 10) & 0x3);
186 temp |= ((wordsNumber & 0x3FF) >> 4);
193 //_____________________________________________________________________________
194 void AliAltroBuffer::WriteChannel(Int_t padNumber, Int_t rowNumber,
196 Int_t nTimeBins, const Int_t* adcValues,
199 //Write all ADC values and the trailer of a channel
200 Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold);
202 if (nWords) WriteTrailer(nWords, padNumber, rowNumber, secNumber);
205 //_____________________________________________________________________________
206 void AliAltroBuffer::WriteChannel(Short_t hwAddress,
207 Int_t nTimeBins, const Int_t* adcValues,
210 //Write all ADC values and the trailer of a channel
211 Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold);
213 if (nWords) WriteTrailer(nWords, hwAddress);
216 //_____________________________________________________________________________
217 Int_t AliAltroBuffer::WriteBunch(Int_t nTimeBins, const Int_t* adcValues,
220 //Write all ADC values
221 //Return number of words written
225 Int_t bunchLength = 0;
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]);
235 } else if (timeBin >= 0) { // end of bunch
237 FillBuffer(bunchLength + 2);
244 if (timeBin >= 0) { // end of bunch
246 FillBuffer(bunchLength + 2);
253 //_____________________________________________________________________________
254 void AliAltroBuffer::WriteDataHeader(Bool_t dummy, Bool_t compressed)
256 //Write a (dummy or real) DDL data header,
257 //set the compression bit if compressed
259 AliRawDataHeaderSim header;
261 //if size=0 it means that this data header is a dummy data header
262 fDataHeaderPos = fFile->Tellp();
263 fFile->WriteBuffer((char*)(&header), sizeof(header));
266 UInt_t currentFilePos = fFile->Tellp();
267 fFile->Seekp(fDataHeaderPos);
268 header.fSize = currentFilePos-fDataHeaderPos;
269 header.SetAttribute(0); // valid data
270 if (compressed) header.SetAttribute(1);
271 fFile->WriteBuffer((char*)(&header), sizeof(header));
272 fFile->Seekp(currentFilePos);
276 //_____________________________________________________________________________
277 void AliAltroBuffer::WriteRCUTrailer(Int_t rcuId)
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
286 UInt_t currentFilePos = fFile->Tellp();
287 UInt_t size = currentFilePos-fDataHeaderPos;
288 size -= sizeof(AliRawDataHeader);
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));
295 // Now put the size in unit of number of 40bit words
297 fFile->WriteBuffer((char *)(&size),sizeof(UInt_t));
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.
304 // fFile->WriteBuffer((char *)(buffer),sizeof(UInt_t)*n);
306 // Now the RCU identifier and size of the trailer
307 // FOr the moment the triler size is 2 32-bit words
309 buffer |= ((rcuId & 0x3FF) << 22);
310 fFile->WriteBuffer((char *)(&buffer),sizeof(UInt_t));