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: Matthias Richter <Matthias.Richter@ift.uib.no> *
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 AliHLTTriggerAgent.cxx
20 @author Matthias Richter
22 @brief Agent of the libAliHLTTrigger library
26 #include "AliHLTTriggerAgent.h"
27 #include "AliHLTTriggerDecision.h"
28 #include "AliHLTGlobalTriggerDecision.h"
29 #include "AliHLTOUT.h"
30 #include "AliHLTMessage.h"
31 #include "AliESDEvent.h"
32 #include "TObjString.h"
33 #include "TObjArray.h"
38 // header files of library components
39 #include "AliHLTEventSummaryProducerComponent.h"
40 #include "AliHLTRunSummaryProducerComponent.h"
41 #include "AliHLTTriggerBarrelMultiplicity.h"
42 #include "AliHLTD0Trigger.h"
43 #include "AliHLTTriggerITSMultiplicity.h"
44 #include "AliHLTTriggerBarrelGeomMultiplicity.h"
45 #include "AliHLTGlobalTriggerComponent.h"
46 #include "AliHLTTriggerPhosClusterEnergy.h"
47 #include "AliHLTTriggerEmcalClusterEnergy.h"
48 #include "AliHLTTriggerPhosMip.h"
49 #include "AliHLTTriggerTrdClusterMultiplicity.h"
50 #include "AliHLTTriggerGammaConversion.h"
51 #include "AliHLTMuonSpectroTriggerComponent.h"
52 #include "AliHLTUpcTriggerComponent.h"
55 /** global instance for agent registration */
56 AliHLTTriggerAgent gAliHLTTriggerAgent;
58 /** ROOT macro for the implementation of ROOT specific class methods */
59 ClassImp(AliHLTTriggerAgent)
61 AliHLTTriggerAgent::AliHLTTriggerAgent()
62 : AliHLTModuleAgent("Trigger")
63 , fTriggerDecisionHandler(NULL)
65 // see header file for class documentation
67 // refer to README to build package
69 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
72 AliHLTTriggerAgent::~AliHLTTriggerAgent()
74 // see header file for class documentation
77 int AliHLTTriggerAgent::RegisterComponents(AliHLTComponentHandler* pHandler) const
79 // see header file for class documentation
81 if (!pHandler) return -EINVAL;
82 pHandler->AddComponent(new AliHLTGlobalTriggerComponent);
83 pHandler->AddComponent(new AliHLTTriggerBarrelMultiplicity);
84 pHandler->AddComponent(new AliHLTTriggerITSMultiplicity);
85 pHandler->AddComponent(new AliHLTD0Trigger);
86 pHandler->AddComponent(new AliHLTTriggerBarrelGeomMultiplicity);
87 pHandler->AddComponent(new AliHLTTriggerPhosClusterEnergy);
88 pHandler->AddComponent(new AliHLTTriggerEmcalClusterEnergy);
89 pHandler->AddComponent(new AliHLTTriggerPhosMip);
90 pHandler->AddComponent(new AliHLTTriggerTrdClusterMultiplicity);
91 pHandler->AddComponent(new AliHLTTriggerGammaConversion);
92 pHandler->AddComponent(new AliHLTMuonSpectroTriggerComponent);
93 pHandler->AddComponent(new AliHLTUpcTriggerComponent);
97 int AliHLTTriggerAgent::CreateConfigurations(AliHLTConfigurationHandler* pHandler,
98 AliRawReader* rawReader,
99 AliRunLoader* runloader) const
101 // see header file for class documentation
102 if (!pHandler) return -EINVAL;
104 TString triggerInputs;
105 TString triggerOutputs;
106 TString configurationId;
107 /////////////////////////////////////////////////////////////////////////////////////
109 // a central barrel charged particle multiplicity trigger
110 configurationId="TRIGGER-Barrel-Multiplicity";
112 // define the inputs for the BarrelMultiplicityTrigger
113 triggerInputs="GLOBAL-esd-converter";
115 // check for the availibility
116 TObjArray* pTokens=triggerInputs.Tokenize(" ");
119 for (int n=0; n<pTokens->GetEntriesFast(); n++) {
120 TString module=((TObjString*)pTokens->At(n))->GetString();
121 if (pHandler->FindConfiguration(module.Data())) {
122 triggerInputs+=module;
130 if (triggerInputs.Length()>0) {
131 // define multiple instances of the BarrelMultiplicityTrigger with different settings
132 HLTInfo("Configuring inputs for %s: %s", configurationId.Data(), triggerInputs.Data());
133 pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), "");
134 if (triggerOutputs.Length()>0) triggerOutputs+=" ";
135 triggerOutputs+=configurationId;
137 configurationId="TRIGGER-Barrel-HighMultiplicity";
138 arg="-triggername BarrelHighMultiplicity";
139 pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
140 if (triggerOutputs.Length()>0) triggerOutputs+=" ";
141 triggerOutputs+=configurationId;
143 configurationId="TRIGGER-Barrel-Pt_v01";
144 arg="-triggername BarrelPt_v01";
145 pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
146 if (triggerOutputs.Length()>0) triggerOutputs+=" ";
147 triggerOutputs+=configurationId;
149 configurationId="TRIGGER-Barrel-Pt_v02";
150 arg="-triggername BarrelPt_v02";
151 pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
152 if (triggerOutputs.Length()>0) triggerOutputs+=" ";
153 triggerOutputs+=configurationId;
155 configurationId="TRIGGER-Barrel-Pt_v03";
156 arg="-triggername BarrelPt_v03";
157 pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
158 if (triggerOutputs.Length()>0) triggerOutputs+=" ";
159 triggerOutputs+=configurationId;
161 HLTWarning("No inputs for %s found, skipping component", configurationId.Data());
164 /////////////////////////////////////////////////////////////////////////////////////
165 // The muon spectrometer trigger
166 configurationId = "TRIGGER-Muon-Spectrometer";
168 // define the inputsfor the muon spectrometer trigger.
169 if (pHandler->FindConfiguration("dHLT-sim-fromRaw")) {
170 triggerInputs = "dHLT-sim-fromRaw";
172 else if (pHandler->FindConfiguration("dHLT-sim")) {
173 triggerInputs = "dHLT-sim";
175 else if (pHandler->FindConfiguration("dHLT-sim-fromMC")) {
176 triggerInputs = "dHLT-sim-fromMC";
179 if (triggerInputs.Length() > 0) {
180 HLTInfo("Configuring inputs for %s: %s", configurationId.Data(), triggerInputs.Data());
181 pHandler->CreateConfiguration(configurationId.Data(), "MuonSpectroTrigger", triggerInputs.Data(), "-makestats");
182 if (triggerOutputs.Length() > 0) triggerOutputs += " ";
183 triggerOutputs += configurationId;
185 HLTWarning("No inputs for %s found, skipping component.", configurationId.Data());
188 /////////////////////////////////////////////////////////////////////////////////////
190 configurationId = "TRIGGER-D0";
191 if(runloader && !rawReader){
192 // simulation without simulated raw data
193 // use ESD as input and add in addition the MC information for trigger evaluation
194 triggerInputs="GLOBAL-esd-converter ";
197 // disable the publishing of MC information. It seems to be way too big for AA
198 // simulation, anyhow the evaluation of the trigger should be done outside the
200 // const char* mcpublisherId="TRIGGER-mc-publisher";
201 // pHandler->CreateConfiguration(mcpublisherId, "ESDMCEventPublisher", NULL, "-entrytype MC -datapath ./");
202 // triggerInputs+=mcpublisherId;
205 // simulation with simulated raw data, or raw data reconstruction
206 // use input from ITS tracker and vertexer directly
207 triggerInputs="ITS-tracker GLOBAL-vertexer";
210 // check for the availibility of inputs
211 pTokens=triggerInputs.Tokenize(" ");
214 for (int n=0; n<pTokens->GetEntriesFast(); n++) {
215 TString module=((TObjString*)pTokens->At(n))->GetString();
216 if (pHandler->FindConfiguration(module.Data())) {
217 triggerInputs+=module;
225 if (triggerInputs.Length()>0) {
226 HLTInfo("Configuring inputs for %s: %s", configurationId.Data(), triggerInputs.Data());
227 pHandler->CreateConfiguration(configurationId.Data(), "D0Trigger", triggerInputs.Data(), argD0.Data());
228 if (triggerOutputs.Length()>0) triggerOutputs+=" ";
229 triggerOutputs+=configurationId;
231 HLTWarning("No inputs for %s found, skipping component", configurationId.Data());
234 /////////////////////////////////////////////////////////////////////////////////////
236 // the global trigger component
237 configurationId="GLOBAL-Trigger";
238 HLTInfo("setting inputs for %s: %s", configurationId.Data(), triggerOutputs.IsNull()?"none":triggerOutputs.Data());
239 pHandler->CreateConfiguration(configurationId.Data(), "HLTGlobalTrigger", triggerOutputs.Data(), "");
244 const char* AliHLTTriggerAgent::GetReconstructionChains(AliRawReader* /*rawReader*/,
245 AliRunLoader* runloader) const
247 // see header file for class documentation
249 // reconstruction chains for AliRoot simulation
250 // Note: run loader is only available while running embedded into
251 // AliRoot simulation
253 // currently disabled due to a problem compiling the runtime trigger library
254 return "GLOBAL-Trigger";
259 const char* AliHLTTriggerAgent::GetRequiredComponentLibraries() const
261 // see header file for class documentation
266 int AliHLTTriggerAgent::GetHandlerDescription(AliHLTComponentDataType dt,
267 AliHLTUInt32_t /*spec*/,
268 AliHLTOUTHandlerDesc& desc) const
270 // see header file for class documentation
272 // handler of the trigger decisions {'ROOTTOBJ':'HLT '}
273 // currently stored as a TObject with the common data type and origin
274 // HLTOUT. However we might need a separate data type in order to
275 // avoid interference with other handlers
276 // the handler produces an ESD object in order to be merged to the
278 // 2009-11-17 adding the data tyepes for (global) trigger decisions
279 // the TObject data types stays for a while in order to preserve
280 // backward compatibility
281 if (dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginOut) ||
282 dt==kAliHLTDataTypeTriggerDecision ||
283 dt==kAliHLTDataTypeGlobalTrigger) {
284 desc=AliHLTOUTHandlerDesc(AliHLTModuleAgent::kEsd, dt, GetModuleId());
288 // handler for the HLT readou list and trigger data data blocks {'HLTRDLST':'HLT '}
289 if (dt==AliHLTComponentDataTypeInitializer("HLTRDLST", kAliHLTDataOriginOut) ||
290 dt==AliHLTComponentDataTypeInitializer("HLTTRGDT", kAliHLTDataOriginOut)) {
291 desc=AliHLTOUTHandlerDesc(kProprietary, dt, GetModuleId());
298 AliHLTOUTHandler* AliHLTTriggerAgent::GetOutputHandler(AliHLTComponentDataType dt,
299 AliHLTUInt32_t /*spec*/)
301 // see header file for class documentation
303 // raw data blocks to be fed into offline reconstruction
304 if ((dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginOut) ||
305 (dt==kAliHLTDataTypeTriggerDecision) ||
306 (dt==kAliHLTDataTypeGlobalTrigger))) {
307 if (!fTriggerDecisionHandler) {
308 fTriggerDecisionHandler=new AliHLTTriggerAgent::AliHLTTriggerDecisionHandler;
310 return fTriggerDecisionHandler;
313 // handler for the HLT readou list and trigger data data blocks {'HLTRDLST':'HLT '}
314 if (dt==AliHLTComponentDataTypeInitializer("HLTRDLST", kAliHLTDataOriginOut) ||
315 dt==AliHLTComponentDataTypeInitializer("HLTTRGDT", kAliHLTDataOriginOut)) {
322 int AliHLTTriggerAgent::DeleteOutputHandler(AliHLTOUTHandler* pInstance)
324 // see header file for class documentation
325 if (pInstance==NULL) return -EINVAL;
327 if (pInstance==fTriggerDecisionHandler) {
328 delete fTriggerDecisionHandler;
329 fTriggerDecisionHandler=NULL;
335 AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::AliHLTTriggerDecisionHandler()
343 // see header file for class documentation
346 AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::~AliHLTTriggerDecisionHandler()
348 // see header file for class documentation
350 fpESDtree->GetUserInfo()->Clear();
361 if (fESD) delete fESD;
364 if (fpData) delete fpData;
369 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::ProcessData(AliHLTOUT* pData)
371 // see header file for class documentation
372 if (!pData) return -EINVAL;
374 AliHLTGlobalTriggerDecision* pGlobalDecision=NULL;
375 TObjArray triggerDecisions;
376 triggerDecisions.SetOwner(kTRUE);
377 for (iResult=pData->SelectFirstDataBlock(); iResult>=0; iResult=pData->SelectNextDataBlock()) {
378 AliHLTComponentDataType dt=kAliHLTVoidDataType;
379 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
380 if ((iResult=pData->GetDataBlockDescription(dt, spec))<0) break;
381 TObject* pObject=pData->GetDataObject();
383 if(dt==kAliHLTDataTypeGlobalTrigger) {
384 if (!pGlobalDecision) {
385 if ((pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pObject))==NULL ||
386 (pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pGlobalDecision->Clone()))==NULL) {
387 HLTFatal("can not convert object of name %s (%s) to HLTGlobalTriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
390 HLTWarning("multiple HLT GlobalTrigger decision objects, ignoring all but the first one");
392 } else if (dt==kAliHLTDataTypeTriggerDecision) {
393 if (pObject->IsA() == AliHLTTriggerDecision::Class() &&
394 !(pObject->IsA() == AliHLTGlobalTriggerDecision::Class())) {
395 AliHLTTriggerDecision* pDecision=dynamic_cast<AliHLTTriggerDecision*>(pObject);
397 if (pGlobalDecision) {
399 pGlobalDecision->AddTriggerInput(*pDecision);
402 triggerDecisions.Add(pDecision->Clone());
405 HLTFatal("can not convert object of name %s (%s) to HLT TriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
408 } else if (dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginOut)){
409 // this is the branch for keeping compatibility
410 // the first version of the trigger framework was using the kAliHLTDataTypeTObject
411 // data type instead of the specific data types for HLT triggers
412 // this effects the cosmic data taken Sep to Oct 2009
413 if (pObject->IsA() == AliHLTGlobalTriggerDecision::Class()) {
414 if (!pGlobalDecision) {
415 if ((pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pObject))==NULL ||
416 (pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pGlobalDecision->Clone()))==NULL) {
417 HLTFatal("can not convert object of name %s (%s) to HLTGlobalTriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
420 HLTWarning("multiple HLT GlobalTrigger decision objects, ignoring all but the first one");
422 } else if (pObject->IsA() == AliHLTTriggerDecision::Class()) {
423 AliHLTTriggerDecision* pDecision=dynamic_cast<AliHLTTriggerDecision*>(pObject);
425 if (pGlobalDecision) {
427 pGlobalDecision->AddTriggerInput(*pDecision);
430 triggerDecisions.Add(pDecision->Clone());
433 HLTFatal("can not convert object of name %s (%s) to HLT TriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
437 pData->ReleaseDataObject(pObject);
440 HLTError("can not get TObject from HLTOUT buffer");
444 // -ENOENT just signals that there are no more entries
445 if (iResult==-ENOENT) iResult=0;
447 if (pGlobalDecision) {
448 for (int i=0; i<triggerDecisions.GetEntriesFast(); i++) {
449 if (triggerDecisions[i]) {
450 pGlobalDecision->AddTriggerInput(*((AliHLTTriggerDecision*)triggerDecisions[i]));
453 triggerDecisions.Delete();
454 AliHLTTriggerDecision* pDecision=pGlobalDecision;
457 //pDecision->Print();
458 HLTDebug("extracted %s", pDecision->GetName());
460 // create the ESD container, but without std content
461 fESD = new AliESDEvent;
463 if (!fpData) fpData=new TArrayC;
464 if (fESD && fpData) {
466 TObject* pESDObject=fESD->FindListObject("HLTGlobalTrigger");
468 // copy the content to the already existing object
469 pDecision->Copy(*pESDObject);
472 fESD->AddObject(pDecision->Clone());
475 AliHLTMessage* pMsg=AliHLTMessage::Stream(fESD);
477 if (!pMsg->CompBuffer()) {
478 fSize=pMsg->Length();
479 fpData->Set(fSize, pMsg->Buffer());
481 fSize=pMsg->CompLength();
482 fpData->Set(fSize, pMsg->CompBuffer());
487 HLTError("streaming of objects failed");
490 HLTError("memory allocation failed");
495 delete pGlobalDecision;
496 pGlobalDecision=NULL;
498 HLTError("no global trigger found in data collection");
508 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::GetProcessedData(const AliHLTUInt8_t* &pData)
510 // see header file for class documentation
516 pData=reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray());
520 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::ReleaseProcessedData(const AliHLTUInt8_t* pData, int size)
522 // see header file for class documentation
524 if (!fpData || size != fSize ||
525 const_cast<AliHLTUInt8_t*>(pData) != reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray())) {
526 HLTError("attempt to release to wrong data buffer %p size %d, expected %p size %d", pData, size, fpData?fpData->GetArray():NULL, fSize);
532 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::WriteESD()
534 // see header file for class documentation
538 fpESDfile=new TFile("HLTdecision.root", "RECREATE");
541 fpESDtree=new TTree("HLTesdTree", "Tree with HLT ESD containing HLT decision");
543 fESD->WriteToTree(fpESDtree);
544 fpESDtree->GetUserInfo()->Add(fESD);
547 if (!fpESDfile || !fpESDtree) return -ENOMEM;
551 fpESDtree->Write(fpESDtree->GetName(),TObject::kOverwrite);