2 // $Id: AliHLTHOMERManager.cxx $
3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de> *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /** @file AliHLTHOMERManager.cxx
20 @author Jochen Thaeder
22 @brief Manger for HOMER in aliroot
25 // see header file for class documentation
27 // refer to README to build package
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
37 #include "AliHLTHOMERManager.h"
38 // -- -- -- -- -- -- --
39 #include "AliHLTHOMERLibManager.h"
40 #include "AliHLTHOMERSourceDesc.h"
41 #include "AliHLTHOMERBlockDesc.h"
42 // -- -- -- -- -- -- --
43 ClassImp(AliHLTHOMERManager)
46 * ---------------------------------------------------------------------------------
47 * Constructor / Destructor
48 * ---------------------------------------------------------------------------------
51 //##################################################################################
52 AliHLTHOMERManager::AliHLTHOMERManager() :
53 fLibManager(new AliHLTHOMERLibManager),
54 fStateHasChanged(kTRUE),
64 fCurrentBufferIdx(-1),
65 fNavigateBufferIdx(-1),
67 // see header file for class documentation
69 // refer to README to build package
71 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
75 //##################################################################################
76 AliHLTHOMERManager::~AliHLTHOMERManager() {
77 // see header file for class documentation
81 fLibManager->DeleteReader(fReader);
87 if ( fProxyHandler != NULL )
91 if ( fSourceList != NULL )
96 fEventBuffer->Clear();
102 //##################################################################################
103 Int_t AliHLTHOMERManager::Initialize() {
104 // see header file for class documentation
108 if ( !fProxyHandler )
109 fProxyHandler = new AliHLTHOMERProxyHandler();
111 if ( fProxyHandler ) {
112 iResult = fProxyHandler->Initialize();
114 HLTError(Form("Initialize of ProxyHandler failed."));
118 HLTError(Form("Creating of ProxyHandler failed."));
121 // -- Initialize Event Buffer
122 if ( !fEventBuffer ) {
123 fEventBuffer = new TClonesArray( "TList", BUFFERSIZE );
126 for ( Int_t idx = 0; idx < BUFFERSIZE; ++idx ) {
127 new ((*fEventBuffer)[idx]) TList();
128 (reinterpret_cast<TList*>((*fEventBuffer)[idx]))->SetOwner(kTRUE);
137 * ---------------------------------------------------------------------------------
139 * ---------------------------------------------------------------------------------
142 //##################################################################################
143 Int_t AliHLTHOMERManager::CreateSourcesList() {
144 // see header file for class documentation
148 if ( fSourceList != NULL )
152 fSourceList = new TList();
153 fSourceList->SetOwner( kTRUE );
155 iResult = fProxyHandler->FillSourceList( fSourceList );
157 HLTWarning(Form("There have been errors, while creating the sources list."));
159 else if ( iResult > 0 ) {
160 HLTWarning(Form("No active services found."));
162 else if ( fSourceList->IsEmpty() ) {
163 HLTWarning(Form("No active services in the list."));
167 HLTInfo(Form("New sources list created."));
169 // -- New SourceList has been created
170 // --> All Sources are new --> State has changed
171 fStateHasChanged = kTRUE;
177 //##################################################################################
178 void AliHLTHOMERManager::SetSourceState( AliHLTHOMERSourceDesc * source, Bool_t state ) {
179 // see header file for class documentation
181 if ( source->IsSelected() != state ) {
182 source->SetState( state );
183 fStateHasChanged = kTRUE;
190 * ---------------------------------------------------------------------------------
191 * Connection Handling - public
192 * ---------------------------------------------------------------------------------
195 //##################################################################################
196 Int_t AliHLTHOMERManager::ConnectHOMER( TString detector ){
197 // see header file for class documentation
201 // -- Check if LibManager is present
202 if ( ! fLibManager ) {
203 HLTError(Form("No LibManager present."));
207 // -- Check if already connected and state has not changed
208 if ( fStateHasChanged == kFALSE && IsConnected() ) {
209 HLTInfo(Form("No need for reconnection."));
213 // -- If already connected, disconnect before connect
217 // -- Create the Readoutlist
218 UShort_t* sourcePorts = new UShort_t [fSourceList->GetEntries()];
219 const char ** sourceHostnames = new const char* [fSourceList->GetEntries()];
220 UInt_t sourceCount = 0;
222 CreateReadoutList( sourceHostnames, sourcePorts, sourceCount, detector );
223 if ( sourceCount == 0 ) {
224 HLTError(Form("No sources selected, aborting."));
228 // *** Connect to data sources
230 fReader = fLibManager->OpenReader( sourceCount, sourceHostnames, sourcePorts );
232 iResult = fReader->GetConnectionStatus();
234 // -- Connection failed
236 UInt_t ndx = fReader->GetErrorConnectionNdx();
238 if ( ndx < sourceCount ) {
239 HLTError(Form("Error establishing connection to TCP source %s:%hu: %s (%d)",
240 sourceHostnames[ndx], sourcePorts[ndx], strerror(iResult), iResult));
243 HLTError(Form("Error establishing connection to unknown source with index %d: %s (%d)",
244 ndx, strerror(iResult), iResult));
248 fLibManager->DeleteReader( fReader );
252 // -- Connection ok - set reader
255 HLTInfo(Form("Connection established."));
258 delete[] sourceHostnames;
259 delete[] sourcePorts;
264 //##################################################################################
265 void AliHLTHOMERManager::DisconnectHOMER(){
266 // see header file for class documentation
268 if ( ! IsConnected() )
272 fLibManager->DeleteReader( fReader );
275 fStateHasChanged = kTRUE;
278 HLTInfo(Form("Connection closed."));
283 //##################################################################################
284 Int_t AliHLTHOMERManager::ReconnectHOMER( TString detector="" ){
285 // see header file for class documentation
292 iResult = ConnectHOMER(detector);
294 HLTError(Form("Error reconnecting."));
301 * ---------------------------------------------------------------------------------
302 * Event Handling - public
303 * ---------------------------------------------------------------------------------
306 //##################################################################################
307 Int_t AliHLTHOMERManager::NextEvent(){
308 // see header file for class documentation
311 Int_t iRetryCount = 0;
313 if ( !IsConnected() || fStateHasChanged )
316 if ( !fReader || !IsConnected() ) {
317 HLTWarning(Form( "Not connected yet." ));
321 // fReader->SetEventRequestAdvanceTime( 20000000 /*timeout in us*/ );
323 // -- Read next event data and error handling for HOMER (error codes and empty blocks)
326 iResult = fReader->ReadNextEvent( 40000000 /*timeout in us*/);
328 if ( iResult == 111 || iResult == 32 || iResult == 6 ) {
329 HLTError(Form("No Connection to source %d: %s (%d)",
330 fReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
333 else if ( iResult == 110 ) {
334 HLTError(Form("Timeout occured, reading event from source %d: %s (%d)",
335 fReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
338 else if ( iResult == 56) {
341 if ( iRetryCount >= 20 ) {
342 HLTError(Form("Retry Failed: Error reading event from source %d: %s (%d)",
343 fReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
347 HLTError(Form("Retry: Error reading event from source %d: %s (%d)",
348 fReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
352 else if ( iResult ) {
353 HLTError(Form("General Error reading event from source %d: %s (%d)",
354 fReader->GetErrorConnectionNdx(), strerror(iResult), iResult));
363 // -- Get blockCnt and eventID
364 fNBlks = static_cast<ULong_t>(fReader->GetBlockCnt());
365 ULong_t eventID = static_cast<ULong64_t>(fReader->GetEventID());
368 HLTInfo(Form("Event 0x%016LX (%Lu) with %lu blocks", eventID,eventID, fNBlks));
371 // Loop for Debug only
372 for ( ULong_t ii = 0; ii < fNBlks; ii++ ) {
373 Char_t tmp1[9], tmp2[5];
374 memset( tmp1, 0, 9 );
375 memset( tmp2, 0, 5 );
377 ULong64_t* tmp12 = static_cast<ULong64_t*>(tmp11);
378 *tmp12 = fReader->GetBlockDataType(ii);
380 ULong_t* tmp22 = static_cast<ULong_t*>(tmp21);
381 *tmp22 = fReader->GetBlockDataOrigin(ii);
382 HLTInfo(Form( "Block %lu length: %lu - type: %s - origin: %s - spec 0x%08X",
383 ii, fReader->GetBlockDataLength(ii), tmp1, tmp2, fReader->GetBlockDataSpec(ii) ));
384 } // end for ( ULong_t ii = 0; ii < fNBlks; ii++ ) {
387 // -- Create BlockList
389 HLTInfo(Form("Add Block List to buffer"));
390 AddBlockListToBuffer();
393 HLTWarning(Form("Event 0x%016LX (%Lu) with %lu blocks", eventID, eventID, fNBlks));
399 /* ---------------------------------------------------------------------------------
400 * Buffer Handling - public
401 * ---------------------------------------------------------------------------------
404 //##################################################################################
405 Int_t AliHLTHOMERManager::NavigateEventBufferBack() {
406 // see header file for class documentation
408 // -- reached the end of the buffer
409 if ( fNavigateBufferIdx == fBufferLowIdx )
412 Int_t newIdx = fNavigateBufferIdx - 1;
414 newIdx = BUFFERSIZE-1;
416 fCurrentBufferIdx = fNavigateBufferIdx = newIdx;
421 //##################################################################################
422 Int_t AliHLTHOMERManager::NavigateEventBufferFwd() {
423 // see header file for class documentation
425 // -- reached the top of the buffer
426 if ( fNavigateBufferIdx == fBufferTopIdx )
429 Int_t newIdx = fNavigateBufferIdx + 1;
430 if ( newIdx == BUFFERSIZE )
433 fCurrentBufferIdx = fNavigateBufferIdx = newIdx;
438 ///////////////////////////////////////////////////////////////////////////////////
441 * ---------------------------------------------------------------------------------
442 * Connection Handling - private
443 * ---------------------------------------------------------------------------------
446 //##################################################################################
447 void AliHLTHOMERManager::CreateReadoutList( const char** sourceHostnames, UShort_t *sourcePorts,
448 UInt_t &sourceCount, TString detector ){
449 // see header file for class documentation
451 AliHLTHOMERSourceDesc * source= NULL;
453 // -- Read all sources and check if they should be read out
454 TIter next( fSourceList );
455 while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
457 // -- If detector NO detector name given
458 if ( ! detector.CompareTo("ALL") ) {
459 // -- Continue if source is not selected
460 if ( ! source->IsSelected() )
463 // -- DetectorName given
465 // -- Continue if detector name doesn't match
466 if ( detector.CompareTo(source->GetDetector()) )
472 Bool_t exists = kFALSE;
474 // -- Loop over existing entries and check if entry is already in readout list
475 for ( UInt_t ii = 0; ii < sourceCount; ii++ ){
476 if ( !strcmp( sourceHostnames[ii], source->GetHostname().Data() )
477 && sourcePorts[ii] == source->GetPort() ) {
483 // -- Add new entires to readout list
485 sourcePorts[sourceCount] = source->GetPort();
486 sourceHostnames[sourceCount] = source->GetHostname().Data();
490 } // while ( ( source = (AliHLTHOMERSourceDesc*)next() ) ) {
492 fStateHasChanged = kFALSE;
498 * ---------------------------------------------------------------------------------
499 * Buffer Handling - private
500 * ---------------------------------------------------------------------------------
503 //##################################################################################
504 void AliHLTHOMERManager::AddBlockListToBuffer() {
505 // see header file for class documentation
509 if ( fBufferTopIdx == BUFFERSIZE )
512 // -- Change the low mark if necessary
513 if ( fBufferLowIdx == -1 )
515 else if ( fBufferTopIdx == fBufferLowIdx ) {
517 if ( fBufferLowIdx == BUFFERSIZE )
521 fNavigateBufferIdx = fCurrentBufferIdx = fBufferTopIdx;
524 fEventID[fBufferTopIdx] = static_cast<ULong64_t>(fReader->GetEventID());
526 // -- Clear Buffer slot
527 (reinterpret_cast<TList*>((*fEventBuffer)[fBufferTopIdx]))->Clear();
531 // -- Fill block list
534 // -- Create new block
535 AliHLTHOMERBlockDesc * block = new AliHLTHOMERBlockDesc();
536 block->SetBlock( GetBlk(), GetBlkSize(), GetBlkOrigin(),
537 GetBlkType(), GetBlkSpecification() );
539 // -- Check sources list if block is requested
540 if ( CheckIfRequested( block ) ) {
541 (reinterpret_cast<TList*>((*fEventBuffer)[fBufferTopIdx]))->Add( block );
545 (reinterpret_cast<TList*>((*fEventBuffer)[fBufferTopIdx]))->Add( block );
550 } while( GetNextBlk() );
555 //##################################################################################
556 TList* AliHLTHOMERManager::GetBlockListEventBuffer( Int_t idx ) {
557 // see header file for class documentation
562 return reinterpret_cast<TList*>((*fEventBuffer)[idx]);
566 * ---------------------------------------------------------------------------------
567 * Block Handling - private
568 * ---------------------------------------------------------------------------------
571 //##################################################################################
572 void* AliHLTHOMERManager::GetBlk( Int_t ndx ) {
573 // see header file for class documentation
574 // Get pointer to current block in current event
576 if ( !fReader || !IsConnected() ) {
577 HLTError(Form("Not connected yet."));
580 if ( ndx < static_cast<Int_t>(fNBlks) )
581 return const_cast<void*> (fReader->GetBlockData(ndx));
586 //##################################################################################
587 ULong_t AliHLTHOMERManager::GetBlkSize( Int_t ndx ) {
588 // see header file for class documentation
590 if ( !fReader || !IsConnected() ) {
591 HLTError(Form("Not connected yet."));
595 if ( ndx < static_cast<Int_t>(fNBlks) )
596 return static_cast<ULong_t> (fReader->GetBlockDataLength(ndx));
601 //##################################################################################
602 TString AliHLTHOMERManager::GetBlkOrigin( Int_t ndx ) {
603 // see header file for class documentation
607 // -- Check for Connection
608 if ( !fReader || ! IsConnected() ) {
609 HLTError(Form("Not connected yet."));
613 // -- Check block index
614 if ( ndx >= static_cast<Int_t>(fNBlks) ) {
615 HLTError(Form("Block index %d out of range.", ndx ));
625 reverseOrigin.data = static_cast<UInt_t>(fReader->GetBlockDataOrigin(ndx));
627 // -- Reverse the order
628 for (Int_t ii = 3; ii >= 0; ii-- )
629 if ( reverseOrigin.array[ii] != ' ')
630 origin.Append( reverseOrigin.array[ii] );
632 origin.Remove( TString::kTrailing, ' ' );
637 //##################################################################################
638 TString AliHLTHOMERManager::GetBlkType( Int_t ndx ) {
639 // see header file for class documentation
643 // -- Check for Connection
644 if ( !fReader || ! IsConnected() ) {
645 HLTError(Form("Not connected yet."));
649 // -- Check block index
650 if ( ndx >= static_cast<Int_t>(fNBlks) ) {
651 HLTError(Form("Block index %d out of range.", ndx ));
661 reverseType.data = static_cast<ULong64_t> (fReader->GetBlockDataType(ndx));
663 // -- Reverse the order
664 for (Int_t ii = 7; ii >= 0; ii-- )
665 if ( reverseType.array[ii] != ' ')
666 type.Append( reverseType.array[ii] );
668 type.Remove( TString::kTrailing, ' ' );
673 //##################################################################################
674 ULong_t AliHLTHOMERManager::GetBlkSpecification( Int_t ndx ) {
675 // see header file for class documentation
677 // -- Check for Connection
678 if ( !fReader || ! IsConnected() ) {
679 HLTError(Form("Not connected yet."));
683 // -- Check block index
684 if ( ndx >= static_cast<Int_t>(fNBlks) ) {
685 HLTError(Form("Block index %d out of range.", ndx ));
689 return static_cast<ULong_t>(fReader->GetBlockDataSpec(ndx));
692 //##################################################################################
693 Bool_t AliHLTHOMERManager::CheckIfRequested( AliHLTHOMERBlockDesc * block ) {
694 // see header file for class documentation
696 Bool_t requested = kFALSE;
698 AliHLTHOMERSourceDesc * source= NULL;
700 // -- Read all sources and check if they should be read out
701 TIter next( fSourceList );
702 while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
704 // -- Check if source is selected
705 if ( ! source->IsSelected() )
708 // -- Check if detector matches
709 if ( source->GetSourceName().CompareTo( block->GetBlockName() ) )
715 } // while ( ( source = dynamic_cast<AliHLTHOMERSourceDesc*>(next()) ) ) {
719 HLTInfo(Form("Block requested : %s", block->GetBlockName().Data()));
722 HLTInfo(Form("Block NOT requested : %s", block->GetBlockName().Data()));