]>
Commit | Line | Data |
---|---|---|
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 | ||
31 | ClassImp(AliAltroBuffer) | |
32 | ||
3ea47630 | 33 | //_____________________________________________________________________________ |
4c846604 | 34 | AliAltroBuffer::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 | //_____________________________________________________________________________ | |
54 | AliAltroBuffer::~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 | //_____________________________________________________________________________ | |
67 | AliAltroBuffer::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 | //_____________________________________________________________________________ | |
83 | AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/) | |
84 | { | |
85 | //Assigment operator | |
86 | ||
87 | Fatal("operator =", "assignment operator not implemented"); | |
88 | return *this; | |
89 | } | |
90 | ||
3ea47630 | 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 | ||
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 | ||
5802cf2d | 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 | ||
3ea47630 | 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 | ||
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 | 171 | void 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 | ||
3ea47630 | 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 | { | |
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 | //_____________________________________________________________________________ | |
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 | |
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 | ||
3ea47630 | 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 | ||
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 | } |