508406978bccd186a329b0e56b207acbee6cdd88
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTHOMERManager.cxx
1 //-*- Mode: C++ -*-
2 // $Id$
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 0
36
37 #include "AliHLTHOMERManager.h"
38 // -- -- -- -- -- -- -- 
39 #include "AliHLTHOMERLibManager.h"
40 #include "AliHLTHOMERSourceDesc.h"
41 #include "AliHLTHOMERBlockDesc.h"
42 // -- -- -- -- -- -- -- 
43 #include "AliHLTGlobalTriggerDecision.h"
44 #include "AliHLTTriggerDecision.h"
45 //---------------------------
46
47 ClassImp(AliHLTHOMERManager)
48
49 /*
50  * ---------------------------------------------------------------------------------
51  *                            Constructor / Destructor
52  * ---------------------------------------------------------------------------------
53  */
54
55 //##################################################################################
56   AliHLTHOMERManager::AliHLTHOMERManager() :
57   fLibManager(new AliHLTHOMERLibManager),
58   fStateHasChanged(kTRUE),
59   fProxyHandler(NULL),
60   fCurrentReader(NULL),
61   fReaderList(NULL),
62   fSourceList(NULL),
63   fNBlks(0),
64   fEventID(),
65   fEventId(-1),
66   fCurrentBlk(0),
67   fAsyncBlockList(NULL),
68   fBlockList(NULL),
69    fEventBuffer(NULL),
70   fBufferTopIdx(-1),
71   fBufferLowIdx(-1),
72   fCurrentBufferIdx(-1),
73   fNavigateBufferIdx(-1),
74   fNEventsAvailable(0),
75   fConnected(kFALSE), 
76   fTriggerString("ALL"), 
77   fNEventsNotTriggered(0),
78   fRetryNextEvent(kFALSE),
79   fIsBlockOwner(kTRUE)
80 {
81   // see header file for class documentation
82   // or
83   // refer to README to build package
84   // or
85   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
86
87 }
88
89 //##################################################################################
90 AliHLTHOMERManager::~AliHLTHOMERManager() {
91   // see header file for class documentation
92
93   if ( fLibManager ) {
94
95     if ( fReaderList ) {
96       TIter next(fReaderList);
97       TObject * object = NULL;
98       while ( ( object = next()) )
99         fLibManager->DeleteReader(static_cast<AliHLTHOMERReader*>(object) );
100       
101       fReaderList->Clear();
102       delete fReaderList;
103     }
104     fReaderList = NULL;   
105     
106     delete fLibManager;
107   } 
108   fLibManager = NULL;
109
110   if ( fProxyHandler != NULL )
111     delete fProxyHandler;
112   fProxyHandler = NULL;
113
114   if ( fSourceList != NULL )
115     delete fSourceList;
116   fSourceList = NULL;
117
118   if ( fEventBuffer ) {
119     fEventBuffer->Clear();
120     delete fEventBuffer;
121   }
122   fEventBuffer = NULL;
123
124   if(fBlockList) {
125     fBlockList->Clear();
126     delete fBlockList;
127   }
128   fBlockList = NULL;
129
130   if ( fAsyncBlockList ) {
131     fAsyncBlockList->Clear();
132     delete fAsyncBlockList;
133   }
134   fAsyncBlockList = NULL;
135 }
136
137 //##################################################################################
138 Int_t AliHLTHOMERManager::Initialize() {
139   // see header file for class documentation
140
141   HLTInfo("Initializing");
142
143   Int_t iResult = 0;
144
145   // -- Initialize ProxyHandler
146   if ( !fProxyHandler )
147     fProxyHandler = new AliHLTHOMERProxyHandler();
148   
149   if ( fProxyHandler ) {
150     iResult = fProxyHandler->Initialize();
151     if (iResult)
152       HLTError(Form("Initialize of ProxyHandler failed."));
153   
154   } else {
155     iResult = -1;
156     HLTError(Form("Creating of ProxyHandler failed."));
157   }
158  
159   // -- Initialize ReaderList
160   //    List ist not owner, as reader have to be created/deleted by the LibManager
161   if( !fReaderList )
162     fReaderList = new TList();
163   
164   // -- Initialize asynchronous BlockList
165   if( !fAsyncBlockList ) {
166     fAsyncBlockList = new TList();
167     fAsyncBlockList->SetOwner(kTRUE);
168   }
169
170   //initialize normal block list
171   if( !fBlockList ) {
172     fBlockList = new TList();
173     fBlockList->SetOwner(kFALSE);
174   }
175
176   // -- Initialize Event Buffer and EventID array
177   if ( !fEventBuffer ) {
178     fEventBuffer = new TClonesArray( "TList", BUFFERSIZE );
179   }
180
181   for ( Int_t idx = 0; idx < BUFFERSIZE; ++idx ) {
182     new ((*fEventBuffer)[idx]) TList( );
183     (reinterpret_cast<TList*>((*fEventBuffer)[idx]))->SetOwner(kTRUE);
184     
185     fEventID[idx] = 0;
186   }
187
188   return iResult;
189 }
190
191 /*
192  * ---------------------------------------------------------------------------------
193  *                                 Source Handling
194  * ---------------------------------------------------------------------------------
195  */
196
197 //##################################################################################
198 Int_t AliHLTHOMERManager::CreateSourcesList() {
199   // see header file for class documentation
200
201   Int_t iResult = 0;
202
203   if ( fSourceList != NULL )
204     delete fSourceList;
205   fSourceList = NULL;
206
207   fSourceList = new TList();
208   fSourceList->SetOwner( kTRUE );
209
210   iResult = fProxyHandler->FillSourceList( fSourceList );
211   if ( iResult < 0 ) {
212     HLTWarning(Form("There have been errors, while creating the sources list."));
213   }
214   else if ( iResult > 0 ) {
215     HLTWarning(Form("No active services found."));
216   }
217   else if ( fSourceList->IsEmpty() ) {
218     HLTWarning(Form("No active services in the list."));
219     iResult = 2;
220   }
221   else {
222      HLTInfo(Form("New sources list created."));
223
224     // -- New SourceList has been created 
225     // --> All Sources are new --> State has changed
226     fStateHasChanged = kTRUE;
227   }
228
229   return iResult;
230 }
231
232 //##################################################################################
233 void AliHLTHOMERManager::SetSourceState( AliHLTHOMERSourceDesc * source, Bool_t state ) {
234   // see header file for class documentation
235
236   if ( source->IsSelected() != state ) {
237     source->SetState( state );
238     fStateHasChanged = kTRUE;
239   }
240
241   return;
242 }
243
244 /*
245  * ---------------------------------------------------------------------------------
246  *                         Connection Handling - public
247  * ---------------------------------------------------------------------------------
248  */
249
250 //##################################################################################
251 Int_t AliHLTHOMERManager::ConnectHOMER( TString detector ){
252   // see header file for class documentation
253
254   Int_t iResult = 0;
255
256   // HAck Jochen
257   //----
258   detector="ALL";
259
260   // -- Check if LibManager is present
261   if ( ! fLibManager ) {
262     HLTError(Form("No LibManager present."));
263     return -1;
264   }
265   
266   // -- Check if already connected and state has not changed
267   if ( fStateHasChanged == kFALSE && IsConnected() ) {
268     HLTInfo(Form("No need for reconnection."));
269     return 0;
270   }
271   
272   // -- If already connected, disconnect before connect
273   //    or if ReaderList already filled
274   if ( IsConnected() || fReaderList->GetSize() != 0 ) {
275     HLTInfo(Form("IsConnected: %d      fReaderList.Size:   %d", IsConnected(), fReaderList->GetSize()));
276     DisconnectHOMER();
277   }
278   // -- Create the Readoutlist
279   UShort_t* sourcePorts = new UShort_t [fSourceList->GetEntries()];
280   const Char_t ** sourceHostnames = new const Char_t* [fSourceList->GetEntries()];
281   UInt_t sourceCount = 0;
282
283   CreateReadoutList( sourceHostnames, sourcePorts, sourceCount, detector );
284   if ( sourceCount == 0 ) {
285     HLTError(Form("No sources selected, aborting."));
286     return -2;
287   }
288
289   // ***
290   // *** Connect to data sources
291   // ***
292   
293   for (UInt_t idx = 0; idx < sourceCount; idx++) {
294     
295     if (sourcePorts[idx] > 60000)
296       continue;
297
298     HLTInfo(Form("Adding source %d as %s : %d", idx, sourceHostnames[idx], sourcePorts[idx]));
299     
300     fReaderList->Add(dynamic_cast<TObject*>(fLibManager->OpenReader(sourceHostnames[idx], sourcePorts[idx])));
301     AliHLTHOMERReader *reader = static_cast<AliHLTHOMERReader*>(fReaderList->Last());
302     if ( !reader ) {
303       HLTError(Form("Adding reader failed, aborting"));
304       return -3;
305     }
306
307     if ( (iResult = reader->GetConnectionStatus()) )  {
308
309       // -- Connection to source failed
310       
311       HLTError(Form("Error establishing connection to TCP source %s:%hu: %s (%d)",
312                     sourceHostnames[idx], sourcePorts[idx], strerror(iResult), iResult));
313
314       if( !(TString(sourceHostnames[idx]).CompareTo("localhost")) ) {
315         HLTInfo("The failed connection is on localhost. is SSH tunnel up????? ");
316         HLTInfo(Form("Do: 'ssh -L %d:alihlt-vobox0.cern.ch:%d cernUser@lxplus.cern.ch -fN'",
317                      sourcePorts[idx], sourcePorts[idx]));
318       }
319       
320       // -- Remove reader
321       fReaderList->RemoveLast();
322
323       if ( reader )
324         fLibManager->DeleteReader( reader );
325       reader = NULL;
326       
327       HLTInfo(Form("Removed source %d,  %s : %d from sourceList", idx, sourceHostnames[idx], sourcePorts[idx]));
328       
329     } 
330     else {
331       // -- Connection succeded
332       fConnected = kTRUE;
333
334       HLTInfo(Form("Connection established to source %s on port %d", sourceHostnames[idx], sourcePorts[idx]));
335     }
336     
337   } // for (Int_t idx = 0; idx < sourceCount; idx++) {
338   
339   delete[] sourceHostnames;
340   delete[] sourcePorts;
341
342   return iResult;
343
344 }
345
346 //##################################################################################
347 void AliHLTHOMERManager::DisconnectHOMER(){
348   // see header file for class documentation
349
350   HLTInfo("Disconnecting");
351
352   if ( fReaderList && fLibManager ) {
353     HLTInfo("Deleting readerlist and libmanager");
354     TIter next(fReaderList);
355     TObject * object = NULL;
356     while ( ( object = next()) ) 
357       fLibManager->DeleteReader(static_cast<AliHLTHOMERReader*>(object) );
358       
359
360     HLTInfo(Form("fReaderList size %d", fReaderList->GetSize()));
361     fReaderList->Clear();
362     HLTInfo(Form("fReaderList size %d", fReaderList->GetSize()));
363     delete fReaderList;
364     fReaderList = new TList ();
365     HLTInfo(Form("fReaderList size %d", fReaderList->GetSize()));
366   }
367   
368   fStateHasChanged = kTRUE;
369   fConnected = kFALSE;
370   
371   HLTInfo(Form("Connection closed."));
372
373   return;
374 }
375
376 //##################################################################################
377 Int_t AliHLTHOMERManager::ReconnectHOMER( TString detector="" ){
378   // see header file for class documentation
379   
380   Int_t iResult = 0;
381
382   if ( IsConnected() )
383     DisconnectHOMER();
384
385   iResult = ConnectHOMER(detector);
386   if ( iResult ) {
387     HLTError(Form("Error reconnecting."));
388   }
389
390   return iResult;
391 }
392
393 /*
394  * ---------------------------------------------------------------------------------
395  *                            Event Handling - public
396  * ---------------------------------------------------------------------------------
397  */
398
399 //##################################################################################
400 Int_t AliHLTHOMERManager::NextEvent(){
401  
402   // see header file for class documentation
403   
404   Int_t iResult = 0;
405   Int_t iRetryCount = 0;
406   
407   if ( !IsConnected() || fStateHasChanged ) {
408     HLTInfo("Not connected or state has changed, returning to AliEveHOMERManager, which will deal with this situation");
409     //    cout << "connectecd  " << IsConnected()  << "haschanged  "<<fStateHasChanged << endl;
410     return 55;//ConnectHOMER();
411   }
412   if ( !IsConnected() ) {
413     HLTWarning(Form( "Not connected yet." ));
414     return -1;
415   }
416
417   // -- Reset asyncronous BlockList
418   fAsyncBlockList->Clear();
419
420   // ***
421   // *** Loop over all readers and get new event data
422   // ***
423   
424   TIter next(fReaderList);
425   TObject * object = NULL;
426   
427   while( (object = next()) ) {
428     
429     fCurrentReader = static_cast<AliHLTHOMERReader*>(object);
430     
431     // -- Read next event data and error handling for HOMER (error codes and empty blocks)
432     while ( 1 ) {
433       
434       iResult = fCurrentReader->ReadNextEvent( 40000000 /*timeout in us*/);
435       
436       if ( iResult == 111 || iResult == 32 || iResult == 6 ) {
437         HLTError(Form("No connection to source %d: %s (%d)", 
438                       fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
439         break;
440       } 
441       else if ( iResult == 110 ) {
442         HLTError(Form("Timeout occured, reading event from source %d: %s (%d)", 
443                       fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
444         break;
445       } 
446       else if ( iResult == 56 ) {
447         ++iRetryCount;
448       
449         if ( iRetryCount >= 20 ) {
450           HLTError(Form("Retry Failed: Error reading event from source %d: %s (%d), returning", 
451                         fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
452           break;
453         } 
454         else {
455           HLTError(Form("Retry: Error reading event from source %d: %s (%d), making another attempt (no %d out of 20)", 
456                         fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult, iRetryCount));
457           //break;
458           continue;
459         }
460       }
461       else if ( iResult ) {
462         HLTError(Form("General Error reading event from source %d: %s (%d), giving up", 
463                       fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
464         fConnected = kFALSE;
465         break;
466       } 
467       else {
468         HLTDebug("Successfully read out event from source");
469         break;
470       }
471
472     } // while( 1 ) {
473     
474     // -- Check if event could be read
475     if ( iResult ) {
476       HLTInfo("Reading event from source failed");
477       continue;
478     }
479
480     // -- Handle Blocks from current reader
481     iResult = HandleBlocks();
482     if ( iResult ) {
483       HLTError(Form("Handling of blocks failed."));
484     }
485
486   } // while( (object = next()) ) {
487
488   return 0;  
489 }
490
491 /* ---------------------------------------------------------------------------------
492  *                           Buffer Handling - public
493  * ---------------------------------------------------------------------------------
494  */
495
496 //##################################################################################
497 Int_t AliHLTHOMERManager::NavigateEventBufferBack() { 
498   // see header file for class documentation
499
500   // -- reached the end of the buffer
501   if ( fNavigateBufferIdx == fBufferLowIdx )
502     return -1;
503
504   Int_t newIdx = fNavigateBufferIdx - 1;
505   if ( newIdx == -1 )
506     newIdx = BUFFERSIZE-1;
507
508   fCurrentBufferIdx = fNavigateBufferIdx = newIdx;
509
510   return newIdx;
511 }
512
513 //##################################################################################
514 Int_t AliHLTHOMERManager::NavigateEventBufferFwd() {
515   // see header file for class documentation
516
517   HLTInfo(Form("fNavigateBufferIdx: %d, fCurrentBufferIdx %d, fBufferTopIdx %d", fNavigateBufferIdx, fCurrentBufferIdx, fBufferTopIdx));
518
519   // -- reached the top of the buffer
520   if ( fNavigateBufferIdx == fBufferTopIdx )
521     return -1;
522
523   Int_t newIdx = fNavigateBufferIdx + 1;
524   if ( newIdx == BUFFERSIZE )
525     newIdx = 0;
526   
527   fCurrentBufferIdx = fNavigateBufferIdx = newIdx;
528   fNEventsAvailable -= 1;
529
530   HLTInfo(Form("fNavigateBufferIdx: %d, fCurrentBufferIdx %d, fBufferTopIdx %d", fNavigateBufferIdx, fCurrentBufferIdx, fBufferTopIdx));
531
532
533   return 0;
534 }
535
536  ///////////////////////////////////////////////////////////////////////////////////
537
538 /*
539  * ---------------------------------------------------------------------------------
540  *                            Connection Handling - private
541  * ---------------------------------------------------------------------------------
542  */
543
544 //##################################################################################
545 void AliHLTHOMERManager::CreateReadoutList( const char** sourceHostnames, UShort_t *sourcePorts, 
546                                             UInt_t &sourceCount, TString detector ){
547   // see header file for class documentation
548
549   AliHLTHOMERSourceDesc * source= NULL;
550
551   // -- Read all sources and check if they should be read out
552   TIter next( fSourceList );
553   while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
554
555     ///Don't use sources from dev cluster
556     if(source->GetPort() > 60000) continue;
557
558     // -- If detector NO detector name given
559     if ( ! detector.CompareTo("ALL") ) {
560       // -- Continue if source is not selected
561       // HACK Jochen
562       //if ( ! source->IsSelected() )
563       //        continue;
564     }
565     // -- DetectorName given
566     else {
567       // -- Continue if detector name doesn't match
568       if ( detector.CompareTo(source->GetDetector()) )
569         continue;
570       else
571         source->Select();
572     }
573     
574     Bool_t exists = kFALSE;
575     
576     // -- Loop over existing entries and check if entry is already in readout list
577     for ( UInt_t ii = 0; ii < sourceCount; ii++ ){
578       if ( !strcmp( sourceHostnames[ii], source->GetHostname().Data() ) 
579            && sourcePorts[ii] == source->GetPort() ) {
580         exists = kTRUE;
581         break;
582       }
583     }
584
585     // -- Add new entires to readout list
586     if ( ! exists ) {
587       sourcePorts[sourceCount] = source->GetPort();
588       sourceHostnames[sourceCount] = source->GetHostname().Data();
589       sourceCount++;
590     }
591
592   } // while ( ( source = (AliHLTHOMERSourceDesc*)next() ) ) {
593
594   fStateHasChanged = kFALSE;
595
596   return;
597 }
598
599 /*
600  * ---------------------------------------------------------------------------------
601  *                          Buffer Handling - private
602  * ---------------------------------------------------------------------------------
603  */
604
605 //##################################################################################
606 void AliHLTHOMERManager::AddBlockListToBuffer() {
607   // see header file for class documentation
608   // -- Check if event is already in buffer
609   ULong_t eventID = static_cast<ULong64_t>(fCurrentReader->GetEventID());  
610   
611   if ( fEventID[fBufferTopIdx] == eventID ) {
612     HLTInfo(Form("Event 0x%016lX (%lu) already in buffer.", eventID, eventID));
613     return;
614   }
615
616   // -- Check if event should be selected on basis of trigger string
617   if( fTriggerString.CompareTo("ALL") ){
618     if ( !CheckTriggerDecision() ) {
619       HLTInfo("Event not triggered");
620       return;
621     } else {
622       HLTInfo("Event triggered");
623     }
624   }
625   else {
626     HLTDebug("No trigger selection.");
627   }
628
629   // -- Set Top mark 
630   ++fBufferTopIdx;
631   if ( fBufferTopIdx == BUFFERSIZE )
632     fBufferTopIdx = 0;
633
634   // -- Change the low mark if necessary
635   if ( fBufferLowIdx == -1 )
636     fBufferLowIdx = 0;
637   else if ( fBufferTopIdx == fBufferLowIdx ) {
638     ++fBufferLowIdx;
639     if ( fBufferLowIdx == BUFFERSIZE )
640       fBufferLowIdx = 0;
641   }
642
643
644   // -- Fill EventID
645   fEventID[fBufferTopIdx] = eventID;
646
647   // -- Clear Buffer slot
648   (reinterpret_cast<TList*>((*fEventBuffer)[fBufferTopIdx]))->Clear();
649   if(fBlockList->IsOwner()) HLTWarning("block list is owner!!");
650   HLTInfo(Form("fBlockList size %d", fBlockList->GetSize()));
651   //fBlockList->Clear();
652   fBlockList = new TList();
653   HLTInfo(Form("fBlockList size %d", fBlockList->GetSize()));
654
655   GetFirstBlk();
656
657   // -- Fill block list
658   do {
659
660     // -- Create new block
661     AliHLTHOMERBlockDesc * block = new AliHLTHOMERBlockDesc();
662     block->SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),
663                      GetBlkType(), GetBlkSpecification() );
664     
665     // -- Check sources list if block is requested
666     if ( CheckIfRequested( block ) ) {
667       (reinterpret_cast<TList*>((*fEventBuffer)[fBufferTopIdx]))->Add( block );
668       fBlockList->Add(block);
669     }
670     else {
671       // XXX HACK Jochen
672       (reinterpret_cast<TList*>((*fEventBuffer)[fBufferTopIdx]))->Add( block );
673       fBlockList->Add(block);
674       // delete block;
675       // block = NULL;
676     }
677  
678   } while( GetNextBlk() );
679
680   //We have one more event available
681   fNEventsAvailable++;
682   HLTInfo(Form("fNEventsAvailable %d", fNEventsAvailable));
683   return;
684 }
685
686 //##################################################################################
687 void AliHLTHOMERManager::AddToAsyncBlockList() {
688   // see header file for class documentation
689
690   HLTInfo("Adding blocks to the asynchroneous block list");
691
692   GetFirstBlk();
693
694   do {
695     
696     AliHLTHOMERBlockDesc * block = new AliHLTHOMERBlockDesc();
697     block->SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),
698                      GetBlkType(), GetBlkSpecification() );
699     
700
701     fAsyncBlockList->Add( block );
702
703     // -- Check sources list if block is requested
704     // if ( CheckIfRequested( block ) ) 
705     //   fAsyncBlockList->Add( block );
706     // else {
707     //   // XXX HACK Jochen
708     // }
709  
710   } while( GetNextBlk() );
711
712   return;
713 }
714 //__________________________________________________________________________________
715 void AliHLTHOMERManager::AddToBlockList() {
716   // see header file for class documentation
717   HLTInfo("Adding blocks to the synchroneous block list");
718
719   ULong_t eventID = static_cast<ULong64_t>(fCurrentReader->GetEventID());  
720   
721   if ( fEventId == eventID ) {
722     HLTInfo(Form("Event 0x%016lX (%lu) already in buffer.", eventID, eventID));
723     return;
724   }
725
726   fEventId = eventID;
727
728   GetFirstBlk();
729   do {
730
731     AliHLTHOMERBlockDesc * block = new AliHLTHOMERBlockDesc();
732     block->SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),
733                      GetBlkType(), GetBlkSpecification() );
734     fBlockList->Add( block );
735   
736   } while( GetNextBlk() );  
737 }
738
739 //__________________________________________________________________________________
740 TList* AliHLTHOMERManager::GetBlockListEventBuffer( Int_t idx ) {
741   // see header file for class documentation
742
743   if(fBlockList)
744     return fBlockList;
745   else 
746     return NULL;
747
748   if ( idx == -1 )
749     return NULL;
750  
751   return reinterpret_cast<TList*>((*fEventBuffer)[idx]);
752
753 }
754
755
756 //__________________________________________________________________________________
757 Int_t AliHLTHOMERManager::HandleBlocks() {
758   // see header file for class documentation
759   
760   Int_t iResult = 0;
761
762   // -- Get blockCnt and eventID
763   fNBlks = static_cast<ULong_t>(fCurrentReader->GetBlockCnt());
764   ULong_t eventID = static_cast<ULong64_t>(fCurrentReader->GetEventID());  
765   fCurrentBlk = 0;
766
767   // -- Check if blocks present
768   if ( fNBlks ==  0 ) {
769     HLTWarning(Form("Event 0x%016lX (%lu) with no blocks", eventID, eventID));
770     return -1;
771   }
772
773   HLTInfo(Form("Event 0x%016lX (%lu) with %lu blocks", eventID, eventID, fNBlks));
774     
775   if ( IsSyncBlocks() ) {
776     //AddBlockListToBuffer();
777     fBlockList->Clear();
778     AddToBlockList();
779   } else {
780     AddToAsyncBlockList();
781   }
782
783   return iResult;
784 }
785
786 //__________________________________________________________________________________
787 Bool_t AliHLTHOMERManager::IsSyncBlocks() {
788   // see header file for class documentation
789   
790   Bool_t bResult = kFALSE;
791
792   GetFirstBlk();
793   
794   do {          
795     
796     if ( !GetBlkType().CompareTo("ALIESDV0")) {
797       bResult = kTRUE;
798       break;
799     }
800
801     if ( !GetBlkType().CompareTo("GLOBTRIG")) {
802       bResult = kTRUE;
803       break;
804     }
805     
806     if ( !GetBlkType().CompareTo("ROOTTOBJ") ) {
807       AliHLTHOMERBlockDesc blockDesc;
808       
809       blockDesc.SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),
810                           GetBlkType(), GetBlkSpecification() );
811       if ( !blockDesc.GetClassName().CompareTo("AliHLTGlobalTriggerDecision") ) {
812
813         bResult = kTRUE;
814         break;
815       }
816     }
817
818   } while( GetNextBlk() );
819
820
821   return bResult;
822 }
823
824 //##################################################################################
825 void* AliHLTHOMERManager::GetBlk( Int_t ndx ) {
826   // see header file for class documentation
827   // Get pointer to current block in current event
828    
829   if ( !fCurrentReader || !IsConnected() ) {
830     HLTError(Form("Not connected yet."));
831     return NULL;
832   }
833   if ( ndx < static_cast<Int_t>(fNBlks) )
834     return  const_cast<void*> (fCurrentReader->GetBlockData(ndx));
835   else
836     return NULL;
837 }
838
839 //##################################################################################
840 ULong_t AliHLTHOMERManager::GetBlkSize( Int_t ndx ) {
841   // see header file for class documentation
842    
843   if ( !fCurrentReader || !IsConnected() ) {
844     HLTError(Form("Not connected yet."));
845     return 0;
846   }
847   
848   if ( ndx < static_cast<Int_t>(fNBlks) )
849     return static_cast<ULong_t> (fCurrentReader->GetBlockDataLength(ndx));
850   else
851     return 0;
852 }
853
854 //##################################################################################
855 TString AliHLTHOMERManager::GetBlkOrigin( Int_t ndx ) {
856   // see header file for class documentation
857
858   TString origin = "";
859
860   // -- Check for Connection
861   if ( !fCurrentReader || ! IsConnected() ) {
862     HLTError(Form("Not connected yet."));
863     return origin;
864   }
865
866   // -- Check block index
867   if ( ndx >= static_cast<Int_t>(fNBlks) ) {
868     HLTError(Form("Block index %d out of range.", ndx ));
869     return origin;
870   }
871
872   // -- Get origin
873   union{
874     UInt_t data;
875     Char_t array[4];
876   } reverseOrigin;
877
878   reverseOrigin.data = static_cast<UInt_t>(fCurrentReader->GetBlockDataOrigin(ndx));
879
880   // -- Reverse the order
881   for (Int_t ii = 3; ii >= 0; ii-- )
882     if ( reverseOrigin.array[ii] != ' ')
883       origin.Append( reverseOrigin.array[ii] );
884
885   origin.Remove( TString::kTrailing, ' ' );
886
887   return origin;
888 }
889
890 //##################################################################################
891 TString AliHLTHOMERManager::GetBlkType( Int_t ndx ) {
892   // see header file for class documentation
893
894   TString type = "";
895
896   // -- Check for Connection
897   if ( !fCurrentReader || ! IsConnected() ) {
898     HLTError(Form("Not connected yet."));
899     return type;
900   }
901
902   // -- Check block index
903   if ( ndx >= static_cast<Int_t>(fNBlks) ) {
904     HLTError(Form("Block index %d out of range.", ndx ));
905     return type;
906   }
907
908   // -- Get type
909   union{
910     ULong64_t data;
911     Char_t array[8];
912   } reverseType;
913
914   reverseType.data = static_cast<ULong64_t> (fCurrentReader->GetBlockDataType(ndx));
915
916   // -- Reverse the order
917   for (Int_t ii = 7; ii >= 0; ii-- )
918     if ( reverseType.array[ii] != ' ')
919       type.Append( reverseType.array[ii] );
920   
921   type.Remove( TString::kTrailing, ' ' );
922
923   return type;
924 }
925
926 //##################################################################################
927 ULong_t AliHLTHOMERManager::GetBlkSpecification( Int_t ndx ) {
928   // see header file for class documentation
929
930   // -- Check for Connection
931   if ( !fCurrentReader || ! IsConnected() ) {
932     HLTError(Form("Not connected yet."));
933     return 0;
934   }
935
936   // -- Check block index
937   if ( ndx >= static_cast<Int_t>(fNBlks) ) {
938     HLTError(Form("Block index %d out of range.", ndx ));
939     return 0;
940   }
941
942   return static_cast<ULong_t>(fCurrentReader->GetBlockDataSpec(ndx));
943 }
944
945 //##################################################################################
946 Bool_t AliHLTHOMERManager::CheckIfRequested( AliHLTHOMERBlockDesc * block ) {
947   // see header file for class documentation
948
949   Bool_t requested = kFALSE;
950
951   AliHLTHOMERSourceDesc * source= NULL;
952
953   // -- Read all sources and check if they should be read out
954   TIter next( fSourceList );
955   while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
956     
957     // -- Check if source is selected
958     if ( ! source->IsSelected() )
959       continue;
960     
961     // -- Check if detector matches
962     if ( source->GetSourceName().CompareTo( block->GetBlockName() ) )
963       continue;
964
965     requested = kTRUE;
966     break;
967
968   } // while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
969   
970 #if EVE_DEBUG
971   if ( requested ) {
972     HLTInfo(Form("Block requested : %s", block->GetBlockName().Data())); 
973   }
974   else {
975     HLTInfo(Form("Block NOT requested : %s", block->GetBlockName().Data())); 
976   }
977 #endif
978
979   return requested;
980 }
981
982 /* ---------------------------------------------------------------------------------
983  *                          Trigger Handling - private
984  * ---------------------------------------------------------------------------------
985  */
986
987 //##################################################################################
988 Bool_t AliHLTHOMERManager::CheckTriggerDecision() {
989   // see header file for class documentation
990
991   Bool_t triggered = kFALSE;
992
993   if ( !fCurrentReader || !IsConnected() ) {
994     HLTError(Form("Not connected yet."));
995     return kFALSE;
996   }
997
998   AliHLTHOMERBlockDesc blockDesc;
999
1000   GetFirstBlk();
1001   
1002   // -- Fill block list
1003   Bool_t foundTriggerBlock = kFALSE;
1004   
1005   do {
1006     if ( (GetBlkType().CompareTo("ROOTTOBJ") == 0) ) {
1007       blockDesc.SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),
1008                           GetBlkType(), GetBlkSpecification() );
1009
1010       if ( ! blockDesc.GetClassName().CompareTo("AliHLTGlobalTriggerDecision") ) {
1011
1012         foundTriggerBlock = kTRUE;
1013         break;
1014       }
1015       
1016     }
1017   } while( GetNextBlk() );
1018   
1019   if ( !foundTriggerBlock ) {
1020     HLTError(Form("No trigger decision object found"));
1021     return kFALSE;
1022   }
1023
1024   // -- Get the global decision object
1025   AliHLTGlobalTriggerDecision* globalDecision = 
1026     static_cast<AliHLTGlobalTriggerDecision*>(blockDesc.GetTObject());
1027
1028   if ( fTriggerString.CompareTo("HLTGlobalTrigger") == 0 ) {
1029     triggered = globalDecision->EventTriggered();
1030   } 
1031   else {
1032     
1033     for (Int_t idx = 0; idx < globalDecision->NumberOfInputObjects(); idx++) {
1034        
1035       const AliHLTTriggerDecision* triggerDecision = 
1036         reinterpret_cast<const AliHLTTriggerDecision*>(globalDecision->InputObject(idx));
1037     
1038       if ( !(fTriggerString.CompareTo(triggerDecision->Description())) ) {
1039         triggered = triggerDecision->EventTriggered();
1040         break;
1041       }
1042     } // for (Int_t idx = 0; idx < globalDecision->NumberOfInputObjects(); idx++) {
1043   }
1044
1045
1046
1047   if ( triggered ) {
1048     fRetryNextEvent = kFALSE;
1049     fNEventsNotTriggered = 0;
1050   }
1051   else {
1052     fRetryNextEvent = kTRUE;
1053     ++fNEventsNotTriggered;
1054   }
1055
1056   return triggered;
1057 }