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