Last fixes before declaring (almost) success
[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 Bool_t
80 AliFMDRawReader::ReadAdcs(TClonesArray* array) 
81 {
82   // Read raw data into the digits array, using AliFMDAltroReader. 
83   if (!array) {
84     AliError("No TClonesArray passed");
85     return kFALSE;
86   }
87   if (!fReader->ReadHeader()) {
88     AliError("Couldn't read header");
89     return kFALSE;
90   }
91   // Get sample rate 
92   AliFMDParameters* pars = AliFMDParameters::Instance();
93
94   // Select FMD DDL's 
95   fReader->Select(AliFMDParameters::kBaseDDL>>8);
96
97   UShort_t stripMin = 0;
98   UShort_t stripMax = 127;
99   UShort_t preSamp  = 0;
100   
101   do {
102     UChar_t* cdata;
103     if (!fReader->ReadNextData(cdata)) break;
104     size_t   nchar = fReader->GetDataSize();
105     UShort_t ddl   = AliFMDParameters::kBaseDDL + fReader->GetDDLID();
106     UShort_t rate  = pars->GetSampleRate(ddl);
107     AliDebug(1, Form("Reading %d bytes (%d 10bit words) from %d", 
108                      nchar, nchar * 8 / 10, ddl));
109     // Make a stream to read from 
110     std::string str((char*)(cdata), nchar);
111     std::istringstream s(str);
112     // Prep the reader class.
113     AliFMDAltroReader r(s);
114     // Data array is approx twice the size needed. 
115     UShort_t data[2048], hwaddr, last;
116     while (r.ReadChannel(hwaddr, last, data) > 0) {
117       AliDebug(5, Form("Read channel 0x%x of size %d", hwaddr, last));
118       UShort_t det, sec, str;
119       Char_t   ring;
120       if (!pars->Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) {
121         AliError(Form("Failed to detector id from DDL %d "
122                       "and hardware address 0x%x", ddl, hwaddr));
123         continue;
124       }
125       AliDebug(5, Form("DDL 0x%04x, address 0x%03x maps to FMD%d%c[%2d,%3d]", 
126                        ddl, hwaddr, det, ring, sec, str));
127
128       // Loop over the `timebins', and make the digits
129       for (size_t i = 0; i < last; i++) {
130         if (i < preSamp) continue;
131         Int_t    n      = array->GetEntries();
132         UShort_t curStr = str + stripMin + i / rate;
133         if ((curStr-str) > stripMax) {
134           AliError(Form("Current strip is %d but DB says max is %d", 
135                         curStr, stripMax));
136         }
137         AliDebug(5, Form("making digit for FMD%d%c[%2d,%3d] from sample %4d", 
138                          det, ring, sec, curStr, i));
139         new ((*array)[n]) AliFMDDigit(det, ring, sec, curStr, data[i], 
140                                       (rate >= 2 ? data[i+1] : 0),
141                                       (rate >= 3 ? data[i+2] : 0));
142         if (rate >= 2) i++;
143         if (rate >= 3) i++;
144         }
145         if (r.IsBof()) break;
146     }
147   } while (true);
148   return kTRUE;
149 }
150
151   
152
153 //____________________________________________________________________
154 void
155 AliFMDRawReader::Exec(Option_t*) 
156 {
157   TClonesArray* array = new TClonesArray("AliFMDDigit");
158   if (!fTree) {
159     AliError("No tree");
160     return;
161   }
162   fTree->Branch("FMD", &array);
163   ReadAdcs(array);
164   Int_t nWrite = fTree->Fill();
165   AliDebug(1, Form("Got a grand total of %d digits, wrote %d bytes to tree", 
166                    array->GetEntries(), nWrite));
167 }
168
169 #if 0
170 // This is the old method, for comparison.   It's really ugly, and far
171 // too convoluted. 
172 //____________________________________________________________________
173 void
174 AliFMDRawReader::Exec(Option_t*) 
175 {
176   // Read raw data into the digits array
177   if (!fReader->ReadHeader()) {
178     Error("ReadAdcs", "Couldn't read header");
179     return;
180   }
181
182   Int_t n = 0;
183   TClonesArray* array = new TClonesArray("AliFMDDigit");
184   fTree->Branch("FMD", &array);
185
186   // Get sample rate 
187   AliFMDParameters* pars = AliFMDParameters::Instance();
188   fSampleRate = pars->GetSampleRate(AliFMDParameters::kBaseDDL);
189
190   // Use AliAltroRawStream to read the ALTRO format.  No need to
191   // reinvent the wheel :-) 
192   AliFMDRawStream input(fReader, fSampleRate);
193   // Select FMD DDL's 
194   fReader->Select(AliFMDParameters::kBaseDDL);
195   
196   Int_t    oldDDL      = -1;
197   Int_t    count       = 0;
198   UShort_t detector    = 1; // Must be one here
199   UShort_t oldDetector = 0;
200   Bool_t   next        = kTRUE;
201
202   // local Cache 
203   TArrayI counts(10);
204   counts.Reset(-1);
205   
206   // Loop over data in file 
207   while (next) {
208     next = input.Next();
209
210     count++; 
211     Int_t ddl = fReader->GetDDLID();
212     AliDebug(10, Form("Current DDL is %d", ddl));
213     if (ddl != oldDDL || input.IsNewStrip() || !next) {
214       // Make a new digit, if we have some data (oldDetector == 0,
215       // means that we haven't really read anything yet - that is,
216       // it's the first time we get here). 
217       if (oldDetector > 0) {
218         // Got a new strip. 
219         AliDebug(10, Form("Add a new strip: FMD%d%c[%2d,%3d] "
220                           "(current: FMD%d%c[%2d,%3d])", 
221                           oldDetector, input.PrevRing(), 
222                           input.PrevSector() , input.PrevStrip(),
223                           detector , input.Ring(), input.Sector(), 
224                           input.Strip()));
225         new ((*array)[n]) AliFMDDigit(oldDetector, 
226                                       input.PrevRing(), 
227                                       input.PrevSector(), 
228                                       input.PrevStrip(), 
229                                       counts[0], counts[1], counts[2]);
230         n++;
231 #if 0
232         AliFMDDigit* digit = 
233           static_cast<AliFMDDigit*>(fFMD->Digits()->
234                                     UncheckedAt(fFMD->GetNdigits()-1));
235 #endif 
236       }
237         
238       if (!next) { 
239         AliDebug(10, Form("Read %d channels for FMD%d", 
240                           count + 1, detector));
241         break;
242       }
243     
244     
245       // If we got a new DDL, it means we have a new detector. 
246       if (ddl != oldDDL) {
247         if (detector != 0) 
248           AliDebug(10, Form("Read %d channels for FMD%d", count + 1, detector));
249         // Reset counts, and update the DDL cache 
250         count       = 0;
251         oldDDL      = ddl;
252         // Check that we're processing a FMD detector 
253         Int_t detId = fReader->GetDetectorID();
254         if (detId != (AliFMDParameters::kBaseDDL >> 8)) {
255           AliError(Form("Detector ID %d != %d",
256                         detId, (AliFMDParameters::kBaseDDL >> 8)));
257           break;
258         }
259         // Figure out what detector we're deling with 
260         oldDetector = detector;
261         switch (ddl) {
262         case 0: detector = 1; break;
263         case 1: detector = 2; break;
264         case 2: detector = 3; break;
265         default:
266           AliError(Form("Unknown DDL 0x%x for FMD", ddl));
267           return;
268         }
269         AliDebug(10, Form("Reading ADCs for 0x%x  - That is FMD%d",
270                           fReader->GetEquipmentId(), detector));
271       }
272       counts.Reset(-1);
273     }
274     
275     counts[input.Sample()] = input.Count();
276     
277     AliDebug(10, Form("ADC of FMD%d%c[%2d,%3d] += %d",
278                       detector, input.Ring(), input.Sector(), 
279                       input.Strip(), input.Count()));
280     oldDetector = detector;
281   }
282   fTree->Fill();
283   return;
284
285 }
286 #endif
287
288 //____________________________________________________________________
289 // 
290 // EOF
291 //