Major update required to handle old and new AliHLTEventDDL structures within HLT...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTCalibrationProcessor.cxx
1 /**************************************************************************
2  * This file is property of and copyright by the ALICE HLT Project        * 
3  * ALICE Experiment at CERN, All rights reserved.                         *
4  *                                                                        *
5  * Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
6  *                  Sebastian Bablok                                      *
7  *                  for The ALICE HLT Project.                            *
8  *                                                                        *
9  * Permission to use, copy, modify and distribute this software and its   *
10  * documentation strictly for non-commercial purposes is hereby granted   *
11  * without fee, provided that the above copyright notice appears in all   *
12  * copies and that both the copyright notice and this permission notice   *
13  * appear in the supporting documentation. The authors make no claims     *
14  * about the suitability of this software for any purpose. It is          *
15  * provided "as is" without express or implied warranty.                  *
16  **************************************************************************/
17
18 /** 
19  * @file   AliHLTCalibrationProcessor.cxx
20  * @author Jochen Thaeder, Sebastian Bablok
21  * @date 
22  * @brief  Base class of HLT calibration components.  */
23
24 // see header file for class documentation
25 // or
26 // refer to README to build package
27 // or
28 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
29
30 #if __GNUC__ >= 3
31 using namespace std;
32 #endif
33
34 #include "AliHLTCalibrationProcessor.h"
35 #include "AliHLTMemoryFile.h"
36 #include "AliHLTReadoutList.h"
37
38 #include <cstdlib>
39 #include <cerrno>
40 #include <string.h>
41 #include <TObjString.h>
42 #include <TFile.h>
43
44 ClassImp(AliHLTCalibrationProcessor);
45
46
47 const AliHLTUInt32_t AliHLTCalibrationProcessor::fgkFXSProtocolHeaderSize = 204;
48 const AliHLTUInt32_t AliHLTCalibrationProcessor::fgkFXSProtocolHeaderVersion = 1;
49
50 /*
51  * ################ Constructor / Destructor ####################
52  */
53
54 AliHLTCalibrationProcessor::AliHLTCalibrationProcessor() : 
55   fEventModulo(0),
56   fUseCorruptEvents(kFALSE),
57   fEventCounter(0),
58   fDDLNumber(),
59   fDummy(0) {
60
61   // see header file for class documentation
62   // or
63   // refer to README to build package
64   // or
65   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
66 }
67
68 AliHLTCalibrationProcessor::~AliHLTCalibrationProcessor() {
69   // see header file for class documentation
70 }
71
72 /*
73  * ######################## InitCalibration #####################
74  */
75
76 Int_t AliHLTCalibrationProcessor::DoInit( int argc, const char** argv ) {
77   // see header file for class documentation
78
79   Int_t iResult = 0;
80   TString argument = "";
81   TString parameter = "";
82   Int_t bMissingParam=0;
83   
84   for ( Int_t ii=0; ii<argc && iResult>=0; ii++ ) {
85     argument = argv[ii];
86
87     if ( argument.IsNull() ) continue;
88
89     // -eventmodulo
90     if ( argument.CompareTo("-eventmodulo") == 0 ) {
91       if ( ( bMissingParam=( ++ii >= argc ) ) ) break;
92       parameter = argv[ii];  
93       parameter.Remove(TString::kLeading, ' '); // remove all blanks
94       if (parameter.IsDigit()) {
95         fEventModulo = parameter.Atoi();
96         HLTInfo("EventModulo is set to %d.", fEventModulo);
97       } 
98       else {
99         HLTError("Cannot convert EventModulo specifier '%s'.", argv[ii]);
100         iResult = -EINVAL;
101         break;
102       }
103     } 
104     // -usecorruptevents
105     else if ( argument.CompareTo( "-usecorruptevents" ) == 0 ) {
106       HLTInfo( "Passing through of corrupted events enabled." );
107       fUseCorruptEvents = kTRUE;
108     } 
109     // not known by calibration processor
110     else {
111       if ( ( iResult = ScanArgument( argc-ii, &argv[ii] ) ) == -EINVAL ) {
112         HLTError( "unknown argument %s", argument.Data() );
113         break;
114       } 
115       else if ( iResult == -EPROTO ) {
116         bMissingParam = 1;
117         break;
118       } 
119       else if ( iResult >= 0 ) {
120         ii += iResult;
121         iResult = 0;
122       }
123     }
124   }
125   
126   if ( bMissingParam ) {
127     HLTError( "missing parameter for argument %s", argument.Data() );
128     iResult = -EPROTO;
129   }
130
131   if ( iResult >= 0 ) {
132     iResult = InitCalibration();
133   }
134
135   // Reset the DDLNumberList
136   memset( fDDLNumber, 0, gkAliHLTFXSHeaderfDDLNumberSize);
137
138   return iResult;
139 }
140
141 Int_t AliHLTCalibrationProcessor::InitCalibration() {
142   // see header file for class documentation
143   
144   // fDummy is just touched here to avoid coding convention violation RC11. 
145   // The function can not be declared  const since it is just the default implementation, 
146   // overloaded virtual function might not be const.
147   fDummy = 0;
148
149   return 0;
150 }
151
152
153 Int_t AliHLTCalibrationProcessor::ScanArgument(int argc, const char** argv) {
154   // see header file for class documentation
155   
156   // there are no other arguments than the standard ones
157   if ( argc == 0 && argv == NULL) {
158     // this is just to get rid of the warning "unused parameter"
159   }
160   
161   // fDummy is just touched here to avoid coding convention violation RC11. 
162   // The function can not be declared  const since it is just the default implementation, 
163   // overloaded virtual function might not be const.
164   fDummy = 0;
165
166   return -EINVAL;
167 }
168
169 /*
170  * ######################## DeinitCalibration #####################
171  */
172
173 Int_t AliHLTCalibrationProcessor::DoDeinit() {
174   // see header file for class documentation
175  
176   int iResult = DeinitCalibration();
177  
178   return iResult;
179 }
180
181 Int_t AliHLTCalibrationProcessor::DeinitCalibration() {
182   // see header file for class documentation
183
184   // fDummy is just touched here to avoid coding convention violation RC11. 
185   // The function can not be declared  const since it is just the default implementation, 
186   // overloaded virtual function might not be const.
187   fDummy = 0;
188
189   return 0;
190 }
191
192 /*
193  * ######################## DoEvent #####################
194  */
195
196 Int_t AliHLTCalibrationProcessor::DoEvent( const AliHLTComponentEventData& evtData,
197                const AliHLTComponentBlockData* blocks, 
198                AliHLTComponentTriggerData& trigData,
199                AliHLTUInt8_t* outputPtr, 
200                AliHLTUInt32_t& size,
201                vector<AliHLTComponentBlockData>& outputBlocks )
202 {
203   // see header file for class documentation
204
205   Int_t iResult = 0;
206
207   const AliHLTComponentBlockData* blkSOR = NULL;
208   blkSOR = GetFirstInputBlock( kAliHLTDataTypeSOR );
209   const AliHLTComponentBlockData* blkEOR = NULL;
210   blkEOR = GetFirstInputBlock( kAliHLTDataTypeEOR );
211
212   // ** if event Type is not SOR or EOR -> fill DDLNumber list and process data
213   if ( ! blkEOR  && !blkSOR ) {
214     // ** ProcessData
215     iResult = ProcessCalibration( evtData, blocks, trigData, outputPtr, size, outputBlocks );
216     fEventCounter++; 
217   }  
218
219   // - if event Type is EOR or event modulo is set -> ship data to FXS
220   // - use event modulo ship data also during the run 
221   if ( ( fEventModulo > 0 && fEventCounter == fEventModulo ) || blkEOR ){
222     HLTDebug ( "Ship Data to FXS!" );
223     iResult = ShipDataToFXS( evtData, blocks, trigData, outputPtr, size, outputBlocks );
224     fEventCounter = 0;
225   }
226
227   return iResult;
228 }
229
230 /*
231  * ######################## ProcessCalibration #####################
232  */
233
234 Int_t AliHLTCalibrationProcessor::ProcessCalibration( const AliHLTComponentEventData& evtData,
235                                                       const AliHLTComponentBlockData* /*blocks*/, 
236                                                       AliHLTComponentTriggerData& trigData,
237                                                       AliHLTUInt8_t* /*outputPtr*/, 
238                                                       AliHLTUInt32_t& /*size*/,
239                                                       vector<AliHLTComponentBlockData>& /*outputBlocks*/ ) {
240   // see header file for class documentation
241
242   // we just forward to the high level method, all other parameters already
243   // have been stored internally
244   return ProcessCalibration( evtData, trigData );
245 }
246
247 Int_t AliHLTCalibrationProcessor::ProcessCalibration( const AliHLTComponentEventData& /*evtData*/, 
248                                                       AliHLTComponentTriggerData& /*trigData*/) {
249   // see header file for class documentation
250
251   HLTFatal( "no processing method implemented" );
252   return -ENOSYS;
253 }
254
255 /*
256  * ######################## ShipDataToFXS #####################
257  */
258
259 Int_t AliHLTCalibrationProcessor::ShipDataToFXS( const AliHLTComponentEventData& evtData,
260                                                  const AliHLTComponentBlockData* /*blocks*/, 
261                                                  AliHLTComponentTriggerData& trigData,
262                                                  AliHLTUInt8_t* /*outputPtr*/, 
263                                                  AliHLTUInt32_t& /*size*/,
264                                                  vector<AliHLTComponentBlockData>& /*outputBlocks*/ ) {
265   // see header file for class documentation
266
267   // we just forward to the high level method, all other parameters already
268   // have been stored internally
269   return ShipDataToFXS( evtData, trigData );
270 }
271
272
273 Int_t AliHLTCalibrationProcessor::ShipDataToFXS( const AliHLTComponentEventData& /*evtData*/, 
274                                                  AliHLTComponentTriggerData& /*trigData*/) {
275   // see header file for class documentation
276
277   HLTFatal( "no processing method implemented" );
278   return -ENOSYS;
279 }
280
281 /*
282  * ######################## CreateFXSHeader #####################
283  */
284
285 Int_t AliHLTCalibrationProcessor::CreateFXSHeader( AliHLTFXSHeader &pHeader, const char* pDetector, const char* pFileID, const AliHLTReadoutList* pDDLList ) {
286   // see header file for class documentation
287
288   Int_t iResult = 0;
289
290   // ** Fill header version
291   pHeader.fHeaderVersion = AliHLTCalibrationProcessor::fgkFXSProtocolHeaderVersion;
292
293   // ** Fill run number
294   pHeader.fRunNumber = GetRunNo(); 
295   
296   // ** Fill origin
297   HLTDebug( "FXS Header Detector  size max %i - actual %i .",gkAliHLTFXSHeaderfOriginSize, strlen( pDetector ) );
298   strncpy ( pHeader.fOrigin, pDetector, gkAliHLTFXSHeaderfOriginSize ) ; 
299
300   // To take care if fileIDs which are longer than gkAliHLTFXSHeaderfOriginSize, write one 0 is cheaper than an if.
301   pHeader.fOrigin[gkAliHLTFXSHeaderfOriginSize-1] = 0;
302
303   // ** Fill file ID
304   HLTDebug( "FXS Header FileID size max %i - actual %i .",gkAliHLTFXSHeaderfFileIDSize, strlen( pFileID ) );
305   strncpy ( pHeader.fFileID, pFileID, gkAliHLTFXSHeaderfFileIDSize ) ; 
306
307   // To take care if fileIDs which are longer than gkAliHLTFXSHeaderfFileIDSize, write one 0 is cheaper than an if.
308   pHeader.fFileID[gkAliHLTFXSHeaderfFileIDSize-1] = 0;
309
310   // ** Fill DDL number
311
312   // -- if component provides list, convert to fDDLNumber
313   if ( pDDLList ) {
314     // use user list
315     
316     AliHLTReadoutList::EDetectorId detid = pDDLList->GetFirstUsedDetector();
317     Int_t wordNdx = AliHLTReadoutList::GetFirstWord(detid);
318     Int_t wordCount = AliHLTReadoutList::GetWordCount(detid);
319     
320     if (pDDLList->GetFirstUsedDetector(detid) != AliHLTReadoutList::kNoDetector or wordNdx < 0)
321     {
322       HLTError("DDLIDs for minimum of TWO detectors ( %s, %s ) set, this function works only for ONE detector.",
323           AliHLTReadoutList::DetectorIdToString(detid),
324           AliHLTReadoutList::DetectorIdToString(pDDLList->GetFirstUsedDetector(detid))
325         );
326       iResult = -1;
327     }
328     else
329     {
330       // check word for word 
331       for ( Int_t ndx = 0; ndx < wordCount; ndx++ ) {
332         AliHLTUInt32_t word = pDDLList->Buffer()->fList[wordNdx+ndx];
333         
334         // set only 4 bit into one Char_t
335         for ( Int_t charNdx = 0; charNdx < 8; charNdx++) {
336           fDDLNumber[(8*ndx)+charNdx] = (Char_t) word & 0x0000000F;
337           word = word >> 4;
338         }
339       }
340     }
341   } //   if ( pDDLList ) {
342
343   // -- fill header with ascii chars
344   for (Int_t ndx = 0; ndx < gkAliHLTFXSHeaderfDDLNumberSize; ndx++ ){
345     Int_t numberToChar = (Int_t) fDDLNumber[ndx];
346     // Get ASCII
347     if ( numberToChar > 9 ) numberToChar += 55;
348     else numberToChar += 48;
349     
350     pHeader.fDDLNumber[ndx] = (Char_t) numberToChar;
351   }
352   
353   return iResult;
354 }  // Int_t AliHLTCalibrationProcessor::CreateFXSHeader( AliHLTXSHeader &pHeader, const char* pDetector, const char* pFileID, const AliHLTReadoutList* pDDLList ) {
355
356 /*
357  * ######################## PushToFXS #####################
358  */
359
360 Int_t AliHLTCalibrationProcessor::PushToFXS(TObject* pObject, const char* pDetector, const char* pFileID, const AliHLTReadoutList* pDDLList ) {
361   // see header file for class documentation
362
363   Int_t iResult = 0;
364   
365   AliHLTFXSHeader pHeader;
366
367   CreateFXSHeader( pHeader, pDetector, pFileID, pDDLList );
368   
369   if ( pObject ) {
370     
371     AliHLTMemoryFile* pMemFile = CreateMemoryFile( kAliHLTDataTypeFXSCalib, kAliHLTVoidDataSpec );
372     if ( pMemFile ) {
373       
374       iResult = pMemFile->WriteHeaderBuffer( (const char*) &pHeader, AliHLTCalibrationProcessor::fgkFXSProtocolHeaderSize );
375
376       if ( iResult ) {
377         HLTError( "Buffer size to small - for header!" ); 
378       }
379       else {
380         iResult = Write( pMemFile, pObject );
381         if ( !iResult ) {
382           HLTError( "Buffer size to small - for data!" ); 
383         }
384         else {
385           iResult = CloseMemoryFile( pMemFile );  
386         }
387       }
388     } 
389     else {
390       iResult = -ENOMEM;
391     }
392   } 
393   else {
394     iResult=-EINVAL;
395   }
396
397   return iResult;
398
399 } // Int_t AliHLTCalibrationProcessor::PushToFXS(TObject* pObject, const char* detector, const char* pFileID, const AliHLTReadoutList* pDDLList ) {
400
401 Int_t AliHLTCalibrationProcessor::PushToFXS( void* pBuffer, int iSize, const char* pDetector, const char* pFileID, const AliHLTReadoutList* pDDLList ) {
402   // see header file for class documentation
403
404   Int_t iResult = 0;
405   
406   AliHLTFXSHeader pHeader;
407
408   CreateFXSHeader( pHeader, pDetector, pFileID, pDDLList );
409   
410   iResult = PushBack( pBuffer, iSize, kAliHLTDataTypeFXSCalib, kAliHLTVoidDataSpec, (void*) (&pHeader), AliHLTCalibrationProcessor::fgkFXSProtocolHeaderSize );
411
412   return iResult;
413
414 } // Int_t AliHLTCalibrationProcessor::PushToFXS(void* pBuffer, int iSize, const char* pDdetector, const char* pFileID, const AliHLTReadoutList* pDDLList ) {
415