]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTHOMERManager.cxx
85794e4857e810efa7cd5baaab184325731de168
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTHOMERManager.cxx
1 //-*- Mode: C++ -*-
2 // $Id: AliHLTHOMERManager.cxx  $
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: Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
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   AliHLTHOMERManager.cxx
20     @author Jochen Thaeder
21     @date
22     @brief  Manger for HOMER in aliroot
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 #if __GNUC__>= 3
32    using namespace std;
33 #endif
34
35 #define EVE_DEBUG 1
36
37 #include "AliHLTHOMERManager.h"
38 // -- -- -- -- -- -- -- 
39 #include "AliHLTHOMERLibManager.h"
40 #include "AliHLTHOMERSourceDesc.h"
41 #include "AliHLTHOMERBlockDesc.h"
42 // -- -- -- -- -- -- -- 
43 ClassImp(AliHLTHOMERManager)
44
45 /*
46  * ---------------------------------------------------------------------------------
47  *                            Constructor / Destructor
48  * ---------------------------------------------------------------------------------
49  */
50
51 //##################################################################################
52   AliHLTHOMERManager::AliHLTHOMERManager() :
53   fLibManager(new AliHLTHOMERLibManager),
54   fStateHasChanged(kTRUE),
55   fProxyHandler(NULL),
56   fReader(NULL),
57   fSourceList(NULL),
58   fBlockList(NULL),
59   fNBlks(0),
60   fEventID(0),
61   fCurrentBlk(0),
62   fConnected(kFALSE) {
63   // see header file for class documentation
64   // or
65   // refer to README to build package
66   // or
67   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
68
69 }
70
71 //##################################################################################
72 AliHLTHOMERManager::~AliHLTHOMERManager() {
73   // see header file for class documentation
74
75   if ( fLibManager ) {
76     if ( fReader )
77       fLibManager->DeleteReader(fReader);
78     delete fLibManager;
79     fLibManager = NULL;
80     fReader = NULL;
81   }
82
83   if ( fProxyHandler != NULL )
84     delete fProxyHandler;
85   fProxyHandler = NULL;
86
87   if ( fSourceList != NULL )
88     delete fSourceList;
89   fSourceList = NULL;
90
91   if ( fBlockList != NULL )
92     delete fBlockList;
93   fBlockList = NULL;
94 }
95
96 //##################################################################################
97 Int_t AliHLTHOMERManager::Initialize() {
98   // see header file for class documentation
99
100   Int_t iResult = 0;
101
102   if ( !fProxyHandler )
103     fProxyHandler = new AliHLTHOMERProxyHandler();
104   
105   if ( fProxyHandler ) {
106     iResult = fProxyHandler->Initialize();
107     if (iResult)
108       HLTError(Form("Initialize of ProxyHandler failed."));
109   }
110   else {
111     iResult = -1;
112     HLTError(Form("Creating of ProxyHandler failed."));
113   }
114  
115   return iResult;
116 }
117
118 /*
119  * ---------------------------------------------------------------------------------
120  *                                 Source Handling
121  * ---------------------------------------------------------------------------------
122  */
123
124 //##################################################################################
125 Int_t AliHLTHOMERManager::CreateSourcesList() {
126   // see header file for class documentation
127
128   Int_t iResult = 0;
129   
130   if ( fSourceList != NULL )
131     delete fSourceList;
132   fSourceList = NULL;
133
134   fSourceList = new TList();
135   fSourceList->SetOwner( kTRUE );
136
137   iResult = fProxyHandler->FillSourceList( fSourceList );
138   if ( iResult < 0 ) {
139     HLTWarning(Form("There have been errors, while creating the sources list."));
140   }
141   else if ( iResult > 0 ) {
142     HLTWarning(Form("No active services found."));
143   }
144   else {
145      HLTInfo(Form("New sources list created."));
146
147     // -- New SourceList has been created 
148     // --> All Sources are new --> State has changed
149     fStateHasChanged = kTRUE;
150   }
151
152   return iResult;
153 }
154
155 //##################################################################################
156 void AliHLTHOMERManager::SetSourceState( AliHLTHOMERSourceDesc * source, Bool_t state ) {
157   // see header file for class documentation
158
159   if ( source->IsSelected() != state ) {
160     source->SetState( state );
161     fStateHasChanged = kTRUE;
162   }
163
164   return;
165 }
166
167 /*
168  * ---------------------------------------------------------------------------------
169  *                         Connection Handling -oublic
170  * ---------------------------------------------------------------------------------
171  */
172
173 //##################################################################################
174 Int_t AliHLTHOMERManager::ConnectHOMER( TString detector ){
175   // see header file for class documentation
176
177   Int_t iResult = 0;
178
179   // -- Check if already connected and state has not changed
180   if ( fStateHasChanged == kFALSE && IsConnected() ) {
181     HLTInfo(Form("No need for reconnection."));
182     return iResult;
183   }
184
185   // -- If already connected, disconnect before connect
186   if ( IsConnected() )
187     DisconnectHOMER();
188
189   // -- Create the Readoutlist
190   UShort_t* sourcePorts = new UShort_t [fSourceList->GetEntries()];
191   const char ** sourceHostnames = new const char* [fSourceList->GetEntries()];
192   UInt_t sourceCount = 0;
193
194   CreateReadoutList( sourceHostnames, sourcePorts, sourceCount, detector );
195   if ( sourceCount == 0 ) {
196     HLTError(Form("No sources selected, aborting."));
197     return -1;
198   }
199
200   // *** Connect to data sources
201   if ( !fReader && fLibManager )
202     fReader = fLibManager->OpenReader( sourceCount, sourceHostnames, sourcePorts );
203   else {
204     HLTError(Form("No LibManager present."));
205     return -2;
206   }
207     
208   iResult = fReader->GetConnectionStatus();
209   if ( iResult ) {
210     // -- Connection failed
211
212     UInt_t ndx = fReader->GetErrorConnectionNdx();
213
214     if ( ndx < sourceCount ) {
215       HLTError(Form("Error establishing connection to TCP source %s:%hu: %s (%d)",
216                     sourceHostnames[ndx], sourcePorts[ndx], strerror(iResult), iResult));
217     }
218     else {
219       HLTError(Form("Error establishing connection to unknown source with index %d: %s (%d)",
220                     ndx, strerror(iResult), iResult));
221     }
222
223     if ( fReader )
224       fLibManager->DeleteReader( fReader );
225     fReader = NULL;
226   }
227   else {
228     // -- Connection ok - set reader
229     fConnected = kTRUE;
230
231     HLTInfo(Form("Connection established."));
232   }
233
234   delete[] sourceHostnames;
235   delete[] sourcePorts;
236
237   return iResult;
238 }
239
240 //##################################################################################
241 void AliHLTHOMERManager::DisconnectHOMER(){
242   // see header file for class documentation
243
244   if ( ! IsConnected() )
245     return;
246
247   if ( fReader )
248     fLibManager->DeleteReader( fReader );
249   fReader = NULL;
250
251   fStateHasChanged = kTRUE;
252   fConnected = kFALSE;
253
254   HLTInfo(Form("Connection closed."));
255
256   return;
257 }
258
259 //##################################################################################
260 Int_t AliHLTHOMERManager::ReconnectHOMER( TString detector="" ){
261   // see header file for class documentation
262   
263   Int_t iResult = 0;
264
265   if ( IsConnected() )
266     DisconnectHOMER();
267
268   iResult = ConnectHOMER(detector);
269   if ( iResult ) {
270     HLTError(Form("Error reconnecting."));
271   }
272
273   return iResult;
274 }
275
276 /*
277  * ---------------------------------------------------------------------------------
278  *                            Event Handling - public
279  * ---------------------------------------------------------------------------------
280  */
281
282
283 //##################################################################################
284 Int_t AliHLTHOMERManager::NextEvent(){
285   // see header file for class documentation
286
287   Int_t iResult = 0;
288   Int_t iRetryCount = 0;
289
290   if ( !fReader || ! IsConnected() ) {
291     HLTWarning(Form( "Not connected yet." ));
292     return -1;
293   }
294
295   //  fReader->SetEventRequestAdvanceTime( 20000000 /*timeout in us*/ );
296
297   // -- Read next event data and error handling for HOMER (error codes and empty blocks)
298   while( 1 ) {
299     
300     iResult = fReader->ReadNextEvent( 40000000 /*timeout in us*/);
301
302     if ( iResult == 111 || iResult == 32 || iResult == 6 ) {
303       HLTError(Form("No Connection to source %d: %s (%d)", 
304                     fReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
305       return -iResult;
306     }
307     else if ( iResult == 110 ) {
308       HLTError(Form("Timout occured, reading event from source %d: %s (%d)", 
309                     fReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
310       return -iResult;
311     }
312     else if ( iResult == 56) {
313       ++iRetryCount;
314
315       if ( iRetryCount >= 20 ) {
316         HLTError(Form("Retry Failed: Error reading event from source %d: %s (%d)", 
317                       fReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
318         return -iResult;
319       }
320       else {
321         HLTError(Form("Retry: Error reading event from source %d: %s (%d)", 
322                       fReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
323         continue;
324       }
325     }
326     else if ( iResult ) {
327       HLTError(Form("General Error reading event from source %d: %s (%d)", 
328                     fReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
329       fConnected = kFALSE;
330       return -iResult;
331     }
332     else {
333       break;
334     }
335   } // while( 1 ) {
336
337   // -- Get blockCnt and eventID
338   fNBlks = static_cast<ULong_t>(fReader->GetBlockCnt());
339   fEventID = static_cast<ULong64_t>(fReader->GetEventID());
340   fCurrentBlk = 0;
341
342   HLTInfo(Form("Event 0x%016LX (%Lu) with %lu blocks", fEventID, fEventID, fNBlks));
343
344 #if EVE_DEBUG
345   // Loop for Debug only
346   for ( ULong_t ii = 0; ii < fNBlks; ii++ ) {
347     Char_t tmp1[9], tmp2[5];
348     memset( tmp1, 0, 9 );
349     memset( tmp2, 0, 5 );
350     void *tmp11 = tmp1;
351     ULong64_t* tmp12 = static_cast<ULong64_t*>(tmp11);
352     *tmp12 = fReader->GetBlockDataType(ii);
353     void *tmp21 = tmp2;
354     ULong_t* tmp22 = static_cast<ULong_t*>(tmp21);
355     *tmp22 = fReader->GetBlockDataOrigin(ii);
356     HLTInfo(Form( "Block %lu length: %lu - type: %s - origin: %s - spec 0x%08X",
357                   ii, fReader->GetBlockDataLength(ii), tmp1, tmp2, fReader->GetBlockDataSpec(ii) ));
358   } // end for ( ULong_t ii = 0; ii < fNBlks; ii++ ) {
359 #endif
360
361   // -- Create BlockList
362   if ( fNBlks > 0 ) {
363     HLTInfo(Form("Create Block List"));
364     CreateBlockList();
365   }
366   else {
367     HLTWarning(Form("Event 0x%016LX (%Lu) with %lu blocks", fEventID, fEventID, fNBlks));
368   }
369     
370   return iResult;
371 }
372
373 /*
374  * ---------------------------------------------------------------------------------
375  *                            Connection Handling - private
376  * ---------------------------------------------------------------------------------
377  */
378
379 //##################################################################################
380 void AliHLTHOMERManager::CreateReadoutList( const char** sourceHostnames, UShort_t *sourcePorts, 
381                                             UInt_t &sourceCount, TString detector ){
382   // see header file for class documentation
383
384   AliHLTHOMERSourceDesc * source= NULL;
385
386   // -- Read all sources and check if they should be read out
387   TIter next( fSourceList );
388   while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
389
390     // -- If detector NO detector name given
391     if ( ! detector.CompareTo("ALL") ) {
392       // -- Continue if source is not selected
393       if ( ! source->IsSelected() )
394         continue;
395     }
396     // -- DetectorName given
397     else {
398       // -- Continue if detector name doesn't match
399       if ( detector.CompareTo(source->GetDetector()) )
400         continue;
401       else
402         source->Select();
403     }
404     
405     Bool_t exists = kFALSE;
406     
407     // -- Loop over existing entries and check if entry is already in readout list
408     for ( UInt_t ii = 0; ii < sourceCount; ii++ ){
409       if ( !strcmp( sourceHostnames[ii], source->GetHostname().Data() ) 
410            && sourcePorts[ii] == source->GetPort() ) {
411         exists = kTRUE;
412         break;
413       }
414     }
415
416     // -- Add new entires to readout list
417     if ( ! exists ) {
418       sourcePorts[sourceCount] = source->GetPort();
419       sourceHostnames[sourceCount] = source->GetHostname().Data();
420       sourceCount++;
421     }
422
423   } // while ( ( source = (AliHLTHOMERSourceDesc*)next() ) ) {
424
425   fStateHasChanged = kFALSE;
426
427   return;
428 }
429
430 /*
431  * ---------------------------------------------------------------------------------
432  *                            Event Handling
433  * ---------------------------------------------------------------------------------
434  */
435
436
437 //##################################################################################
438 void AliHLTHOMERManager::CreateBlockList() {
439   // see header file for class documentation
440
441   // -- Initialize block list
442   if ( fBlockList != NULL )
443     delete fBlockList;
444   fBlockList = NULL;
445
446   fBlockList = new TList();
447   fBlockList->SetOwner(kTRUE);
448
449   GetFirstBlk();
450
451   // -- Fill block list
452   do {
453
454     // -- Create new block
455     AliHLTHOMERBlockDesc * block = new AliHLTHOMERBlockDesc();
456     block->SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),
457                      GetBlkType(), GetBlkSpecification() );
458     
459     // -- Check sources list if block is requested
460     if ( CheckIfRequested( block ) ) {
461       fBlockList->Add( block );
462       
463     }
464     else {
465       delete block;
466       block = NULL;
467     }
468  
469   } while( GetNextBlk() );
470     
471   return;
472 }
473
474 /*
475  * ---------------------------------------------------------------------------------
476  *                            BlockHandling
477  * ---------------------------------------------------------------------------------
478  */
479
480 //##################################################################################
481 void* AliHLTHOMERManager::GetBlk( Int_t ndx ) {
482   // see header file for class documentation
483   // Get pointer to current block in current event
484    
485   if ( !fReader || !IsConnected() ) {
486     HLTError(Form("Not connected yet."));
487     return NULL;
488   }
489   if ( ndx < static_cast<Int_t>(fNBlks) )
490     return  const_cast<void*> (fReader->GetBlockData(ndx));
491   else
492     return NULL;
493 }
494
495 //##################################################################################
496 ULong_t AliHLTHOMERManager::GetBlkSize( Int_t ndx ) {
497   // see header file for class documentation
498    
499   if ( !fReader || !IsConnected() ) {
500     HLTError(Form("Not connected yet."));
501     return 0;
502   }
503   
504   if ( ndx < static_cast<Int_t>(fNBlks) )
505     return static_cast<ULong_t> (fReader->GetBlockDataLength(ndx));
506   else
507     return 0;
508 }
509
510 //##################################################################################
511 TString AliHLTHOMERManager::GetBlkOrigin( Int_t ndx ) {
512   // see header file for class documentation
513
514   TString origin = "";
515
516   // -- Check for Connection
517   if ( !fReader || ! IsConnected() ) {
518     HLTError(Form("Not connected yet."));
519     return origin;
520   }
521
522   // -- Check block index
523   if ( ndx >= static_cast<Int_t>(fNBlks) ) {
524     HLTError(Form("Block index %d out of range.", ndx ));
525     return origin;
526   }
527
528   // -- Get origin
529   union{
530     UInt_t data;
531     Char_t array[4];
532   } reverseOrigin;
533
534   reverseOrigin.data = static_cast<UInt_t>(fReader->GetBlockDataOrigin(ndx));
535
536   // -- Reverse the order
537   for (Int_t ii = 3; ii >= 0; ii-- )
538     if ( reverseOrigin.array[ii] != ' ')
539       origin.Append( reverseOrigin.array[ii] );
540
541   origin.Remove( TString::kTrailing, ' ' );
542
543   return origin;
544 }
545
546 //##################################################################################
547 TString AliHLTHOMERManager::GetBlkType( Int_t ndx ) {
548   // see header file for class documentation
549
550   TString type = "";
551
552   // -- Check for Connection
553   if ( !fReader || ! IsConnected() ) {
554     HLTError(Form("Not connected yet."));
555     return type;
556   }
557
558   // -- Check block index
559   if ( ndx >= static_cast<Int_t>(fNBlks) ) {
560     HLTError(Form("Block index %d out of range.", ndx ));
561     return type;
562   }
563
564   // -- Get type
565   union{
566     ULong64_t data;
567     Char_t array[8];
568   } reverseType;
569
570   reverseType.data = static_cast<ULong64_t> (fReader->GetBlockDataType(ndx));
571
572   // -- Reverse the order
573   for (Int_t ii = 7; ii >= 0; ii-- )
574     if ( reverseType.array[ii] != ' ')
575       type.Append( reverseType.array[ii] );
576   
577   type.Remove( TString::kTrailing, ' ' );
578
579   return type;
580 }
581
582 //##################################################################################
583 ULong_t AliHLTHOMERManager::GetBlkSpecification( Int_t ndx ) {
584   // see header file for class documentation
585
586   // -- Check for Connection
587   if ( !fReader || ! IsConnected() ) {
588     HLTError(Form("Not connected yet."));
589     return 0;
590   }
591
592   // -- Check block index
593   if ( ndx >= static_cast<Int_t>(fNBlks) ) {
594     HLTError(Form("Block index %d out of range.", ndx ));
595     return 0;
596   }
597
598   return static_cast<ULong_t>(fReader->GetBlockDataSpec(ndx));
599 }
600
601 //##################################################################################
602 Bool_t AliHLTHOMERManager::CheckIfRequested( AliHLTHOMERBlockDesc * block ) {
603   // see header file for class documentation
604
605   Bool_t requested = kFALSE;
606
607   AliHLTHOMERSourceDesc * source= NULL;
608
609   // -- Read all sources and check if they should be read out
610   TIter next( fSourceList );
611   while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
612     
613     // -- Check if source is selected
614     if ( ! source->IsSelected() )
615       continue;
616         
617     // -- Check if detector matches
618     if ( source->GetSourceName().CompareTo( block->GetBlockName() ) )
619       continue;
620
621     requested = kTRUE;
622     break;
623
624   } // while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
625   
626 #if 0 //EVE_DEBUG
627   if ( requested ) {
628     HLTInfo(Form("Block requested : %s", block->GetBlockName().Data())); 
629   }
630   else {
631     HLTInfo(Form("Block NOT requested : %s", block->GetBlockName().Data())); 
632   }
633 #endif
634
635   return requested;
636 }
637