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