]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDAltroIO.cxx
Additiona TOF data members (S.Arcelli)
[u/mrichter/AliRoot.git] / FMD / AliFMDAltroIO.cxx
CommitLineData
1e8f773e 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//____________________________________________________________________
19//
20// Mapping of ALTRO hardware channel to detector coordinates
21//
22#include "AliFMDAltroIO.h"
23#include <AliRawDataHeader.h>
24#include <AliRawReader.h>
25#include "AliLog.h"
26#include <iostream>
27#include <iomanip>
28#define PRETTY_HEX(N,X) \
29 " 0x" << std::setfill('0') << std::setw(N) << std::hex << X \
30 << std::setfill(' ') << std::dec
31
32//====================================================================
33ClassImp(AliFMDAltroIO)
34#if 0
35 ; // This is here to keep Emacs for indenting the next line
36#endif
37
38//____________________________________________________________________
39const AliFMDAltroIO::W40_t AliFMDAltroIO::fgkTrailerMask =
40((AliFMDAltroIO::W40_t(0x2aaa) << 26) + (AliFMDAltroIO::W40_t(0xa) << 12));
41
42//____________________________________________________________________
43AliFMDAltroIO::AliFMDAltroIO()
44 : fBuffer(0), fIBuffer(0)
45{}
46
47//____________________________________________________________________
48const char*
49AliFMDAltroIO::ErrorString(Int_t err) const
50{
51 switch (err) {
52 case kNoError: return "No error"; break;
53 case kBadFile: return "Bad state after open/close file"; break;
54 case kBadBits: return "Bad bit offset specified"; break;
55 case kBadRead: return "Bad state after reading from file"; break;
56 case kBadWrite: return "Bad state after writing to file"; break;
57 case kBadSeek: return "Bad state after seeking in file"; break;
58 case kBadTell: return "Could not tell position in file"; break;
59 case kBadTrailer: return "Bad trailer 40 bit word in file"; break;
60 case kBadFill: return "Bad fill word in file"; break;
61 }
62 return "Unknown";
63}
64
65
66//____________________________________________________________________
67AliFMDAltroIO::W40_t
68AliFMDAltroIO::ConcatW40(size_t n, const W10_t& w) const
69{
70 if (n > 3) return -kBadBits;
71 return W40_t(w & 0x3ff) << (10 * n);
72}
73
74//____________________________________________________________________
75AliFMDAltroIO::W10_t
76AliFMDAltroIO::ExtractW10(size_t n, const W40_t w) const
77{
78 if (n > 3) return -kBadBits;
79 return (w >> (10 * n)) & 0x3ff;
80}
81
82//====================================================================
83ClassImp(AliFMDAltroReader)
84#if 0
85 ; // This is here to keep Emacs for indenting the next line
86#endif
87
88//____________________________________________________________________
89AliFMDAltroReader::AliFMDAltroReader(std::istream& stream)
90 : fInput(stream)
91 // : fBuffer(buffer), fCurrent(n / 10 * sizeof(char))
92{
93 // fInput.open(filename);
94 if (!fInput) throw -kBadFile;
95 fBegin = fInput.tellg();
96 if (fInput.bad()) throw -kBadTell;
97 fInput.seekg(0, std::ios_base::end);
98 if (fInput.bad()) throw -kBadSeek;
99 fCurrent = fInput.tellg();
100 if (fInput.bad()) throw -kBadTell;
101#if 0
102 fInput.seekg(fBegin);
103 size_t i = 0;
104 do {
105 W40_t w = 0;
106 fInput.read((char*)&w, 5);
107 std::cout << std::setw(6) << i << ": " << PRETTY_HEX(10, w) << std::endl;
108 i++;
109 } while (!fInput.eof());
110 fInput.seekg(fCurrent);
111#endif
112}
113
114//____________________________________________________________________
115Int_t
116AliFMDAltroReader::ReadChannel(UShort_t& board, UShort_t& chip,
117 UShort_t& channel, UShort_t& last,
118 UShort_t* data)
119{
120 UShort_t hwaddr;
121 Int_t ret = ReadChannel(hwaddr, last, data);
122 board = (hwaddr >> 7) & 0x1f;
123 chip = (hwaddr >> 4) & 0x3;
124 channel = hwaddr & 0xf;
125 return ret;
126}
127
128//____________________________________________________________________
129Int_t
130AliFMDAltroReader::ReadChannel(UShort_t& hwaddr, UShort_t& last,
131 UShort_t* data)
132{
133 Int_t ret, tmp;
134 AliDebug(15, Form("Reading a channel"));
135 if ((ret = ExtractTrailer(hwaddr, last)) < 0) {
136 AliError(Form("Failed to read trailer: %s", ErrorString(-ret)));
137 return ret;
138 }
139 AliDebug(15, Form("Now extracting bunches from %d 10 bit words", last));
140 tmp = ExtractBunches(last, data);
141 if (tmp < 0) {
142 AliError(Form("Failed to read bunches: %s", ErrorString(-tmp)));
143 return tmp;
144 }
145 ret += tmp;
146 last = (last == 0 ? 0 : last - 2);
147 return ret;
148}
149
150//____________________________________________________________________
151Int_t
152AliFMDAltroReader::ExtractTrailer(UShort_t& hwaddr, UShort_t& last)
153{
154 AliDebug(15, "Extracting trailer");
155 W40_t trailer = GetNextW40();
156 if (trailer < 0) {
157 AliError(Form("Trailer 0x%x is bad: %s", trailer, ErrorString(-trailer)));
158 return trailer;
159 }
160 if (!IsTrailer(trailer)) {
161 AliError(Form("Bad trailer: 0x%08x", trailer));
162 return -kBadTrailer;
163 }
164 last = (trailer >> 16) & 0x3ff;
165 hwaddr = (trailer & 0xfff);
166 return 4;
167}
168
169//____________________________________________________________________
170Int_t
171AliFMDAltroReader::ExtractBunches(UShort_t last, UShort_t* data)
172{
173 Int_t ret;
174 if ((ret = ExtractFillWords(last)) < 0) {
175 AliError(Form("Failed to read fill words: %s", ErrorString(-ret)));
176 return ret;
177 }
178 while (last > 0) {
179 Int_t tmp = ExtractBunch(data);
180 if (tmp <= 0) {
181 AliError(Form("Failed to extract bunch at %d: %s",
182 last, ErrorString(-tmp)));
183 return tmp;
184 }
185 ret += tmp;
186 last -= tmp;
187 }
188 return ret;
189}
190
191//____________________________________________________________________
192Int_t
193AliFMDAltroReader::ExtractFillWords(UShort_t last)
194{
195 // Number of fill words
196 size_t nFill = (last % 4 == 0 ? 0 : 4 - last % 4);
197 // Read the fill words
198 for (size_t i = 3; i >= 4 - nFill; i--) {
199 W10_t f = GetNextW10();
200 if (f != 0x2aa) return -kBadFill;
201 }
202 return nFill;
203}
204
205//____________________________________________________________________
206Int_t
207AliFMDAltroReader::ExtractBunch(UShort_t* data)
208{
209 Int_t ret = 0;
210 W10_t l = GetNextW10();
211 if (l < 0) {
212 AliError(Form("Failed to read bunch length: %s", ErrorString(-l)));
213 return l;
214 }
215 W10_t t = GetNextW10();
216 if (t < 0) {
217 AliError(Form("Failed to read bunch time: %s", ErrorString(-t)));
218 return t;
219 }
220 ret += 2;
221 for (Int_t i = 2; i < l; i++) {
222 W10_t s = GetNextW10();
223 if (s < 0) {
224 AliError(Form("Failed to read bunch data: %s", ErrorString(-s)));
225 return 2;
226 }
227 AliDebug(50,Form("Assigning to data[%d - (%d - 1)] = 0x%X", t, i, s));
228 data[t - (i-1)] = s;
229 ret++;
230 }
231 return ret;
232}
233
234//____________________________________________________________________
235Bool_t
236AliFMDAltroReader::IsTrailer(W40_t x)
237{
238 return ((x & fgkTrailerMask) == fgkTrailerMask);
239}
240
241//____________________________________________________________________
242Bool_t
243AliFMDAltroReader::IsBof()
244{
245 return fCurrent == fBegin;
246}
247
248//____________________________________________________________________
249Int_t
250AliFMDAltroReader::ReadW40()
251{
252 fInput.seekg(fCurrent-std::istream::pos_type(5));
253 if (fInput.bad()) return -kBadSeek;
254 fCurrent = fInput.tellg();
255 if (fInput.bad()) return -kBadTell;
256 fInput.read((char*)&fBuffer, 5 * sizeof(char));
257 if (fInput.bad()) return -kBadRead;
258 fIBuffer = 4;
259 AliDebug(15, Form(" 0x%03x 0x%03x 0x%03x 0x%03x 0x%010x %6d",
260 ExtractW10(3, fBuffer), ExtractW10(2, fBuffer),
261 ExtractW10(1, fBuffer), ExtractW10(0, fBuffer),
262 fBuffer, fCurrent));
263 return fCurrent;
264}
265
266//____________________________________________________________________
267AliFMDAltroIO::W10_t
268AliFMDAltroReader::GetNextW10()
269{
270 if (fIBuffer <= 0) {
271 Int_t ret;
272 if ((ret = ReadW40()) < 0) return ret;
273 }
274 fIBuffer--;
275 W10_t w10 = ExtractW10(fIBuffer, fBuffer);
276 return w10;
277}
278
279//____________________________________________________________________
280AliFMDAltroIO::W40_t
281AliFMDAltroReader::GetNextW40()
282{
283 W40_t w40 = 0;
284 for (Int_t i = 3; i >= 0; i--) {
285 W10_t tmp = GetNextW10();
286 W40_t bits = ConcatW40(i, tmp);
287 if (bits < 0) return bits;
288 w40 += bits;
289 }
290 return w40;
291}
292
293//====================================================================
294ClassImp(AliFMDAltroWriter)
295#if 0
296 ; // This is here to keep Emacs for indenting the next line
297#endif
298
299//____________________________________________________________________
300AliFMDAltroWriter::AliFMDAltroWriter(std::ostream& stream)
301 : fThreshold(0), fTotal(0), fOutput(stream)
302{
303 AliDebug(15, "New AliFMDAltroWriter object");
304 fTime = 0;
305 fLength = 0;
306 fLast = 0;
307 // Write a dummy header
308 fHeader = fOutput.tellp();
309 if (fOutput.bad()) throw -kBadTell;
310 AliRawDataHeader header;
311 fOutput.write((char*)(&header), sizeof(header));
312 if (fOutput.bad()) throw -kBadWrite;
313 fBegin = fOutput.tellp();
314 if (fOutput.bad()) throw -kBadTell;
315}
316
317//____________________________________________________________________
318Int_t
319AliFMDAltroWriter::Flush()
320{
321 if (fIBuffer == 0) return 0;
322 fOutput.write((char*)&fBuffer, 5 * sizeof(char));
323 if (fOutput.bad()) return -kBadWrite;
324 // for (size_t i = 0; i < 4; i++)
325 // std::cout << "\t" << PRETTY_HEX(3, ExtractW10(i, fBuffer));
326 // std::cout << "\t" << PRETTY_HEX(10, fBuffer) << std::endl;
327 fTotal += 5;
328 fIBuffer = 0;
329 fBuffer = 0;
330 return 5;
331}
332
333//____________________________________________________________________
334Int_t
335AliFMDAltroWriter::Close()
336{
337 Flush();
338 std::ostream::pos_type end = fOutput.tellp();
339 if (fOutput.bad()) return -kBadTell;
340 fOutput.seekp(fHeader, std::ios_base::beg);
341 if (fOutput.bad()) return -kBadSeek;
342 AliRawDataHeader header;
343 header.fSize = (size_t(end) - fHeader);
344 AliDebug(15, Form("Size set to %d (%d)", header.fSize, fTotal));
345 header.SetAttribute(0);
346 fOutput.write((char*)(&header), sizeof(header));
347 if (fOutput.bad()) return -kBadWrite;
348 fOutput.seekp(end);
349 if (fOutput.bad()) return -kBadSeek;
350 return sizeof(header);
351}
352
353
354//____________________________________________________________________
355Int_t
356AliFMDAltroWriter::AddSignal(UShort_t adc)
357{
358 Int_t ret = 0;
359 if (adc < fThreshold)
360 ret = AddBunchTrailer();
361 else {
362 ret = AddToBuffer(adc);
363 fLength++;
364 }
365 fTime++;
366 if (ret < 0) AliError(Form("Failed to add signal %x: %s", ErrorString(ret)));
367 return ret;
368}
369
370//____________________________________________________________________
371Int_t
372AliFMDAltroWriter::AddChannelTrailer(UShort_t board, UShort_t chip,
373 UShort_t channel)
374{
375 UInt_t hwaddr = (channel & 0xf)+((chip & 0x3) << 4)+((board & 0x1f) << 7);
376 return AddChannelTrailer(hwaddr);
377}
378
379//____________________________________________________________________
380Int_t
381AliFMDAltroWriter::AddChannelTrailer(UInt_t hwaddr)
382{
383 Int_t ret =0, tmp;
384 if ((tmp = AddBunchTrailer()) < 0) {
385 AliError(Form("Failed to bad bunch trailer: %s", ErrorString(tmp)));
386 return tmp;
387 }
388 ret += tmp;
389 if ((tmp = AddFillWords()) < 0) {
390 AliError(Form("Failed to bad fill words: %s", ErrorString(tmp)));
391 return tmp;
392 }
393 ret += tmp;
394 W40_t trailer = (fgkTrailerMask + hwaddr + ((fLast & 0x3ff) << 16));
395 fBuffer = trailer;
396 fIBuffer = 3;
397 ret += 4;
398 if ((tmp = Flush()) < 0) {
399 AliError(Form("Failed to flush: %s", ErrorString(tmp)));
400 return tmp;
401 }
402 ret += tmp;
403 fTime = 0;
404 fLast = 0;
405 return ret;
406}
407
408//____________________________________________________________________
409Int_t
410AliFMDAltroWriter::AddToBuffer(UShort_t x)
411{
412 W40_t tmp = ConcatW40(fIBuffer, x);
413 if (tmp < 0) return tmp;
414 fBuffer += tmp;
415 fIBuffer++;
416 fLast++;
417 Int_t ret = 0;
418 if (fIBuffer > 3 && (ret = Flush() < 0)) return ret;
419 return 1;
420}
421
422//____________________________________________________________________
423Int_t
424AliFMDAltroWriter::AddBunchTrailer()
425{
426 if (fLength <= 0) return 0;
427 Int_t ret = 0, tmp;
428 if ((tmp = AddToBuffer(fTime)) < 0) return tmp;
429 ret += tmp;
430 if ((tmp = AddToBuffer(fLength+2)) < 0) return tmp;
431 ret += tmp;
432 fLength = 0;
433 return ret;
434}
435
436//____________________________________________________________________
437Int_t
438AliFMDAltroWriter::AddFillWords()
439{
440 Int_t ret = 0, tmp;
441 if (fIBuffer == 0) return ret;
442 for (Int_t i = fIBuffer; i < 4; i++) {
443 if ((tmp = AddToBuffer(0x2aa)) < 0) return tmp;
444 ret += tmp;
445 fLast--;
446 }
447 if ((tmp = Flush() < 0)) return tmp;
448 return ret;
449}
450
451//_____________________________________________________________________________
452//
453// EOF
454//