2 // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3 // Author: Jochen Thaeder <thaeder@kip.uni-heidelberg.de> *
4 // for The ALICE HLT Project. *
8 /** @file AliEveHOMERManager.cxx
11 @brief Manger for HOMER in offline
18 #include "AliEveHOMERManager.h"
21 // -- -- -- -- -- -- --
22 #include "AliHLTHOMERLibManager.h"
23 #include "AliHLTHOMERSourceDesc.h"
24 #include "AliHLTHOMERBlockDesc.h"
25 // -- -- -- -- -- -- --
26 #include "AliEveHOMERSource.h"
27 // -- -- -- -- -- -- --
29 #include <TApplication.h>
30 #include "Riostream.h"
32 #include "TCollection.h"
34 #include "TObjString.h"
35 #include "TObjArray.h"
36 // -- -- -- -- -- -- --
39 //______________________________________________________________________________
41 // Manage connections to HLT data-sources.
43 ClassImp(AliEveHOMERManager)
46 * ---------------------------------------------------------------------------------
47 * Constructor / Destructor
48 * ---------------------------------------------------------------------------------
51 //##################################################################################
52 AliEveHOMERManager::AliEveHOMERManager( TString xmlFile ) :
53 TEveElementList("AliEveHOMERManager"),
54 fLibManager(new AliHLTHOMERLibManager),
55 fXMLHandler( new AliEveHOMERXMLHandler( xmlFile ) ),
63 fStateHasChanged(kTRUE),
65 // This Class should handle the communication
66 // from the HLT to AliEVE. The HLT sends data via
67 // the HOMER interface on several TCP ports of nodes
68 // in the CERN GPN and DCS network.
69 // All this communication is hidden from the user.
71 // Right now, a xml file ( SCC1 ) is used to get the
72 // configuration, this will/ has to change to a proxy
73 // running on dedicated nodes.
77 //##################################################################################
78 AliEveHOMERManager::~AliEveHOMERManager() {
83 fLibManager->DeleteReader(fReader);
89 if ( fXMLHandler != NULL )
93 if ( fSourceList != NULL )
97 if ( fBlockList != NULL )
101 if ( fSrcList != NULL )
107 * ---------------------------------------------------------------------------------
109 * ---------------------------------------------------------------------------------
112 //##################################################################################
113 Int_t AliEveHOMERManager::CreateHOMERSourcesList() {
114 // Create Sources List from HOMER-Proxy
118 // -- Initialize sources list
120 if ( fSourceList != NULL )
124 fSourceList = new TList();
125 fSourceList->SetOwner( kTRUE );
127 iResult = fXMLHandler->FillSourceList( fSourceList );
130 AliWarning( Form("There have been errors, while creating the sources list.") );
133 AliInfo( Form("New sources list created.") );
135 // -- New SourceList has been created --> All Sources are new --> State has changed
136 fStateHasChanged = kTRUE;
141 // -- Create new AliEVE sources list
142 fSrcList = new AliEveHOMERSourceList("HLT Sources");
143 fSrcList->SetManager(this);
145 AddElement(fSrcList);
146 fSrcList->CreateByType();
152 //##################################################################################
153 void AliEveHOMERManager::SetSourceState( AliHLTHOMERSourceDesc * source, Bool_t state ) {
154 // Set state of a source
155 // * param source Pointer to AliHLTHOMERSourceDesc object.
156 // * param state New (selected/not selected) state.
158 if ( source->IsSelected() != state ) {
159 source->SetState( state );
160 fStateHasChanged = kTRUE;
167 * ---------------------------------------------------------------------------------
168 * Connection Handling
169 * ---------------------------------------------------------------------------------
172 //##################################################################################
173 Int_t AliEveHOMERManager::ConnectHOMER(){
174 // Connect to HOMER sources, out of Readout List, which gets created when state has changed
175 // * return 0 on sucess, "HOMER" errors on error
179 fStateHasChanged = fSrcList->GetSelectedSources();
181 // -- Check if already connected and state has not changed
182 if ( fStateHasChanged == kFALSE && IsConnected() ) {
183 AliInfo( Form("No need for reconnection.") );
187 // -- If already connected, disconnect before connect
191 // *** Create the Readoutlist
193 UShort_t* sourcePorts = new UShort_t [fSourceList->GetEntries()];
194 const char ** sourceHostnames = new const char* [fSourceList->GetEntries()];
195 UInt_t sourceCount = 0;
197 CreateReadoutList( sourceHostnames, sourcePorts, sourceCount );
199 if ( sourceCount == 0 ) {
200 AliError(Form("No sources selected, aborting.") );
204 // *** Connect to data sources
208 fReader = fLibManager->OpenReader( sourceCount, sourceHostnames, sourcePorts );
211 iResult = fReader->GetConnectionStatus();
214 // -- Connection failed
216 UInt_t ndx = fReader->GetErrorConnectionNdx();
218 if ( ndx < sourceCount ) {
219 AliError( Form("Error : Error establishing connection to TCP source %s:%hu: %s (%d)",
220 sourceHostnames[ndx], sourcePorts[ndx], strerror(iResult), iResult) );
223 AliError( Form("Error : Error establishing connection to unknown source with index %d: %s (%d)",
224 ndx, strerror(iResult), iResult) );
228 fLibManager->DeleteReader( fReader );
233 // -- Connection ok - set reader
236 AliInfo( Form("Connection established") );
239 delete[] sourceHostnames;
240 delete[] sourcePorts;
245 //##################################################################################
246 void AliEveHOMERManager::DisconnectHOMER(){
247 // Disconnect from HOMER sources
249 if ( ! IsConnected() )
253 fLibManager->DeleteReader( fReader );
256 fStateHasChanged = kTRUE;
259 AliInfo( Form("Connection closed") );
264 //##################################################################################
265 Int_t AliEveHOMERManager::ReconnectHOMER(){
266 // Reconnect from HOMER sources
267 // * return 0 on sucess, "ConnectHOMER()" errors on error
274 iResult = ConnectHOMER();
276 AliError( Form("Error connecting.") );
282 //##################################################################################
283 void AliEveHOMERManager::CreateReadoutList( const char** sourceHostnames, UShort_t *sourcePorts, UInt_t &sourceCount ){
284 // Create a readout list for Hostname and ports
285 // * param socurceHostnames Array of selected hostnames
286 // * param socurcePorts Array of selected ports
287 // * param socurceCount Number of selected hostname:port
289 AliHLTHOMERSourceDesc * source= NULL;
291 // -- Read all sources and check if they should be read out
292 TIter next( fSourceList );
293 while ( ( source = (AliHLTHOMERSourceDesc*)next() ) ) {
295 if ( ! source->IsSelected() )
298 Bool_t exists = kFALSE;
300 // -- Loop over existing entries and check if entry is already in readout list
301 for ( UInt_t ii = 0; ii < sourceCount; ii++ ){
302 if ( !strcmp( sourceHostnames[ii], source->GetHostname().Data() ) && sourcePorts[ii] == source->GetPort() ) {
308 // -- Add new entires to readout list
310 sourcePorts[sourceCount] = source->GetPort();
311 sourceHostnames[sourceCount] = source->GetHostname().Data();
315 } // while ( ( source = (AliHLTHOMERSourceDesc*)next() ) ) {
317 fStateHasChanged = kFALSE;
323 * ---------------------------------------------------------------------------------
325 * ---------------------------------------------------------------------------------
328 //##################################################################################
329 Int_t AliEveHOMERManager::NextEvent(){
330 // Loads the next Event, after being connected
331 // * return 0 on sucess, "HOMER" errors on error
334 Int_t iRetryCount = 0;
336 if ( !fReader || ! IsConnected() ) {
337 AliWarning( Form( "Not connected yet." ) );
341 // fReader->SetEventRequestAdvanceTime( 20000000 /*timeout in us*/ );
343 // -- Read next event data and error handling for HOMER (error codes and empty blocks)
346 iResult = fReader->ReadNextEvent( 40000000 /*timeout in us*/);
348 if ( iResult == 111 || iResult == 32 || iResult == 6 ) {
349 Int_t ndx = fReader->GetErrorConnectionNdx();
350 AliError( Form("Error, No Connection to source %d: %s (%d)",
351 ndx, strerror(iResult), iResult) );
354 else if ( iResult == 110 ) {
355 Int_t ndx = fReader->GetErrorConnectionNdx();
356 AliError( Form("Timout occured, reading event from source %d: %s (%d)",
357 ndx, strerror(iResult), iResult) );
360 else if ( iResult == 56) {
361 Int_t ndx = fReader->GetErrorConnectionNdx();
365 if ( iRetryCount >= 20 ) {
366 AliError( Form("Retry Failed: Error reading event from source %d: %s (%d)",
367 ndx, strerror(iResult), iResult) );
371 AliError( Form("Retry: Error reading event from source %d: %s (%d)",
372 ndx, strerror(iResult), iResult) );
376 else if ( iResult ) {
377 Int_t ndx = fReader->GetErrorConnectionNdx();
378 AliError( Form("General Error reading event from source %d: %s (%d)",
379 ndx, strerror(iResult), iResult) );
391 // -- Get blockCnt and eventID
392 fNBlks = (ULong_t) fReader->GetBlockCnt();
393 fEventID = (ULong64_t) fReader->GetEventID();
396 AliInfo( Form("Event 0x%016LX (%Lu) with %lu blocks", fEventID, fEventID, fNBlks) );
399 // Loop for Debug only
400 for ( ULong_t i = 0; i < fNBlks; i++ ) {
401 Char_t tmp1[9], tmp2[5];
402 memset( tmp1, 0, 9 );
403 memset( tmp2, 0, 5 );
405 ULong64_t* tmp12 = (ULong64_t*)tmp11;
406 *tmp12 = fReader->GetBlockDataType( i );
408 ULong_t* tmp22 = (ULong_t*)tmp21;
409 *tmp22 = fReader->GetBlockDataOrigin( i );
410 AliInfo( Form("Block %lu length: %lu - type: %s - origin: %s",
411 i, fReader->GetBlockDataLength( i ), tmp1, tmp2) );
412 } // end for ( ULong_t i = 0; i < fNBlks; i++ ) {
415 // -- Create BlockList
416 AliInfo( Form("Create Block List") );
417 iResult = CreateBlockList();
422 //##################################################################################
423 Int_t AliEveHOMERManager::CreateBlockList() {
424 // Create a TList of blocks, which have been readout
429 // -- Initialize block list
430 if ( fBlockList != NULL )
434 fBlockList = new TList();
435 fBlockList->SetOwner( kTRUE );
437 void* iter = GetFirstBlk();
439 // -- Fill block list
440 while ( iter != NULL ){
442 // -- Create new block
443 AliHLTHOMERBlockDesc * block = new AliHLTHOMERBlockDesc( GetBlk(), GetBlkSize(), GetBlkOrigin(),
444 GetBlkType(), GetBlkSpecification() );
446 // -- Check sources list if block is requested
447 if ( CheckIfRequested( block ) )
448 fBlockList->Add( block );
450 //The Following 2 line commented out and the previous is added.
453 fBlockList->Add( block );
457 } // while ( iter != NULL ){
463 * ---------------------------------------------------------------------------------
465 * ---------------------------------------------------------------------------------
468 //##################################################################################
469 void* AliEveHOMERManager::GetBlk( Int_t ndx ) {
470 // Get pointer to current block in current event
471 // * param ndx Block index
472 // * return returns pointer to blk, NULL if no block present
476 if ( !fReader || ! IsConnected() ) {
477 AliError( Form("Not connected yet.") );
480 if ( ( ndx ) < (Int_t) fNBlks )
481 data = (void*) fReader->GetBlockData( ndx );
487 //##################################################################################
488 ULong_t AliEveHOMERManager::GetBlkSize( Int_t ndx ) {
489 // Get size of block ndx
490 // * param ndx Block index
491 // * return returns pointer to blk, 0 if no block present
495 if ( !fReader || ! IsConnected() ) {
496 AliError( Form("Not connected yet.") );
499 if ( ( ndx ) < (Int_t) fNBlks )
500 length = (ULong_t) fReader->GetBlockDataLength( ndx );
506 //##################################################################################
507 TString AliEveHOMERManager::GetBlkOrigin( Int_t ndx ) {
508 // Get origin of block ndx
509 // * param ndx Block index
510 // * return origin of block
514 // -- Check for Connection
515 if ( !fReader || ! IsConnected() ) {
516 AliError( Form("Not connected yet.") );
520 // -- Check block index
521 if ( ( ndx ) >= (Int_t) fNBlks ) {
522 AliError( Form("Block index %d out of range.", ndx ) );
532 reverseOrigin.data = (UInt_t) fReader->GetBlockDataOrigin( ndx );
534 // -- Reverse the order
535 for (Int_t ii = 3; ii >= 0; ii-- )
536 if ( reverseOrigin.array[ii] != ' ')
537 origin.Append( reverseOrigin.array[ii] );
542 //##################################################################################
543 TString AliEveHOMERManager::GetBlkType( Int_t ndx ) {
544 // Get type of block ndx
545 // * param ndx Block index
546 // * return type of block
550 // -- Check for Connection
551 if ( !fReader || ! IsConnected() ) {
552 AliError( Form("Not connected yet.") );
556 // -- Check blockk index
557 if ( ( ndx ) >= (Int_t) fNBlks ) {
558 AliError( Form("Block index %d out of range.", ndx ) );
568 reverseType.data = (ULong64_t) fReader->GetBlockDataType( ndx );
570 // -- Reverse the order
571 for (Int_t ii = 7; ii >= 0; ii-- )
572 if ( reverseType.array[ii] != ' ')
573 type.Append( reverseType.array[ii] );
578 //##################################################################################
579 ULong_t AliEveHOMERManager::GetBlkSpecification( Int_t ndx ) {
580 // Get specification of block ndx
581 // * param ndx Block index
582 // * return specification of block
586 // -- Check for Connection
587 if ( !fReader || ! IsConnected() ) {
588 AliError( Form("Not connected yet.") );
592 // -- Check blockk index
593 if ( ( ndx ) >= (Int_t) fNBlks ) {
594 AliError( Form("Block index %d out of range.", ndx ) );
598 spec = (ULong_t) fReader->GetBlockDataSpec( ndx );
603 //##################################################################################
604 Bool_t AliEveHOMERManager::CheckIfRequested( AliHLTHOMERBlockDesc */* block*/ ) {
605 // Checks if current Block should was requested
606 // * return returns kTRUE, if block should was requested
608 Bool_t requested = kFALSE;
610 AliHLTHOMERSourceDesc * source= NULL;
612 // -- Read all sources and check if they should be read out
613 TIter next( fSourceList );
614 while ( ( source = (AliHLTHOMERSourceDesc*)next() ) ) {
616 if ( ! source->IsSelected() )
619 if ( !( block->GetDetector().CompareTo( "*** " ) && block->GetDetector().CompareTo( "***" ) ) ) {
620 // if not any detector
621 if ( source->GetDetector().CompareTo( block->GetDetector() ) )
625 if ( ! ( block->GetDataType().CompareTo( "******* " ) && block->GetDataType().CompareTo( "******* " ) ) ) {
626 if ( source->GetDataType().CompareTo( block->GetDataType() ) )
630 if ( ! block->HasSubDetectorRange() ) {
631 if ( source->GetSubDetector().Atoi() != block->GetSubDetector().Atoi() )
634 if ( ! block->HasSubSubDetectorRange() ) {
636 if ( source->GetSubSubDetector().Atoi() != block->GetSubSubDetector().Atoi() )
639 } // if ( ! block->HasSubSubDetectorRange ) {
640 } // if ( ! block->HasSubDetectorRange ) {
645 } // while ( ( source = (AliHLTHOMERSourceDesc*)next() ) ) {
649 if ( block->GetDataType().CompareTo("CLUSTERS") ) {
651 AliError( Form("Block requested : %s - %s : %s/%s -> %s ", block->GetDetector().Data(), block->GetDataType().Data(),
652 block->GetSubDetector().Data(), block->GetSubSubDetector().Data(), block->GetClassName().Data() ) );
655 AliError( Form("Block NOT requested : %s - %s : %s/%s -> %s ", block->GetDetector().Data(), block->GetDataType().Data(),
656 block->GetSubDetector().Data(), block->GetSubSubDetector().Data(), block->GetClassName().Data() ) );