]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/util/AliHLTRawReaderPublisherComponent.cxx
New Component:
[u/mrichter/AliRoot.git] / HLT / BASE / util / AliHLTRawReaderPublisherComponent.cxx
1 // @(#) $Id$
2
3 /**************************************************************************
4  * This file is property of and copyright by the ALICE HLT Project        * 
5  * ALICE Experiment at CERN, All rights reserved.                         *
6  *                                                                        *
7  * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8  *                  for The ALICE HLT Project.                            *
9  *                                                                        *
10  * Permission to use, copy, modify and distribute this software and its   *
11  * documentation strictly for non-commercial purposes is hereby granted   *
12  * without fee, provided that the above copyright notice appears in all   *
13  * copies and that both the copyright notice and this permission notice   *
14  * appear in the supporting documentation. The authors make no claims     *
15  * about the suitability of this software for any purpose. It is          *
16  * provided "as is" without express or implied warranty.                  *
17  **************************************************************************/
18
19 /** @file   AliHLTRawReaderPublisherComponent.cxx
20     @author Matthias Richter
21     @date   
22     @brief  A general tree publisher component for the AliRawReader.
23 */
24
25 // see header file for class documentation
26 // or
27 // refer to README to build package
28 // or
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
30
31 #include "AliHLTRawReaderPublisherComponent.h"
32 #include "AliRawReader.h"
33 #include "AliDAQ.h"
34 #include "AliLog.h"
35 #include <cerrno>
36 #include <cassert>
37 #include <list>
38
39 /** ROOT macro for the implementation of ROOT specific class methods */
40 ClassImp(AliHLTRawReaderPublisherComponent)
41
42 AliHLTRawReaderPublisherComponent::AliHLTRawReaderPublisherComponent()
43   :
44   fMaxSize(5000000),
45   fDetector(),
46   fMinEquId(-1),
47   fMaxEquId(-1),
48   fVerbosity(1),
49   fDataType(kAliHLTVoidDataType),
50   fSpecification(kAliHLTVoidDataSpec),
51   fSkipEmpty(kFALSE)
52 {
53   // see header file for class documentation
54   // or
55   // refer to README to build package
56   // or
57   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
58 }
59
60 AliHLTRawReaderPublisherComponent::~AliHLTRawReaderPublisherComponent()
61 {
62   // see header file for class documentation
63 }
64
65 const char* AliHLTRawReaderPublisherComponent::GetComponentID()
66 {
67   // see header file for class documentation
68   return "AliRawReaderPublisher";
69 }
70
71 AliHLTComponentDataType AliHLTRawReaderPublisherComponent::GetOutputDataType()
72 {
73   // see header file for class documentation
74   return fDataType;
75 }
76
77 void AliHLTRawReaderPublisherComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
78 {
79   // see header file for class documentation
80   constBase=fMaxSize;
81   inputMultiplier=1;
82 }
83
84 AliHLTComponent* AliHLTRawReaderPublisherComponent::Spawn()
85 {
86   // see header file for class documentation
87   return new AliHLTRawReaderPublisherComponent;
88 }
89
90 int AliHLTRawReaderPublisherComponent::DoInit( int argc, const char** argv )
91 {
92   // see header file for class documentation
93   int iResult=0;
94
95   // scan arguments
96   TString argument="";
97   int bMissingParam=0;
98   for (int i=0; i<argc && iResult>=0; i++) {
99     argument=argv[i];
100     if (argument.IsNull()) continue;
101
102     // -detector
103     if (argument.CompareTo("-detector")==0) {
104       if ((bMissingParam=(++i>=argc))) break;
105       fDetector=argv[i];
106
107       // -equipmentid, -minid
108     } else if (argument.CompareTo("-equipmentid")==0 ||
109                argument.CompareTo("-minid")==0) {
110       if ((bMissingParam=(++i>=argc))) break;
111       TString parameter(argv[i]);
112       parameter.Remove(TString::kLeading, ' '); // remove all blanks
113       if (parameter.IsDigit()) {
114         fMinEquId=(AliHLTUInt32_t)parameter.Atoi();
115       } else {
116         HLTError("wrong parameter for argument %s, number expected", argument.Data());
117         iResult=-EINVAL;
118       }
119
120       // -maxid
121     } else if (argument.CompareTo("-maxid")==0) {
122       if ((bMissingParam=(++i>=argc))) break;
123       TString parameter(argv[i]);
124       parameter.Remove(TString::kLeading, ' '); // remove all blanks
125       if (parameter.IsDigit()) {
126         fMaxEquId=(AliHLTUInt32_t)parameter.Atoi();
127       } else {
128         HLTError("wrong parameter for argument %s, number expected", argument.Data());
129         iResult=-EINVAL;
130       }
131
132       // -verbose
133     } else if (argument.CompareTo("-verbose")==0) {
134       fVerbosity=2;
135
136       // -silent
137     } else if (argument.CompareTo("-silent")==0) {
138       fVerbosity=0;
139
140       // -skipempty
141     } else if (argument.CompareTo("-skipempty")==0) {
142       fSkipEmpty=kTRUE;
143
144       // -datatype
145     } else if (argument.CompareTo("-datatype")==0) {
146       if ((bMissingParam=(++i>=argc))) break;
147       memcpy(&fDataType.fID, argv[i], TMath::Min(kAliHLTComponentDataTypefIDsize, (Int_t)strlen(argv[i])));
148       if ((bMissingParam=(++i>=argc))) break;
149       memcpy(&fDataType.fOrigin, argv[i], TMath::Min(kAliHLTComponentDataTypefOriginSize, (Int_t)strlen(argv[i])));
150
151       // -dataspec
152     } else if (argument.CompareTo("-dataspec")==0) {
153       if ((bMissingParam=(++i>=argc))) break;
154       TString parameter(argv[i]);
155       parameter.Remove(TString::kLeading, ' '); // remove all blanks
156       if (parameter.IsDigit()) {
157         fSpecification=(AliHLTUInt32_t)parameter.Atoi();
158       } else if (parameter.BeginsWith("0x") &&
159                  parameter.Replace(0,2,"",0).IsHex()) {
160         sscanf(parameter.Data(),"%x", &fSpecification);
161       } else {
162         HLTError("wrong parameter for argument %s, number expected", argument.Data());
163         iResult=-EINVAL;
164       }
165     } else {
166       HLTError("unknown argument %s", argument.Data());
167       iResult=-EINVAL;
168     }
169   }
170   if (bMissingParam) {
171     HLTError("missing parameter for argument %s", argument.Data());
172     iResult=-EINVAL;
173   }
174
175   if (iResult<0) return iResult;
176
177   if (!fDetector.IsNull()) {
178     int ddloffset=-1;
179     int ddlcount=-1;
180     if ((ddloffset=AliDAQ::DdlIDOffset(fDetector))<0 || 
181         (ddlcount=AliDAQ::NumberOfDdls(fDetector))<0) {
182       return -EINVAL;
183     }
184     if (fMinEquId<0) fMinEquId=ddloffset;
185     else fMinEquId+=ddloffset;
186
187     if (fMaxEquId<0 || fMaxEquId>ddlcount) fMaxEquId=ddloffset+ddlcount;
188     else fMaxEquId+=ddloffset;
189   }
190
191   if (fMinEquId>fMaxEquId) fMaxEquId=fMinEquId;
192
193   if (fMinEquId<0) {
194     AliErrorStream() << "equipment id required, use \'-equipmentid\' or \'-detector\' option" << endl;
195     return -EINVAL;
196   }
197
198   AliHLTUInt32_t dummy;
199   if (fMinEquId!=fMaxEquId && GetSpecificationFromEquipmentId(0, dummy)==-ENOSYS) {
200     AliWarningStream() << "publication of multiple equipment ids needs implementation of a child and function GetSpecificationFromEquipmentId to set correct specifications" << endl;
201     //return -EINVAL;
202   }
203
204   AliRawReader* pRawReader=GetRawReader();
205   if ((pRawReader=GetRawReader())!=NULL) {
206   } else {
207     AliErrorStream() << "RawReader instance needed" << endl;
208     return -EINVAL;
209   }
210
211   return iResult;
212 }
213
214 int AliHLTRawReaderPublisherComponent::DoDeinit()
215 {
216   // see header file for class documentation
217   int iResult=0;
218   return iResult;
219 }
220
221 int AliHLTRawReaderPublisherComponent::GetEvent(const AliHLTComponentEventData& /*evtData*/, 
222                                                 AliHLTComponentTriggerData& /*trigData*/, 
223                                                 AliHLTUInt8_t* outputPtr, 
224                                                 AliHLTUInt32_t& size, 
225                                                 vector<AliHLTComponentBlockData>& outputBlocks)
226 {
227   // see header file for class documentation
228   int iResult=0;
229   AliHLTUInt32_t capacity=size;
230   size=0;
231
232   // process data events only
233   if (!IsDataEvent()) return 0;
234
235   unsigned int offset=0;
236   assert(outputPtr!=NULL || size==0);
237   AliRawReader* pRawReader=GetRawReader();
238   if (pRawReader) {
239     pRawReader->Reset();
240     pRawReader->SelectEquipment(-1, fMinEquId, fMaxEquId);
241     if (fVerbosity>1) {
242       AliInfo(Form("get event from RawReader %p equipment id range [%d,%d]", pRawReader, fMinEquId, fMaxEquId));
243     } else {
244       AliDebug(0, Form("get event from RawReader %p equipment id range [%d,%d]", pRawReader, fMinEquId, fMaxEquId));
245     }
246     list<int> processedIds;
247     while (pRawReader->ReadHeader() && (iResult>=0 || iResult==-ENOSPC)) {
248       const AliRawDataHeader* pHeader=pRawReader->GetDataHeader();
249       if (pHeader==NULL) {
250         HLTError("can not get data header from RawReader, skipping data block ...");
251         continue;
252       }
253       unsigned int readSize=pRawReader->GetDataSize()+sizeof(AliRawDataHeader);
254       int id=pRawReader->GetEquipmentId();
255       if (fVerbosity>0) {
256         AliInfo(Form("got header for id %d, size %d", id, readSize));
257       } else {
258         AliDebug(0, Form("got header for id %d, size %d", id, readSize));
259       }
260       if (fMinEquId>id || fMaxEquId<id) {
261         AliError(Form("id %d returned from RawReader is outside range [%d,%d]", id, fMinEquId, fMaxEquId));
262         continue;
263       }
264       processedIds.push_back(id);
265       if (readSize+offset<=capacity) {
266         memcpy(outputPtr+offset, pHeader, sizeof(AliRawDataHeader));
267         if (readSize>sizeof(AliRawDataHeader)) {
268           if (!pRawReader->ReadNext(outputPtr+offset+sizeof(AliRawDataHeader), readSize-sizeof(AliRawDataHeader))) {
269             AliError(Form("error reading %d bytes from RawReader %p", readSize-sizeof(AliRawDataHeader), pRawReader));
270             iResult=-ENODATA;
271             break;
272           }
273         }
274         AliHLTComponentBlockData bd;
275         FillBlockData( bd );
276         bd.fOffset = offset;
277         bd.fSize = readSize;
278         bd.fDataType = fDataType;
279         if (fSpecification == kAliHLTVoidDataSpec) {
280           GetSpecificationFromEquipmentId(id, bd.fSpecification);
281         } else {
282           bd.fSpecification=fSpecification;
283         }
284         outputBlocks.push_back( bd );
285       } else {
286         // we keep the loop going in order to collect the full size
287         fMaxSize=offset+readSize;
288         iResult=-ENOSPC;
289       }
290       offset+=readSize;
291     }
292     if (!fSkipEmpty && processedIds.size()!=size_t(fMaxEquId-fMinEquId+1)) {
293       // add further empty data blocks
294       AliRawDataHeader header;
295       header.fSize=sizeof(AliRawDataHeader);
296       processedIds.sort();
297       list<int>::iterator curr=processedIds.begin();
298       for (int id=fMinEquId; id<=fMaxEquId; id++) {
299         if (curr!=processedIds.end() && *curr<=id) {
300           curr++;
301         } else {
302           if (sizeof(AliRawDataHeader)<=capacity-offset) {
303             HLTInfo("add empty data block for equipment id %d", id);
304             memcpy(outputPtr+offset, &header, sizeof(AliRawDataHeader));
305             AliHLTComponentBlockData bd;
306             FillBlockData( bd );
307             bd.fOffset = offset;
308             bd.fSize = sizeof(AliRawDataHeader);
309             bd.fDataType = fDataType;
310             if (fSpecification == kAliHLTVoidDataSpec) {
311               GetSpecificationFromEquipmentId(id, bd.fSpecification);
312             } else {
313               bd.fSpecification=fSpecification;
314             }
315             outputBlocks.push_back( bd );
316           } else {
317             // we keep the loop going in order to collect the full size
318             fMaxSize=offset+sizeof(AliRawDataHeader);
319             iResult=-ENOSPC;
320           }
321           offset+=sizeof(AliRawDataHeader);
322         }
323       }
324     }
325     if (offset<=capacity) {
326       size=offset;
327     } else {
328       outputBlocks.clear();
329     }
330   } else {
331     AliErrorStream() << "RawReader uninitialized" << endl;
332     iResult=-EFAULT;
333   }
334   return iResult;
335 }
336
337 int AliHLTRawReaderPublisherComponent::GetSpecificationFromEquipmentId(int id, AliHLTUInt32_t& specification) const {
338   // see header file for class documentation
339   return specification=id;
340 }