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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 /// This is the base class for reading raw data.
22 /// The derived classes, which operate on concrete raw data formats,
24 /// - ReadHeader to read the next (data/equipment) header
25 /// - ReadNextData to read the next raw data block (=1 DDL)
26 /// - ReadNext to read a given number of bytes
27 /// - several getters like GetType
29 /// Sequential access to the raw data is provided by the methods
30 /// ReadHeader, ReadNextData, ReadNextInt, ReadNextShort, ReadNextChar
32 /// If only data from a specific detector (and a given range of DDL numbers)
33 /// should be read, this can be achieved by the Select method.
34 /// Several getters provide information about the current event and the
35 /// current type of raw data.
37 ///////////////////////////////////////////////////////////////////////////////
40 #include <TPluginManager.h>
43 #include <Riostream.h>
44 #include "AliRawReader.h"
45 #include "AliRawReaderFile.h"
46 #include "AliRawReaderDate.h"
47 #include "AliRawReaderRoot.h"
51 ClassImp(AliRawReader)
54 AliRawReader::AliRawReader() :
55 fEquipmentIdsIn(NULL),
56 fEquipmentIdsOut(NULL),
57 fRequireHeader(kTRUE),
60 fSelectEquipmentType(-1),
61 fSelectMinEquipmentId(-1),
62 fSelectMaxEquipmentId(-1),
65 fSelectTriggerMask(0),
68 fErrorLogs("AliRawDataErrorLog",100),
71 // default constructor: initialize data members
72 // Allocate the swapped header in case of Mac
74 fHeaderSwapped=new AliRawDataHeader();
78 Bool_t AliRawReader::LoadEquipmentIdsMap(const char *fileName)
80 // Open the mapping file
81 // and load the mapping data
82 ifstream input(fileName);
83 if (input.is_open()) {
84 Warning("AliRawReader","Equipment ID mapping file is found !");
85 const Int_t kMaxDDL = 256;
86 fEquipmentIdsIn = new TArrayI(kMaxDDL);
87 fEquipmentIdsOut = new TArrayI(kMaxDDL);
88 Int_t equipIn, equipOut;
90 while (input >> equipIn >> equipOut) {
91 if (nIds >= kMaxDDL) {
92 Error("AliRawReader","Too many equipment Id mappings found ! Truncating the list !");
95 fEquipmentIdsIn->AddAt(equipIn,nIds);
96 fEquipmentIdsOut->AddAt(equipOut,nIds);
99 fEquipmentIdsIn->Set(nIds);
100 fEquipmentIdsOut->Set(nIds);
105 Error("AliRawReader","equipment id map file is not found ! Skipping the mapping !");
110 AliRawReader::AliRawReader(const AliRawReader& rawReader) :
112 fEquipmentIdsIn(rawReader.fEquipmentIdsIn),
113 fEquipmentIdsOut(rawReader.fEquipmentIdsOut),
114 fRequireHeader(rawReader.fRequireHeader),
115 fHeader(rawReader.fHeader),
116 fCount(rawReader.fCount),
117 fSelectEquipmentType(rawReader.fSelectEquipmentType),
118 fSelectMinEquipmentId(rawReader.fSelectMinEquipmentId),
119 fSelectMaxEquipmentId(rawReader.fSelectMaxEquipmentId),
120 fSkipInvalid(rawReader.fSkipInvalid),
121 fSelectEventType(rawReader.fSelectEventType),
122 fSelectTriggerMask(rawReader.fSelectTriggerMask),
125 fErrorLogs("AliRawDataErrorLog",100),
129 // Allocate the swapped header in case of Mac
131 fHeaderSwapped=new AliRawDataHeader(*rawReader.fHeaderSwapped);
135 AliRawReader& AliRawReader::operator = (const AliRawReader& rawReader)
137 // assignment operator
138 fEquipmentIdsIn = rawReader.fEquipmentIdsIn;
139 fEquipmentIdsOut = rawReader.fEquipmentIdsOut;
141 fHeader = rawReader.fHeader;
142 fCount = rawReader.fCount;
144 fSelectEquipmentType = rawReader.fSelectEquipmentType;
145 fSelectMinEquipmentId = rawReader.fSelectMinEquipmentId;
146 fSelectMaxEquipmentId = rawReader.fSelectMaxEquipmentId;
147 fSkipInvalid = rawReader.fSkipInvalid;
148 fSelectEventType = rawReader.fSelectEventType;
149 fSelectTriggerMask = rawReader.fSelectTriggerMask;
151 fErrorCode = rawReader.fErrorCode;
153 fEventNumber = rawReader.fEventNumber;
154 fErrorLogs = *((TClonesArray*)rawReader.fErrorLogs.Clone());
159 AliRawReader::~AliRawReader()
162 // delete the mapping arrays if
164 if (fEquipmentIdsIn) delete fEquipmentIdsIn;
165 if (fEquipmentIdsOut) delete fEquipmentIdsOut;
167 if (fHeaderSwapped) delete fHeaderSwapped;
170 AliRawReader* AliRawReader::Create(const char *uri)
172 // RawReader's factory
173 // It instantiate corresponding raw-reader implementation class object
174 // depending on the URI provided
175 // Normal URIs point to files, while the URI starting with
176 // 'mem://:' or 'mem://<filename>' will create
177 // AliRawReaderDateOnline object which is supposed to be used
178 // in the online reconstruction
180 TString strURI = uri;
182 if (strURI.IsNull()) {
183 AliWarningClass("No raw-reader created");
187 TObjArray *fields = strURI.Tokenize("?");
188 TString &fileURI = ((TObjString*)fields->At(0))->String();
190 AliRawReader *rawReader = NULL;
191 if (!fileURI.BeginsWith("mem://")) {
192 AliInfoClass(Form("Creating raw-reader in order to read raw-data file: %s",fileURI.Data()));
193 if (fileURI.EndsWith("/")) {
194 rawReader = new AliRawReaderFile(fileURI);
195 } else if (fileURI.EndsWith(".root")) {
196 rawReader = new AliRawReaderRoot(fileURI);
198 rawReader = new AliRawReaderDate(fileURI);
202 fileURI.ReplaceAll("mem://","");
203 AliInfoClass(Form("Creating raw-reader in order to read events in shared memory (option=%s)",fileURI.Data()));
205 TPluginManager* pluginManager = gROOT->GetPluginManager();
206 TString rawReaderName = "AliRawReaderDateOnline";
207 TPluginHandler* pluginHandler = pluginManager->FindHandler("AliRawReader", "online");
208 // if not, add a plugin for it
209 if (!pluginHandler) {
210 pluginManager->AddHandler("AliRawReader", "online",
211 "AliRawReaderDateOnline", "RAWDatarecOnline", "AliRawReaderDateOnline(const char*)");
212 pluginHandler = pluginManager->FindHandler("AliRawReader", "online");
214 if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
215 rawReader = (AliRawReader*)pluginHandler->ExecPlugin(1,fileURI.Data());
222 // Now apply event selection criteria (if specified)
223 if (fields->GetEntries() > 1) {
224 Int_t eventType = -1;
225 ULong64_t triggerMask = 0;
226 for(Int_t i = 1; i < fields->GetEntries(); i++) {
227 if (!fields->At(i)) continue;
228 TString &option = ((TObjString*)fields->At(i))->String();
229 if (option.BeginsWith("EventType=",TString::kIgnoreCase)) {
230 option.ReplaceAll("EventType=","");
231 eventType = option.Atoi();
234 if (option.BeginsWith("Trigger=",TString::kIgnoreCase)) {
235 option.ReplaceAll("Trigger=","");
236 triggerMask = option.Atoll();
239 AliWarningClass(Form("Ignoring invalid event selection option: %s",option.Data()));
241 AliInfoClass(Form("Event selection criteria specified: eventype=%d trigger mask=%llx",
242 eventType,triggerMask));
243 rawReader->SelectEvents(eventType,triggerMask);
252 Int_t AliRawReader::GetMappedEquipmentId() const
254 if (!fEquipmentIdsIn || !fEquipmentIdsOut) {
255 Error("AliRawReader","equipment Ids mapping is not initialized !");
256 return GetEquipmentId();
258 Int_t equipmentId = GetEquipmentId();
259 for(Int_t iId = 0; iId < fEquipmentIdsIn->GetSize(); iId++) {
260 if (equipmentId == fEquipmentIdsIn->At(iId)) {
261 equipmentId = fEquipmentIdsOut->At(iId);
268 Int_t AliRawReader::GetDetectorID() const
270 // Get the detector ID
271 // The list of detector IDs
272 // can be found in AliDAQ.h
274 if (fEquipmentIdsIn && fEquipmentIdsIn)
275 equipmentId = GetMappedEquipmentId();
277 equipmentId = GetEquipmentId();
279 if (equipmentId >= 0) {
281 return AliDAQ::DetectorIDFromDdlID(equipmentId,ddlIndex);
287 Int_t AliRawReader::GetDDLID() const
289 // Get the DDL ID (within one sub-detector)
290 // The list of detector IDs
291 // can be found in AliDAQ.h
293 if (fEquipmentIdsIn && fEquipmentIdsIn)
294 equipmentId = GetMappedEquipmentId();
296 equipmentId = GetEquipmentId();
298 if (equipmentId >= 0) {
300 AliDAQ::DetectorIDFromDdlID(equipmentId,ddlIndex);
307 void AliRawReader::Select(const char *detectorName, Int_t minDDLID, Int_t maxDDLID)
309 // read only data of the detector with the given name and in the given
310 // range of DDLs (minDDLID <= DDLID <= maxDDLID).
311 // no selection is applied if a value < 0 is used.
312 Int_t detectorID = AliDAQ::DetectorID(detectorName);
314 Select(detectorID,minDDLID,maxDDLID);
317 void AliRawReader::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID)
319 // read only data of the detector with the given ID and in the given
320 // range of DDLs (minDDLID <= DDLID <= maxDDLID).
321 // no selection is applied if a value < 0 is used.
323 fSelectEquipmentType = -1;
326 fSelectMinEquipmentId = AliDAQ::DdlIDOffset(detectorID);
328 fSelectMinEquipmentId = AliDAQ::DdlID(detectorID,minDDLID);
331 fSelectMaxEquipmentId = AliDAQ::DdlID(detectorID,AliDAQ::NumberOfDdls(detectorID)-1);
333 fSelectMaxEquipmentId = AliDAQ::DdlID(detectorID,maxDDLID);
336 void AliRawReader::SelectEquipment(Int_t equipmentType,
337 Int_t minEquipmentId, Int_t maxEquipmentId)
339 // read only data of the equipment with the given type and in the given
340 // range of IDs (minEquipmentId <= EquipmentId <= maxEquipmentId).
341 // no selection is applied if a value < 0 is used.
343 fSelectEquipmentType = equipmentType;
344 fSelectMinEquipmentId = minEquipmentId;
345 fSelectMaxEquipmentId = maxEquipmentId;
348 void AliRawReader::SelectEvents(Int_t type, ULong64_t triggerMask)
350 // read only events with the given type and optionally
352 // no selection is applied if a value < 0 is used.
354 fSelectEventType = type;
355 fSelectTriggerMask = triggerMask;
358 Bool_t AliRawReader::IsSelected() const
360 // apply the selection (if any)
362 if (fSkipInvalid && !IsValid()) return kFALSE;
364 if (fSelectEquipmentType >= 0)
365 if (GetEquipmentType() != fSelectEquipmentType) return kFALSE;
368 if (fEquipmentIdsIn && fEquipmentIdsIn)
369 equipmentId = GetMappedEquipmentId();
371 equipmentId = GetEquipmentId();
373 if ((fSelectMinEquipmentId >= 0) &&
374 (equipmentId < fSelectMinEquipmentId))
376 if ((fSelectMaxEquipmentId >= 0) &&
377 (equipmentId > fSelectMaxEquipmentId))
383 Bool_t AliRawReader::IsEventSelected() const
385 // apply the event selection (if any)
387 // First check the event type
388 if (fSelectEventType >= 0) {
389 if (GetType() != (UInt_t) fSelectEventType) return kFALSE;
392 // Then check the trigger pattern and compared it
393 // to the required trigger mask
394 if (fSelectTriggerMask != 0) {
395 if ((GetClassMask() & fSelectTriggerMask) != fSelectTriggerMask) return kFALSE;
401 UInt_t AliRawReader::SwapWord(UInt_t x) const
403 // Swap the endianess of the integer value 'x'
405 return (((x & 0x000000ffU) << 24) | ((x & 0x0000ff00U) << 8) |
406 ((x & 0x00ff0000U) >> 8) | ((x & 0xff000000U) >> 24));
409 UShort_t AliRawReader::SwapShort(UShort_t x) const
411 // Swap the endianess of the short value 'x'
413 return (((x & 0x00ffU) << 8) | ((x & 0xff00U) >> 8)) ;
416 Bool_t AliRawReader::ReadNextInt(UInt_t& data)
418 // reads the next 4 bytes at the current position
419 // returns kFALSE if the data could not be read
421 while (fCount == 0) {
422 if (!ReadHeader()) return kFALSE;
424 if (fCount < (Int_t) sizeof(data)) {
426 "too few data left (%d bytes) to read an UInt_t!", fCount);
429 if (!ReadNext((UChar_t*) &data, sizeof(data))) {
430 Error("ReadNextInt", "could not read data!");
439 Bool_t AliRawReader::ReadNextShort(UShort_t& data)
441 // reads the next 2 bytes at the current position
442 // returns kFALSE if the data could not be read
444 while (fCount == 0) {
445 if (!ReadHeader()) return kFALSE;
447 if (fCount < (Int_t) sizeof(data)) {
448 Error("ReadNextShort",
449 "too few data left (%d bytes) to read an UShort_t!", fCount);
452 if (!ReadNext((UChar_t*) &data, sizeof(data))) {
453 Error("ReadNextShort", "could not read data!");
457 data=SwapShort(data);
462 Bool_t AliRawReader::ReadNextChar(UChar_t& data)
464 // reads the next 1 byte at the current stream position
465 // returns kFALSE if the data could not be read
467 while (fCount == 0) {
468 if (!ReadHeader()) return kFALSE;
470 if (!ReadNext((UChar_t*) &data, sizeof(data))) {
471 Error("ReadNextChar", "could not read data!");
478 Int_t AliRawReader::CheckData() const
480 // check the consistency of the data
481 // derived classes should overwrite the default method which returns 0 (no err)
487 void AliRawReader::DumpData(Int_t limit)
489 // print the raw data
490 // if limit is not negative, only the first and last "limit" lines of raw data
495 Error("DumpData", "no header");
499 " type = %d run = %d ", GetType(), GetRunNumber());
501 printf("event = %8.8x %8.8x\n", GetEventId()[1], GetEventId()[0]);
503 printf("event = -------- --------\n");
505 if (GetTriggerPattern()) {
506 printf(" trigger = %8.8x %8.8x ",
507 GetTriggerPattern()[1], GetTriggerPattern()[0]);
509 printf(" trigger = -------- -------- ");
511 if (GetDetectorPattern()) {
512 printf("detector = %8.8x\n", GetDetectorPattern()[0]);
514 printf("detector = --------\n");
516 if (GetAttributes()) {
517 printf(" attributes = %8.8x %8.8x %8.8x ",
518 GetAttributes()[2], GetAttributes()[1], GetAttributes()[0]);
520 printf(" attributes = -------- -------- -------- ");
522 printf("GDC = %d\n", GetGDCId());
526 printf("-------------------------------------------------------------------------------\n");
527 printf("LDC = %d\n", GetLDCId());
529 printf("equipment:\n"
530 " size = %d type = %d id = %d\n",
531 GetEquipmentSize(), GetEquipmentType(), GetEquipmentId());
532 if (GetEquipmentAttributes()) {
533 printf(" attributes = %8.8x %8.8x %8.8x ", GetEquipmentAttributes()[2],
534 GetEquipmentAttributes()[1], GetEquipmentAttributes()[0]);
536 printf(" attributes = -------- -------- -------- ");
538 printf("element size = %d\n", GetEquipmentElementSize());
540 printf("data header:\n"
541 " size = %d version = %d valid = %d compression = %d\n",
542 GetDataSize(), GetVersion(), IsValid(), IsCompressed());
545 if (limit == 0) continue;
547 Int_t size = GetDataSize();
549 for (Int_t i = 0; i < 70; i++) line[i] = ' ';
555 for (Int_t n = 0; n < size; n++) {
556 if (!ReadNextChar(byte)) {
557 Error("DumpData", "couldn't read byte number %d\n", n);
561 printf("%8.8x %s\n", n-pos, line);
562 for (Int_t i = 0; i < 70; i++) line[i] = ' ';
565 if ((limit > 0) && (n/max == limit)) {
566 Int_t nContinue = ((size-1)/max+1-limit) * max;
568 printf(" [skipping %d bytes]\n", nContinue-n);
574 Int_t offset = pos/4;
575 if ((byte > 0x20) && (byte < 0x7f)) {
576 line[pos+offset] = byte;
578 line[pos+offset] = '.';
581 sprintf(hex, "%2.2x", byte);
582 line[max+max/4+3+2*pos+offset] = hex[0];
583 line[max+max/4+4+2*pos+offset] = hex[1];
587 if (pos > 0) printf("%8.8x %s\n", size-pos, line);
590 } while (ReadHeader());
593 void AliRawReader::AddErrorLog(AliRawDataErrorLog::ERawDataErrorLevel level,
597 // Add a raw data error message to the list
598 // of raw-data decoding errors
599 if (fEventNumber < 0) {
602 Int_t ddlId = GetEquipmentId();
604 AliError("No ddl raw data have been read so far! Impossible to add a raw data error log!");
608 Int_t prevEventNumber = -1;
609 Int_t prevDdlId = -1;
610 Int_t prevErrorCode = -1;
611 AliRawDataErrorLog *prevLog = (AliRawDataErrorLog *)fErrorLogs.Last();
613 prevEventNumber = prevLog->GetEventNumber();
614 prevDdlId = prevLog->GetDdlID();
615 prevErrorCode = prevLog->GetErrorCode();
618 if ((prevEventNumber != fEventNumber) ||
619 (prevDdlId != ddlId) ||
620 (prevErrorCode != code)) {
621 new (fErrorLogs[fErrorLogs.GetEntriesFast()])
622 AliRawDataErrorLog(fEventNumber,
629 if (prevLog) prevLog->AddCount();