+// $Id$
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project *
+ * ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Primary Authors: Artur Szostak <artursz@iafrica.com> *
+ * 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 AliHLTTrigger.h
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date 12 Aug 2008
+/// @brief Implementation of the AliHLTTrigger base component class.
+///
+/// The AliHLTTrigger class is the base class from which all HLT trigger components
+/// should be derived.
#include "AliHLTTrigger.h"
-#include "AliHLTTrackArray.h"
-#include "AliHLTTransform.h"
-#include "AliHLTVertex.h"
-#include "AliHLTDefs.h"
-#include "AliHLTDigitData.h"
-#include "AliHLTLogging.h"
-#include "AliHLTTrack.h"
-#include "AliHLTMemHandler.h"
+#include "AliHLTTriggerDecision.h"
+#include "AliHLTReadoutList.h"
+#include "AliHLTTriggerDomain.h"
+#include "AliHLTDomainEntry.h"
+#include "AliHLTCTPData.h"
ClassImp(AliHLTTrigger)
-AliHLTTrigger::AliHLTTrigger()
+
+AliHLTTrigger::AliHLTTrigger() :
+ AliHLTProcessor(),
+ fEventData(NULL),
+ fTriggerData(NULL),
+ fDecisionMade(false),
+ fClearInfo(true),
+ fTriggerEventResult(0),
+ fDescription(),
+ fReadoutList(),
+ fTriggerDomain(),
+ fReadoutListSpecBits(kAliHLTVoidDataSpec)
{
- fDataSize=0;
- fTracks=0;
- fDigitRowData=0;
- fOutput=0;
- fVertex=0;
+ // Default constructor sets pointers to NULL.
}
+
AliHLTTrigger::~AliHLTTrigger()
{
- if(fTracks)
- delete fTracks;
+ // Default destructor.
}
-void AliHLTTrigger::InitTrigger()
+
+void AliHLTTrigger::GetInputDataTypes(AliHLTComponentDataTypeList& list) const
{
- if(fTracks)
- delete fTracks;
- fTracks = new AliHLTTrackArray();
+ // Returns the kAliHLTAnyDataType type as input.
+ list.push_back(kAliHLTAnyDataType);
}
-void AliHLTTrigger::InitPatch(Int_t slice,Int_t patch)
+
+void AliHLTTrigger::GetOutputDataTypes(AliHLTComponentDataTypeList& list) const
{
- fSlice=slice;
- fPatch=patch;
- fTracks->Reset();
+ // Returns the kAliHLTDataTypeTriggerDecision type as output.
+ list.push_back(kAliHLTDataTypeTriggerDecision);
}
-void AliHLTTrigger::FillTracks(Int_t ntracks,AliHLTTrackSegmentData *tr)
+
+void AliHLTTrigger::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
{
- fTracks->FillTracks(ntracks,tr);
+ // Returns output data size estimate.
+ // See header file for more details.
+
+ // Matthias 2009-07-03 this is presumably to small as the streamed object might be
+ // bigger. This is actually the case in root v5-24-00
+ // Just take 2x the size of the object
+ constBase = 2*sizeof(AliHLTTriggerDecision);
+ inputMultiplier = 1;
}
-void AliHLTTrigger::FillData(AliHLTDigitRowData *data)
+
+int AliHLTTrigger::DoEvent(const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData)
{
- fDigitRowData = data;
+ // Sets the pointers to the evtData and trigData, then calls the DoTrigger to
+ // execute the actual trigger algorithm.
+
+ fEventData = &evtData;
+ fTriggerData = &trigData;
+ fDecisionMade = false;
+ fTriggerEventResult = 0;
+ // Reset the description, readout list and trigger domain used by TriggerEvent
+ // if requested to do so.
+ if (fClearInfo)
+ {
+ fDescription = "";
+ fReadoutList.Clear();
+ fTriggerDomain.Clear();
+ }
+
+ int result = DoTrigger();
+ if (result != 0) return result;
+
+ // Fill in a default decision of false if none was made.
+ if (not fDecisionMade)
+ {
+ TriggerEvent(false);
+ }
+
+ // Cleanup
+ fEventData = NULL;
+ fTriggerData = NULL;
+ return fTriggerEventResult;
}
-void AliHLTTrigger::SetParameters(Float_t zcut,Int_t timematch,Int_t padmatch)
+
+int AliHLTTrigger::TriggerEvent(bool value)
{
- fZcut=zcut;
- fTimeMatch=timematch;
- fPadMatch=padmatch;
+ // Sets the trigger decision for the current event.
+ // See header file for more details.
+
+ if (fTriggerEventResult != 0) return fTriggerEventResult; // Do not do anything if a previous call failed.
+ AliHLTTriggerDecision triggerResult(value, GetTriggerName(), fTriggerDomain, fDescription);
+ // Append the readout list if it contains anything.
+ triggerResult.TriggerDomain().Add(fReadoutList);
+ return TriggerEvent(&triggerResult, kAliHLTDataTypeTriggerDecision);
}
-void AliHLTTrigger::SetOutputData(AliHLTDigitRowData *ptr)
+
+int AliHLTTrigger::TriggerEvent(
+ AliHLTTriggerDecision* result, const AliHLTComponentDataType& type,
+ AliHLTUInt32_t spec
+ )
{
- fOutput=ptr;
+ // Sets a custom trigger decision for the current event.
+ // See header file for more details.
+
+ if (fTriggerEventResult != 0) return fTriggerEventResult; // Do not do anything if a previous call failed.
+
+ AliHLTReadoutList readoutlist = result->ReadoutList();
+
+ fTriggerEventResult = PushBack(result, type, spec);
+ if (fTriggerEventResult == 0) {
+ fTriggerEventResult = PushBack(readoutlist.Buffer(), readoutlist.BufferSize(), kAliHLTDataTypeReadoutList, fReadoutListSpecBits);
+ }
+
+ if (fTriggerEventResult == 0) fDecisionMade = true;
+ return fTriggerEventResult;
}
-void AliHLTTrigger::RemovePileupTracks()
+
+void AliHLTTrigger::GetInputDataTypes(AliHLTComponentDataTypeList& list)
{
- Double_t xc,yc,zc;
- for(Int_t i=0; i<fTracks->GetNTracks(); i++)
- {
- AliHLTTrack *track = fTracks->GetCheckedTrack(i);
- if(!track) continue;
- track->Rotate(fSlice,kTRUE);
- track->CalculateHelix();
- track->GetClosestPoint(fVertex,xc,yc,zc);
- if(fabs(zc) > fZcut)
- {
- fTracks->Remove(i);
- continue;
- }
- }
- fTracks->Compress();
+ // Calls the const version of this method.
+
+ // Assign to const temporary variable to make sure we call the constant version
+ // of the GetOutputDataTypes method.
+ const AliHLTTrigger* t = this;
+ t->GetInputDataTypes(list);
}
-void AliHLTTrigger::RemovePileupData()
+
+int AliHLTTrigger::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
{
- Float_t hit[3];
- Int_t sector,row;
- struct rowhit {Int_t pad; Int_t time;};
- rowhit row_cross[(fTracks->GetNTracks())];
- Int_t digitcount[(NumRows[fPatch])];
- Int_t totalcount=0;
- AliHLTDigitRowData *rowPt = fDigitRowData;
- for(Int_t i=NRows[fPatch][0]; i<=NRows[fPatch][1]; i++)
- {
- digitcount[(i-NRows[fPatch][0])]=0;
- for(Int_t j=0; j<fTracks->GetNTracks(); j++)
- {
- AliHLTTrack *track = fTracks->GetCheckedTrack(j);
- if(!track) continue;
- track->GetCrossingPoint(i,hit);
- AliHLTTransform::Slice2Sector(fSlice,i,sector,row);
- AliHLTTransform::Local2Raw(hit,sector,row);
- row_cross[j].pad = (Int_t)rint(hit[1]);
- row_cross[j].time = (Int_t)rint(hit[2]);
- }
- AliHLTDigitData *digPt = (AliHLTDigitData*)rowPt->fDigitData;
- Bool_t mark;
- for(Int_t k=0; k<rowPt->fNDigit; k++)
- {
- mark = kFALSE;
- for(Int_t l=0; l<fTracks->GetNTracks(); l++)
- {
- if(abs((Int_t)digPt[k].fPad-row_cross[l].pad) < fPadMatch &&
- abs((Int_t)digPt[k].fTime-row_cross[l].time) < fTimeMatch)
- {
- digitcount[(i-NRows[fPatch][0])]++;
- totalcount++;
- mark=kTRUE;
- break;
- }
- }
- if(mark==kTRUE)
- digPt[k].fCharge=0;
- }
- AliHLTMemHandler::UpdateRowPointer(rowPt);
- }
+ // Calls the const version of this method.
- Int_t size = totalcount*sizeof(AliHLTDigitData) + NumRows[fPatch]*sizeof(AliHLTDigitRowData);
- fDataSize = size;
- LOG(AliHLTLog::kDebug,"AliHLTTrigger::RemovePileupData","Memory")
- <<"Allocating "<<size<<" bytes of data for trigger event"<<ENDLOG;
- Byte_t *data = new Byte_t[size];
- memset(data,0,size);
- AliHLTDigitRowData *tempPt = (AliHLTDigitRowData*)data;
- rowPt = fDigitRowData;
-
- Int_t localcount;
- for(Int_t i=NRows[fPatch][0]; i<=NRows[fPatch][1]; i++)
- {
- tempPt->fRow = i;
- tempPt->fNDigit = digitcount[(i-NRows[fPatch][0])];
- AliHLTDigitData *digPt = (AliHLTDigitData*)rowPt->fDigitData;
- localcount=0;
- for(Int_t j=0; j<rowPt->fNDigit; j++)
- {
- if(digPt[j].fCharge==0) continue;
- if(localcount >= digitcount[(i-NRows[fPatch][0])])
- {
- LOG(AliHLTLog::kFatal,"AliL§Trigger::RemovePileupData","Array")
- <<"Mismatch in digitcount: "<<localcount<<" "<<digitcount[(i-NRows[fPatch][0])]<<ENDLOG;
- return;
- }
- tempPt->fDigitData[localcount].fCharge=digPt[j].fCharge;
- tempPt->fDigitData[localcount].fPad=digPt[j].fPad;
- tempPt->fDigitData[localcount].fTime=digPt[j].fTime;
- localcount++;
- }
- if(digitcount[(i-NRows[fPatch][0])]!=localcount)
- {
- LOG(AliHLTLog::kFatal,"AliL§Trigger::RemovePileupData","Array")
- <<"Mismatch in digitcount: "<<localcount<<" "<<digitcount[(i-NRows[fPatch][0])]<<ENDLOG;
- }
- AliHLTMemHandler::UpdateRowPointer(rowPt);
- Byte_t *tmp = (Byte_t*)tempPt;
- Int_t size = sizeof(AliHLTDigitRowData)+digitcount[(i-NRows[fPatch][0])]*sizeof(AliHLTDigitData);
- tmp += size;
- tempPt = (AliHLTDigitRowData*)tmp;
- }
-
- fOutput=(AliHLTDigitRowData*)data;
+ // Assign to const temporary variable to make sure we call the constant version
+ // of the GetOutputDataTypes method.
+ const AliHLTTrigger* t = this;
+ t->GetOutputDataTypes(list);
+ list.push_back(kAliHLTDataTypeReadoutList);
+ return list.size();
}
+int AliHLTTrigger::CreateEventDoneReadoutFilter(const AliHLTTriggerDomain& domain, unsigned type)
+{
+ // add a readout filter to the EventDoneData
+ int iResult=0;
+ unsigned nofEntries=0;
+ switch (type) {
+ /* readout filter */
+ case 3:
+ /* monitoring filter */
+ case 4:
+ nofEntries=domain.GetNofEntries();
+ break;
+ /* monitoring event command */
+ case 5:
+ break;
+ default:
+ HLTError("unknown event done data command code 0x%08x", type);
+ return -EINVAL;
+ }
+
+ // we need:
+ // 1 word for the filter command: readout filter, monitoring filter, monitoring event
+ // 1 word for the readout filter size
+ // 4*n words for the filter list
+ if ((iResult=ReserveEventDoneData((nofEntries*4 + 2) * sizeof(AliHLTUInt32_t)))<0) return iResult;
+ AliHLTUInt32_t eddbuffer[4];
+
+ // add the specific command
+ eddbuffer[0]=type;
+ if ((iResult=PushEventDoneData(eddbuffer[0]))<0) return iResult;
+ // find the valid entries
+ unsigned block=0;
+ vector<const AliHLTDomainEntry*> entries;
+ for (block=0; block<nofEntries; block++) {
+ // skip all DAQ readout entries as they are handled by the readout list
+ // 2009-12-03: this turned out to cause a bug, since all blocks with data type
+ // id 'any' will also match this condition. In fact, it is not necessary to
+ // filter the entries, disable this condition. Code can be cleaned up later
+ // if this schema has been established and tested
+ // https://savannah.cern.ch/bugs/index.php?60082
+ //if (domain[block]==AliHLTDomainEntry(kAliHLTDataTypeDAQRDOUT)) continue;
+ if (domain[block].Exclusive()) {
+ // 2009-12-03 comment out that warning for the moment
+ // there are suddenly exclusive entries in the list
+ // https://savannah.cern.ch/bugs/index.php?60083
+ //HLTWarning("exclusive trigger domain entries are currently not handled, skipping entry %s", domain[block].AsString().Data());
+ continue;
+ }
+ entries.push_back(&(domain[block]));
+ }
+
+ // add the number of blocks if not monitoring event command
+ if (type!=5) {
+ eddbuffer[0]=entries.size();
+ if ((iResult=PushEventDoneData(eddbuffer[0]))<0) return iResult;
+ }
+
+ for (vector<const AliHLTDomainEntry*>::iterator entry=entries.begin();
+ entry!=entries.end(); entry++) {
+ (*entry)->AsBinary(eddbuffer);
+ for (int n=0; n<4; n++)
+ if ((iResult=PushEventDoneData(eddbuffer[n]))<0) return iResult;
+ }
+ return iResult;
+}