]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTHOMERManager.cxx
* changed return value for no active service
[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   fProxyHandler(NULL),
55   fReader(NULL),
56   fSourceList(NULL),
57   fBlockList(NULL),
58   fNBlks(0),
59   fEventID(0),
60   fCurrentBlk(0),
61   fConnected(kFALSE),
62   fStateHasChanged(kTRUE) {
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("Initialize of ProxyHandler failed.");
109   }
110   else {
111     iResult = -1;
112     HLTError("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("There have been errors, while creating the sources list.");
140   }
141   else if ( iResult > 0 ) {
142     HLTWarning("No active services found.");
143   }
144   else {
145     HLTInfo("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("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("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("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("Error establishing connection to TCP source %s:%hu: %s (%d)",
216                sourceHostnames[ndx], sourcePorts[ndx], strerror(iResult), iResult);
217     }
218     else {
219       HLTError("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("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("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("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( "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("No Connection to source %d: %s (%d)", 
304                fReader->GetErrorConnectionNdx(), strerror(iResult), iResult);
305       return -iResult;
306     }
307     else if ( iResult == 110 ) {
308       HLTError("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("Retry Failed: Error reading event from source %d: %s (%d)", 
317                  fReader->GetErrorConnectionNdx(), strerror(iResult), iResult);
318         return -iResult;
319       }
320       else {
321         HLTError("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("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("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("Block %lu length: %lu - type: %s - origin: %s",
357             ii, fReader->GetBlockDataLength( ii ), tmp1, tmp2);
358   } // end for ( ULong_t ii = 0; ii < fNBlks; ii++ ) {
359 #endif
360
361   // -- Create BlockList
362   HLTInfo("Create Block List");
363   CreateBlockList();
364
365   return iResult;
366 }
367
368 /*
369  * ---------------------------------------------------------------------------------
370  *                            Connection Handling - private
371  * ---------------------------------------------------------------------------------
372  */
373
374 //##################################################################################
375 void AliHLTHOMERManager::CreateReadoutList( const char** sourceHostnames, UShort_t *sourcePorts, 
376                                             UInt_t &sourceCount, TString detector ){
377   // see header file for class documentation
378
379   AliHLTHOMERSourceDesc * source= NULL;
380
381   // -- Read all sources and check if they should be read out
382   TIter next( fSourceList );
383   while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
384
385     
386
387     // -- If detector name given
388     if ( ! detector.IsNull() ) {
389       // -- Continue if detector name doesn't match
390       if ( detector.CompareTo(source->GetDetector()) )
391         continue;
392     }
393     else {
394       // -- Continue if source is not selected
395       if ( ! source->IsSelected() )
396         continue;
397     }
398     
399     Bool_t exists = kFALSE;
400     
401     // -- Loop over existing entries and check if entry is already in readout list
402     for ( UInt_t ii = 0; ii < sourceCount; ii++ ){
403       if ( !strcmp( sourceHostnames[ii], source->GetHostname().Data() ) 
404            && sourcePorts[ii] == source->GetPort() ) {
405         exists = kTRUE;
406         break;
407       }
408     }
409
410     // -- Add new entires to readout list
411     if ( ! exists ) {
412       sourcePorts[sourceCount] = source->GetPort();
413       sourceHostnames[sourceCount] = source->GetHostname().Data();
414       sourceCount++;
415     }
416
417   } // while ( ( source = (AliHLTHOMERSourceDesc*)next() ) ) {
418
419   fStateHasChanged = kFALSE;
420
421   return;
422 }
423
424 /*
425  * ---------------------------------------------------------------------------------
426  *                            Event Handling
427  * ---------------------------------------------------------------------------------
428  */
429
430
431 //##################################################################################
432 void AliHLTHOMERManager::CreateBlockList() {
433   // see header file for class documentation
434
435   // -- Initialize block list
436   if ( fBlockList != NULL )
437     delete fBlockList;
438   fBlockList = NULL;
439
440   fBlockList = new TList();
441   fBlockList->SetOwner(kTRUE);
442
443   GetFirstBlk();
444
445   // -- Fill block list
446   do {
447
448     // -- Create new block
449     AliHLTHOMERBlockDesc * block = new AliHLTHOMERBlockDesc();
450     block->SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),
451                      GetBlkType(), GetBlkSpecification() );
452     
453     // -- Check sources list if block is requested
454     if ( CheckIfRequested( block ) )
455       fBlockList->Add( block );
456     else {
457       delete block;
458       block = NULL;
459     }
460  
461   } while( GetNextBlk() );
462     
463   return;
464 }
465
466 /*
467  * ---------------------------------------------------------------------------------
468  *                            BlockHandling
469  * ---------------------------------------------------------------------------------
470  */
471
472 //##################################################################################
473 void* AliHLTHOMERManager::GetBlk( Int_t ndx ) {
474   // see header file for class documentation
475   // Get pointer to current block in current event
476    
477   if ( !fReader || !IsConnected() ) {
478     HLTError("Not connected yet.");
479     return NULL;
480   }
481   if ( ndx < static_cast<Int_t>(fNBlks) )
482     return  const_cast<void*> (fReader->GetBlockData(ndx));
483   else
484     return NULL;
485 }
486
487 //##################################################################################
488 ULong_t AliHLTHOMERManager::GetBlkSize( Int_t ndx ) {
489   // see header file for class documentation
490    
491   if ( !fReader || !IsConnected() ) {
492     HLTError("Not connected yet.");
493     return 0;
494   }
495   
496   if ( ndx < static_cast<Int_t>(fNBlks) )
497     return static_cast<ULong_t> (fReader->GetBlockDataLength(ndx));
498   else
499     return 0;
500 }
501
502 //##################################################################################
503 TString AliHLTHOMERManager::GetBlkOrigin( Int_t ndx ) {
504   // see header file for class documentation
505
506   TString origin = "";
507
508   // -- Check for Connection
509   if ( !fReader || ! IsConnected() ) {
510     HLTError("Not connected yet.");
511     return origin;
512   }
513
514   // -- Check block index
515   if ( ndx >= static_cast<Int_t>(fNBlks) ) {
516     HLTError("Block index %d out of range.", ndx );
517     return origin;
518   }
519
520   // -- Get origin
521   union{
522     UInt_t data;
523     Char_t array[4];
524   } reverseOrigin;
525
526   reverseOrigin.data = static_cast<UInt_t>(fReader->GetBlockDataOrigin(ndx));
527
528   // -- Reverse the order
529   for (Int_t ii = 3; ii >= 0; ii-- )
530     if ( reverseOrigin.array[ii] != ' ')
531       origin.Append( reverseOrigin.array[ii] );
532
533   origin.Remove( TString::kTrailing, ' ' );
534
535   return origin;
536 }
537
538 //##################################################################################
539 TString AliHLTHOMERManager::GetBlkType( Int_t ndx ) {
540   // see header file for class documentation
541
542   TString type = "";
543
544   // -- Check for Connection
545   if ( !fReader || ! IsConnected() ) {
546     HLTError("Not connected yet.");
547     return type;
548   }
549
550   // -- Check block index
551   if ( ndx >= static_cast<Int_t>(fNBlks) ) {
552     HLTError("Block index %d out of range.", ndx );
553     return type;
554   }
555
556   // -- Get type
557   union{
558     ULong64_t data;
559     Char_t array[8];
560   } reverseType;
561
562   reverseType.data = static_cast<ULong64_t> (fReader->GetBlockDataType(ndx));
563
564   // -- Reverse the order
565   for (Int_t ii = 7; ii >= 0; ii-- )
566     if ( reverseType.array[ii] != ' ')
567       type.Append( reverseType.array[ii] );
568   
569   type.Remove( TString::kTrailing, ' ' );
570
571   return type;
572 }
573
574 //##################################################################################
575 ULong_t AliHLTHOMERManager::GetBlkSpecification( Int_t ndx ) {
576   // see header file for class documentation
577
578   // -- Check for Connection
579   if ( !fReader || ! IsConnected() ) {
580     HLTError("Not connected yet.");
581     return 0;
582   }
583
584   // -- Check block index
585   if ( ndx >= static_cast<Int_t>(fNBlks) ) {
586     HLTError("Block index %d out of range.", ndx );
587     return 0;
588   }
589
590   return static_cast<ULong_t>(fReader->GetBlockDataSpec(ndx));
591 }
592
593 //##################################################################################
594 Bool_t AliHLTHOMERManager::CheckIfRequested( AliHLTHOMERBlockDesc * block ) {
595   // see header file for class documentation
596
597   Bool_t requested = kFALSE;
598
599   AliHLTHOMERSourceDesc * source= NULL;
600
601   // -- Read all sources and check if they should be read out
602   TIter next( fSourceList );
603   while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
604     
605     // -- Check if source is selected
606     if ( ! source->IsSelected() )
607       continue;
608
609     // -- Check if detector matches
610     if ( source->GetSourceName().CompareTo( block->GetBlockName() ) )
611       continue;
612
613     requested = kTRUE;
614     break;
615
616   } // while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
617   
618 #if EVE_DEBUG
619   if ( requested ) {
620     HLTInfo ("Block requested : %s", block->GetBlockName().Data()); 
621   }
622   else {
623     HLTInfo("Block NOT requested : %s", block->GetBlockName().Data()); 
624   }
625 #endif
626
627   return requested;
628 }
629