o) making selector proof ready
[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//_____________________________________________________________________________
4c846604 34AliAltroBuffer::AliAltroBuffer(const char* fileName, const AliAltroMapping *mapping):
3ea47630 35 fShift(0),
36 fCurrentCell(0),
37 fFreeCellBuffer(0),
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 fFreeCellBuffer = 16;
47 fShift = 32;
48 //open the output file
49 fFile = new AliFstream(fileName);
5802cf2d 50
3ea47630 51}
52
53//_____________________________________________________________________________
54AliAltroBuffer::~AliAltroBuffer()
55{
56// destructor
57
4c846604 58 //Flush out the Buffer content at the end only if Buffer wasn't completely filled
59 Flush();
60 if (fVerbose) Info("~AliAltroBuffer", "File Created");
61
3ea47630 62 delete fFile;
5802cf2d 63
3ea47630 64}
65
66//_____________________________________________________________________________
67AliAltroBuffer::AliAltroBuffer(const AliAltroBuffer& source):
68 TObject(source),
69 fShift(source.fShift),
70 fCurrentCell(source.fCurrentCell),
71 fFreeCellBuffer(source.fFreeCellBuffer),
3ea47630 72 fVerbose(source.fVerbose),
73 fFile(NULL),
3ea47630 74 fDataHeaderPos(source.fDataHeaderPos),
5802cf2d 75 fMapping(source.fMapping)
3ea47630 76{
77// Copy Constructor
78
79 Fatal("AliAltroBuffer", "copy constructor not implemented");
80}
81
82//_____________________________________________________________________________
83AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/)
84{
85//Assigment operator
86
87 Fatal("operator =", "assignment operator not implemented");
88 return *this;
89}
90
3ea47630 91//_____________________________________________________________________________
92void AliAltroBuffer::Flush()
93{
94// Flushes the Buffer content
95 if (fFreeCellBuffer != 16) {
96 Int_t temp = fFreeCellBuffer;
97 for (Int_t i = 0; i < temp; i++){
98 FillBuffer(0x2AA);
99 }//end for
100 }//end if
101}
102
103//_____________________________________________________________________________
104void AliAltroBuffer::FillBuffer(Int_t val)
105{
106//Fills the Buffer with 16 ten bits words and write into a file
107
23b19451 108 if ((val > 0x3FF) || (val < 0)) {
109 Error("FillBuffer", "Value out of range (10 bits): %d", val);
110 val = 0x3FF;
111 }
3ea47630 112 fFreeCellBuffer--;
113 if (fShift < 10) {
114 Int_t temp = val;
115 val = val >> (10-fShift);
116 fBuffer[fCurrentCell] |= val;
117 fCurrentCell++;
118 fShift += 32;
119 val = temp;
120 }
121 fShift -= 10;
122 val = val << fShift;
123 fBuffer[fCurrentCell] |= val;
124 if (!fShift) {
125 //Buffer is written into a file
4c846604 126 fFile->WriteBuffer((char*)fBuffer, sizeof(UInt_t)*5);
3ea47630 127 //Buffer is empty
128 for (Int_t j = 0; j < 5; j++) fBuffer[j] = 0;
129 fShift = 32;
130 fCurrentCell = 0;
131 fFreeCellBuffer = 16;
132 }
133}
134
135
136//_____________________________________________________________________________
5802cf2d 137void AliAltroBuffer::WriteDummyTrailer(Int_t wordsNumber, Int_t padNumber,
138 Int_t rowNumber, Int_t secNumber)
139{
140//Writes a trailer of 40 bits
141
142 Int_t num = fFreeCellBuffer % 4;
143 for(Int_t i = 0; i < num; i++) {
144 FillBuffer(0x2AA);
145 }//end for
146 FillBuffer(wordsNumber);
147 FillBuffer(padNumber);
148 FillBuffer(rowNumber);
149 FillBuffer(secNumber);
150}
151
152//_____________________________________________________________________________
3ea47630 153void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Int_t padNumber,
154 Int_t rowNumber, Int_t secNumber)
155{
156//Writes a trailer of 40 bits
157
5802cf2d 158 if (!fMapping) {
159 AliError("No ALTRO mapping information is loaded! Filling a dummy trailer!");
160 return WriteDummyTrailer(wordsNumber,padNumber,
161 rowNumber,secNumber);
162 }
163
cc934096 164 Short_t hwAddress = fMapping->GetHWAddress(rowNumber,padNumber,secNumber);
165 if (hwAddress == -1)
20daa34d 166 AliFatal(Form("No hardware (ALTRO) adress found for these pad-row (%d) and pad (%d) indeces !",rowNumber,padNumber));
cc934096 167 WriteTrailer(wordsNumber,hwAddress);
20daa34d 168}
169
170//_____________________________________________________________________________
cc934096 171void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Short_t hwAddress)
20daa34d 172{
173//Writes a trailer of 40 bits using
174//a given hardware adress
3ea47630 175 Int_t num = fFreeCellBuffer % 4;
176 for(Int_t i = 0; i < num; i++) {
177 FillBuffer(0x2AA);
178 }//end for
5802cf2d 179 Int_t temp;
cc934096 180 temp = hwAddress & 0x3FF;
5802cf2d 181 FillBuffer(temp);
cc934096 182
5802cf2d 183 temp = (wordsNumber << 6) & 0x3FF;
184 temp |= (0xA << 2);
cc934096 185 temp |= ((hwAddress >> 10) & 0x3);
186 FillBuffer(temp);
5802cf2d 187
cc934096 188 temp = 0xA << 6;
189 temp |= ((wordsNumber & 0x3FF) >> 4);
5802cf2d 190 FillBuffer(temp);
cc934096 191
192 temp = 0x2AA;
5802cf2d 193 FillBuffer(temp);
3ea47630 194}
195
196//_____________________________________________________________________________
3ea47630 197void AliAltroBuffer::WriteChannel(Int_t padNumber, Int_t rowNumber,
198 Int_t secNumber,
199 Int_t nTimeBins, const Int_t* adcValues,
200 Int_t threshold)
201{
cc934096 202 //Write all ADC values and the trailer of a channel
203 Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold);
204 // write the trailer
205 WriteTrailer(nWords, padNumber, rowNumber, secNumber);
206}
207
208//_____________________________________________________________________________
209void AliAltroBuffer::WriteChannel(Short_t hwAddress,
210 Int_t nTimeBins, const Int_t* adcValues,
211 Int_t threshold)
212{
213 //Write all ADC values and the trailer of a channel
214 Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold);
215 // write the trailer
216 WriteTrailer(nWords, hwAddress);
217}
218
219//_____________________________________________________________________________
220Int_t AliAltroBuffer::WriteBunch(Int_t nTimeBins, const Int_t* adcValues,
221 Int_t threshold)
222{
223 //Write all ADC values
224 //Return number of words written
3ea47630 225
226 Int_t nWords = 0;
227 Int_t timeBin = -1;
228 Int_t bunchLength = 0;
229
230 // loop over time bins
231 for (Int_t iTime = 0; iTime < nTimeBins; iTime++) {
232 if (adcValues[iTime] >= threshold) { // ADC value above threshold
233 FillBuffer(adcValues[iTime]);
234 nWords++;
235 timeBin = iTime;
236 bunchLength++;
237
238 } else if (timeBin >= 0) { // end of bunch
239 FillBuffer(timeBin);
240 FillBuffer(bunchLength + 2);
241 nWords += 2;
242 timeBin = -1;
243 bunchLength = 0;
244 }
245 }
246
247 if (timeBin >= 0) { // end of bunch
248 FillBuffer(timeBin);
249 FillBuffer(bunchLength + 2);
250 nWords += 2;
251 }
252
cc934096 253 return nWords;
3ea47630 254}
255
20daa34d 256//_____________________________________________________________________________
3ea47630 257void AliAltroBuffer::WriteDataHeader(Bool_t dummy, Bool_t compressed)
258{
259//Write a (dummy or real) DDL data header,
260//set the compression bit if compressed
261
74b154bd 262 AliRawDataHeaderSim header;
3ea47630 263 if (dummy) {
264 //if size=0 it means that this data header is a dummy data header
4c846604 265 fDataHeaderPos = fFile->Tellp();
266 fFile->WriteBuffer((char*)(&header), sizeof(header));
3ea47630 267 } else {
4c846604 268 UInt_t currentFilePos = fFile->Tellp();
269 fFile->Seekp(fDataHeaderPos);
3ea47630 270 header.fSize = currentFilePos-fDataHeaderPos;
271 header.SetAttribute(0); // valid data
272 if (compressed) header.SetAttribute(1);
4c846604 273 fFile->WriteBuffer((char*)(&header), sizeof(header));
274 fFile->Seekp(currentFilePos);
3ea47630 275 }
276}