1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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
22 //____________________________________________________________________
24 // Class to read ADC values from a AliRawReader object.
26 // This class uses the AliFMDRawStreamer class to read the ALTRO
34 // +-----------------+ <<references>> +--------------+
35 // | AliFMDRawReader |<>----------------| AliRawReader |
36 // +-----------------+ +--------------+
40 // +-----------------+ <<uses>> |
41 // | AliFMDRawStream |------------------------+
42 // +-----------------+
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>
62 //____________________________________________________________________
63 ClassImp(AliFMDRawReader)
65 ; // This is here to keep Emacs for indenting the next line
68 //____________________________________________________________________
69 AliFMDRawReader::AliFMDRawReader(AliRawReader* reader, TTree* tree)
70 : TTask("FMDRawReader", "Reader of Raw ADC values from the FMD"),
78 //____________________________________________________________________
80 AliFMDRawReader::Exec(Option_t*)
83 TClonesArray* array = new TClonesArray("AliFMDDigit");
88 fTree->Branch("FMD", &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));
97 //____________________________________________________________________
99 AliFMDRawReader::ReadAdcs(TClonesArray* array)
101 // Read raw data into the digits array, using AliFMDAltroReader.
103 AliError("No TClonesArray passed");
106 // if (!fReader->ReadHeader()) {
107 // AliError("Couldn't read header");
111 AliFMDParameters* pars = AliFMDParameters::Instance();
112 AliFMDRawStream input(fReader);
114 UShort_t stripMin = 0;
115 UShort_t stripMax = 127;
116 UShort_t preSamp = 0;
122 // Data array is approx twice the size needed.
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;
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));
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));
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",
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));
160 //____________________________________________________________________
162 AliFMDRawReader::ReadAdcs(TClonesArray* array)
164 // Read raw data into the digits array, using AliFMDAltroReader.
166 AliError("No TClonesArray passed");
169 // if (!fReader->ReadHeader()) {
170 // AliError("Couldn't read header");
174 AliFMDParameters* pars = AliFMDParameters::Instance();
177 fReader->Select("FMD");
179 UShort_t stripMin = 0;
180 UShort_t stripMax = 127;
181 UShort_t preSamp = 0;
185 if (!fReader->ReadNextData(cdata)) break;
186 size_t nchar = fReader->GetDataSize();
187 UShort_t ddl = fReader->GetDDLID();
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;
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));
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));
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",
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));
230 if (r.IsBof()) break;
238 // This is the old method, for comparison. It's really ugly, and far
240 //____________________________________________________________________
242 AliFMDRawReader::Exec(Option_t*)
244 // Read raw data into the digits array
245 // if (!fReader->ReadHeader()) {
246 // Error("ReadAdcs", "Couldn't read header");
251 TClonesArray* array = new TClonesArray("AliFMDDigit");
252 fTree->Branch("FMD", &array);
255 AliFMDParameters* pars = AliFMDParameters::Instance();
256 fSampleRate = pars->GetSampleRate(0);
258 // Use AliAltroRawStream to read the ALTRO format. No need to
259 // reinvent the wheel :-)
260 AliFMDRawStream input(fReader, fSampleRate);
262 fReader->Select("FMD");
266 UShort_t detector = 1; // Must be one here
267 UShort_t oldDetector = 0;
274 // Loop over data in file
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) {
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(),
293 new ((*array)[n]) AliFMDDigit(oldDetector,
297 counts[0], counts[1], counts[2]);
301 static_cast<AliFMDDigit*>(fFMD->Digits()->
302 UncheckedAt(fFMD->GetNdigits()-1));
307 AliDebug(10, Form("Read %d channels for FMD%d",
308 count + 1, detector));
313 // If we got a new DDL, it means we have a new detector.
316 AliDebug(10, Form("Read %d channels for FMD%d", count + 1, detector));
317 // Reset counts, and update the DDL cache
320 // Check that we're processing a FMD detector
321 Int_t detId = fReader->GetDetectorID();
322 if (detId != (AliDAQ::DetectorID("FMD"))) {
323 AliError(Form("Detector ID %d != %d",
324 detId, (AliDAQ::DetectorID("FMD"))));
327 // Figure out what detector we're deling with
328 oldDetector = detector;
330 case 0: detector = 1; break;
331 case 1: detector = 2; break;
332 case 2: detector = 3; break;
334 AliError(Form("Unknown DDL 0x%x for FMD", ddl));
337 AliDebug(10, Form("Reading ADCs for 0x%x - That is FMD%d",
338 fReader->GetEquipmentId(), detector));
343 counts[input.Sample()] = input.Count();
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;
356 //____________________________________________________________________