-//-*- Mode: C++ -*-\r
-// $Id: AliHLTHOMERManager.cxx $\r
-//**************************************************************************\r
-//* This file is property of and copyright by the ALICE HLT Project * \r
-//* ALICE Experiment at CERN, All rights reserved. *\r
-//* *\r
-//* Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de> *\r
-//* for The ALICE HLT Project. *\r
-//* *\r
-//* Permission to use, copy, modify and distribute this software and its *\r
-//* documentation strictly for non-commercial purposes is hereby granted *\r
-//* without fee, provided that the above copyright notice appears in all *\r
-//* copies and that both the copyright notice and this permission notice *\r
-//* appear in the supporting documentation. The authors make no claims *\r
-//* about the suitability of this software for any purpose. It is *\r
-//* provided "as is" without express or implied warranty. *\r
-//**************************************************************************\r
-\r
-/** @file AliHLTHOMERManager.cxx\r
- @author Jochen Thaeder\r
- @date\r
- @brief Manger for HOMER in aliroot\r
-*/\r
-\r
-// see header file for class documentation\r
-// or\r
-// refer to README to build package\r
-// or\r
-// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt\r
-\r
-#if __GNUC__>= 3\r
- using namespace std;\r
-#endif\r
-\r
-#define EVE_DEBUG 0\r
-\r
-#include "AliHLTHOMERManager.h"\r
-// -- -- -- -- -- -- -- \r
-#include "AliHLTHOMERLibManager.h"\r
-#include "AliHLTHOMERSourceDesc.h"\r
-#include "AliHLTHOMERBlockDesc.h"\r
-// -- -- -- -- -- -- -- \r
-#include "AliHLTGlobalTriggerDecision.h"\r
-#include "AliHLTTriggerDecision.h"\r
-//---------------------------\r
-\r
-ClassImp(AliHLTHOMERManager)\r
-\r
-/*\r
- * ---------------------------------------------------------------------------------\r
- * Constructor / Destructor\r
- * ---------------------------------------------------------------------------------\r
- */\r
-\r
-//##################################################################################\r
- AliHLTHOMERManager::AliHLTHOMERManager() :\r
- fLibManager(new AliHLTHOMERLibManager),\r
- fStateHasChanged(kTRUE),\r
- fProxyHandler(NULL),\r
- fCurrentReader(NULL),\r
- fReaderList(NULL),\r
- fSourceList(NULL),\r
- fNBlks(0),\r
- fEventID(),\r
- fCurrentBlk(0),\r
- fAsyncBlockList(NULL),\r
- fEventBuffer(NULL),\r
- fBufferTopIdx(-1),\r
- fBufferLowIdx(-1),\r
- fCurrentBufferIdx(-1),\r
- fNavigateBufferIdx(-1),\r
- fConnected(kFALSE), \r
- fTriggerString("ALL"), \r
- fNEventsNotTriggered(0),\r
- fRetryNextEvent(kFALSE) {\r
- // see header file for class documentation\r
- // or\r
- // refer to README to build package\r
- // or\r
- // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt\r
-\r
-}\r
-\r
-//##################################################################################\r
-AliHLTHOMERManager::~AliHLTHOMERManager() {\r
- // see header file for class documentation\r
-\r
- if ( fLibManager ) {\r
-\r
- if ( fReaderList ) {\r
- TIter next(fReaderList);\r
- TObject * object = NULL;\r
- while ( ( object = next()) )\r
- fLibManager->DeleteReader(static_cast<AliHLTHOMERReader*>(object) );\r
- \r
- fReaderList->Clear();\r
- delete fReaderList;\r
- }\r
- fReaderList = NULL; \r
- \r
- delete fLibManager;\r
- } \r
- fLibManager = NULL;\r
-\r
- if ( fProxyHandler != NULL )\r
- delete fProxyHandler;\r
- fProxyHandler = NULL;\r
-\r
- if ( fSourceList != NULL )\r
- delete fSourceList;\r
- fSourceList = NULL;\r
-\r
- if ( fEventBuffer ) {\r
- fEventBuffer->Clear();\r
- delete fEventBuffer;\r
- }\r
- fEventBuffer = NULL;\r
-\r
- if ( fAsyncBlockList ) {\r
- fAsyncBlockList->Clear();\r
- delete fAsyncBlockList;\r
- }\r
- fAsyncBlockList = NULL;\r
-}\r
-\r
-//##################################################################################\r
-Int_t AliHLTHOMERManager::Initialize() {\r
- // see header file for class documentation\r
-\r
- Int_t iResult = 0;\r
-\r
- // -- Initialize ProxyHandler\r
- if ( !fProxyHandler )\r
- fProxyHandler = new AliHLTHOMERProxyHandler();\r
- \r
- if ( fProxyHandler ) {\r
- iResult = fProxyHandler->Initialize();\r
- if (iResult)\r
- HLTError(Form("Initialize of ProxyHandler failed."));\r
- }\r
- else {\r
- iResult = -1;\r
- HLTError(Form("Creating of ProxyHandler failed."));\r
- }\r
- \r
- // -- Initialize ReaderList\r
- // List ist not owner, as reader have to be created/deleted by the LibManager\r
- if( !fReaderList )\r
- fReaderList = new TList();\r
- \r
- // -- Initialize asynchronous BlockList\r
- if( !fAsyncBlockList ) {\r
- fAsyncBlockList = new TList();\r
- fAsyncBlockList->SetOwner(kFALSE);\r
- }\r
-\r
- // -- Initialize Event Buffer and EventID array\r
- if ( !fEventBuffer ) {\r
- fEventBuffer = new TClonesArray( "TList", BUFFERSIZE );\r
- }\r
-\r
- for ( Int_t idx = 0; idx < BUFFERSIZE; ++idx ) {\r
- new ((*fEventBuffer)[idx]) TList( );\r
- (reinterpret_cast<TList*>((*fEventBuffer)[idx]))->SetOwner(kTRUE);\r
- \r
- fEventID[idx] = 0;\r
- }\r
-\r
- return iResult;\r
-}\r
-\r
-/*\r
- * ---------------------------------------------------------------------------------\r
- * Source Handling\r
- * ---------------------------------------------------------------------------------\r
- */\r
-\r
-//##################################################################################\r
-Int_t AliHLTHOMERManager::CreateSourcesList() {\r
- // see header file for class documentation\r
-\r
- Int_t iResult = 0;\r
- \r
- if ( fSourceList != NULL )\r
- delete fSourceList;\r
- fSourceList = NULL;\r
-\r
- fSourceList = new TList();\r
- fSourceList->SetOwner( kTRUE );\r
-\r
- iResult = fProxyHandler->FillSourceList( fSourceList );\r
- if ( iResult < 0 ) {\r
- HLTWarning(Form("There have been errors, while creating the sources list."));\r
- }\r
- else if ( iResult > 0 ) {\r
- HLTWarning(Form("No active services found."));\r
- }\r
- else if ( fSourceList->IsEmpty() ) {\r
- HLTWarning(Form("No active services in the list."));\r
- iResult = 2;\r
- }\r
- else {\r
- HLTInfo(Form("New sources list created."));\r
-\r
- // -- New SourceList has been created \r
- // --> All Sources are new --> State has changed\r
- fStateHasChanged = kTRUE;\r
- }\r
-\r
- return iResult;\r
-}\r
-\r
-//##################################################################################\r
-void AliHLTHOMERManager::SetSourceState( AliHLTHOMERSourceDesc * source, Bool_t state ) {\r
- // see header file for class documentation\r
-\r
- if ( source->IsSelected() != state ) {\r
- source->SetState( state );\r
- fStateHasChanged = kTRUE;\r
- }\r
-\r
- return;\r
-}\r
-\r
-/*\r
- * ---------------------------------------------------------------------------------\r
- * Connection Handling - public\r
- * ---------------------------------------------------------------------------------\r
- */\r
-\r
-//##################################################################################\r
-Int_t AliHLTHOMERManager::ConnectHOMER( TString detector ){\r
- // see header file for class documentation\r
-\r
- Int_t iResult = 0;\r
-\r
- // -- Check if LibManager is present\r
- if ( ! fLibManager ) {\r
- HLTError(Form("No LibManager present."));\r
- return -1;\r
- }\r
- \r
- // -- Check if already connected and state has not changed\r
- if ( fStateHasChanged == kFALSE && IsConnected() ) {\r
- HLTInfo(Form("No need for reconnection."));\r
- return 0;\r
- }\r
- \r
- // -- If already connected, disconnect before connect\r
- // or if ReaderList already filled\r
- if ( IsConnected() || fReaderList->GetSize() != 0 )\r
- DisconnectHOMER();\r
- \r
- // -- Create the Readoutlist\r
- UShort_t* sourcePorts = new UShort_t [fSourceList->GetEntries()];\r
- const Char_t ** sourceHostnames = new const Char_t* [fSourceList->GetEntries()];\r
- UInt_t sourceCount = 0;\r
-\r
- CreateReadoutList( sourceHostnames, sourcePorts, sourceCount, detector );\r
- if ( sourceCount == 0 ) {\r
- HLTError(Form("No sources selected, aborting."));\r
- return -2;\r
- }\r
-\r
- // ***\r
- // *** Connect to data sources\r
- // ***\r
- \r
- for (UInt_t idx = 0; idx < sourceCount; idx++) {\r
- \r
- HLTInfo(Form("Adding source %d as %s : %d", idx, sourceHostnames[idx], sourcePorts[idx]));\r
- \r
- fReaderList->Add(dynamic_cast<TObject*>(fLibManager->OpenReader(sourceHostnames[idx], sourcePorts[idx])));\r
- AliHLTHOMERReader *reader = static_cast<AliHLTHOMERReader*>(fReaderList->Last());\r
- if ( !reader ) {\r
- HLTError(Form("Adding reader failed, aborting"));\r
- return -3;\r
- }\r
-\r
- if ( (iResult = reader->GetConnectionStatus()) ) {\r
-\r
- // -- Connection to source failed\r
- \r
- HLTError(Form("Error establishing connection to TCP source %s:%hu: %s (%d)",\r
- sourceHostnames[idx], sourcePorts[idx], strerror(iResult), iResult));\r
-\r
- if( !(TString(sourceHostnames[idx]).CompareTo("localhost")) ) {\r
- HLTInfo("The failed connection is on localhost. is SSH tunnel up????? ");\r
- HLTInfo(Form("Do: 'ssh -L %s:alihlt-vobox0.cern.ch:%d cernUser@lxplus.cern.ch -fN'",\r
- sourcePorts[idx], sourcePorts[idx]));\r
- }\r
- \r
- // -- Remove reader\r
- if ( reader )\r
- fLibManager->DeleteReader( reader );\r
- reader = NULL;\r
- \r
- fReaderList->RemoveLast();\r
- } \r
- else {\r
- // -- Connection succeded\r
- fConnected = kTRUE;\r
-\r
- HLTInfo(Form("Connection established to source %s on port %d", sourceHostnames[idx], sourcePorts[idx]));\r
- }\r
- \r
- } // for (Int_t idx = 0; idx < sourceCount; idx++) {\r
- \r
- delete[] sourceHostnames;\r
- delete[] sourcePorts;\r
-\r
- return iResult;\r
-\r
-}\r
-\r
-//##################################################################################\r
-void AliHLTHOMERManager::DisconnectHOMER(){\r
- // see header file for class documentation\r
-\r
- if ( ! IsConnected() )\r
- return;\r
-\r
- if ( fReaderList && fLibManager ) {\r
- TIter next(fReaderList);\r
- TObject * object = NULL;\r
- while ( ( object = next()) ) \r
- fLibManager->DeleteReader(static_cast<AliHLTHOMERReader*>(object) );\r
- \r
- fReaderList->Clear();\r
- delete fReaderList;\r
- fReaderList = NULL;\r
- }\r
- \r
- fStateHasChanged = kTRUE;\r
- fConnected = kFALSE;\r
-\r
- HLTInfo(Form("Connection closed."));\r
-\r
- return;\r
-}\r
-\r
-//##################################################################################\r
-Int_t AliHLTHOMERManager::ReconnectHOMER( TString detector="" ){\r
- // see header file for class documentation\r
- \r
- Int_t iResult = 0;\r
-\r
- if ( IsConnected() )\r
- DisconnectHOMER();\r
-\r
- iResult = ConnectHOMER(detector);\r
- if ( iResult ) {\r
- HLTError(Form("Error reconnecting."));\r
- }\r
-\r
- return iResult;\r
-}\r
-\r
-/*\r
- * ---------------------------------------------------------------------------------\r
- * Event Handling - public\r
- * ---------------------------------------------------------------------------------\r
- */\r
-\r
-//##################################################################################\r
-Int_t AliHLTHOMERManager::NextEvent(){\r
- \r
- // see header file for class documentation\r
- \r
-\r
- Int_t iResult = 0;\r
- Int_t iRetryCount = 0;\r
- \r
- if ( !IsConnected() || fStateHasChanged ) \r
- ConnectHOMER();\r
- \r
- if ( !IsConnected() ) {\r
- HLTWarning(Form( "Not connected yet." ));\r
- return -1;\r
- }\r
-\r
- // -- Reset asyncronous BlockList\r
- fAsyncBlockList->Clear();\r
-\r
- // ***\r
- // *** Loop over all readers and get new event data\r
- // ***\r
- \r
- TIter next(fReaderList);\r
- TObject * object = NULL;\r
- \r
- while( (object = next()) ) {\r
- \r
- fCurrentReader = static_cast<AliHLTHOMERReader*>(object);\r
- \r
- // -- Read next event data and error handling for HOMER (error codes and empty blocks)\r
- while ( 1 ) {\r
- \r
- iResult = fCurrentReader->ReadNextEvent( 40000000 /*timeout in us*/);\r
- \r
- if ( iResult == 111 || iResult == 32 || iResult == 6 ) {\r
- HLTError(Form("No connection to source %d: %s (%d)", \r
- fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult));\r
- break;\r
- } \r
- else if ( iResult == 110 ) {\r
- HLTError(Form("Timeout occured, reading event from source %d: %s (%d)", \r
- fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult));\r
- break;\r
- } \r
- else if ( iResult == 56 ) {\r
- ++iRetryCount;\r
- \r
- if ( iRetryCount >= 20 ) {\r
- HLTError(Form("Retry Failed: Error reading event from source %d: %s (%d), returning", \r
- fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult));\r
- break;\r
- } \r
- else {\r
- HLTError(Form("Retry: Error reading event from source %d: %s (%d), making another attempt (no %d out of 20)", \r
- fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult, iRetryCount));\r
- //break;\r
- continue;\r
- }\r
- }\r
- else if ( iResult ) {\r
- HLTError(Form("General Error reading event from source %d: %s (%d), giving up", \r
- fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult));\r
- fConnected = kFALSE;\r
- break;\r
- } \r
- else {\r
- break;\r
- }\r
-\r
- } // while( 1 ) {\r
- \r
- \r
- // -- Check if event could be read\r
- if ( iResult )\r
- continue;\r
-\r
- // -- Handle Blocks from current reader\r
- iResult = HandleBlocks();\r
- if ( iResult ) {\r
- HLTError(Form("Handling of blocks failed."));\r
- }\r
-\r
- } // while( (object = next()) ) {\r
-\r
- // -- Check if NextEvent should be recalled, \r
- // to catch the next event with a trigger\r
- if ( fRetryNextEvent ) {\r
- usleep(1000000);\r
- fRetryNextEvent = kFALSE;\r
- \r
- HLTInfo(Form("Checked trigger of %d events, without triggering", fNEventsNotTriggered));\r
- return NextEvent();\r
- }\r
- else\r
- return 0; \r
-}\r
-\r
-/* ---------------------------------------------------------------------------------\r
- * Buffer Handling - public\r
- * ---------------------------------------------------------------------------------\r
- */\r
-\r
-//##################################################################################\r
-Int_t AliHLTHOMERManager::NavigateEventBufferBack() { \r
- // see header file for class documentation\r
-\r
- // -- reached the end of the buffer\r
- if ( fNavigateBufferIdx == fBufferLowIdx )\r
- return -1;\r
-\r
- Int_t newIdx = fNavigateBufferIdx - 1;\r
- if ( newIdx == -1 )\r
- newIdx = BUFFERSIZE-1;\r
-\r
- fCurrentBufferIdx = fNavigateBufferIdx = newIdx;\r
-\r
- return newIdx;\r
-}\r
-\r
-//##################################################################################\r
-Int_t AliHLTHOMERManager::NavigateEventBufferFwd() {\r
- // see header file for class documentation\r
-\r
- // -- reached the top of the buffer\r
- if ( fNavigateBufferIdx == fBufferTopIdx )\r
- return -1;\r
-\r
- Int_t newIdx = fNavigateBufferIdx + 1;\r
- if ( newIdx == BUFFERSIZE )\r
- newIdx = 0;\r
- \r
- fCurrentBufferIdx = fNavigateBufferIdx = newIdx;\r
-\r
- return newIdx;\r
-}\r
-\r
- ///////////////////////////////////////////////////////////////////////////////////\r
-\r
-/*\r
- * ---------------------------------------------------------------------------------\r
- * Connection Handling - private\r
- * ---------------------------------------------------------------------------------\r
- */\r
-\r
-//##################################################################################\r
-void AliHLTHOMERManager::CreateReadoutList( const char** sourceHostnames, UShort_t *sourcePorts, \r
- UInt_t &sourceCount, TString detector ){\r
- // see header file for class documentation\r
-\r
- AliHLTHOMERSourceDesc * source= NULL;\r
-\r
- // -- Read all sources and check if they should be read out\r
- TIter next( fSourceList );\r
- while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {\r
-\r
- // -- If detector NO detector name given\r
- if ( ! detector.CompareTo("ALL") ) {\r
- // -- Continue if source is not selected\r
- if ( ! source->IsSelected() )\r
- continue;\r
- }\r
- // -- DetectorName given\r
- else {\r
- // -- Continue if detector name doesn't match\r
- if ( detector.CompareTo(source->GetDetector()) )\r
- continue;\r
- else\r
- source->Select();\r
- }\r
- \r
- Bool_t exists = kFALSE;\r
- \r
- // -- Loop over existing entries and check if entry is already in readout list\r
- for ( UInt_t ii = 0; ii < sourceCount; ii++ ){\r
- if ( !strcmp( sourceHostnames[ii], source->GetHostname().Data() ) \r
- && sourcePorts[ii] == source->GetPort() ) {\r
- exists = kTRUE;\r
- break;\r
- }\r
- }\r
-\r
- // -- Add new entires to readout list\r
- if ( ! exists ) {\r
- sourcePorts[sourceCount] = source->GetPort();\r
- sourceHostnames[sourceCount] = source->GetHostname().Data();\r
- sourceCount++;\r
- }\r
-\r
- } // while ( ( source = (AliHLTHOMERSourceDesc*)next() ) ) {\r
-\r
- fStateHasChanged = kFALSE;\r
-\r
- return;\r
-}\r
-\r
-/*\r
- * ---------------------------------------------------------------------------------\r
- * Buffer Handling - private\r
- * ---------------------------------------------------------------------------------\r
- */\r
-\r
-//##################################################################################\r
-void AliHLTHOMERManager::AddBlockListToBuffer() {\r
- // see header file for class documentation\r
-\r
- // -- Check if event is already in buffer\r
- ULong_t eventID = static_cast<ULong64_t>(fCurrentReader->GetEventID()); \r
- \r
- if ( fEventID[fBufferTopIdx] == eventID ) {\r
- HLTInfo(Form("Event 0x%016LX (%Lu) already in buffer.", eventID, eventID));\r
- return;\r
- }\r
-\r
- // -- Check if event should be selected on basis of trigger string\r
- if( fTriggerString.CompareTo("ALL") ){\r
- if ( !CheckTriggerDecision() ) {\r
- HLTInfo(Form("Event 0x%016LX (%Lu) is not triggered by %s.", \r
- eventID, eventID, fTriggerString.Data()));\r
- return;\r
- }\r
- }\r
- else {\r
- HLTInfo("No trigger selection.");\r
- }\r
-\r
- // -- Set Top mark \r
- ++fBufferTopIdx;\r
- if ( fBufferTopIdx == BUFFERSIZE )\r
- fBufferTopIdx = 0;\r
-\r
- // -- Change the low mark if necessary\r
- if ( fBufferLowIdx == -1 )\r
- fBufferLowIdx = 0;\r
- else if ( fBufferTopIdx == fBufferLowIdx ) {\r
- ++fBufferLowIdx;\r
- if ( fBufferLowIdx == BUFFERSIZE )\r
- fBufferLowIdx = 0;\r
- }\r
-\r
- fNavigateBufferIdx = fCurrentBufferIdx = fBufferTopIdx; \r
-\r
- // -- Fill EventID\r
- fEventID[fBufferTopIdx] = eventID;\r
-\r
- // -- Clear Buffer slot\r
- (reinterpret_cast<TList*>((*fEventBuffer)[fBufferTopIdx]))->Clear();\r
-\r
-\r
- GetFirstBlk();\r
-\r
- // -- Fill block list\r
- do {\r
-\r
- // -- Create new block\r
- AliHLTHOMERBlockDesc * block = new AliHLTHOMERBlockDesc();\r
- block->SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),\r
- GetBlkType(), GetBlkSpecification() );\r
- \r
- // -- Check sources list if block is requested\r
- if ( CheckIfRequested( block ) ) {\r
- (reinterpret_cast<TList*>((*fEventBuffer)[fBufferTopIdx]))->Add( block );\r
- }\r
- else {\r
- // XXX HACK Jochen\r
- (reinterpret_cast<TList*>((*fEventBuffer)[fBufferTopIdx]))->Add( block );\r
- // delete block;\r
- // block = NULL;\r
- }\r
- \r
- } while( GetNextBlk() );\r
-\r
- return;\r
-}\r
-\r
-//##################################################################################\r
-void AliHLTHOMERManager::AddToAsyncBlockList() {\r
- // see header file for class documentation\r
-\r
- HLTInfo("Adding blocks to the asynchroneous block list");\r
-\r
-\r
- GetFirstBlk();\r
-\r
- // -- Fill block list\r
- do {\r
- \r
-\r
- // -- Create new block\r
- AliHLTHOMERBlockDesc * block = new AliHLTHOMERBlockDesc();\r
- block->SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),\r
- GetBlkType(), GetBlkSpecification() );\r
- \r
- // -- Check sources list if block is requested\r
- if ( CheckIfRequested( block ) ) \r
- fAsyncBlockList->Add( block );\r
- else {\r
- // XXX HACK Jochen\r
- fAsyncBlockList->Add( block );\r
- // delete block;\r
- // block = NULL;\r
- }\r
- \r
- } while( GetNextBlk() );\r
-\r
- return;\r
-}\r
-//##################################################################################\r
-TList* AliHLTHOMERManager::GetBlockListEventBuffer( Int_t idx ) {\r
- // see header file for class documentation\r
-\r
- if ( idx == -1 )\r
- return NULL;\r
-\r
- return reinterpret_cast<TList*>((*fEventBuffer)[idx]);\r
-\r
-}\r
-\r
-/*\r
- * ---------------------------------------------------------------------------------\r
- * Block Handling - private\r
- * ---------------------------------------------------------------------------------\r
- */\r
-\r
-//##################################################################################\r
-Int_t AliHLTHOMERManager::HandleBlocks() {\r
- // see header file for class documentation\r
- \r
- Int_t iResult = 0;\r
-\r
- // -- Get blockCnt and eventID\r
- fNBlks = static_cast<ULong_t>(fCurrentReader->GetBlockCnt());\r
- ULong_t eventID = static_cast<ULong64_t>(fCurrentReader->GetEventID()); \r
- fCurrentBlk = 0;\r
-\r
- // -- Check if blocks present\r
- if ( fNBlks == 0 ) {\r
- HLTWarning(Form("Event 0x%016LX (%Lu) with no blocks", eventID, eventID));\r
- return -1;\r
- }\r
-\r
- HLTInfo(Form("Event 0x%016LX (%Lu) with %lu blocks", eventID, eventID, fNBlks));\r
-\r
-#if 1// EVE_DEBUG\r
- // Loop for Debug only\r
- for ( ULong_t ii = 0; ii < fNBlks; ii++ ) {\r
- Char_t tmp1[9], tmp2[5];\r
- memset( tmp1, 0, 9 );\r
- memset( tmp2, 0, 5 );\r
- void *tmp11 = tmp1;\r
- ULong64_t* tmp12 = static_cast<ULong64_t*>(tmp11);\r
- *tmp12 = fCurrentReader->GetBlockDataType(ii);\r
- void *tmp21 = tmp2;\r
- ULong_t* tmp22 = static_cast<ULong_t*>(tmp21);\r
- *tmp22 = fCurrentReader->GetBlockDataOrigin(ii);\r
- HLTInfo(Form( "Block %lu length: %lu - type: %s - origin: %s - spec 0x%08X",\r
- ii, fCurrentReader->GetBlockDataLength(ii), tmp1, tmp2, fCurrentReader->GetBlockDataSpec(ii) ));\r
- } // end for ( ULong_t ii = 0; ii < fNBlks; ii++ ) {\r
-#endif\r
- \r
- // -- Check if blocks are from syncronous source\r
-\r
- if ( IsSyncBlocks() )\r
- AddBlockListToBuffer();\r
- else\r
- AddToAsyncBlockList();\r
- \r
- return iResult;\r
-}\r
-\r
-//##################################################################################\r
-Bool_t AliHLTHOMERManager::IsSyncBlocks() {\r
- // see header file for class documentation\r
- \r
- Bool_t bResult = kFALSE;\r
-\r
- GetFirstBlk();\r
- \r
- do {\r
- \r
- \r
- // if ( !GetBlkType().CompareTo("ALIESDV0") ||\r
- \r
- if ( !GetBlkType().CompareTo("ALIESDV0") ||\r
- !GetBlkType().CompareTo("CLUSTERS") ) {\r
- \r
- bResult = kTRUE;\r
- break;\r
- \r
- }\r
- \r
- if ( !GetBlkType().CompareTo("ROOTTOBJ") ) {\r
- AliHLTHOMERBlockDesc blockDesc;\r
- \r
- blockDesc.SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),\r
- GetBlkType(), GetBlkSpecification() );\r
- if ( !blockDesc.GetClassName().CompareTo("AliHLTGlobalTriggerDecision") ) {\r
-\r
- bResult = kTRUE;\r
- break;\r
- }\r
- }\r
-\r
- } while( GetNextBlk() );\r
-\r
-\r
- return bResult;\r
-}\r
-\r
-//##################################################################################\r
-void* AliHLTHOMERManager::GetBlk( Int_t ndx ) {\r
- // see header file for class documentation\r
- // Get pointer to current block in current event\r
- \r
- if ( !fCurrentReader || !IsConnected() ) {\r
- HLTError(Form("Not connected yet."));\r
- return NULL;\r
- }\r
- if ( ndx < static_cast<Int_t>(fNBlks) )\r
- return const_cast<void*> (fCurrentReader->GetBlockData(ndx));\r
- else\r
- return NULL;\r
-}\r
-\r
-//##################################################################################\r
-ULong_t AliHLTHOMERManager::GetBlkSize( Int_t ndx ) {\r
- // see header file for class documentation\r
- \r
- if ( !fCurrentReader || !IsConnected() ) {\r
- HLTError(Form("Not connected yet."));\r
- return 0;\r
- }\r
- \r
- if ( ndx < static_cast<Int_t>(fNBlks) )\r
- return static_cast<ULong_t> (fCurrentReader->GetBlockDataLength(ndx));\r
- else\r
- return 0;\r
-}\r
-\r
-//##################################################################################\r
-TString AliHLTHOMERManager::GetBlkOrigin( Int_t ndx ) {\r
- // see header file for class documentation\r
-\r
- TString origin = "";\r
-\r
- // -- Check for Connection\r
- if ( !fCurrentReader || ! IsConnected() ) {\r
- HLTError(Form("Not connected yet."));\r
- return origin;\r
- }\r
-\r
- // -- Check block index\r
- if ( ndx >= static_cast<Int_t>(fNBlks) ) {\r
- HLTError(Form("Block index %d out of range.", ndx ));\r
- return origin;\r
- }\r
-\r
- // -- Get origin\r
- union{\r
- UInt_t data;\r
- Char_t array[4];\r
- } reverseOrigin;\r
-\r
- reverseOrigin.data = static_cast<UInt_t>(fCurrentReader->GetBlockDataOrigin(ndx));\r
-\r
- // -- Reverse the order\r
- for (Int_t ii = 3; ii >= 0; ii-- )\r
- if ( reverseOrigin.array[ii] != ' ')\r
- origin.Append( reverseOrigin.array[ii] );\r
-\r
- origin.Remove( TString::kTrailing, ' ' );\r
-\r
- return origin;\r
-}\r
-\r
-//##################################################################################\r
-TString AliHLTHOMERManager::GetBlkType( Int_t ndx ) {\r
- // see header file for class documentation\r
-\r
- TString type = "";\r
-\r
- // -- Check for Connection\r
- if ( !fCurrentReader || ! IsConnected() ) {\r
- HLTError(Form("Not connected yet."));\r
- return type;\r
- }\r
-\r
- // -- Check block index\r
- if ( ndx >= static_cast<Int_t>(fNBlks) ) {\r
- HLTError(Form("Block index %d out of range.", ndx ));\r
- return type;\r
- }\r
-\r
- // -- Get type\r
- union{\r
- ULong64_t data;\r
- Char_t array[8];\r
- } reverseType;\r
-\r
- reverseType.data = static_cast<ULong64_t> (fCurrentReader->GetBlockDataType(ndx));\r
-\r
- // -- Reverse the order\r
- for (Int_t ii = 7; ii >= 0; ii-- )\r
- if ( reverseType.array[ii] != ' ')\r
- type.Append( reverseType.array[ii] );\r
- \r
- type.Remove( TString::kTrailing, ' ' );\r
-\r
- return type;\r
-}\r
-\r
-//##################################################################################\r
-ULong_t AliHLTHOMERManager::GetBlkSpecification( Int_t ndx ) {\r
- // see header file for class documentation\r
-\r
- // -- Check for Connection\r
- if ( !fCurrentReader || ! IsConnected() ) {\r
- HLTError(Form("Not connected yet."));\r
- return 0;\r
- }\r
-\r
- // -- Check block index\r
- if ( ndx >= static_cast<Int_t>(fNBlks) ) {\r
- HLTError(Form("Block index %d out of range.", ndx ));\r
- return 0;\r
- }\r
-\r
- return static_cast<ULong_t>(fCurrentReader->GetBlockDataSpec(ndx));\r
-}\r
-\r
-//##################################################################################\r
-Bool_t AliHLTHOMERManager::CheckIfRequested( AliHLTHOMERBlockDesc * block ) {\r
- // see header file for class documentation\r
-\r
- Bool_t requested = kFALSE;\r
-\r
- AliHLTHOMERSourceDesc * source= NULL;\r
-\r
- // -- Read all sources and check if they should be read out\r
- TIter next( fSourceList );\r
- while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {\r
- \r
- // -- Check if source is selected\r
- if ( ! source->IsSelected() )\r
- continue;\r
- \r
- // -- Check if detector matches\r
- if ( source->GetSourceName().CompareTo( block->GetBlockName() ) )\r
- continue;\r
-\r
- requested = kTRUE;\r
- break;\r
-\r
- } // while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {\r
- \r
-#if EVE_DEBUG\r
- if ( requested ) {\r
- HLTInfo(Form("Block requested : %s", block->GetBlockName().Data())); \r
- }\r
- else {\r
- HLTInfo(Form("Block NOT requested : %s", block->GetBlockName().Data())); \r
- }\r
-#endif\r
-\r
- return requested;\r
-}\r
-\r
-/* ---------------------------------------------------------------------------------\r
- * Trigger Handling - private\r
- * ---------------------------------------------------------------------------------\r
- */\r
-\r
-//##################################################################################\r
-Bool_t AliHLTHOMERManager::CheckTriggerDecision() {\r
- // see header file for class documentation\r
-\r
- Bool_t triggered = kFALSE;\r
-\r
- if ( !fCurrentReader || !IsConnected() ) {\r
- HLTError(Form("Not connected yet."));\r
- return NULL;\r
- }\r
-\r
- AliHLTHOMERBlockDesc blockDesc;\r
-\r
- GetFirstBlk();\r
- \r
- // -- Fill block list\r
- Bool_t foundTriggerBlock = kFALSE;\r
- \r
- do {\r
- if ( (GetBlkType().CompareTo("ROOTTOBJ") == 0) ) {\r
- blockDesc.SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),\r
- GetBlkType(), GetBlkSpecification() );\r
-\r
- if ( ! blockDesc.GetClassName().CompareTo("AliHLTGlobalTriggerDecision") ) {\r
-\r
- foundTriggerBlock = kTRUE;\r
- break;\r
- }\r
- \r
- }\r
- } while( GetNextBlk() );\r
- \r
- if ( !foundTriggerBlock ) {\r
- HLTError(Form("No trigger decision object found"));\r
- return kFALSE;\r
- }\r
-\r
- // -- Get the global decision object\r
- AliHLTGlobalTriggerDecision* globalDecision = \r
- static_cast<AliHLTGlobalTriggerDecision*>(blockDesc.GetTObject());\r
-\r
- if ( fTriggerString.CompareTo("HLTGlobalTrigger") == 0 ) {\r
- triggered = globalDecision->EventTriggered();\r
- } \r
- else {\r
- \r
- for (Int_t idx = 0; idx < globalDecision->NumberOfInputObjects(); idx++) {\r
- \r
- const AliHLTTriggerDecision* triggerDecision = \r
- reinterpret_cast<const AliHLTTriggerDecision*>(globalDecision->InputObject(idx));\r
- \r
- if ( !(fTriggerString.CompareTo(triggerDecision->Description())) ) {\r
- triggered = triggerDecision->EventTriggered();\r
- break;\r
- }\r
- } // for (Int_t idx = 0; idx < globalDecision->NumberOfInputObjects(); idx++) {\r
- }\r
-\r
-\r
-\r
- if ( triggered ) {\r
- fRetryNextEvent = kFALSE;\r
- fNEventsNotTriggered = 0;\r
- }\r
- else {\r
- fRetryNextEvent = kTRUE;\r
- ++fNEventsNotTriggered;\r
- }\r
-\r
- return triggered;\r
-}\r
+//-*- Mode: C++ -*-
+// $Id$
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project *
+//* ALICE Experiment at CERN, All rights reserved. *
+//* *
+//* Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de> *
+//* for The ALICE HLT Project. *
+//* *
+//* Permission to use, copy, modify and distribute this software and its *
+//* documentation strictly for non-commercial purposes is hereby granted *
+//* without fee, provided that the above copyright notice appears in all *
+//* copies and that both the copyright notice and this permission notice *
+//* appear in the supporting documentation. The authors make no claims *
+//* about the suitability of this software for any purpose. It is *
+//* provided "as is" without express or implied warranty. *
+//**************************************************************************
+
+/** @file AliHLTHOMERManager.cxx
+ @author Jochen Thaeder
+ @date
+ @brief Manger for HOMER in aliroot
+*/
+
+// see header file for class documentation
+// or
+// refer to README to build package
+// or
+// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+
+#define EVE_DEBUG 0
+
+#include "AliHLTHOMERManager.h"
+// -- -- -- -- -- -- --
+#include "AliHLTHOMERLibManager.h"
+#include "AliHLTHOMERSourceDesc.h"
+#include "AliHLTHOMERBlockDesc.h"
+// -- -- -- -- -- -- --
+#include "AliHLTGlobalTriggerDecision.h"
+#include "AliHLTTriggerDecision.h"
+//---------------------------
+
+using std::cout;
+
+ClassImp(AliHLTHOMERManager)
+
+/*
+ * ---------------------------------------------------------------------------------
+ * Constructor / Destructor
+ * ---------------------------------------------------------------------------------
+ */
+
+//##################################################################################
+ AliHLTHOMERManager::AliHLTHOMERManager() :
+ fLibManager(new AliHLTHOMERLibManager),
+ fStateHasChanged(kTRUE),
+ fProxyHandler(NULL),
+ fCurrentReader(NULL),
+ fReaderList(NULL),
+ fSourceList(NULL),
+ fNBlks(0),
+ fEventID(),
+ fEventId(-1),
+ fCurrentBlk(0),
+ fAsyncBlockList(NULL),
+ fBlockList(NULL),
+ fEventBuffer(NULL),
+ fBufferTopIdx(-1),
+ fBufferLowIdx(-1),
+ fCurrentBufferIdx(-1),
+ fNavigateBufferIdx(-1),
+ fNEventsAvailable(0),
+ fConnected(kFALSE),
+ fTriggerString("ALL"),
+ fNEventsNotTriggered(0),
+ fRetryNextEvent(kFALSE),
+ fIsBlockOwner(kTRUE)
+{
+ // see header file for class documentation
+ // or
+ // refer to README to build package
+ // or
+ // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+
+}
+
+//##################################################################################
+AliHLTHOMERManager::~AliHLTHOMERManager() {
+ // see header file for class documentation
+
+ if ( fLibManager ) {
+
+ if ( fReaderList ) {
+ TIter next(fReaderList);
+ TObject * object = NULL;
+ while ( ( object = next()) )
+ fLibManager->DeleteReader(static_cast<AliHLTHOMERReader*>(object) );
+
+ fReaderList->Clear();
+ delete fReaderList;
+ }
+ fReaderList = NULL;
+
+ delete fLibManager;
+ }
+ fLibManager = NULL;
+
+ if ( fProxyHandler != NULL )
+ delete fProxyHandler;
+ fProxyHandler = NULL;
+
+ if ( fSourceList != NULL )
+ delete fSourceList;
+ fSourceList = NULL;
+
+ if ( fEventBuffer ) {
+ fEventBuffer->Clear();
+ delete fEventBuffer;
+ }
+ fEventBuffer = NULL;
+
+ if(fBlockList) {
+ fBlockList->Clear();
+ delete fBlockList;
+ }
+ fBlockList = NULL;
+
+ if ( fAsyncBlockList ) {
+ fAsyncBlockList->Delete();
+ delete fAsyncBlockList;
+ }
+ fAsyncBlockList = NULL;
+}
+
+//##################################################################################
+Int_t AliHLTHOMERManager::Initialize() {
+ // see header file for class documentation
+
+ HLTInfo("Initializing");
+
+ Int_t iResult = 0;
+
+ // -- Initialize ProxyHandler
+ if ( !fProxyHandler )
+ fProxyHandler = new AliHLTHOMERProxyHandler();
+
+ if ( fProxyHandler ) {
+ iResult = fProxyHandler->Initialize();
+ if (iResult)
+ HLTError("Initialize of ProxyHandler failed.");
+
+ } else {
+ iResult = -1;
+ HLTError("Creating of ProxyHandler failed.");
+ }
+
+ // -- Initialize ReaderList
+ // List ist not owner, as reader have to be created/deleted by the LibManager
+ if( !fReaderList )
+ fReaderList = new TList();
+
+ // -- Initialize asynchronous BlockList
+ if( !fAsyncBlockList ) {
+ fAsyncBlockList = new TList();
+ fAsyncBlockList->SetOwner(kTRUE);
+ }
+
+ //initialize normal block list
+ if( !fBlockList ) {
+ fBlockList = new TList();
+ fBlockList->SetOwner(kFALSE);
+ }
+
+ // -- Initialize Event Buffer and EventID array
+ if ( !fEventBuffer ) {
+ fEventBuffer = new TClonesArray( "TList", BUFFERSIZE );
+ }
+
+ for ( Int_t idx = 0; idx < BUFFERSIZE; ++idx ) {
+ new ((*fEventBuffer)[idx]) TList( );
+ (reinterpret_cast<TList*>((*fEventBuffer)[idx]))->SetOwner(kTRUE);
+
+ fEventID[idx] = 0;
+ }
+
+ return iResult;
+}
+
+/*
+ * ---------------------------------------------------------------------------------
+ * Source Handling
+ * ---------------------------------------------------------------------------------
+ */
+
+//##################################################################################
+Int_t AliHLTHOMERManager::CreateSourcesList() {
+ // see header file for class documentation
+
+ if (fProxyHandler == NULL)
+ {
+ HLTError("The object must first be initialised with a call to Initialize().");
+ return -1;
+ }
+
+ Int_t iResult = 0;
+
+ if ( fSourceList != NULL )
+ delete fSourceList;
+ fSourceList = NULL;
+
+ fSourceList = new TList();
+ fSourceList->SetOwner( kTRUE );
+
+ iResult = fProxyHandler->FillSourceList( fSourceList );
+ if ( iResult < 0 ) {
+ HLTWarning("There have been errors, while creating the sources list.");
+ }
+ else if ( iResult > 0 ) {
+ HLTWarning("No active services found.");
+ }
+ else if ( fSourceList->IsEmpty() ) {
+ HLTWarning("No active services in the list.");
+ iResult = 2;
+ }
+ else {
+ HLTInfo("New sources list created.");
+
+ // -- New SourceList has been created
+ // --> All Sources are new --> State has changed
+ fStateHasChanged = kTRUE;
+ }
+
+ return iResult;
+}
+
+//##################################################################################
+void AliHLTHOMERManager::SetSourceState( AliHLTHOMERSourceDesc * source, Bool_t state ) {
+ // see header file for class documentation
+
+ if ( source->IsSelected() != state ) {
+ source->SetState( state );
+ fStateHasChanged = kTRUE;
+ }
+
+ return;
+}
+
+/*
+ * ---------------------------------------------------------------------------------
+ * Connection Handling - public
+ * ---------------------------------------------------------------------------------
+ */
+
+//##################################################################################
+Int_t AliHLTHOMERManager::ConnectHOMER( TString detector ){
+ // see header file for class documentation
+
+ if (fReaderList == NULL or fSourceList == NULL)
+ {
+ HLTError("Must first create a source list with a call to CreateSourcesList().");
+ return -1;
+ }
+
+ Int_t iResult = 0;
+
+ // HAck Jochen
+ //----
+ detector="ALL";
+
+ // -- Check if LibManager is present
+ if ( ! fLibManager ) {
+ HLTError("No LibManager present.");
+ return -1;
+ }
+
+ // -- Check if already connected and state has not changed
+ if ( fStateHasChanged == kFALSE && IsConnected() ) {
+ HLTInfo("No need for reconnection.");
+ return 0;
+ }
+
+ // -- If already connected, disconnect before connect
+ // or if ReaderList already filled
+ if ( IsConnected() || fReaderList->GetSize() != 0 ) {
+ HLTInfo(Form("IsConnected: %d fReaderList.Size: %d", IsConnected(), fReaderList->GetSize()));
+ DisconnectHOMER();
+ }
+ // -- Create the Readoutlist
+ UShort_t* sourcePorts = new UShort_t [fSourceList->GetEntries()];
+ const Char_t ** sourceHostnames = new const Char_t* [fSourceList->GetEntries()];
+ for(Int_t i = 0; i < fSourceList->GetEntries(); i++) {
+ sourceHostnames[i] = "";
+ }
+ UInt_t sourceCount = 0;
+
+ CreateReadoutList( sourceHostnames, sourcePorts, sourceCount, detector );
+ if ( sourceCount == 0 ) {
+ HLTError("No sources selected, aborting.");
+ delete [] sourcePorts;
+ delete [] sourceHostnames;
+ return -2;
+ }
+
+ // ***
+ // *** Connect to data sources
+ // ***
+
+ for (UInt_t idx = 0; idx < sourceCount; idx++) {
+
+ if (sourcePorts[idx] > 60000)
+ continue;
+
+ HLTInfo(Form("Adding source %d as %s : %d", idx, sourceHostnames[idx], sourcePorts[idx]));
+
+ fReaderList->Add(dynamic_cast<TObject*>(fLibManager->OpenReader(sourceHostnames[idx], sourcePorts[idx])));
+ AliHLTHOMERReader *reader = static_cast<AliHLTHOMERReader*>(fReaderList->Last());
+ if ( !reader ) {
+ HLTError("Adding reader failed, aborting");
+ delete [] sourcePorts;
+ delete [] sourceHostnames;
+ return -3;
+ }
+
+ if ( (iResult = reader->GetConnectionStatus()) ) {
+
+ // -- Connection to source failed
+
+ HLTError(Form("Error establishing connection to TCP source %s:%hu: %s (%d)",
+ sourceHostnames[idx], sourcePorts[idx], strerror(iResult), iResult));
+
+ if( !(TString(sourceHostnames[idx]).CompareTo("localhost")) ) {
+ HLTInfo("The failed connection is on localhost. is SSH tunnel up????? ");
+ HLTInfo(Form("Do: 'ssh -L %d:alihlt-vobox0.cern.ch:%d cernUser@lxplus.cern.ch -fN'",
+ sourcePorts[idx], sourcePorts[idx]));
+ }
+
+ // -- Remove reader
+ fReaderList->RemoveLast();
+
+ if ( reader )
+ fLibManager->DeleteReader( reader );
+ reader = NULL;
+
+ HLTInfo(Form("Removed source %d, %s : %d from sourceList", idx, sourceHostnames[idx], sourcePorts[idx]));
+
+ }
+ else {
+ // -- Connection succeded
+ fConnected = kTRUE;
+
+ HLTInfo(Form("Connection established to source %s on port %d", sourceHostnames[idx], sourcePorts[idx]));
+ }
+
+ } // for (Int_t idx = 0; idx < sourceCount; idx++) {
+
+ delete[] sourceHostnames;
+ delete[] sourcePorts;
+
+ return iResult;
+
+}
+
+//##################################################################################
+void AliHLTHOMERManager::DisconnectHOMER(){
+ // see header file for class documentation
+
+ HLTInfo("Disconnecting");
+
+ if ( fReaderList && fLibManager ) {
+ HLTInfo("Deleting readerlist and libmanager");
+ TIter next(fReaderList);
+ TObject * object = NULL;
+ while ( ( object = next()) )
+ fLibManager->DeleteReader(static_cast<AliHLTHOMERReader*>(object) );
+
+
+ HLTInfo(Form("fReaderList size %d", fReaderList->GetSize()));
+ fReaderList->Clear();
+ HLTInfo(Form("fReaderList size %d", fReaderList->GetSize()));
+ delete fReaderList;
+ fReaderList = new TList ();
+ HLTInfo(Form("fReaderList size %d", fReaderList->GetSize()));
+ }
+
+ fStateHasChanged = kTRUE;
+ fConnected = kFALSE;
+
+ HLTInfo("Connection closed.");
+
+ return;
+}
+
+//##################################################################################
+Int_t AliHLTHOMERManager::ReconnectHOMER( TString detector="" ){
+ // see header file for class documentation
+
+ Int_t iResult = 0;
+
+ if ( IsConnected() )
+ DisconnectHOMER();
+
+ iResult = ConnectHOMER(detector);
+ if ( iResult ) {
+ HLTError("Error reconnecting.");
+ }
+
+ return iResult;
+}
+
+/*
+ * ---------------------------------------------------------------------------------
+ * Event Handling - public
+ * ---------------------------------------------------------------------------------
+ */
+
+//##################################################################################
+Int_t AliHLTHOMERManager::NextEvent(){
+
+ // see header file for class documentation
+
+ Int_t iResult = 0;
+ Int_t iRetryCount = 0;
+
+ if ( !IsConnected() || fStateHasChanged ) {
+ HLTInfo("Not connected or state has changed, returning to AliEveHOMERManager, which will deal with this situation");
+ // cout << "connectecd " << IsConnected() << "haschanged "<<fStateHasChanged << endl;
+ return 55;//ConnectHOMER();
+ }
+ if ( !IsConnected() ) {
+ HLTWarning("Not connected yet.");
+ return -1;
+ }
+
+ // -- Reset asyncronous BlockList
+ fAsyncBlockList->Delete();
+
+ // ***
+ // *** Loop over all readers and get new event data
+ // ***
+
+ TIter next(fReaderList);
+ TObject * object = NULL;
+
+ while( (object = next()) ) {
+
+ fCurrentReader = static_cast<AliHLTHOMERReader*>(object);
+
+ // -- Read next event data and error handling for HOMER (error codes and empty blocks)
+ while ( 1 ) {
+
+ iResult = fCurrentReader->ReadNextEvent( 40000000 /*timeout in us*/);
+
+ if ( iResult == 111 || iResult == 32 || iResult == 6 ) {
+ HLTError(Form("No connection to source %d: %s (%d)",
+ fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
+ break;
+ }
+ else if ( iResult == 110 ) {
+ HLTError(Form("Timeout occured, reading event from source %d: %s (%d)",
+ fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
+ break;
+ }
+ else if ( iResult == 56 ) {
+ ++iRetryCount;
+
+ if ( iRetryCount >= 20 ) {
+ HLTError(Form("Retry Failed: Error reading event from source %d: %s (%d), returning",
+ fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
+ break;
+ }
+ else {
+ HLTError(Form("Retry: Error reading event from source %d: %s (%d), making another attempt (no %d out of 20)",
+ fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult, iRetryCount));
+ //break;
+ continue;
+ }
+ }
+ else if ( iResult ) {
+ HLTError(Form("General Error reading event from source %d: %s (%d), giving up",
+ fCurrentReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
+ fConnected = kFALSE;
+ break;
+ }
+ else {
+ HLTDebug("Successfully read out event from source");
+ break;
+ }
+
+ } // while( 1 ) {
+
+ // -- Check if event could be read
+ if ( iResult ) {
+ HLTInfo("Reading event from source failed");
+ continue;
+ }
+
+ // -- Handle Blocks from current reader
+ iResult = HandleBlocks();
+ if ( iResult ) {
+ HLTError("Handling of blocks failed.");
+ }
+
+ } // while( (object = next()) ) {
+
+ return iResult;
+}
+
+/* ---------------------------------------------------------------------------------
+ * Buffer Handling - public
+ * ---------------------------------------------------------------------------------
+ */
+
+//##################################################################################
+Int_t AliHLTHOMERManager::NavigateEventBufferBack() {
+ // see header file for class documentation
+
+ // -- reached the end of the buffer
+ if ( fNavigateBufferIdx == fBufferLowIdx )
+ return -1;
+
+ Int_t newIdx = fNavigateBufferIdx - 1;
+ if ( newIdx == -1 )
+ newIdx = BUFFERSIZE-1;
+
+ fCurrentBufferIdx = fNavigateBufferIdx = newIdx;
+
+ return newIdx;
+}
+
+//##################################################################################
+Int_t AliHLTHOMERManager::NavigateEventBufferFwd() {
+ // see header file for class documentation
+
+ HLTInfo(Form("fNavigateBufferIdx: %d, fCurrentBufferIdx %d, fBufferTopIdx %d", fNavigateBufferIdx, fCurrentBufferIdx, fBufferTopIdx));
+
+ // -- reached the top of the buffer
+ if ( fNavigateBufferIdx == fBufferTopIdx )
+ return -1;
+
+ Int_t newIdx = fNavigateBufferIdx + 1;
+ if ( newIdx == BUFFERSIZE )
+ newIdx = 0;
+
+ fCurrentBufferIdx = fNavigateBufferIdx = newIdx;
+ fNEventsAvailable -= 1;
+
+ HLTInfo(Form("fNavigateBufferIdx: %d, fCurrentBufferIdx %d, fBufferTopIdx %d", fNavigateBufferIdx, fCurrentBufferIdx, fBufferTopIdx));
+
+
+ return 0;
+}
+
+ ///////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * ---------------------------------------------------------------------------------
+ * Connection Handling - private
+ * ---------------------------------------------------------------------------------
+ */
+
+//##################################################################################
+void AliHLTHOMERManager::CreateReadoutList( const char** sourceHostnames, UShort_t *sourcePorts,
+ UInt_t &sourceCount, TString detector ){
+ // see header file for class documentation
+
+ AliHLTHOMERSourceDesc * source= NULL;
+
+ // -- Read all sources and check if they should be read out
+ TIter next( fSourceList );
+ while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
+
+ ///Don't use sources from dev cluster
+ if(source->GetPort() > 60000) continue;
+
+ // -- If detector NO detector name given
+ if ( ! detector.CompareTo("ALL") ) {
+ // -- Continue if source is not selected
+ // HACK Jochen
+ //if ( ! source->IsSelected() )
+ // continue;
+ }
+ // -- DetectorName given
+ else {
+ // -- Continue if detector name doesn't match
+ if ( detector.CompareTo(source->GetDetector()) )
+ continue;
+ else
+ source->Select();
+ }
+
+ Bool_t exists = kFALSE;
+
+ // -- Loop over existing entries and check if entry is already in readout list
+ for ( UInt_t ii = 0; ii < sourceCount; ii++ ){
+ if ( !strcmp( sourceHostnames[ii], source->GetHostname().Data() )
+ && sourcePorts[ii] == source->GetPort() ) {
+ exists = kTRUE;
+ break;
+ }
+ }
+
+ // -- Add new entires to readout list
+ if ( ! exists ) {
+ sourcePorts[sourceCount] = source->GetPort();
+ sourceHostnames[sourceCount] = source->GetHostname().Data();
+ sourceCount++;
+ }
+
+ } // while ( ( source = (AliHLTHOMERSourceDesc*)next() ) ) {
+
+ fStateHasChanged = kFALSE;
+
+ return;
+}
+
+/*
+ * ---------------------------------------------------------------------------------
+ * Buffer Handling - private
+ * ---------------------------------------------------------------------------------
+ */
+
+//##################################################################################
+void AliHLTHOMERManager::AddBlockListToBuffer() {
+ // see header file for class documentation
+ // -- Check if event is already in buffer
+ ULong_t eventID = static_cast<ULong64_t>(fCurrentReader->GetEventID());
+
+ if ( fEventID[fBufferTopIdx] == eventID ) {
+ HLTInfo(Form("Event 0x%016lX (%lu) already in buffer.", eventID, eventID));
+ return;
+ }
+
+ // -- Check if event should be selected on basis of trigger string
+ if( fTriggerString.CompareTo("ALL") ){
+ if ( !CheckTriggerDecision() ) {
+ HLTInfo("Event not triggered");
+ return;
+ } else {
+ HLTInfo("Event triggered");
+ }
+ }
+ else {
+ HLTDebug("No trigger selection.");
+ }
+
+ // -- Set Top mark
+ ++fBufferTopIdx;
+ if ( fBufferTopIdx == BUFFERSIZE )
+ fBufferTopIdx = 0;
+
+ // -- Change the low mark if necessary
+ if ( fBufferLowIdx == -1 )
+ fBufferLowIdx = 0;
+ else if ( fBufferTopIdx == fBufferLowIdx ) {
+ ++fBufferLowIdx;
+ if ( fBufferLowIdx == BUFFERSIZE )
+ fBufferLowIdx = 0;
+ }
+
+
+ // -- Fill EventID
+ fEventID[fBufferTopIdx] = eventID;
+
+ // -- Clear Buffer slot
+ (reinterpret_cast<TList*>((*fEventBuffer)[fBufferTopIdx]))->Clear();
+ if(fBlockList->IsOwner()) HLTWarning("block list is owner!!");
+ HLTInfo(Form("fBlockList size %d", fBlockList->GetSize()));
+ //fBlockList->Clear();
+ fBlockList = new TList();
+ HLTInfo(Form("fBlockList size %d", fBlockList->GetSize()));
+
+ GetFirstBlk();
+
+ // -- Fill block list
+ do {
+
+ // -- Create new block
+ AliHLTHOMERBlockDesc * block = new AliHLTHOMERBlockDesc();
+ block->SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),
+ GetBlkType(), GetBlkSpecification() );
+
+ // -- Check sources list if block is requested
+ if ( CheckIfRequested( block ) ) {
+ (reinterpret_cast<TList*>((*fEventBuffer)[fBufferTopIdx]))->Add( block );
+ fBlockList->Add(block);
+ }
+ else {
+ // XXX HACK Jochen
+ (reinterpret_cast<TList*>((*fEventBuffer)[fBufferTopIdx]))->Add( block );
+ fBlockList->Add(block);
+ // delete block;
+ // block = NULL;
+ }
+
+ } while( GetNextBlk() );
+
+ //We have one more event available
+ fNEventsAvailable++;
+ HLTInfo(Form("fNEventsAvailable %d", fNEventsAvailable));
+ return;
+}
+
+//##################################################################################
+void AliHLTHOMERManager::AddToAsyncBlockList() {
+ // see header file for class documentation
+
+ HLTInfo("Adding blocks to the asynchroneous block list");
+
+ GetFirstBlk();
+
+ do {
+
+ AliHLTHOMERBlockDesc * block = new AliHLTHOMERBlockDesc();
+ block->SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),
+ GetBlkType(), GetBlkSpecification() );
+
+
+ fAsyncBlockList->Add( block );
+
+ } while( GetNextBlk() );
+
+ return;
+}
+//__________________________________________________________________________________
+void AliHLTHOMERManager::AddToBlockList() {
+ // see header file for class documentation
+ HLTInfo("Adding blocks to the synchroneous block list");
+
+ ULong_t eventID = static_cast<ULong64_t>(fCurrentReader->GetEventID());
+
+ if ( fEventId == eventID ) {
+ HLTInfo(Form("Event 0x%016lX (%lu) already in buffer.", eventID, eventID));
+ return;
+ }
+
+ fEventId = eventID;
+
+ GetFirstBlk();
+ do {
+
+ AliHLTHOMERBlockDesc * block = new AliHLTHOMERBlockDesc();
+ block->SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),
+ GetBlkType(), GetBlkSpecification() );
+ fBlockList->Add( block );
+
+ } while( GetNextBlk() );
+}
+
+//__________________________________________________________________________________
+TList* AliHLTHOMERManager::GetBlockListEventBuffer() {
+ // see header file for class documentation
+
+ if(fBlockList)
+ return fBlockList;
+ else
+ return NULL;
+
+
+}
+
+
+//__________________________________________________________________________________
+Int_t AliHLTHOMERManager::HandleBlocks() {
+ // see header file for class documentation
+
+ Int_t iResult = 0;
+
+ // -- Get blockCnt and eventID
+ fNBlks = static_cast<ULong_t>(fCurrentReader->GetBlockCnt());
+ ULong_t eventID = static_cast<ULong64_t>(fCurrentReader->GetEventID());
+ fCurrentBlk = 0;
+
+ // -- Check if blocks present
+ if ( fNBlks == 0 ) {
+ HLTWarning(Form("Event 0x%016lX (%lu) with no blocks", eventID, eventID));
+ return -1;
+ }
+
+ HLTInfo(Form("Event 0x%016lX (%lu) with %lu blocks", eventID, eventID, fNBlks));
+
+ if ( IsSyncBlocks() ) {
+ //AddBlockListToBuffer();
+ fBlockList->Clear();
+ AddToBlockList();
+ } else {
+ AddToAsyncBlockList();
+ }
+
+ return iResult;
+}
+
+//__________________________________________________________________________________
+Bool_t AliHLTHOMERManager::IsSyncBlocks() {
+ // see header file for class documentation
+
+ Bool_t bResult = kFALSE;
+
+ GetFirstBlk();
+
+ do {
+
+ if ( !GetBlkType().CompareTo("ALIESDV0")) {
+ bResult = kTRUE;
+ break;
+ }
+
+ if ( !GetBlkType().CompareTo("GLOBTRIG")) {
+ bResult = kTRUE;
+ break;
+ }
+
+ if ( !GetBlkType().CompareTo("ROOTTOBJ") ) {
+ AliHLTHOMERBlockDesc blockDesc;
+
+ blockDesc.SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),
+ GetBlkType(), GetBlkSpecification() );
+ if ( !blockDesc.GetClassName().CompareTo("AliHLTGlobalTriggerDecision") ) {
+
+ bResult = kTRUE;
+ break;
+ }
+ }
+
+ } while( GetNextBlk() );
+
+
+ return bResult;
+}
+
+//##################################################################################
+void* AliHLTHOMERManager::GetBlk( Int_t ndx ) {
+ // see header file for class documentation
+ // Get pointer to current block in current event
+
+ if ( !fCurrentReader || !IsConnected() ) {
+ HLTError("Not connected yet.");
+ return NULL;
+ }
+ if ( ndx < static_cast<Int_t>(fNBlks) )
+ return const_cast<void*> (fCurrentReader->GetBlockData(ndx));
+ else
+ return NULL;
+}
+
+//##################################################################################
+ULong_t AliHLTHOMERManager::GetBlkSize( Int_t ndx ) {
+ // see header file for class documentation
+
+ if ( !fCurrentReader || !IsConnected() ) {
+ HLTError("Not connected yet.");
+ return 0;
+ }
+
+ if ( ndx < static_cast<Int_t>(fNBlks) )
+ return static_cast<ULong_t> (fCurrentReader->GetBlockDataLength(ndx));
+ else
+ return 0;
+}
+
+//##################################################################################
+TString AliHLTHOMERManager::GetBlkOrigin( Int_t ndx ) {
+ // see header file for class documentation
+
+ TString origin = "";
+
+ // -- Check for Connection
+ if ( !fCurrentReader || ! IsConnected() ) {
+ HLTError("Not connected yet.");
+ return origin;
+ }
+
+ // -- Check block index
+ if ( ndx >= static_cast<Int_t>(fNBlks) ) {
+ HLTError(Form("Block index %d out of range.", ndx ));
+ return origin;
+ }
+
+ // -- Get origin
+ union{
+ UInt_t data;
+ Char_t array[4];
+ } reverseOrigin;
+
+ reverseOrigin.data = static_cast<UInt_t>(fCurrentReader->GetBlockDataOrigin(ndx));
+
+ // -- Reverse the order
+ for (Int_t ii = 3; ii >= 0; ii-- )
+ if ( reverseOrigin.array[ii] != ' ')
+ origin.Append( reverseOrigin.array[ii] );
+
+ origin.Remove( TString::kTrailing, ' ' );
+
+ return origin;
+}
+
+//##################################################################################
+TString AliHLTHOMERManager::GetBlkType( Int_t ndx ) {
+ // see header file for class documentation
+
+ TString type = "";
+
+ // -- Check for Connection
+ if ( !fCurrentReader || ! IsConnected() ) {
+ HLTError("Not connected yet.");
+ return type;
+ }
+
+ // -- Check block index
+ if ( ndx >= static_cast<Int_t>(fNBlks) ) {
+ HLTError(Form("Block index %d out of range.", ndx ));
+ return type;
+ }
+
+ // -- Get type
+ union{
+ ULong64_t data;
+ Char_t array[8];
+ } reverseType;
+
+ reverseType.data = static_cast<ULong64_t> (fCurrentReader->GetBlockDataType(ndx));
+
+ // -- Reverse the order
+ for (Int_t ii = 7; ii >= 0; ii-- )
+ if ( reverseType.array[ii] != ' ')
+ type.Append( reverseType.array[ii] );
+
+ type.Remove( TString::kTrailing, ' ' );
+
+ return type;
+}
+
+//##################################################################################
+ULong_t AliHLTHOMERManager::GetBlkSpecification( Int_t ndx ) {
+ // see header file for class documentation
+
+ // -- Check for Connection
+ if ( !fCurrentReader || ! IsConnected() ) {
+ HLTError("Not connected yet.");
+ return 0;
+ }
+
+ // -- Check block index
+ if ( ndx >= static_cast<Int_t>(fNBlks) ) {
+ HLTError(Form("Block index %d out of range.", ndx ));
+ return 0;
+ }
+
+ return static_cast<ULong_t>(fCurrentReader->GetBlockDataSpec(ndx));
+}
+
+//##################################################################################
+Bool_t AliHLTHOMERManager::CheckIfRequested( AliHLTHOMERBlockDesc * block ) {
+ // see header file for class documentation
+
+ Bool_t requested = kFALSE;
+
+ AliHLTHOMERSourceDesc * source= NULL;
+
+ // -- Read all sources and check if they should be read out
+ TIter next( fSourceList );
+ while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
+
+ // -- Check if source is selected
+ if ( ! source->IsSelected() )
+ continue;
+
+ // -- Check if detector matches
+ if ( source->GetSourceName().CompareTo( block->GetBlockName() ) )
+ continue;
+
+ requested = kTRUE;
+ break;
+
+ } // while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
+
+#if EVE_DEBUG
+ if ( requested ) {
+ HLTInfo(Form("Block requested : %s", block->GetBlockName().Data()));
+ }
+ else {
+ HLTInfo(Form("Block NOT requested : %s", block->GetBlockName().Data()));
+ }
+#endif
+
+ return requested;
+}
+
+/* ---------------------------------------------------------------------------------
+ * Trigger Handling - private
+ * ---------------------------------------------------------------------------------
+ */
+
+//##################################################################################
+Bool_t AliHLTHOMERManager::CheckTriggerDecision() {
+ // see header file for class documentation
+
+ Bool_t triggered = kFALSE;
+
+ if ( !fCurrentReader || !IsConnected() ) {
+ HLTError("Not connected yet.");
+ return kFALSE;
+ }
+
+ AliHLTHOMERBlockDesc blockDesc;
+
+ GetFirstBlk();
+
+ // -- Fill block list
+ Bool_t foundTriggerBlock = kFALSE;
+
+ do {
+ if ( (GetBlkType().CompareTo("ROOTTOBJ") == 0) ) {
+ blockDesc.SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),
+ GetBlkType(), GetBlkSpecification() );
+
+ if ( ! blockDesc.GetClassName().CompareTo("AliHLTGlobalTriggerDecision") ) {
+
+ foundTriggerBlock = kTRUE;
+ break;
+ }
+
+ }
+ } while( GetNextBlk() );
+
+ if ( !foundTriggerBlock ) {
+ HLTError("No trigger decision object found");
+ return kFALSE;
+ }
+
+ // -- Get the global decision object
+ AliHLTGlobalTriggerDecision* globalDecision =
+ static_cast<AliHLTGlobalTriggerDecision*>(blockDesc.GetTObject());
+
+ if ( fTriggerString.CompareTo("HLTGlobalTrigger") == 0 ) {
+ triggered = globalDecision->EventTriggered();
+ }
+ else {
+
+ for (Int_t idx = 0; idx < globalDecision->NumberOfInputObjects(); idx++) {
+
+ const AliHLTTriggerDecision* triggerDecision =
+ reinterpret_cast<const AliHLTTriggerDecision*>(globalDecision->InputObject(idx));
+
+ if ( !(fTriggerString.CompareTo(triggerDecision->Description())) ) {
+ triggered = triggerDecision->EventTriggered();
+ break;
+ }
+ } // for (Int_t idx = 0; idx < globalDecision->NumberOfInputObjects(); idx++) {
+ }
+
+
+
+ if ( triggered ) {
+ fRetryNextEvent = kFALSE;
+ fNEventsNotTriggered = 0;
+ }
+ else {
+ fRetryNextEvent = kTRUE;
+ ++fNEventsNotTriggered;
+ }
+
+ return triggered;
+}