1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 // This class for running the Central Trigger Processor //
23 // Load Configuration //
24 // Make a list the trigger detectors involved (from the classes) //
25 // For the each event //
26 // Run the Trigger for the each detector //
28 // Check the trigger classes //
29 // Create the class mask //
33 ///////////////////////////////////////////////////////////////////////////////
36 #include <TObjString.h>
37 #include <TObjArray.h>
38 #include <TStopwatch.h>
44 #include "AliRunLoader.h"
45 #include "AliLoader.h"
46 #include "AliModule.h"
48 #include "AliTriggerInput.h"
49 #include "AliTriggerDetector.h"
50 #include "AliTriggerConfiguration.h"
51 #include "AliTriggerClass.h"
52 #include "AliTriggerCluster.h"
53 #include "AliCentralTrigger.h"
54 #include "AliDetectorEventHeader.h"
55 #include "AliHeader.h"
57 #include "AliCDBManager.h"
58 #include "AliCDBPath.h"
59 #include "AliCDBEntry.h"
65 ClassImp( AliCentralTrigger )
67 //_____________________________________________________________________________
68 AliCentralTrigger::AliCentralTrigger() :
77 // Default constructor
81 //_____________________________________________________________________________
82 AliCentralTrigger::AliCentralTrigger( TString & config ) :
91 // Default constructor
92 LoadConfiguration( config );
95 //_____________________________________________________________________________
96 AliCentralTrigger::~AliCentralTrigger()
99 DeleteConfiguration();
102 //_____________________________________________________________________________
103 void AliCentralTrigger::DeleteConfiguration()
105 // Delete the active configuration
108 fL0TriggerInputs = 0;
109 fL1TriggerInputs = 0;
110 fL2TriggerInputs = 0;
111 if (fConfiguration) {
112 if (IsOwner()) delete fConfiguration;
113 fConfiguration = 0x0;
117 //_____________________________________________________________________________
118 void AliCentralTrigger::Reset()
120 // Reset Class Mask and classes
123 fL0TriggerInputs = 0;
124 fL1TriggerInputs = 0;
125 fL2TriggerInputs = 0;
127 if (fConfiguration) {
128 const TObjArray& classesArray = fConfiguration->GetClasses();
129 Int_t nclasses = classesArray.GetEntriesFast();
130 for( Int_t j=0; j<nclasses; j++ ) {
131 AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
137 //_____________________________________________________________________________
138 void AliCentralTrigger::MakeBranch( TString name, TTree * tree )
140 // Make a branch to store only trigger class mask event by event
143 AliDebug( 1, "Got Tree from folder." );
144 TBranch* branch = tree->GetBranch( name );
145 if( branch == 0x0 ) {
146 AliDebug( 1, "Creating new branch" );
147 branch = tree->Branch( name, &(this->fClassMask), "fClassMask/l:fClusterMask/i:fL0TriggerInputs/i:fL1TriggerInputs/i:fL2TriggerInputs/s" );
148 branch->SetAutoDelete( kFALSE );
151 AliDebug( 1, "Got Branch from Tree" );
152 branch->SetAddress( &(this->fClassMask) );
157 //_____________________________________________________________________________
158 Bool_t AliCentralTrigger::LoadConfiguration( TString & config )
160 // Load one and only one pre-created COnfiguration from database/file that match
161 // with the input string 'config'
162 // Ej: "p-p", "Pb-Pb" or "p-p-DIMUON CALIBRATION-CENTRAL-BARREL"
164 // Delete the active configuration, if any
165 DeleteConfiguration();
167 // Load the selected configuration
168 if (!config.IsNull()) {
169 fConfiguration = AliTriggerConfiguration::LoadConfiguration( config );
174 AliError( Form( "Valid TriggerConfiguration (%s) is not found ! Disabling the trigger simulation !", config.Data() ) );
179 // Load one and only one trigger descriptor from CDB
180 AliInfo( "Getting trigger configuration from OCDB!" );
182 AliCDBPath path( "GRP", "CTP", "Config" );
184 AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
186 if( !entry ) AliFatal( "Couldn't load trigger description data from CDB!" );
188 fConfiguration = (AliTriggerConfiguration *)entry->GetObject();
192 AliError( "No valid configuration is found in the CDB ! Disabling the trigger simulation !" );
198 //_____________________________________________________________________________
199 TString AliCentralTrigger::GetDetectors()
201 // return TString with the detectors (modules) to be used for triggering
206 result = fConfiguration->GetTriggeringModules();
211 //_____________________________________________________________________________
212 Bool_t AliCentralTrigger::RunTrigger( AliRunLoader* runLoader, const char *detectors )
216 if( !fConfiguration ) {
217 AliError( "No trigger configuration loaded, skipping trigger" );
221 TTree *tree = runLoader->TreeCT();
223 AliError( "No folder with trigger loaded, skipping trigger" );
227 TStopwatch stopwatch;
230 AliInfo( Form(" Triggering Detectors: %s \n", GetDetectors().Data() ) );
231 AliInfo( Form(" Detectors with digits: %s \n", detectors ) );
233 // Process each event
234 for( Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++ ) {
235 runLoader->GetEvent( iEvent );
236 // Get detectors involve
237 TString detStr = GetDetectors();
238 TString detWithDigits = detectors;
239 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
243 // Reset configuration object (inputs and classes)
244 fConfiguration->Reset();
245 TObjArray trgdetArray; // use as garbage collector
246 for( Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++ ) {
247 AliModule* det = (AliModule*) detArray->At( iDet );
248 if( !det || !det->IsActive() ) continue;
249 if( IsSelected(det->GetName(), detStr) &&
250 IsSelected(det->GetName(), detWithDigits) ) {
252 AliDebug(1,Form("Triggering from digits for %s", det->GetName() ) );
253 AliTriggerDetector* trgdet = det->CreateTriggerDetector();
254 trgdet->AssignInputs(fConfiguration->GetInputs());
255 TStopwatch stopwatchDet;
256 stopwatchDet.Start();
258 AliDebug(1, Form("Execution time for %s: R:%.2fs C:%.2fs",
259 det->GetName(), stopwatchDet.RealTime(), stopwatchDet.CpuTime() ) );
261 trgdetArray.AddLast( trgdet );
263 // Write trigger detector in Event folder in Digits file
264 TString loadername = det->GetName();
265 loadername.Append( "Loader" );
266 AliLoader * loader = runLoader->GetLoader( loadername );
268 AliDataLoader * dataLoader = loader->GetDigitsDataLoader();
269 if( !dataLoader->IsFileOpen() ) {
270 if( dataLoader->OpenFile( "UPDATE" ) ) {
271 AliWarning( Form( "\n\nCan't write trigger for %s\n", det->GetName() ) );
275 if( gFile && !gFile->IsWritable() ) {
276 gFile->ReOpen( "UPDATE" );
279 trgdet->Write( "Trigger", TObject::kOverwrite );
280 dataLoader->CloseFile();
282 else AliWarning( Form( "Not loader found for %s", det->GetName() ) );
286 // Check trigger conditions and create the trigger class mask
288 // Calculate trigger Input pattern
291 // Clear trigger detectors
292 trgdetArray.SetOwner();
293 trgdetArray.Delete();
295 if( (detStr.CompareTo( "ALL" ) != 0) && !detStr.IsNull() ) {
296 AliError( Form("the following detectors were not found: %s",
303 AliDebug(1, Form("Event:%d Class Mask:0x%llX", iEvent,fClassMask ) );
307 // cout << endl << " Print " << endl;
311 runLoader->WriteTrigger( "OVERWRITE" );
315 //----------------------------------------------------------------------------
316 void AliCentralTrigger::TriggerInputs()
318 // Find which inputs are in configuration
319 // and calculate input pattern
324 const TObjArray& inputsArray = fConfiguration->GetInputs();
325 Int_t ninputs = inputsArray.GetEntriesFast();
326 for( Int_t j=0; j<ninputs; j++ ) {
327 AliTriggerInput* input = (AliTriggerInput*)inputsArray.At( j );
328 if(input->GetValue()){
329 UChar_t level=input->GetLevel();
330 if(level == 0) fL0TriggerInputs |= (input->GetMask());
331 else if(level == 1) fL1TriggerInputs |= (input->GetMask());
332 else if(level == 2) fL2TriggerInputs |= (input->GetMask());
334 AliError(Form("Unknown input level:%c:",level));
340 //_____________________________________________________________________________
341 ULong64_t AliCentralTrigger::TriggerClasses()
343 // Check trigger conditions and create the trigger class
344 // and trigger cluster masks
347 if (fConfiguration) {
348 const TObjArray& classesArray = fConfiguration->GetClasses();
349 Int_t nclasses = classesArray.GetEntriesFast();
350 for( Int_t j=0; j<nclasses; j++ ) {
351 AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
352 trclass->Trigger( fConfiguration->GetInputs(), fConfiguration->GetFunctions() );
353 fClassMask |= trclass->GetValue();
354 if (trclass->GetStatus()) {
355 AliTriggerCluster *trclust = trclass->GetCluster();
356 fClusterMask |= AliDAQ::DetectorPattern(trclust->GetDetectorsInCluster());
362 //_____________________________________________________________________________
363 TObjArray* AliCentralTrigger::GetFiredClasses() const
365 // return only the true conditions
367 TObjArray* result = new TObjArray();
369 if (fConfiguration) {
370 const TObjArray& classesArray = fConfiguration->GetClasses();
371 Int_t nclasses = classesArray.GetEntriesFast();
372 for( Int_t j=0; j<nclasses; j++ ) {
373 AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
374 if( trclass->GetStatus() ) result->AddLast( trclass );
381 //_____________________________________________________________________________
382 void AliCentralTrigger::Print( const Option_t* ) const
385 cout << "Central Trigger: " << endl;
386 cout << " Trigger Class Mask: 0x" << hex << fClassMask << dec << endl;
387 if (fConfiguration) fConfiguration->Print();
392 //////////////////////////////////////////////////////////////////////////////
395 //_____________________________________________________________________________
396 Bool_t AliCentralTrigger::IsSelected( TString detName, TString& detectors ) const
398 // check whether detName is contained in detectors
399 // if yes, it is removed from detectors
401 // check if all detectors are selected
402 if( (detectors.CompareTo("ALL") == 0 ) ||
403 detectors.BeginsWith("ALL ") ||
404 detectors.EndsWith(" ALL") ||
405 detectors.Contains(" ALL ") ) {
410 // search for the given detector
411 Bool_t result = kFALSE;
412 if( (detectors.CompareTo( detName ) == 0) ||
413 detectors.BeginsWith( detName+" " ) ||
414 detectors.EndsWith( " "+detName ) ||
415 detectors.Contains( " "+detName+" " ) ) {
416 detectors.ReplaceAll( detName, "" );
420 // clean up the detectors string
421 while( detectors.Contains(" ") ) detectors.ReplaceAll( " ", " " );
422 while( detectors.BeginsWith(" ") ) detectors.Remove( 0, 1 );
423 while( detectors.EndsWith(" ") ) detectors.Remove( detectors.Length()-1, 1 );
428 //_____________________________________________________________________________
429 Bool_t AliCentralTrigger::CheckTriggeredDetectors() const
431 // Check the trigger mask, finds which trigger classes
432 // have been fired, load the corresponding trigger clusters and
433 // finally makes a list of the detectors that have been readout
434 // for each particular event. This list is then compared to the
435 // one stored in fClusterMask. Return value:
436 // true = two lists are equal
437 // false = two lists are not equal meaning wrong trigger config
440 if (!fConfiguration) {
441 AliError("The trigger confiration has not yet been loaded! Cross-check is not possible!");
446 // Make a cross-check so that to exclude wrong trigger configuration used
447 // Loop over the trigger classes
448 UInt_t clusterMask = 0;
449 const TObjArray& classesArray = fConfiguration->GetClasses();
450 Int_t nclasses = classesArray.GetEntriesFast();
451 for( Int_t j=0; j<nclasses; j++ ) {
452 AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
453 if (trclass->GetMask() & fClassMask) { // class was fired
454 AliTriggerCluster *trclust = trclass->GetCluster();
455 clusterMask |= AliDAQ::DetectorPattern(trclust->GetDetectorsInCluster());
458 // Compare the stored cluster mask with the one
459 // that we get from trigger classes
460 if (clusterMask != fClusterMask) {
461 if ((clusterMask & fClusterMask) == clusterMask) {
462 AliInfo(Form("Cluster mask from trigger classes (%x) and from data (%x) differ. Concurrent DAQ run(s) could be the reason.",
463 (UInt_t)clusterMask,(UInt_t)fClusterMask));
467 AliError(Form("Wrong cluster mask from trigger classes (%x), expecting (%x)! Loaded trigger configuration is possibly wrong!",
468 (UInt_t)clusterMask,(UInt_t)fClusterMask));