New RAW I/O. I rolled my own, because I wasn't happy with the old
[u/mrichter/AliRoot.git] / FMD / AliFMDRawReader.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 // Class to read ADC values from a AliRawReader object. 
21 //
22 // This class uses the AliFMDRawStreamer class to read the ALTRO
23 // formatted data. 
24 // 
25 //          +-------+
26 //          | TTask |
27 //          +-------+
28 //              ^
29 //              |
30 //      +-----------------+  <<references>>  +--------------+
31 //      | AliFMDRawReader |<>----------------| AliRawReader |
32 //      +-----------------+                  +--------------+
33 //              |                                  ^
34 //              | <<uses>>                         |
35 //              V                                  |
36 //      +-----------------+      <<uses>>          |
37 //      | AliFMDRawStream |------------------------+
38 //      +-----------------+
39 //              |
40 //              V
41 //      +----------------+
42 //      | AliAltroStream |
43 //      +----------------+
44 //
45 #include <AliLog.h>             // ALILOG_H
46 #include "AliFMDParameters.h"   // ALIFMDPARAMETERS_H
47 #include "AliFMDDigit.h"        // ALIFMDDIGIT_H
48 #include "AliFMDRawStream.h"    // ALIFMDRAWSTREAM_H 
49 #include "AliRawReader.h"       // ALIRAWREADER_H 
50 #include "AliFMDRawReader.h"    // ALIFMDRAWREADER_H 
51 #include "AliFMDAltroIO.h"      // ALIFMDALTROIO_H 
52 #include <TArrayI.h>            // ROOT_TArrayI
53 #include <TTree.h>              // ROOT_TTree
54 #include <TClonesArray.h>       // ROOT_TClonesArray
55 #include <iostream>
56 #include <iomanip>
57 #include <sstream>
58 #define PRETTY_HEX(N,X) \
59   "  0x" << std::setfill('0') << std::setw(N) << std::hex << X \
60          << std::setfill(' ') << std::dec
61
62 //____________________________________________________________________
63 ClassImp(AliFMDRawReader)
64 #if 0
65   ; // This is here to keep Emacs for indenting the next line
66 #endif
67
68 //____________________________________________________________________
69 AliFMDRawReader::AliFMDRawReader(AliRawReader* reader, TTree* tree) 
70   : TTask("FMDRawReader", "Reader of Raw ADC values from the FMD"),
71     fTree(tree),
72     fReader(reader), 
73     fSampleRate(1)
74 {
75   // Default CTOR
76 }
77
78
79 //____________________________________________________________________
80 void
81 AliFMDRawReader::Exec(Option_t*) 
82 {
83   // Read raw data into the digits array, using AliFMDAltroReader. 
84   if (!fReader->ReadHeader()) {
85     Error("ReadAdcs", "Couldn't read header");
86     return;
87   }
88
89   TClonesArray* array = new TClonesArray("AliFMDDigit");
90   fTree->Branch("FMD", &array);
91
92   // Get sample rate 
93   AliFMDParameters* pars = AliFMDParameters::Instance();
94
95   // Select FMD DDL's 
96   fReader->Select(AliFMDParameters::kBaseDDL>>8);
97
98   UShort_t stripMin = 0;
99   UShort_t stripMax = 127;
100   UShort_t preSamp  = 0;
101   
102   do {
103     UChar_t* cdata;
104     if (!fReader->ReadNextData(cdata)) break;
105     size_t   nchar = fReader->GetDataSize();
106     UShort_t ddl   = AliFMDParameters::kBaseDDL + fReader->GetDDLID();
107     UShort_t rate  = pars->GetSampleRate(ddl);
108     AliDebug(1, Form("Reading %d bytes (%d 10bit words) from %d", 
109                      nchar, nchar * 8 / 10, ddl));
110     // Make a stream to read from 
111     std::string str((char*)(cdata), nchar);
112     std::istringstream s(str);
113     // Prep the reader class.
114     AliFMDAltroReader r(s);
115     // Data array is approx twice the size needed. 
116     UShort_t data[2048], hwaddr, last;
117     while (r.ReadChannel(hwaddr, last, data) > 0) {
118       AliDebug(5, Form("Read channel 0x%x of size %d", hwaddr, last));
119       UShort_t det, sec, str;
120       Char_t   ring;
121       if (!pars->Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) {
122         AliError(Form("Failed to detector id from DDL %d "
123                       "and hardware address 0x%x", ddl, hwaddr));
124         continue;
125       }
126       AliDebug(5, Form("DDL 0x%04x, address 0x%03x maps to FMD%d%c[%2d,%3d]", 
127                        ddl, hwaddr, det, ring, sec, str));
128
129       // Loop over the `timebins', and make the digits
130       for (size_t i = 0; i < last; i++) {
131         if (i < preSamp) continue;
132         Int_t n = array->GetEntries();
133         UShort_t curStr = str + stripMin + i / rate;
134         if ((curStr-str) > stripMax) {
135           AliError(Form("Current strip is %d but DB says max is %d", 
136                         curStr, stripMax));
137         }
138         AliDebug(5, Form("making digit for FMD%d%c[%2d,%3d] from sample %4d", 
139                          det, ring, sec, curStr, i));
140         new ((*array)[n]) AliFMDDigit(det, ring, sec, curStr, data[i], 
141                                       (rate >= 2 ? data[i+1] : 0),
142                                       (rate >= 3 ? data[i+2] : 0));
143         if (rate >= 2) i++;
144         if (rate >= 3) i++;
145         }
146         if (r.IsBof()) break;
147     }
148   } while (true);
149   AliDebug(1, Form("Got a grand total of %d digits", array->GetEntries()));
150 }
151
152 #if 0
153 // This is the old method, for comparison.   It's really ugly, and far
154 // too convoluted. 
155 //____________________________________________________________________
156 void
157 AliFMDRawReader::Exec(Option_t*) 
158 {
159   // Read raw data into the digits array
160   if (!fReader->ReadHeader()) {
161     Error("ReadAdcs", "Couldn't read header");
162     return;
163   }
164
165   Int_t n = 0;
166   TClonesArray* array = new TClonesArray("AliFMDDigit");
167   fTree->Branch("FMD", &array);
168
169   // Get sample rate 
170   AliFMDParameters* pars = AliFMDParameters::Instance();
171   fSampleRate = pars->GetSampleRate(AliFMDParameters::kBaseDDL);
172
173   // Use AliAltroRawStream to read the ALTRO format.  No need to
174   // reinvent the wheel :-) 
175   AliFMDRawStream input(fReader, fSampleRate);
176   // Select FMD DDL's 
177   fReader->Select(AliFMDParameters::kBaseDDL);
178   
179   Int_t    oldDDL      = -1;
180   Int_t    count       = 0;
181   UShort_t detector    = 1; // Must be one here
182   UShort_t oldDetector = 0;
183   Bool_t   next        = kTRUE;
184
185   // local Cache 
186   TArrayI counts(10);
187   counts.Reset(-1);
188   
189   // Loop over data in file 
190   while (next) {
191     next = input.Next();
192
193     count++; 
194     Int_t ddl = fReader->GetDDLID();
195     AliDebug(10, Form("Current DDL is %d", ddl));
196     if (ddl != oldDDL || input.IsNewStrip() || !next) {
197       // Make a new digit, if we have some data (oldDetector == 0,
198       // means that we haven't really read anything yet - that is,
199       // it's the first time we get here). 
200       if (oldDetector > 0) {
201         // Got a new strip. 
202         AliDebug(10, Form("Add a new strip: FMD%d%c[%2d,%3d] "
203                           "(current: FMD%d%c[%2d,%3d])", 
204                           oldDetector, input.PrevRing(), 
205                           input.PrevSector() , input.PrevStrip(),
206                           detector , input.Ring(), input.Sector(), 
207                           input.Strip()));
208         new ((*array)[n]) AliFMDDigit(oldDetector, 
209                                       input.PrevRing(), 
210                                       input.PrevSector(), 
211                                       input.PrevStrip(), 
212                                       counts[0], counts[1], counts[2]);
213         n++;
214 #if 0
215         AliFMDDigit* digit = 
216           static_cast<AliFMDDigit*>(fFMD->Digits()->
217                                     UncheckedAt(fFMD->GetNdigits()-1));
218 #endif 
219       }
220         
221       if (!next) { 
222         AliDebug(10, Form("Read %d channels for FMD%d", 
223                           count + 1, detector));
224         break;
225       }
226     
227     
228       // If we got a new DDL, it means we have a new detector. 
229       if (ddl != oldDDL) {
230         if (detector != 0) 
231           AliDebug(10, Form("Read %d channels for FMD%d", count + 1, detector));
232         // Reset counts, and update the DDL cache 
233         count       = 0;
234         oldDDL      = ddl;
235         // Check that we're processing a FMD detector 
236         Int_t detId = fReader->GetDetectorID();
237         if (detId != (AliFMDParameters::kBaseDDL >> 8)) {
238           AliError(Form("Detector ID %d != %d",
239                         detId, (AliFMDParameters::kBaseDDL >> 8)));
240           break;
241         }
242         // Figure out what detector we're deling with 
243         oldDetector = detector;
244         switch (ddl) {
245         case 0: detector = 1; break;
246         case 1: detector = 2; break;
247         case 2: detector = 3; break;
248         default:
249           AliError(Form("Unknown DDL 0x%x for FMD", ddl));
250           return;
251         }
252         AliDebug(10, Form("Reading ADCs for 0x%x  - That is FMD%d",
253                           fReader->GetEquipmentId(), detector));
254       }
255       counts.Reset(-1);
256     }
257     
258     counts[input.Sample()] = input.Count();
259     
260     AliDebug(10, Form("ADC of FMD%d%c[%2d,%3d] += %d",
261                       detector, input.Ring(), input.Sector(), 
262                       input.Strip(), input.Count()));
263     oldDetector = detector;
264   }
265   fTree->Fill();
266   return;
267
268 }
269 #endif
270
271 //____________________________________________________________________
272 // 
273 // EOF
274 //