ROOT logo
// $Id$

//**************************************************************************
//* This file is property of and copyright by the                          * 
//* ALICE Experiment at CERN, All rights reserved.                         *
//*                                                                        *
//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
//*                  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   AliHLTOUTHandlerChain.cxx
/// @author Matthias Richter
/// @date   24.06.2008
/// @brief  HLTOUT handler of type kChain.
///

#include "AliHLTOUTHandlerChain.h"
#include "AliHLTOUT.h"
#include "AliHLTSystem.h"
#include "AliHLTOUTTask.h"
#include "TString.h"
#include "TObjString.h"
#include "TObjArray.h"
#include <cassert>

/** ROOT macro for the implementation of ROOT specific class methods */
ClassImp(AliHLTOUTHandlerChain)

AliHLTOUTHandlerChain::AliHLTOUTHandlerChain(const char* arguments)
  :
  fChains(),
  fOptions(),
  fpSystem(NULL),
  fbHaveOutput(false)
{ 
  // The handler implements the kChain processing of HLTOUT data.
  // The ids of the chains to be run during processing are provided
  // as parameter to the constructor. The AliHLTModuleAgent
  // can just create a new instance and specify the chains in order
  // to define the HLTOUT handling of type kChain for a certain data
  // block. The same instance can be returned for multiple data blocks.
  // The handler will run once on all data blocks.
  if (arguments) {
    TString args=arguments;
    TObjArray* pTokens=args.Tokenize(" ");
    if (pTokens) {
      int iEntries=pTokens->GetEntries();
      for (int i=0; i<iEntries; i++) {
	TString token=(((TObjString*)pTokens->At(i))->GetString());
	if (token.Contains("chains=")) {
	  TString param=token.ReplaceAll("chains=", "");
	  fChains=param.ReplaceAll(",", " ");
	} else {
	  if (!fOptions.IsNull()) fOptions+=" ";
	  fOptions+=token;
	}
      }
      delete pTokens;
    }
  } 
}

AliHLTOUTHandlerChain::~AliHLTOUTHandlerChain()
{
  // destructor
  if (fpSystem) {
    // TODO: the EOR is currenttly not send because the reconstruction
    // chian is not stopped. Trying it here gives an error, there is
    // some state mismatch in AliHLTSystem. Probably due to the fact,
    // that the AliHLTSystem::Reconstruct method is not used
//     if (!fpSystem->CheckStatus(AliHLTSystem::kError)) {
//       // send specific 'event' to execute the stop sequence
//       fpSystem->Reconstruct(0, NULL, NULL);
//     }
    delete fpSystem;
  }
}

int AliHLTOUTHandlerChain::ProcessData(AliHLTOUT* pData)
{
  // data processing function
  if (!pData) return -EINVAL;
  int iResult=0;

  if (CheckStatus(kHandlerError)) {
    HLTWarning("kChain handler '%s' in error state, skipping processing of associated HLTOUT blocks", fChains.Data());
    return -EPERM;
  }

  if (!fpSystem && (iResult=InitSystem())<0) {
    return iResult;
  }

  if (fpSystem->CheckStatus(AliHLTSystem::kError)) {
    HLTWarning("kChain handler '%s': system in error state, skipping processing of associated HLTOUT blocks", fChains.Data());
    return -EACCES;
  }

  // run one event and do not stop the chain
  {
    AliHLTOUT::AliHLTOUTGlobalInstanceGuard g(pData);
    if ((iResult=fpSystem->Run(1,0))>=0) {
      // sub-collection is going to be reset from the
      // parent HLTOUT collection
      AliHLTOUTTask* pTask=fpSystem->GetHLTOUTTask();

      // either have the task or none of the chains controlled by the chain
      // handler has output
      assert(pTask || !fbHaveOutput);
      if (pTask) {
      AliHLTOUT* pSubCollection=dynamic_cast<AliHLTOUT*>(pTask);
      pSubCollection->Init();

      // filter out some data blocks which should not be processed
      // in the next stage:
      // 1. we are not interested in the component statistics
      //    produced in the HLTOUT handler chain
      for (iResult=pSubCollection->SelectFirstDataBlock();
	   iResult>=0;
	   iResult=pSubCollection->SelectNextDataBlock()) {
	AliHLTComponentDataType dt=kAliHLTVoidDataType;
	AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
	pSubCollection->GetDataBlockDescription(dt, spec);
	if (dt==kAliHLTDataTypeComponentStatistics) {
	  pSubCollection->MarkDataBlockProcessed();
	}
      }
      pData->AddSubCollection(pSubCollection);
      } else if (fbHaveOutput) {
	// this is an error condition since task has been created and should
	// be available
	HLTError("can not get instance of HLTOUT task from HLT system %p", fpSystem);
      }
    }
  }

  return iResult;
}

int AliHLTOUTHandlerChain::CreateConfigurations(AliHLTConfigurationHandler* /*handler*/)
{
  //default implementation, nothing to do
  return 0;
}

int AliHLTOUTHandlerChain::InitSystem()
{
  // initialize the AliHLTSystem instance
  int iResult=0;
  if (!fpSystem) {
    // init AliHLTSystem
    TString systemName="kChain_"; systemName+=fChains;
    systemName.ReplaceAll(" ", "_");
    fpSystem = new AliHLTSystem(GetGlobalLoggingLevel(), systemName);
    if (fpSystem) {
      if ((iResult=fpSystem->ScanOptions(fOptions.Data()))>=0) {
	// load configurations if not specified by external macro
	if (!fOptions.Contains("config="))
	  iResult=CreateConfigurations(fpSystem->GetConfigurationHandler());

	if (iResult>=0) {
	  iResult=fpSystem->BuildTaskList(fChains.Data());
	}

	// add AliHLTOUTTask on top of the configuartions in order to
	// collect the data
	// remember if task has been created (result>0)
	fbHaveOutput=((iResult=fpSystem->AddHLTOUTTask(fChains.Data()))>0);
      }
    } else {
      iResult=-ENOMEM;
    }
    if (iResult<0) {
      SetStatusFlag(kHandlerError);
      if (fpSystem) delete fpSystem; fpSystem=NULL;
    }
  }
  return iResult;
}
 AliHLTOUTHandlerChain.cxx:1
 AliHLTOUTHandlerChain.cxx:2
 AliHLTOUTHandlerChain.cxx:3
 AliHLTOUTHandlerChain.cxx:4
 AliHLTOUTHandlerChain.cxx:5
 AliHLTOUTHandlerChain.cxx:6
 AliHLTOUTHandlerChain.cxx:7
 AliHLTOUTHandlerChain.cxx:8
 AliHLTOUTHandlerChain.cxx:9
 AliHLTOUTHandlerChain.cxx:10
 AliHLTOUTHandlerChain.cxx:11
 AliHLTOUTHandlerChain.cxx:12
 AliHLTOUTHandlerChain.cxx:13
 AliHLTOUTHandlerChain.cxx:14
 AliHLTOUTHandlerChain.cxx:15
 AliHLTOUTHandlerChain.cxx:16
 AliHLTOUTHandlerChain.cxx:17
 AliHLTOUTHandlerChain.cxx:18
 AliHLTOUTHandlerChain.cxx:19
 AliHLTOUTHandlerChain.cxx:20
 AliHLTOUTHandlerChain.cxx:21
 AliHLTOUTHandlerChain.cxx:22
 AliHLTOUTHandlerChain.cxx:23
 AliHLTOUTHandlerChain.cxx:24
 AliHLTOUTHandlerChain.cxx:25
 AliHLTOUTHandlerChain.cxx:26
 AliHLTOUTHandlerChain.cxx:27
 AliHLTOUTHandlerChain.cxx:28
 AliHLTOUTHandlerChain.cxx:29
 AliHLTOUTHandlerChain.cxx:30
 AliHLTOUTHandlerChain.cxx:31
 AliHLTOUTHandlerChain.cxx:32
 AliHLTOUTHandlerChain.cxx:33
 AliHLTOUTHandlerChain.cxx:34
 AliHLTOUTHandlerChain.cxx:35
 AliHLTOUTHandlerChain.cxx:36
 AliHLTOUTHandlerChain.cxx:37
 AliHLTOUTHandlerChain.cxx:38
 AliHLTOUTHandlerChain.cxx:39
 AliHLTOUTHandlerChain.cxx:40
 AliHLTOUTHandlerChain.cxx:41
 AliHLTOUTHandlerChain.cxx:42
 AliHLTOUTHandlerChain.cxx:43
 AliHLTOUTHandlerChain.cxx:44
 AliHLTOUTHandlerChain.cxx:45
 AliHLTOUTHandlerChain.cxx:46
 AliHLTOUTHandlerChain.cxx:47
 AliHLTOUTHandlerChain.cxx:48
 AliHLTOUTHandlerChain.cxx:49
 AliHLTOUTHandlerChain.cxx:50
 AliHLTOUTHandlerChain.cxx:51
 AliHLTOUTHandlerChain.cxx:52
 AliHLTOUTHandlerChain.cxx:53
 AliHLTOUTHandlerChain.cxx:54
 AliHLTOUTHandlerChain.cxx:55
 AliHLTOUTHandlerChain.cxx:56
 AliHLTOUTHandlerChain.cxx:57
 AliHLTOUTHandlerChain.cxx:58
 AliHLTOUTHandlerChain.cxx:59
 AliHLTOUTHandlerChain.cxx:60
 AliHLTOUTHandlerChain.cxx:61
 AliHLTOUTHandlerChain.cxx:62
 AliHLTOUTHandlerChain.cxx:63
 AliHLTOUTHandlerChain.cxx:64
 AliHLTOUTHandlerChain.cxx:65
 AliHLTOUTHandlerChain.cxx:66
 AliHLTOUTHandlerChain.cxx:67
 AliHLTOUTHandlerChain.cxx:68
 AliHLTOUTHandlerChain.cxx:69
 AliHLTOUTHandlerChain.cxx:70
 AliHLTOUTHandlerChain.cxx:71
 AliHLTOUTHandlerChain.cxx:72
 AliHLTOUTHandlerChain.cxx:73
 AliHLTOUTHandlerChain.cxx:74
 AliHLTOUTHandlerChain.cxx:75
 AliHLTOUTHandlerChain.cxx:76
 AliHLTOUTHandlerChain.cxx:77
 AliHLTOUTHandlerChain.cxx:78
 AliHLTOUTHandlerChain.cxx:79
 AliHLTOUTHandlerChain.cxx:80
 AliHLTOUTHandlerChain.cxx:81
 AliHLTOUTHandlerChain.cxx:82
 AliHLTOUTHandlerChain.cxx:83
 AliHLTOUTHandlerChain.cxx:84
 AliHLTOUTHandlerChain.cxx:85
 AliHLTOUTHandlerChain.cxx:86
 AliHLTOUTHandlerChain.cxx:87
 AliHLTOUTHandlerChain.cxx:88
 AliHLTOUTHandlerChain.cxx:89
 AliHLTOUTHandlerChain.cxx:90
 AliHLTOUTHandlerChain.cxx:91
 AliHLTOUTHandlerChain.cxx:92
 AliHLTOUTHandlerChain.cxx:93
 AliHLTOUTHandlerChain.cxx:94
 AliHLTOUTHandlerChain.cxx:95
 AliHLTOUTHandlerChain.cxx:96
 AliHLTOUTHandlerChain.cxx:97
 AliHLTOUTHandlerChain.cxx:98
 AliHLTOUTHandlerChain.cxx:99
 AliHLTOUTHandlerChain.cxx:100
 AliHLTOUTHandlerChain.cxx:101
 AliHLTOUTHandlerChain.cxx:102
 AliHLTOUTHandlerChain.cxx:103
 AliHLTOUTHandlerChain.cxx:104
 AliHLTOUTHandlerChain.cxx:105
 AliHLTOUTHandlerChain.cxx:106
 AliHLTOUTHandlerChain.cxx:107
 AliHLTOUTHandlerChain.cxx:108
 AliHLTOUTHandlerChain.cxx:109
 AliHLTOUTHandlerChain.cxx:110
 AliHLTOUTHandlerChain.cxx:111
 AliHLTOUTHandlerChain.cxx:112
 AliHLTOUTHandlerChain.cxx:113
 AliHLTOUTHandlerChain.cxx:114
 AliHLTOUTHandlerChain.cxx:115
 AliHLTOUTHandlerChain.cxx:116
 AliHLTOUTHandlerChain.cxx:117
 AliHLTOUTHandlerChain.cxx:118
 AliHLTOUTHandlerChain.cxx:119
 AliHLTOUTHandlerChain.cxx:120
 AliHLTOUTHandlerChain.cxx:121
 AliHLTOUTHandlerChain.cxx:122
 AliHLTOUTHandlerChain.cxx:123
 AliHLTOUTHandlerChain.cxx:124
 AliHLTOUTHandlerChain.cxx:125
 AliHLTOUTHandlerChain.cxx:126
 AliHLTOUTHandlerChain.cxx:127
 AliHLTOUTHandlerChain.cxx:128
 AliHLTOUTHandlerChain.cxx:129
 AliHLTOUTHandlerChain.cxx:130
 AliHLTOUTHandlerChain.cxx:131
 AliHLTOUTHandlerChain.cxx:132
 AliHLTOUTHandlerChain.cxx:133
 AliHLTOUTHandlerChain.cxx:134
 AliHLTOUTHandlerChain.cxx:135
 AliHLTOUTHandlerChain.cxx:136
 AliHLTOUTHandlerChain.cxx:137
 AliHLTOUTHandlerChain.cxx:138
 AliHLTOUTHandlerChain.cxx:139
 AliHLTOUTHandlerChain.cxx:140
 AliHLTOUTHandlerChain.cxx:141
 AliHLTOUTHandlerChain.cxx:142
 AliHLTOUTHandlerChain.cxx:143
 AliHLTOUTHandlerChain.cxx:144
 AliHLTOUTHandlerChain.cxx:145
 AliHLTOUTHandlerChain.cxx:146
 AliHLTOUTHandlerChain.cxx:147
 AliHLTOUTHandlerChain.cxx:148
 AliHLTOUTHandlerChain.cxx:149
 AliHLTOUTHandlerChain.cxx:150
 AliHLTOUTHandlerChain.cxx:151
 AliHLTOUTHandlerChain.cxx:152
 AliHLTOUTHandlerChain.cxx:153
 AliHLTOUTHandlerChain.cxx:154
 AliHLTOUTHandlerChain.cxx:155
 AliHLTOUTHandlerChain.cxx:156
 AliHLTOUTHandlerChain.cxx:157
 AliHLTOUTHandlerChain.cxx:158
 AliHLTOUTHandlerChain.cxx:159
 AliHLTOUTHandlerChain.cxx:160
 AliHLTOUTHandlerChain.cxx:161
 AliHLTOUTHandlerChain.cxx:162
 AliHLTOUTHandlerChain.cxx:163
 AliHLTOUTHandlerChain.cxx:164
 AliHLTOUTHandlerChain.cxx:165
 AliHLTOUTHandlerChain.cxx:166
 AliHLTOUTHandlerChain.cxx:167
 AliHLTOUTHandlerChain.cxx:168
 AliHLTOUTHandlerChain.cxx:169
 AliHLTOUTHandlerChain.cxx:170
 AliHLTOUTHandlerChain.cxx:171
 AliHLTOUTHandlerChain.cxx:172
 AliHLTOUTHandlerChain.cxx:173
 AliHLTOUTHandlerChain.cxx:174
 AliHLTOUTHandlerChain.cxx:175
 AliHLTOUTHandlerChain.cxx:176
 AliHLTOUTHandlerChain.cxx:177
 AliHLTOUTHandlerChain.cxx:178
 AliHLTOUTHandlerChain.cxx:179
 AliHLTOUTHandlerChain.cxx:180
 AliHLTOUTHandlerChain.cxx:181
 AliHLTOUTHandlerChain.cxx:182
 AliHLTOUTHandlerChain.cxx:183
 AliHLTOUTHandlerChain.cxx:184
 AliHLTOUTHandlerChain.cxx:185
 AliHLTOUTHandlerChain.cxx:186
 AliHLTOUTHandlerChain.cxx:187