TRD nSigma OADB related new codes and modifications and OADB root file -- Xianguo Lu
[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, AliAltroMapping *mapping):
35   fShift(0),
36   fCurrentCell(0),
37   fFreeCellBuffer(16),
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   //open the output file
47   fFile = new AliFstream(fileName);
48
49 }
50
51 //_____________________________________________________________________________
52 AliAltroBuffer::~AliAltroBuffer()
53 {
54 // destructor
55
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
60   delete fFile;
61
62 }
63
64 //_____________________________________________________________________________
65 AliAltroBuffer::AliAltroBuffer(const AliAltroBuffer& source):
66   TObject(source),
67   fShift(source.fShift),
68   fCurrentCell(source.fCurrentCell),
69   fFreeCellBuffer(source.fFreeCellBuffer),
70   fVerbose(source.fVerbose),
71   fFile(NULL),
72   fDataHeaderPos(source.fDataHeaderPos),
73   fMapping(source.fMapping)
74 {
75 // Copy Constructor
76
77   Fatal("AliAltroBuffer", "copy constructor not implemented");
78 }
79
80 //_____________________________________________________________________________
81 AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/)
82 {
83 //Assigment operator
84
85   Fatal("operator =", "assignment operator not implemented");
86   return *this;
87 }
88
89 //_____________________________________________________________________________
90 void 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 //_____________________________________________________________________________
102 void AliAltroBuffer::FillBuffer(Int_t val)
103 {
104 //Fills the Buffer with 16 ten bits words and write into a file 
105
106   if ((val > 0x3FF) || (val < 0)) {
107     Error("FillBuffer", "Value out of range (10 bits): %d", val);
108     val = 0x3FF;
109   }
110   fFreeCellBuffer--;
111
112   fBuffer[fCurrentCell] |= (val << fShift);
113   fShift += 10;
114
115   if (fShift > 32) {
116     fCurrentCell++;
117     fShift -= 32;
118     fBuffer[fCurrentCell] |= (val >> (10 - fShift));
119   }
120
121   if (fShift == 32) {
122     //Buffer is written into a file
123     fFile->WriteBuffer((char*)fBuffer, sizeof(UInt_t)*5);
124     //Buffer is empty
125     for (Int_t j = 0; j < 5; j++) fBuffer[j] = 0;
126     fShift = 0;
127     fCurrentCell = 0;
128     fFreeCellBuffer = 16;
129   }
130 }
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   if (!fMapping) {
139     AliFatal("No ALTRO mapping information is loaded!");
140   }
141
142   Short_t hwAddress = fMapping->GetHWAddress(rowNumber,padNumber,secNumber);
143   if (hwAddress == -1)
144     AliFatal(Form("No hardware (ALTRO) adress found for these pad-row (%d) and pad (%d) indeces !",rowNumber,padNumber));
145   WriteTrailer(wordsNumber,hwAddress);
146 }
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   Int_t num = fFreeCellBuffer % 4;
154   for(Int_t i = 0; i < num; i++) {
155     FillBuffer(0x2AA);
156   }//end for
157   Int_t temp;
158   temp = hwAddress & 0x3FF;
159   FillBuffer(temp);
160
161   temp = (wordsNumber << 6) & 0x3FF;
162   temp |= (0xA << 2);
163   temp |= ((hwAddress >> 10) & 0x3);
164   FillBuffer(temp);
165
166   temp = 0xA << 6;
167   temp |= ((wordsNumber & 0x3FF) >> 4);
168   FillBuffer(temp);
169
170   temp = 0x2AA;
171   FillBuffer(temp);
172 }
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   Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold);
182   // write the trailer
183   if (nWords) WriteTrailer(nWords, padNumber, rowNumber, secNumber);
184 }
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   Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold);
193   // write the trailer
194   if (nWords) WriteTrailer(nWords, hwAddress);
195 }
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   for (Int_t iTime = 0; iTime < nTimeBins; iTime++) {
210     if (adcValues[iTime] >= threshold) { // ADC value above threshold
211       FillBuffer(adcValues[iTime]);
212       nWords++;
213       timeBin = iTime;
214       bunchLength++;
215
216     } else if (timeBin >= 0) {  // end of bunch
217       FillBuffer(timeBin);
218       FillBuffer(bunchLength + 2);
219       nWords += 2;
220       timeBin = -1;
221       bunchLength = 0;
222     }
223   }
224
225   if (timeBin >= 0) {  // end of bunch
226     FillBuffer(timeBin);
227     FillBuffer(bunchLength + 2);
228     nWords += 2;
229   }
230
231   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   AliRawDataHeaderSim header;
241   if (dummy) {
242     //if size=0 it means that this data header is a dummy data header
243     fDataHeaderPos = fFile->Tellp();
244     fFile->WriteBuffer((char*)(&header), sizeof(header));
245   } else {
246     UChar_t rcuVer = WriteRCUTrailer(0);
247     UInt_t currentFilePos = fFile->Tellp();
248     fFile->Seekp(fDataHeaderPos);
249     header.fSize = 0xFFFFFFFF; // RCU can't write raw-data size so we always get an 'invalid' size field
250     header.fAttributesSubDetectors |= (rcuVer << 24);
251     fFile->WriteBuffer((char*)(&header), sizeof(header));
252     fFile->Seekp(currentFilePos);
253   }
254 }
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   UInt_t currentFilePos = fFile->Tellp();
267   UInt_t size = currentFilePos-fDataHeaderPos;
268   size -= sizeof(AliRawDataHeaderV3);
269   
270   if ((size % 5) != 0) {
271     AliFatal(Form("The current raw data payload is not a mutiple of 5 (%d) ! Can not write the RCU trailer !",size));
272     return 0;
273   }
274
275   // Now put the size in unit of number of 40bit words
276   size /= 5;
277   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   UInt_t buffer = (2 & 0x7F);
289   buffer |= ((rcuId & 0x1FF) << 7);
290   buffer |= 0xAAAAU << 16;
291   fFile->WriteBuffer((char *)(&buffer),sizeof(UInt_t));
292
293   return 0;
294 }