Illegal calls to ReadHeader method of the raw reader. The raw reader was not reset...
[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 /* $Id$ */
16 /** @file    AliFMDRawReader.cxx
17     @author  Christian Holm Christensen <cholm@nbi.dk>
18     @date    Mon Mar 27 12:45:23 2006
19     @brief   Class to read raw data 
20     @ingroup FMD_rec
21 */
22 //____________________________________________________________________
23 //
24 // Class to read ADC values from a AliRawReader object. 
25 //
26 // This class uses the AliFMDRawStreamer class to read the ALTRO
27 // formatted data. 
28 // 
29 //          +-------+
30 //          | TTask |
31 //          +-------+
32 //              ^
33 //              |
34 //      +-----------------+  <<references>>  +--------------+
35 //      | AliFMDRawReader |<>----------------| AliRawReader |
36 //      +-----------------+                  +--------------+
37 //              |                                  ^
38 //              | <<uses>>                         |
39 //              V                                  |
40 //      +-----------------+      <<uses>>          |
41 //      | AliFMDRawStream |------------------------+
42 //      +-----------------+
43 //              |
44 //              V
45 //      +----------------+
46 //      | AliAltroStream |
47 //      +----------------+
48 //
49 #include <AliLog.h>             // ALILOG_H
50 #include "AliFMDParameters.h"   // ALIFMDPARAMETERS_H
51 #include "AliFMDDigit.h"        // ALIFMDDIGIT_H
52 #include "AliFMDRawStream.h"    // ALIFMDRAWSTREAM_H 
53 #include "AliRawReader.h"       // ALIRAWREADER_H 
54 #include "AliFMDRawReader.h"    // ALIFMDRAWREADER_H 
55 // #include "AliFMDAltroIO.h"   // ALIFMDALTROIO_H 
56 // #include <TArrayI.h>         // ROOT_TArrayI
57 #include <TTree.h>              // ROOT_TTree
58 #include <TClonesArray.h>       // ROOT_TClonesArray
59 // #include <iostream>
60 // #include <iomanip>
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 void
80 AliFMDRawReader::Exec(Option_t*) 
81 {
82   // Read the data 
83   TClonesArray* array = new TClonesArray("AliFMDDigit");
84   if (!fTree) {
85     AliError("No tree");
86     return;
87   }
88   fTree->Branch("FMD", &array);
89   ReadAdcs(array);
90   Int_t nWrite = fTree->Fill();
91   AliDebug(1, Form("Got a grand total of %d digits, wrote %d bytes to tree", 
92                    array->GetEntries(), nWrite));
93 }
94
95
96 #if 1
97 //____________________________________________________________________
98 Bool_t
99 AliFMDRawReader::ReadAdcs(TClonesArray* array) 
100 {
101   // Read raw data into the digits array, using AliFMDAltroReader. 
102   if (!array) {
103     AliError("No TClonesArray passed");
104     return kFALSE;
105   }
106   //  if (!fReader->ReadHeader()) {
107   //    AliError("Couldn't read header");
108   //    return kFALSE;
109   //  }
110   // Get sample rate 
111   AliFMDParameters* pars = AliFMDParameters::Instance();
112   AliFMDRawStream input(fReader);
113
114   UShort_t stripMin = 0;
115   UShort_t stripMax = 127;
116   UShort_t preSamp  = 0;
117   
118   UInt_t ddl    = 0;
119   UInt_t rate   = 0;
120   UInt_t last   = 0;
121   UInt_t hwaddr = 0;
122   // Data array is approx twice the size needed. 
123   UShort_t data[2048];
124   while (input.ReadChannel(ddl, hwaddr, last, data)) {
125     AliDebug(5, Form("Read channel 0x%x of size %d", hwaddr, last));
126     UShort_t det, sec, str;
127     Char_t   ring;
128     if (!pars->Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) {
129       AliError(Form("Failed to get detector id from DDL %d "
130                     "and hardware address 0x%x", ddl, hwaddr));
131       continue;
132     }
133     rate     = pars->GetSampleRate(det, ring, sec, str);
134     stripMin = pars->GetMinStrip(det, ring, sec, str);
135     stripMax = pars->GetMaxStrip(det, ring, sec, str);
136     AliDebug(5, Form("DDL 0x%04x, address 0x%03x maps to FMD%d%c[%2d,%3d]", 
137                        ddl, hwaddr, det, ring, sec, str));
138     
139     // Loop over the `timebins', and make the digits
140     for (size_t i = 0; i < last; i++) {
141       if (i < preSamp) continue;
142       Int_t    n      = array->GetEntries();
143       UShort_t curStr = str + stripMin + i / rate;
144       if ((curStr-str) > stripMax) {
145         AliError(Form("Current strip is %d but DB says max is %d", 
146                       curStr, stripMax));
147       }
148       AliDebug(5, Form("making digit for FMD%d%c[%2d,%3d] from sample %4d", 
149                        det, ring, sec, curStr, i));
150       new ((*array)[n]) AliFMDDigit(det, ring, sec, curStr, data[i], 
151                                     (rate >= 2 ? data[i+1] : 0),
152                                     (rate >= 3 ? data[i+2] : 0));
153       if (rate >= 2) i++;
154       if (rate >= 3) i++;
155     }
156   }
157   return kTRUE;
158 }
159 #else
160 //____________________________________________________________________
161 Bool_t
162 AliFMDRawReader::ReadAdcs(TClonesArray* array) 
163 {
164   // Read raw data into the digits array, using AliFMDAltroReader. 
165   if (!array) {
166     AliError("No TClonesArray passed");
167     return kFALSE;
168   }
169   //  if (!fReader->ReadHeader()) {
170   //    AliError("Couldn't read header");
171   //    return kFALSE;
172   //  }
173   // Get sample rate 
174   AliFMDParameters* pars = AliFMDParameters::Instance();
175
176   // Select FMD DDL's 
177   fReader->Select(AliFMDParameters::kBaseDDL>>8);
178
179   UShort_t stripMin = 0;
180   UShort_t stripMax = 127;
181   UShort_t preSamp  = 0;
182   
183   do {
184     UChar_t* cdata;
185     if (!fReader->ReadNextData(cdata)) break;
186     size_t   nchar = fReader->GetDataSize();
187     UShort_t ddl   = AliFMDParameters::kBaseDDL + fReader->GetDDLID();
188     UShort_t rate  = 0;
189     AliDebug(1, Form("Reading %d bytes (%d 10bit words) from %d", 
190                      nchar, nchar * 8 / 10, ddl));
191     // Make a stream to read from 
192     std::string str((char*)(cdata), nchar);
193     std::istringstream s(str);
194     // Prep the reader class.
195     AliFMDAltroReader r(s);
196     // Data array is approx twice the size needed. 
197     UShort_t data[2048], hwaddr, last;
198     while (r.ReadChannel(hwaddr, last, data) > 0) {
199       AliDebug(5, Form("Read channel 0x%x of size %d", hwaddr, last));
200       UShort_t det, sec, str;
201       Char_t   ring;
202       if (!pars->Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) {
203         AliError(Form("Failed to detector id from DDL %d "
204                       "and hardware address 0x%x", ddl, hwaddr));
205         continue;
206       }
207       rate     = pars->GetSampleRate(det, ring, sec, str);
208       stripMin = pars->GetMinStrip(det, ring, sec, str);
209       stripMax = pars->GetMaxStrip(det, ring, sec, str);
210       AliDebug(5, Form("DDL 0x%04x, address 0x%03x maps to FMD%d%c[%2d,%3d]", 
211                        ddl, hwaddr, det, ring, sec, str));
212
213       // Loop over the `timebins', and make the digits
214       for (size_t i = 0; i < last; i++) {
215         if (i < preSamp) continue;
216         Int_t    n      = array->GetEntries();
217         UShort_t curStr = str + stripMin + i / rate;
218         if ((curStr-str) > stripMax) {
219           AliError(Form("Current strip is %d but DB says max is %d", 
220                         curStr, stripMax));
221         }
222         AliDebug(5, Form("making digit for FMD%d%c[%2d,%3d] from sample %4d", 
223                          det, ring, sec, curStr, i));
224         new ((*array)[n]) AliFMDDigit(det, ring, sec, curStr, data[i], 
225                                       (rate >= 2 ? data[i+1] : 0),
226                                       (rate >= 3 ? data[i+2] : 0));
227         if (rate >= 2) i++;
228         if (rate >= 3) i++;
229         }
230         if (r.IsBof()) break;
231     }
232   } while (true);
233   return kTRUE;
234 }
235
236   
237
238 // This is the old method, for comparison.   It's really ugly, and far
239 // too convoluted. 
240 //____________________________________________________________________
241 void
242 AliFMDRawReader::Exec(Option_t*) 
243 {
244   // Read raw data into the digits array
245   //  if (!fReader->ReadHeader()) {
246   //    Error("ReadAdcs", "Couldn't read header");
247   //    return;
248   //  }
249
250   Int_t n = 0;
251   TClonesArray* array = new TClonesArray("AliFMDDigit");
252   fTree->Branch("FMD", &array);
253
254   // Get sample rate 
255   AliFMDParameters* pars = AliFMDParameters::Instance();
256   fSampleRate = pars->GetSampleRate(AliFMDParameters::kBaseDDL);
257
258   // Use AliAltroRawStream to read the ALTRO format.  No need to
259   // reinvent the wheel :-) 
260   AliFMDRawStream input(fReader, fSampleRate);
261   // Select FMD DDL's 
262   fReader->Select(AliFMDParameters::kBaseDDL);
263   
264   Int_t    oldDDL      = -1;
265   Int_t    count       = 0;
266   UShort_t detector    = 1; // Must be one here
267   UShort_t oldDetector = 0;
268   Bool_t   next        = kTRUE;
269
270   // local Cache 
271   TArrayI counts(10);
272   counts.Reset(-1);
273   
274   // Loop over data in file 
275   while (next) {
276     next = input.Next();
277
278     count++; 
279     Int_t ddl = fReader->GetDDLID();
280     AliDebug(10, Form("Current DDL is %d", ddl));
281     if (ddl != oldDDL || input.IsNewStrip() || !next) {
282       // Make a new digit, if we have some data (oldDetector == 0,
283       // means that we haven't really read anything yet - that is,
284       // it's the first time we get here). 
285       if (oldDetector > 0) {
286         // Got a new strip. 
287         AliDebug(10, Form("Add a new strip: FMD%d%c[%2d,%3d] "
288                           "(current: FMD%d%c[%2d,%3d])", 
289                           oldDetector, input.PrevRing(), 
290                           input.PrevSector() , input.PrevStrip(),
291                           detector , input.Ring(), input.Sector(), 
292                           input.Strip()));
293         new ((*array)[n]) AliFMDDigit(oldDetector, 
294                                       input.PrevRing(), 
295                                       input.PrevSector(), 
296                                       input.PrevStrip(), 
297                                       counts[0], counts[1], counts[2]);
298         n++;
299 #if 0
300         AliFMDDigit* digit = 
301           static_cast<AliFMDDigit*>(fFMD->Digits()->
302                                     UncheckedAt(fFMD->GetNdigits()-1));
303 #endif 
304       }
305         
306       if (!next) { 
307         AliDebug(10, Form("Read %d channels for FMD%d", 
308                           count + 1, detector));
309         break;
310       }
311     
312     
313       // If we got a new DDL, it means we have a new detector. 
314       if (ddl != oldDDL) {
315         if (detector != 0) 
316           AliDebug(10, Form("Read %d channels for FMD%d", count + 1, detector));
317         // Reset counts, and update the DDL cache 
318         count       = 0;
319         oldDDL      = ddl;
320         // Check that we're processing a FMD detector 
321         Int_t detId = fReader->GetDetectorID();
322         if (detId != (AliFMDParameters::kBaseDDL >> 8)) {
323           AliError(Form("Detector ID %d != %d",
324                         detId, (AliFMDParameters::kBaseDDL >> 8)));
325           break;
326         }
327         // Figure out what detector we're deling with 
328         oldDetector = detector;
329         switch (ddl) {
330         case 0: detector = 1; break;
331         case 1: detector = 2; break;
332         case 2: detector = 3; break;
333         default:
334           AliError(Form("Unknown DDL 0x%x for FMD", ddl));
335           return;
336         }
337         AliDebug(10, Form("Reading ADCs for 0x%x  - That is FMD%d",
338                           fReader->GetEquipmentId(), detector));
339       }
340       counts.Reset(-1);
341     }
342     
343     counts[input.Sample()] = input.Count();
344     
345     AliDebug(10, Form("ADC of FMD%d%c[%2d,%3d] += %d",
346                       detector, input.Ring(), input.Sector(), 
347                       input.Strip(), input.Count()));
348     oldDetector = detector;
349   }
350   fTree->Fill();
351   return;
352
353 }
354 #endif
355
356 //____________________________________________________________________
357 // 
358 // EOF
359 //