]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RAW/AliAltroBuffer.cxx
o) making selector proof ready
[u/mrichter/AliRoot.git] / RAW / AliAltroBuffer.cxx
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 ClassImp(AliAltroBuffer)
32
33 //_____________________________________________________________________________
34 AliAltroBuffer::AliAltroBuffer(const char* fileName, const AliAltroMapping *mapping):
35   fShift(0),
36   fCurrentCell(0),
37   fFreeCellBuffer(0),
38   fVerbose(0),
39   fFile(NULL),
40   fDataHeaderPos(0),
41   fMapping(mapping)
42 {
43   //the buffer is cleaned 
44   for (Int_t i = 0; i < 5; i++) fBuffer[i] = 0;
45
46   fFreeCellBuffer = 16;
47   fShift = 32; 
48   //open the output file
49   fFile = new AliFstream(fileName);
50
51 }
52
53 //_____________________________________________________________________________
54 AliAltroBuffer::~AliAltroBuffer()
55 {
56 // destructor
57
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
62   delete fFile;
63
64 }
65
66 //_____________________________________________________________________________
67 AliAltroBuffer::AliAltroBuffer(const AliAltroBuffer& source):
68   TObject(source),
69   fShift(source.fShift),
70   fCurrentCell(source.fCurrentCell),
71   fFreeCellBuffer(source.fFreeCellBuffer),
72   fVerbose(source.fVerbose),
73   fFile(NULL),
74   fDataHeaderPos(source.fDataHeaderPos),
75   fMapping(source.fMapping)
76 {
77 // Copy Constructor
78
79   Fatal("AliAltroBuffer", "copy constructor not implemented");
80 }
81
82 //_____________________________________________________________________________
83 AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/)
84 {
85 //Assigment operator
86
87   Fatal("operator =", "assignment operator not implemented");
88   return *this;
89 }
90
91 //_____________________________________________________________________________
92 void 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 //_____________________________________________________________________________
104 void AliAltroBuffer::FillBuffer(Int_t val)
105 {
106 //Fills the Buffer with 16 ten bits words and write into a file 
107
108   if ((val > 0x3FF) || (val < 0)) {
109     Error("FillBuffer", "Value out of range (10 bits): %d", val);
110     val = 0x3FF;
111   }
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
126     fFile->WriteBuffer((char*)fBuffer, sizeof(UInt_t)*5);
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 //_____________________________________________________________________________
137 void 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 //_____________________________________________________________________________
153 void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Int_t padNumber,
154                                   Int_t rowNumber, Int_t secNumber)
155 {
156 //Writes a trailer of 40 bits
157
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
164   Short_t hwAddress = fMapping->GetHWAddress(rowNumber,padNumber,secNumber);
165   if (hwAddress == -1)
166     AliFatal(Form("No hardware (ALTRO) adress found for these pad-row (%d) and pad (%d) indeces !",rowNumber,padNumber));
167   WriteTrailer(wordsNumber,hwAddress);
168 }
169
170 //_____________________________________________________________________________
171 void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Short_t hwAddress)
172 {
173 //Writes a trailer of 40 bits using
174 //a given hardware adress
175   Int_t num = fFreeCellBuffer % 4;
176   for(Int_t i = 0; i < num; i++) {
177     FillBuffer(0x2AA);
178   }//end for
179   Int_t temp;
180   temp = hwAddress & 0x3FF;
181   FillBuffer(temp);
182
183   temp = (wordsNumber << 6) & 0x3FF;
184   temp |= (0xA << 2);
185   temp |= ((hwAddress >> 10) & 0x3);
186   FillBuffer(temp);
187
188   temp = 0xA << 6;
189   temp |= ((wordsNumber & 0x3FF) >> 4);
190   FillBuffer(temp);
191
192   temp = 0x2AA;
193   FillBuffer(temp);
194 }
195
196 //_____________________________________________________________________________
197 void 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 {
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 //_____________________________________________________________________________
209 void 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 //_____________________________________________________________________________
220 Int_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
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
253   return nWords;
254 }
255
256 //_____________________________________________________________________________
257 void 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
262   AliRawDataHeaderSim header;
263   if (dummy) {
264     //if size=0 it means that this data header is a dummy data header
265     fDataHeaderPos = fFile->Tellp();
266     fFile->WriteBuffer((char*)(&header), sizeof(header));
267   } else {
268     UInt_t currentFilePos = fFile->Tellp();
269     fFile->Seekp(fDataHeaderPos);
270     header.fSize = currentFilePos-fDataHeaderPos;
271     header.SetAttribute(0);  // valid data
272     if (compressed) header.SetAttribute(1); 
273     fFile->WriteBuffer((char*)(&header), sizeof(header));
274     fFile->Seekp(currentFilePos);
275   }
276 }