]> git.uio.no Git - u/mrichter/AliRoot.git/blob - FMD/AliFMDRawStream.cxx
New RAW I/O. I rolled my own, because I wasn't happy with the old
[u/mrichter/AliRoot.git] / FMD / AliFMDRawStream.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 //____________________________________________________________________
19 //                                                                          
20 // Buffer to read RAW ALTRO FMD format from a AliRawReader 
21 // 
22 // This class derives from AliAltroBuffer, but overloads the memer
23 // function Next to do some extra processing.  In particular, it tries
24 // to autodetect the sample rate.  If zero-suppression was used when
25 // writing the raw data, then the automatic discovery will not work,
26 // and the sample rate should be set explicitly. 
27 //
28 #include "AliFMDRawStream.h"            // ALIFMDRAWSTREAM_H
29 #include <AliRawReader.h>               // ALIRAWREADER_H
30 #include <AliLog.h>
31 #include <iomanip>
32 #include <iostream>
33
34 //____________________________________________________________________
35 ClassImp(AliFMDRawStream)
36 #if 0
37   ; // This is here to keep Emacs for indenting the next line
38 #endif
39
40 //____________________________________________________________________
41 AliFMDRawStream::AliFMDRawStream(AliRawReader* reader, UShort_t sampleRate) 
42   : AliAltroRawStream(reader), 
43     fSampleRate(sampleRate),
44     fPrevTime(-1), 
45     fExplicitSampleRate(kFALSE), 
46     fPos(0),
47     fCur(0),
48     fRead(0)
49 {
50   if (fSampleRate > 0) fExplicitSampleRate = kTRUE;
51 }
52
53 //_____________________________________________________________________________
54 Int_t
55 AliFMDRawStream::ReadTrailer(UInt_t& addr, UInt_t& len)
56 {
57   if (fPos <= 0) return 0;
58   if (fPos <  4) {
59     AliError("could not read trailer");
60     return -1;
61   }
62   AliDebug(1, Form("Reading a trailer at %d", fPos));
63   Int_t temp = Get10BitWord();
64   if (temp != 0x2AA) {
65     AliError(Form("Incorrect trailer! Expected 0x2AA but got %x!",temp));
66     return -1;
67   }
68   temp = Get10BitWord();
69   if ((temp >> 6) != 0xA) {
70     AliError(Form("Incorrect trailer! Expected 0xA but got %x!",temp >> 6));
71     return -1;
72   }
73
74   len  =  (temp << 4) & 0x3FF;
75   temp =  Get10BitWord();
76   len  |= (temp >> 6);
77   if (((temp >> 2) & 0xF) != 0xA) {
78     AliError(Form("Incorrect trailer! Expected 0xA but got %x!",temp >> 6));
79     return -1;
80   }
81   addr =  (temp & 0x3) << 10;
82   temp =  Get10BitWord();
83   addr |= temp;
84
85   return 4;
86 }
87
88 //_____________________________________________________________________________
89 Int_t 
90 AliFMDRawStream::ReadFillWords(UInt_t len)
91 {
92   if (len % 4 == 0) return 0;
93   Int_t nFill = (4 - (len % 4)) % 4;
94   AliDebug(1, Form("Reading %d fill words", nFill));
95   for (Int_t i = 0; i < nFill; i++) {
96     UInt_t fill = Get10BitWord();
97     if (fill != 0x2AA) {
98       AliError(Form("Invalid fill! Expected 0x2AA, but got %X!", fill));
99       return -1;
100     }
101   }
102   return nFill;
103 }
104
105 //_____________________________________________________________________________
106 Int_t 
107 AliFMDRawStream::ReadBunch(UShort_t* data)
108 {
109   AliDebug(1, "Reading a bunch");
110   if (fPos <= 0) {
111     AliError("could not read bunch length");
112     return -1;
113   }
114   UShort_t len  = Get10BitWord();
115   if (fPos <= 0) {
116     AliError("could not read bunch length");
117     return -1;
118   }
119   UShort_t time = Get10BitWord();
120   
121   AliDebug(1, Form("Bunch is %d long and ends at t=%d", len, time));
122   for (UInt_t i = 2; i < len; i++) {
123     Int_t amp = Get10BitWord();
124     if (amp < 0) { 
125       AliError(Form("Bad adc value (%X) !", amp));
126       return -1;
127     }
128     data[time - (i-2)] = amp;
129   }
130   return len;
131 }
132
133 //_____________________________________________________________________________
134 Int_t 
135 AliFMDRawStream::ReadIntoBuffer()
136 {
137   if (fPos > 0) return kTRUE;
138   do {
139     AliDebug(1, Form("Reading into the buffer"));
140     if (!fRawReader->ReadNextData(fRead)) return -1;
141   } while (fRawReader->GetDataSize() == 0);
142   fPos = (fRawReader->GetDataSize() * 8) / 10;
143   // Skip trailing `0x2AA's - is this needed?  Won't it break the
144   // trailer? 
145 #if 0
146   UShort_t skip;
147   while ((skip = Get10BitWord()) != 0x2AA) 
148     AliDebug(1,Form("Skipping one %x", skip));
149 #endif
150   fPos++;
151   return fPos;
152 }
153
154 //_____________________________________________________________________________
155 Bool_t 
156 AliFMDRawStream::ReadChannel(UInt_t& addr, UInt_t& len, UShort_t* data)
157 {
158   Int_t ret = 0;
159   AliDebug(1, "Reading a channel");
160   if ((ret = ReadIntoBuffer())       < 0) return kFALSE;
161   if ((ret = ReadTrailer(addr, len)) < 0) return kFALSE;
162   if ((ret = ReadFillWords(len))     < 0) return kFALSE;
163   Int_t toRead = len;
164   while (toRead > 0) {
165     if ((ret = ReadBunch(data)) < 0) return kFALSE;
166     toRead -= ret;
167   }
168   len -= 2;
169   return kTRUE;
170 }
171
172 //_____________________________________________________________________________
173 Bool_t 
174 AliFMDRawStream::DumpData()
175 {
176   Int_t ret;
177   if ((ret = ReadIntoBuffer())       < 0) return kFALSE;
178   UShort_t data;
179   Int_t i = 0;
180   while ((data = Get10BitWord()) != 0xffff) {
181     if (i % 4 == 0) {
182       if (i != 0) std::cout << "\n";
183       std::cout << std::setw(6) << i << ":";
184     }
185     std::cout << "  0x" << std::setfill('0') << std::setw(3) 
186               << std::hex << data << std::dec << std::setfill(' ')
187               << std::flush;
188     i++;
189   }
190   return kTRUE;
191 }
192
193 //_____________________________________________________________________________
194 UShort_t 
195 AliFMDRawStream::Get10BitWord()
196 {
197   // return a word in a 10 bit array as an UShort_t
198   --fPos;
199   if (fPos < 0) { 
200     AliWarning("At high water mark");
201     return 0xFFFF;
202   }
203   Int_t iBit  = fPos * 10;
204   Int_t iByte = iBit / 8;
205   Int_t shift = iBit % 8;
206   // return ((buffer[iByte+1] * 256 + buffer[iByte]) >> shift) & 0x03FF;
207
208   // recalculate the byte numbers and the shift because
209   // the raw data is written as integers where the high bits are filled first
210   // -> little endian is assumed here !
211   Int_t iByteHigh = 4 * (iByte / 4) + 3 - (iByte % 4);
212   iByte++;
213   Int_t iByteLow  = 4 * (iByte / 4) + 3 - (iByte % 4);
214   shift = 6 - shift;
215   return ((fRead[iByteHigh] * 256 + fRead[iByteLow]) >> shift) & 0x03FF;
216 }
217
218 //_____________________________________________________________________________
219 Bool_t 
220 AliFMDRawStream::Next()
221 {
222   // read the next raw digit
223   // returns kFALSE if there is no digit left
224   fPrevTime = fTime;
225   if (AliAltroRawStream::Next()) {
226     if (!fExplicitSampleRate && fPrevPad != fPad) 
227       fSampleRate = fTimeBunch / 128;
228     return kTRUE;
229   }
230   return kFALSE;
231 }
232
233 //_____________________________________________________________________________
234 //
235 // EOF
236 //