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 "AliHLTTriggerBarrelMultiplicity.h"
40 #include "AliHLTD0Trigger.h"
41 #include "AliHLTTriggerITSMultiplicity.h"
42 #include "AliHLTTriggerBarrelGeomMultiplicity.h"
43 #include "AliHLTGlobalTriggerComponent.h"
44 #include "AliHLTTriggerPhosClusterEnergy.h"
45 #include "AliHLTTriggerEmcalClusterEnergy.h"
46 #include "AliHLTTriggerPhosMip.h"
47 #include "AliHLTTriggerTrdClusterMultiplicity.h"
48 #include "AliHLTTriggerGammaConversion.h"
49 #include "AliHLTMuonSpectroTriggerComponent.h"
50 #include "AliHLTUpcTriggerComponent.h"
51 #include "AliHLTTriggerCosmics.h"
52 #include "AliHLTTriggerCounterComponent.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);
94 pHandler->AddComponent(new AliHLTTriggerCosmics);
95 pHandler->AddComponent(new AliHLTTriggerCounterComponent);
99 int AliHLTTriggerAgent::CreateConfigurations(AliHLTConfigurationHandler* pHandler,
100 AliRawReader* rawReader,
101 AliRunLoader* runloader) const
103 // see header file for class documentation
104 if (!pHandler) return -EINVAL;
106 TString triggerInputs;
107 TString triggerOutputs;
108 TString configurationId;
109 /////////////////////////////////////////////////////////////////////////////////////
111 // a central barrel charged particle multiplicity trigger
112 configurationId="TRIGGER-Barrel-Multiplicity";
114 // define the inputs for the BarrelMultiplicityTrigger
115 triggerInputs="GLOBAL-esd-converter";
117 // check for the availibility
118 TObjArray* pTokens=triggerInputs.Tokenize(" ");
121 for (int n=0; n<pTokens->GetEntriesFast(); n++) {
122 TString module=((TObjString*)pTokens->At(n))->GetString();
123 if (pHandler->FindConfiguration(module.Data())) {
124 triggerInputs+=module;
132 if (triggerInputs.Length()>0) {
133 // define multiple instances of the BarrelMultiplicityTrigger with different settings
134 HLTInfo("Configuring inputs for %s: %s", configurationId.Data(), triggerInputs.Data());
135 pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), "");
136 if (triggerOutputs.Length()>0) triggerOutputs+=" ";
137 triggerOutputs+=configurationId;
139 configurationId="TRIGGER-Barrel-HighMultiplicity";
140 arg="-triggername BarrelHighMultiplicity";
141 pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
142 if (triggerOutputs.Length()>0) triggerOutputs+=" ";
143 triggerOutputs+=configurationId;
145 configurationId="TRIGGER-Barrel-Pt_v01";
146 arg="-triggername BarrelPt_v01";
147 pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
148 if (triggerOutputs.Length()>0) triggerOutputs+=" ";
149 triggerOutputs+=configurationId;
151 configurationId="TRIGGER-Barrel-Pt_v02";
152 arg="-triggername BarrelPt_v02";
153 pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
154 if (triggerOutputs.Length()>0) triggerOutputs+=" ";
155 triggerOutputs+=configurationId;
157 configurationId="TRIGGER-Barrel-Pt_v03";
158 arg="-triggername BarrelPt_v03";
159 pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
160 if (triggerOutputs.Length()>0) triggerOutputs+=" ";
161 triggerOutputs+=configurationId;
163 HLTWarning("No inputs for %s found, skipping component", configurationId.Data());
166 /////////////////////////////////////////////////////////////////////////////////////
167 // The muon spectrometer trigger
168 configurationId = "TRIGGER-Muon-Spectrometer";
170 // define the inputsfor the muon spectrometer trigger.
171 if (pHandler->FindConfiguration("dHLT-sim-fromRaw")) {
172 triggerInputs = "dHLT-sim-fromRaw";
174 else if (pHandler->FindConfiguration("dHLT-sim")) {
175 triggerInputs = "dHLT-sim";
177 else if (pHandler->FindConfiguration("dHLT-sim-fromMC")) {
178 triggerInputs = "dHLT-sim-fromMC";
181 if (triggerInputs.Length() > 0) {
182 HLTInfo("Configuring inputs for %s: %s", configurationId.Data(), triggerInputs.Data());
183 pHandler->CreateConfiguration(configurationId.Data(), "MuonSpectroTrigger", triggerInputs.Data(), "-makestats");
184 if (triggerOutputs.Length() > 0) triggerOutputs += " ";
185 triggerOutputs += configurationId;
187 HLTWarning("No inputs for %s found, skipping component.", configurationId.Data());
190 /////////////////////////////////////////////////////////////////////////////////////
192 configurationId = "TRIGGER-D0";
193 if(runloader && !rawReader){
194 // simulation without simulated raw data
196 triggerInputs="GLOBAL-esd-converter ";
199 // simulation with simulated raw data, or raw data reconstruction
200 // use input from ITS tracker and vertexer directly
201 triggerInputs="ITS-tracker GLOBAL-vertexer";
204 // check for the availibility of inputs
205 pTokens=triggerInputs.Tokenize(" ");
208 for (int n=0; n<pTokens->GetEntriesFast(); n++) {
209 TString module=((TObjString*)pTokens->At(n))->GetString();
210 if (pHandler->FindConfiguration(module.Data())) {
211 triggerInputs+=module;
219 if (triggerInputs.Length()>0) {
220 HLTInfo("Configuring inputs for %s: %s", configurationId.Data(), triggerInputs.Data());
221 pHandler->CreateConfiguration(configurationId.Data(), "D0Trigger", triggerInputs.Data(), argD0.Data());
222 // FIXME: due to a rare segfault for reconstruction of PbPb data the
223 // component is temporarily excluded
224 // https://savannah.cern.ch/bugs/?72590
225 //if (triggerOutputs.Length()>0) triggerOutputs+=" ";
226 //triggerOutputs+=configurationId;
228 HLTWarning("No inputs for %s found, skipping component", configurationId.Data());
231 /////////////////////////////////////////////////////////////////////////////////////
233 // the global trigger component
234 configurationId="GLOBAL-Trigger";
235 HLTInfo("setting inputs for %s: %s", configurationId.Data(), triggerOutputs.IsNull()?"none":triggerOutputs.Data());
236 pHandler->CreateConfiguration(configurationId.Data(), "HLTGlobalTrigger", triggerOutputs.Data(), "");
241 const char* AliHLTTriggerAgent::GetReconstructionChains(AliRawReader* /*rawReader*/,
242 AliRunLoader* runloader) const
244 // see header file for class documentation
246 // reconstruction chains for AliRoot simulation
247 // Note: run loader is only available while running embedded into
248 // AliRoot simulation
250 // currently disabled due to a problem compiling the runtime trigger library
251 return "GLOBAL-Trigger";
256 const char* AliHLTTriggerAgent::GetRequiredComponentLibraries() const
258 // see header file for class documentation
263 int AliHLTTriggerAgent::GetHandlerDescription(AliHLTComponentDataType dt,
264 AliHLTUInt32_t /*spec*/,
265 AliHLTOUTHandlerDesc& desc) const
267 // see header file for class documentation
269 // handler of the trigger decisions {'ROOTTOBJ':'HLT '}
270 // currently stored as a TObject with the common data type and origin
271 // HLTOUT. However we might need a separate data type in order to
272 // avoid interference with other handlers
273 // the handler produces an ESD object in order to be merged to the
275 // 2009-11-17 adding the data tyepes for (global) trigger decisions
276 // the TObject data types stays for a while in order to preserve
277 // backward compatibility
278 if (dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginOut) ||
279 dt==kAliHLTDataTypeTriggerDecision ||
280 dt==kAliHLTDataTypeGlobalTrigger) {
281 desc=AliHLTOUTHandlerDesc(AliHLTModuleAgent::kEsd, dt, GetModuleId());
285 // handler for the HLT readou list and trigger data data blocks {'HLTRDLST':'HLT '}
286 if (dt==AliHLTComponentDataTypeInitializer("HLTRDLST", kAliHLTDataOriginOut) ||
287 dt==AliHLTComponentDataTypeInitializer("HLTTRGDT", kAliHLTDataOriginOut)) {
288 desc=AliHLTOUTHandlerDesc(kProprietary, dt, GetModuleId());
295 AliHLTOUTHandler* AliHLTTriggerAgent::GetOutputHandler(AliHLTComponentDataType dt,
296 AliHLTUInt32_t /*spec*/)
298 // see header file for class documentation
300 // raw data blocks to be fed into offline reconstruction
301 if ((dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginOut) ||
302 (dt==kAliHLTDataTypeTriggerDecision) ||
303 (dt==kAliHLTDataTypeGlobalTrigger))) {
304 if (!fTriggerDecisionHandler) {
305 fTriggerDecisionHandler=new AliHLTTriggerAgent::AliHLTTriggerDecisionHandler;
307 return fTriggerDecisionHandler;
310 // handler for the HLT readou list and trigger data data blocks {'HLTRDLST':'HLT '}
311 if (dt==AliHLTComponentDataTypeInitializer("HLTRDLST", kAliHLTDataOriginOut) ||
312 dt==AliHLTComponentDataTypeInitializer("HLTTRGDT", kAliHLTDataOriginOut)) {
319 int AliHLTTriggerAgent::DeleteOutputHandler(AliHLTOUTHandler* pInstance)
321 // see header file for class documentation
322 if (pInstance==NULL) return -EINVAL;
324 if (pInstance==fTriggerDecisionHandler) {
325 delete fTriggerDecisionHandler;
326 fTriggerDecisionHandler=NULL;
332 AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::AliHLTTriggerDecisionHandler()
340 // see header file for class documentation
343 AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::~AliHLTTriggerDecisionHandler()
345 // see header file for class documentation
347 fpESDtree->GetUserInfo()->Clear();
358 if (fESD) delete fESD;
361 if (fpData) delete fpData;
366 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::ProcessData(AliHLTOUT* pData)
368 // see header file for class documentation
369 if (!pData) return -EINVAL;
371 AliHLTGlobalTriggerDecision* pGlobalDecision=NULL;
372 TObjArray triggerDecisions;
373 triggerDecisions.SetOwner(kTRUE);
374 for (iResult=pData->SelectFirstDataBlock(); iResult>=0; iResult=pData->SelectNextDataBlock()) {
375 AliHLTComponentDataType dt=kAliHLTVoidDataType;
376 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
377 if ((iResult=pData->GetDataBlockDescription(dt, spec))<0) break;
378 TObject* pObject=pData->GetDataObject();
380 if(dt==kAliHLTDataTypeGlobalTrigger) {
381 if (!pGlobalDecision) {
382 if ((pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pObject))==NULL ||
383 (pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pGlobalDecision->Clone()))==NULL) {
384 HLTFatal("can not convert object of name %s (%s) to HLTGlobalTriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
387 HLTWarning("multiple HLT GlobalTrigger decision objects, ignoring all but the first one");
389 } else if (dt==kAliHLTDataTypeTriggerDecision) {
390 if (pObject->IsA() == AliHLTTriggerDecision::Class() &&
391 !(pObject->IsA() == AliHLTGlobalTriggerDecision::Class())) {
392 AliHLTTriggerDecision* pDecision=dynamic_cast<AliHLTTriggerDecision*>(pObject);
394 if (pGlobalDecision) {
396 pGlobalDecision->AddTriggerInput(*pDecision);
399 triggerDecisions.Add(pDecision->Clone());
402 HLTFatal("can not convert object of name %s (%s) to HLT TriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
405 } else if (dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginOut)){
406 // this is the branch for keeping compatibility
407 // the first version of the trigger framework was using the kAliHLTDataTypeTObject
408 // data type instead of the specific data types for HLT triggers
409 // this effects the cosmic data taken Sep to Oct 2009
410 if (pObject->IsA() == AliHLTGlobalTriggerDecision::Class()) {
411 if (!pGlobalDecision) {
412 if ((pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pObject))==NULL ||
413 (pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pGlobalDecision->Clone()))==NULL) {
414 HLTFatal("can not convert object of name %s (%s) to HLTGlobalTriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
417 HLTWarning("multiple HLT GlobalTrigger decision objects, ignoring all but the first one");
419 } else if (pObject->IsA() == AliHLTTriggerDecision::Class()) {
420 AliHLTTriggerDecision* pDecision=dynamic_cast<AliHLTTriggerDecision*>(pObject);
422 if (pGlobalDecision) {
424 pGlobalDecision->AddTriggerInput(*pDecision);
427 triggerDecisions.Add(pDecision->Clone());
430 HLTFatal("can not convert object of name %s (%s) to HLT TriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
434 pData->ReleaseDataObject(pObject);
437 HLTError("can not get TObject from HLTOUT buffer");
441 // -ENOENT just signals that there are no more entries
442 if (iResult==-ENOENT) iResult=0;
444 if (pGlobalDecision) {
445 for (int i=0; i<triggerDecisions.GetEntriesFast(); i++) {
446 if (triggerDecisions[i]) {
447 pGlobalDecision->AddTriggerInput(*((AliHLTTriggerDecision*)triggerDecisions[i]));
450 triggerDecisions.Delete();
451 AliHLTTriggerDecision* pDecision=pGlobalDecision;
454 //pDecision->Print();
455 HLTDebug("extracted %s", pDecision->GetName());
457 // create the ESD container, but without std content
458 fESD = new AliESDEvent;
460 if (!fpData) fpData=new TArrayC;
461 if (fESD && fpData) {
463 TObject* pESDObject=fESD->FindListObject("HLTGlobalTrigger");
465 // copy the content to the already existing object
466 pDecision->Copy(*pESDObject);
469 fESD->AddObject(pDecision->Clone());
472 AliHLTMessage* pMsg=AliHLTMessage::Stream(fESD);
474 if (!pMsg->CompBuffer()) {
475 fSize=pMsg->Length();
476 fpData->Set(fSize, pMsg->Buffer());
478 fSize=pMsg->CompLength();
479 fpData->Set(fSize, pMsg->CompBuffer());
484 HLTError("streaming of objects failed");
487 HLTError("memory allocation failed");
492 delete pGlobalDecision;
493 pGlobalDecision=NULL;
495 HLTError("no global trigger found in data collection");
505 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::GetProcessedData(const AliHLTUInt8_t* &pData)
507 // see header file for class documentation
513 pData=reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray());
517 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::ReleaseProcessedData(const AliHLTUInt8_t* pData, int size)
519 // see header file for class documentation
521 if (!fpData || size != fSize ||
522 const_cast<AliHLTUInt8_t*>(pData) != reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray())) {
523 HLTError("attempt to release to wrong data buffer %p size %d, expected %p size %d", pData, size, fpData?fpData->GetArray():NULL, fSize);
529 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::WriteESD()
531 // see header file for class documentation
535 fpESDfile=new TFile("HLTdecision.root", "RECREATE");
538 fpESDtree=new TTree("HLTesdTree", "Tree with HLT ESD containing HLT decision");
540 fESD->WriteToTree(fpESDtree);
541 fpESDtree->GetUserInfo()->Add(fESD);
544 if (!fpESDfile || !fpESDtree) return -ENOMEM;
548 fpESDtree->Write(fpESDtree->GetName(),TObject::kOverwrite);