]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/trigger/AliHLTTriggerAgent.cxx
Merge branch 'trigger'
[u/mrichter/AliRoot.git] / HLT / trigger / AliHLTTriggerAgent.cxx
1 // $Id$
2
3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project        * 
5 //* ALICE Experiment at CERN, All rights reserved.                         *
6 //*                                                                        *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8 //*                  for The ALICE HLT Project.                            *
9 //*                                                                        *
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 //**************************************************************************
18
19 /** @file   AliHLTTriggerAgent.cxx
20     @author Matthias Richter
21     @date   
22     @brief  Agent of the libAliHLTTrigger library
23 */
24
25 #include <cassert>
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"
34 #include "TArrayC.h"
35 #include "TFile.h"
36 #include "TTree.h"
37
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 "AliHLTTriggerBarrelCosmic.h"
46 #include "AliHLTGlobalTriggerComponent.h"
47 #include "AliHLTTriggerPhosClusterEnergy.h"
48 #include "AliHLTTriggerEmcalClusterEnergy.h"
49 #include "AliHLTTriggerPhosMip.h"
50 #include "AliHLTTriggerTrdClusterMultiplicity.h"
51 #include "AliHLTTriggerGammaConversion.h"
52 #include "AliHLTMuonSpectroTriggerComponent.h"
53
54 /** global instance for agent registration */
55 AliHLTTriggerAgent gAliHLTTriggerAgent;
56
57 /** ROOT macro for the implementation of ROOT specific class methods */
58 ClassImp(AliHLTTriggerAgent)
59
60 AliHLTTriggerAgent::AliHLTTriggerAgent()
61   : AliHLTModuleAgent("Trigger")
62   , fTriggerDecisionHandler(NULL)
63 {
64   // see header file for class documentation
65   // or
66   // refer to README to build package
67   // or
68   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
69 }
70
71 AliHLTTriggerAgent::~AliHLTTriggerAgent()
72 {
73   // see header file for class documentation
74 }
75
76 int AliHLTTriggerAgent::RegisterComponents(AliHLTComponentHandler* pHandler) const
77 {
78   // see header file for class documentation
79   assert(pHandler);
80   if (!pHandler) return -EINVAL;
81   pHandler->AddComponent(new AliHLTGlobalTriggerComponent);
82   pHandler->AddComponent(new AliHLTTriggerBarrelMultiplicity);
83   pHandler->AddComponent(new AliHLTTriggerITSMultiplicity);
84   pHandler->AddComponent(new AliHLTD0Trigger);
85   pHandler->AddComponent(new AliHLTTriggerBarrelGeomMultiplicity);
86   pHandler->AddComponent(new AliHLTTriggerBarrelCosmic);
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   return 0;
94 }
95
96 int AliHLTTriggerAgent::CreateConfigurations(AliHLTConfigurationHandler* pHandler,
97                                             AliRawReader* /*rawReader*/,
98                                             AliRunLoader* /*runloader*/) const
99 {
100   // see header file for class documentation
101   if (!pHandler) return -EINVAL;
102
103   TString triggerInputs;
104   TString triggerOutputs;
105   TString configurationId;
106   /////////////////////////////////////////////////////////////////////////////////////
107   //
108   // a central barrel charged particle multiplicity trigger
109   configurationId="TRIGGER-Barrel-Multiplicity";
110
111   // define the inputs for the BarrelMultiplicityTrigger
112   triggerInputs="GLOBAL-esd-converter";
113
114   // check for the availibility
115   TObjArray* pTokens=triggerInputs.Tokenize(" ");
116   triggerInputs="";
117   if (pTokens) {
118     for (int n=0; n<pTokens->GetEntriesFast(); n++) {
119       TString module=((TObjString*)pTokens->At(n))->GetString();
120       if (pHandler->FindConfiguration(module.Data())) {
121         triggerInputs+=module;
122         triggerInputs+=" ";
123       }
124     }
125     delete pTokens;
126   }
127
128   TString arg;
129   if (triggerInputs.Length()>0) {
130     // define multiple instances of the BarrelMultiplicityTrigger with different settings
131     HLTInfo("Configuring inputs for %s: %s", configurationId.Data(), triggerInputs.Data());
132     pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), "");
133     if (triggerOutputs.Length()>0) triggerOutputs+=" ";
134     triggerOutputs+=configurationId;
135
136     configurationId="TRIGGER-Barrel-HighMultiplicity";
137     arg="-triggername BarrelHighMultiplicity";
138     pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
139     if (triggerOutputs.Length()>0) triggerOutputs+=" ";
140     triggerOutputs+=configurationId;
141
142     configurationId="TRIGGER-Barrel-Pt_v01";
143     arg="-triggername BarrelPt_v01";
144     pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
145     if (triggerOutputs.Length()>0) triggerOutputs+=" ";
146     triggerOutputs+=configurationId;
147
148     configurationId="TRIGGER-Barrel-Pt_v02";
149     arg="-triggername BarrelPt_v02";
150     pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
151     if (triggerOutputs.Length()>0) triggerOutputs+=" ";
152     triggerOutputs+=configurationId;
153
154     configurationId="TRIGGER-Barrel-Pt_v03";
155     arg="-triggername BarrelPt_v03";
156     pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
157     if (triggerOutputs.Length()>0) triggerOutputs+=" ";
158     triggerOutputs+=configurationId;
159   } else {
160     HLTWarning("No inputs for %s found, skipping component", configurationId.Data());
161   }
162   
163   /////////////////////////////////////////////////////////////////////////////////////
164   // The muon spectrometer trigger
165   configurationId = "TRIGGER-Muon-Spectrometer";
166
167   // define the inputsfor the muon spectrometer trigger.
168   if (pHandler->FindConfiguration("dHLT-sim-fromRaw")) {
169     triggerInputs = "dHLT-sim-fromRaw";
170   }
171   else if (pHandler->FindConfiguration("dHLT-sim")) {
172     triggerInputs = "dHLT-sim";
173   }
174   else if (pHandler->FindConfiguration("dHLT-sim-fromMC")) {
175     triggerInputs = "dHLT-sim-fromMC";
176   }
177
178   if (triggerInputs.Length() > 0) {
179     HLTInfo("Configuring inputs for %s: %s", configurationId.Data(), triggerInputs.Data());
180     pHandler->CreateConfiguration(configurationId.Data(), "MuonSpectroTrigger", triggerInputs.Data(), "-makestats");
181     if (triggerOutputs.Length() > 0) triggerOutputs += " ";
182     triggerOutputs += configurationId;
183   } else {
184     HLTWarning("No inputs for %s found, skipping component.", configurationId.Data());
185   }
186
187   /////////////////////////////////////////////////////////////////////////////////////
188   //
189   // the global trigger component
190   configurationId="GLOBAL-Trigger";
191   HLTInfo("setting inputs for %s: %s", configurationId.Data(), triggerOutputs.IsNull()?"none":triggerOutputs.Data());
192   pHandler->CreateConfiguration(configurationId.Data(), "HLTGlobalTrigger", triggerOutputs.Data(), "");
193   
194   return 0;
195 }
196
197 const char* AliHLTTriggerAgent::GetReconstructionChains(AliRawReader* /*rawReader*/,
198                                                     AliRunLoader* runloader) const
199 {
200   // see header file for class documentation
201   if (runloader) {
202     // reconstruction chains for AliRoot simulation
203     // Note: run loader is only available while running embedded into
204     // AliRoot simulation
205
206     // currently disabled due to a problem compiling the runtime trigger library
207     return "GLOBAL-Trigger";
208   }
209   return NULL;
210 }
211
212 const char* AliHLTTriggerAgent::GetRequiredComponentLibraries() const
213 {
214   // see header file for class documentation
215
216   return "libAliHLTUtil.so libAliHLTRCU.so libAliHLTTPC.so libAliHLTITS.so libAliHLTGlobal.so libAliHLTMUON.so";
217 }
218
219 int AliHLTTriggerAgent::GetHandlerDescription(AliHLTComponentDataType dt,
220                                            AliHLTUInt32_t /*spec*/,
221                                           AliHLTOUTHandlerDesc& desc) const
222 {
223   // see header file for class documentation
224
225   // handler of the trigger decisions {'ROOTTOBJ':'HLT '}
226   // currently stored as a TObject with the common data type and origin
227   // HLTOUT. However we might need a separate data type in order to
228   // avoid interference with other handlers
229   // the handler produces an ESD object in order to be merged to the
230   // hltEsd afterwards
231   // 2009-11-17 adding the data tyepes for (global) trigger decisions
232   // the TObject data types stays for a while in order to preserve
233   // backward compatibility
234   if (dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginOut) ||
235       dt==kAliHLTDataTypeTriggerDecision ||
236       dt==kAliHLTDataTypeGlobalTrigger) {
237     desc=AliHLTOUTHandlerDesc(AliHLTModuleAgent::kEsd, dt, GetModuleId());
238     return 1;
239   }
240
241   // handler for the HLT readou list and trigger data data blocks {'HLTRDLST':'HLT '}
242   if (dt==AliHLTComponentDataTypeInitializer("HLTRDLST", kAliHLTDataOriginOut) ||
243       dt==AliHLTComponentDataTypeInitializer("HLTTRGDT", kAliHLTDataOriginOut)) {
244       desc=AliHLTOUTHandlerDesc(kProprietary, dt, GetModuleId());
245       return 1;
246   }
247
248   return 0;
249 }
250
251 AliHLTOUTHandler* AliHLTTriggerAgent::GetOutputHandler(AliHLTComponentDataType dt,
252                                                        AliHLTUInt32_t /*spec*/)
253 {
254   // see header file for class documentation
255
256   // raw data blocks to be fed into offline reconstruction
257   if ((dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginOut) ||
258        (dt==kAliHLTDataTypeTriggerDecision) ||
259        (dt==kAliHLTDataTypeGlobalTrigger))) {
260     if (!fTriggerDecisionHandler) {
261       fTriggerDecisionHandler=new AliHLTTriggerAgent::AliHLTTriggerDecisionHandler;
262     }
263     return fTriggerDecisionHandler;
264   }
265
266   // handler for the HLT readou list and trigger data data blocks {'HLTRDLST':'HLT '}
267   if (dt==AliHLTComponentDataTypeInitializer("HLTRDLST", kAliHLTDataOriginOut) ||
268       dt==AliHLTComponentDataTypeInitializer("HLTTRGDT", kAliHLTDataOriginOut)) {
269     return NULL;
270   }
271
272   return NULL;
273 }
274
275 int AliHLTTriggerAgent::DeleteOutputHandler(AliHLTOUTHandler* pInstance)
276 {
277   // see header file for class documentation
278   if (pInstance==NULL) return -EINVAL;
279
280   if (pInstance==fTriggerDecisionHandler) {
281     delete fTriggerDecisionHandler;
282     fTriggerDecisionHandler=NULL;
283   }
284
285   return 0;
286 }
287
288 AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::AliHLTTriggerDecisionHandler()
289   : AliHLTOUTHandler() 
290   , fESD(NULL)
291   , fpData(NULL)
292   , fSize(0)
293   , fpESDfile(NULL)
294   , fpESDtree(NULL)
295 {
296   // see header file for class documentation
297 }
298
299 AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::~AliHLTTriggerDecisionHandler()
300 {
301   // see header file for class documentation
302   if (fpESDtree) {
303     fpESDtree->GetUserInfo()->Clear();
304     delete fpESDtree;
305   }
306   fpESDtree=NULL;
307
308   if (fpESDfile) {
309     fpESDfile->Close();
310     delete fpESDfile;
311   }
312   fpESDfile=NULL;
313
314   if (fESD) delete fESD;
315   fESD=NULL;
316
317   if (fpData) delete fpData;
318   fpData=NULL;
319   fSize=0;
320 }
321
322 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::ProcessData(AliHLTOUT* pData)
323 {
324   // see header file for class documentation
325   if (!pData) return -EINVAL;
326   int iResult=0;
327   AliHLTGlobalTriggerDecision* pGlobalDecision=NULL;
328   TObjArray triggerDecisions;
329   triggerDecisions.SetOwner(kTRUE);
330   for (iResult=pData->SelectFirstDataBlock(); iResult>=0; iResult=pData->SelectNextDataBlock()) {
331     AliHLTComponentDataType dt=kAliHLTVoidDataType;
332     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
333     if ((iResult=pData->GetDataBlockDescription(dt, spec))<0) break;
334     TObject* pObject=pData->GetDataObject();
335     if (pObject) {
336       if(dt==kAliHLTDataTypeGlobalTrigger) {
337         if (!pGlobalDecision) {
338           if ((pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pObject))==NULL ||
339               (pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pGlobalDecision->Clone()))==NULL) {
340             HLTFatal("can not convert object of name %s (%s) to HLTGlobalTriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
341           }
342         } else {
343           HLTWarning("multiple HLT GlobalTrigger decision objects, ignoring all but the first one");
344         }
345       } else if (dt==kAliHLTDataTypeTriggerDecision) {
346         if (pObject->IsA() == AliHLTTriggerDecision::Class() &&
347             !(pObject->IsA() == AliHLTGlobalTriggerDecision::Class())) {
348           AliHLTTriggerDecision* pDecision=dynamic_cast<AliHLTTriggerDecision*>(pObject);
349           if (pDecision) {
350             if (pGlobalDecision) {
351               // add directly
352               pGlobalDecision->AddTriggerInput(*pDecision);
353             } else {
354               // schedule
355               triggerDecisions.Add(pDecision->Clone());
356             }
357           } else {
358             HLTFatal("can not convert object of name %s (%s) to HLT TriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
359           }
360         }
361       } else if (dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginOut)){
362         // this is the branch for keeping compatibility
363         // the first version of the trigger framework was using the kAliHLTDataTypeTObject
364         // data type instead of the specific data types for HLT triggers
365           // this effects the cosmic data taken Sep to Oct 2009
366         if (pObject->IsA() == AliHLTGlobalTriggerDecision::Class()) {
367           if (!pGlobalDecision) {
368             if ((pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pObject))==NULL ||
369                 (pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pGlobalDecision->Clone()))==NULL) {
370               HLTFatal("can not convert object of name %s (%s) to HLTGlobalTriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
371             }
372           } else {
373             HLTWarning("multiple HLT GlobalTrigger decision objects, ignoring all but the first one");
374           }
375         } else if (pObject->IsA() == AliHLTTriggerDecision::Class()) {
376           AliHLTTriggerDecision* pDecision=dynamic_cast<AliHLTTriggerDecision*>(pObject);
377           if (pDecision) {
378             if (pGlobalDecision) {
379               // add directly
380               pGlobalDecision->AddTriggerInput(*pDecision);
381             } else {
382               // schedule
383               triggerDecisions.Add(pDecision->Clone());
384             }
385           } else {
386             HLTFatal("can not convert object of name %s (%s) to HLT TriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
387           }
388         }
389       }
390       pData->ReleaseDataObject(pObject);
391       pObject=NULL;
392     } else {
393       HLTError("can not get TObject from HLTOUT buffer");
394       iResult=-ENODATA;
395     }
396   }
397   // -ENOENT just signals that there  are no more entries
398   if (iResult==-ENOENT) iResult=0;
399
400   if (pGlobalDecision) {
401     for (int i=0; i<triggerDecisions.GetEntriesFast(); i++) {
402       if (triggerDecisions[i]) {
403         pGlobalDecision->AddTriggerInput(*((AliHLTTriggerDecision*)triggerDecisions[i]));
404       }
405     }
406     triggerDecisions.Delete();
407     AliHLTTriggerDecision* pDecision=pGlobalDecision;
408     {
409       if (pDecision) {
410         //pDecision->Print();
411         HLTDebug("extracted %s", pDecision->GetName());
412         if (!fESD) {
413           // create the ESD container, but without std content
414           fESD = new AliESDEvent;
415         }
416         if (!fpData) fpData=new TArrayC;
417         if (fESD && fpData) {
418           fESD->Reset();
419           TObject* pESDObject=fESD->FindListObject("HLTGlobalTrigger");
420           if (pESDObject) {
421             // copy the content to the already existing object
422             pDecision->Copy(*pESDObject);
423           } else {
424             // add a new object
425             fESD->AddObject(pDecision->Clone());
426           }
427           WriteESD();
428           AliHLTMessage* pMsg=AliHLTMessage::Stream(fESD);
429           if (pMsg) {
430             if (!pMsg->CompBuffer()) {
431               fSize=pMsg->Length();
432               fpData->Set(fSize, pMsg->Buffer());
433             } else {
434               fSize=pMsg->CompLength();
435               fpData->Set(fSize, pMsg->CompBuffer());
436             }
437           } else {
438             HLTError("streaming of objects failed");
439           }
440         } else {
441           HLTError("memory allocation failed");
442           iResult=-ENOMEM;
443         }
444       }
445     }
446     delete pGlobalDecision;
447     pGlobalDecision=NULL;
448   } else {
449     HLTError("no global trigger found in data collection");
450   }
451
452   if (iResult>=0) {
453     return fSize;
454   }
455   fSize=0;
456   return iResult;
457 }
458
459 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::GetProcessedData(const AliHLTUInt8_t* &pData)
460 {
461   // see header file for class documentation
462   if (!fpData) {
463     pData=NULL;
464     return 0;
465   }
466
467   pData=reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray());
468   return fSize;
469 }
470
471 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::ReleaseProcessedData(const AliHLTUInt8_t* pData, int size)
472 {
473   // see header file for class documentation
474   int iResult=0;
475   if (!fpData || size != fSize ||
476       const_cast<AliHLTUInt8_t*>(pData) != reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray())) {
477     HLTError("attempt to release to wrong data buffer %p size %d, expected %p size %d", pData, size, fpData?fpData->GetArray():NULL, fSize);
478   }
479   fSize=0;
480   return iResult;
481 }
482
483 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::WriteESD()
484 {
485   // see header file for class documentation
486   int iResult=0;
487   if (!fESD) return 0;
488   if (!fpESDfile) {
489     fpESDfile=new TFile("HLTdecision.root", "RECREATE");
490   }
491   if (!fpESDtree) {
492     fpESDtree=new TTree("HLTesdTree", "Tree with HLT ESD containing HLT decision");
493     if (fpESDtree) {
494       fESD->WriteToTree(fpESDtree);
495       fpESDtree->GetUserInfo()->Add(fESD);
496     }
497   }
498   if (!fpESDfile || !fpESDtree) return -ENOMEM;
499
500   fpESDtree->Fill();
501   fpESDfile->cd();
502   fpESDtree->Write(fpESDtree->GetName(),TObject::kOverwrite);
503
504   return iResult;
505 }