Bug corrected.
[u/mrichter/AliRoot.git] / STEER / AliCentralTrigger.cxx
CommitLineData
a5a091ce 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/* $Id$ */
17
18///////////////////////////////////////////////////////////////////////////////
19// //
20// This class for running the Central Trigger Processor //
21// //
22// //
51f6d619 23// Load Configuration //
24// Make a list the trigger detectors involved (from the classes) //
a5a091ce 25// For the each event //
26// Run the Trigger for the each detector //
27// Get the inputs //
51f6d619 28// Check the trigger classes //
a5a091ce 29// Create the class mask //
30// Save result //
31// //
32// //
33///////////////////////////////////////////////////////////////////////////////
34
35#include <TString.h>
36#include <TObjString.h>
37#include <TObjArray.h>
38#include <TStopwatch.h>
bacbe0fd 39#include <TFile.h>
40#include <TTree.h>
a5a091ce 41
42#include "AliLog.h"
43#include "AliRun.h"
44#include "AliRunLoader.h"
45#include "AliModule.h"
46
47#include "AliTriggerInput.h"
48#include "AliTriggerDetector.h"
51f6d619 49#include "AliTriggerConfiguration.h"
50#include "AliTriggerClass.h"
51#include "AliTriggerCluster.h"
a5a091ce 52#include "AliCentralTrigger.h"
bacbe0fd 53#include "AliDetectorEventHeader.h"
54#include "AliHeader.h"
55
51f6d619 56#include "AliCDBManager.h"
57#include "AliCDBPath.h"
58#include "AliCDBEntry.h"
a5a091ce 59
60ClassImp( AliCentralTrigger )
61
62//_____________________________________________________________________________
63AliCentralTrigger::AliCentralTrigger() :
64 TObject(),
75e3794b 65 fClassMask(0),
51f6d619 66 fClusterMask(0),
d3f1f232 67 fL0TriggerInputs(0),
68 fL1TriggerInputs(0),
69 fL2TriggerInputs(0),
51f6d619 70 fConfiguration(NULL)
a5a091ce 71{
72 // Default constructor
596735df 73 SetOwner();
a5a091ce 74}
75
76//_____________________________________________________________________________
51f6d619 77AliCentralTrigger::AliCentralTrigger( TString & config ) :
a5a091ce 78 TObject(),
75e3794b 79 fClassMask(0),
51f6d619 80 fClusterMask(0),
d3f1f232 81 fL0TriggerInputs(0),
82 fL1TriggerInputs(0),
83 fL2TriggerInputs(0),
51f6d619 84 fConfiguration(NULL)
a5a091ce 85{
86 // Default constructor
51f6d619 87 LoadConfiguration( config );
bacbe0fd 88}
89
90//_____________________________________________________________________________
a5a091ce 91AliCentralTrigger::~AliCentralTrigger()
92{
51f6d619 93 // Destructor
94 DeleteConfiguration();
bacbe0fd 95}
96
97//_____________________________________________________________________________
51f6d619 98void AliCentralTrigger::DeleteConfiguration()
bacbe0fd 99{
51f6d619 100 // Delete the active configuration
101 fClassMask = 0;
102 fClusterMask = 0;
d3f1f232 103 fL0TriggerInputs = 0;
104 fL1TriggerInputs = 0;
105 fL2TriggerInputs = 0;
596735df 106 if (fConfiguration) {
107 if (IsOwner()) delete fConfiguration;
108 fConfiguration = 0x0;
109 }
a5a091ce 110}
111
112//_____________________________________________________________________________
bacbe0fd 113void AliCentralTrigger::Reset()
114{
51f6d619 115 // Reset Class Mask and classes
bacbe0fd 116 fClassMask = 0;
51f6d619 117 fClusterMask = 0;
d3f1f232 118 fL0TriggerInputs = 0;
119 fL1TriggerInputs = 0;
120 fL2TriggerInputs = 0;
51f6d619 121
122 if (fConfiguration) {
123 const TObjArray& classesArray = fConfiguration->GetClasses();
124 Int_t nclasses = classesArray.GetEntriesFast();
125 for( Int_t j=0; j<nclasses; j++ ) {
126 AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
127 trclass->Reset();
128 }
bacbe0fd 129 }
130}
131
132//_____________________________________________________________________________
133void AliCentralTrigger::MakeBranch( TString name, TTree * tree )
134{
135 // Make a branch to store only trigger class mask event by event
136
137 if( tree ) {
138 AliDebug( 1, "Got Tree from folder." );
139 TBranch* branch = tree->GetBranch( name );
140 if( branch == 0x0 ) {
141 AliDebug( 1, "Creating new branch" );
d3f1f232 142 branch = tree->Branch( name, &(this->fClassMask), "fClassMask/l:fClusterMask/i:fL0TriggerInputs/i:fL1TriggerInputs/i:fL2TriggerInputs/s" );
bacbe0fd 143 branch->SetAutoDelete( kFALSE );
144 }
145 else {
146 AliDebug( 1, "Got Branch from Tree" );
147 branch->SetAddress( &(this->fClassMask) );
148 }
149 }
150}
151
152//_____________________________________________________________________________
51f6d619 153Bool_t AliCentralTrigger::LoadConfiguration( TString & config )
a5a091ce 154{
51f6d619 155 // Load one and only one pre-created COnfiguration from database/file that match
156 // with the input string 'config'
157 // Ej: "p-p", "Pb-Pb" or "p-p-DIMUON CALIBRATION-CENTRAL-BARREL"
158
159 // Delete the active configuration, if any
160 DeleteConfiguration();
161
162 // Load the selected configuration
163 if (!config.IsNull()) {
164 fConfiguration = AliTriggerConfiguration::LoadConfiguration( config );
596735df 165 SetOwner();
51f6d619 166 if(fConfiguration)
167 return kTRUE;
168 else {
169 AliError( Form( "Valid TriggerConfiguration (%s) is not found ! Disabling the trigger simulation !", config.Data() ) );
170 return kFALSE;
171 }
172 }
173 else {
174 // Load one and only one trigger descriptor from CDB
7e88424f 175 AliInfo( "Getting trigger configuration from OCDB!" );
51f6d619 176
177 AliCDBPath path( "GRP", "CTP", "Config" );
178
179 AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
596735df 180 SetOwner(kFALSE);
51f6d619 181 if( !entry ) AliFatal( "Couldn't load trigger description data from CDB!" );
182
183 fConfiguration = (AliTriggerConfiguration *)entry->GetObject();
184 if(fConfiguration)
185 return kTRUE;
186 else {
187 AliError( "No valid configuration is found in the CDB ! Disabling the trigger simulation !" );
188 return kFALSE;
189 }
a5a091ce 190 }
a5a091ce 191}
192
193//_____________________________________________________________________________
194TString AliCentralTrigger::GetDetectors()
195{
51f6d619 196 // return TString with the detectors (modules) to be used for triggering
a5a091ce 197
198 TString result;
199
51f6d619 200 if (fConfiguration)
201 result = fConfiguration->GetTriggeringModules();
a5a091ce 202
203 return result;
204}
205
206//_____________________________________________________________________________
8480396b 207Bool_t AliCentralTrigger::RunTrigger( AliRunLoader* runLoader, const char *detectors )
a5a091ce 208{
209 // run the trigger
bacbe0fd 210
51f6d619 211 if( !fConfiguration ) {
212 AliError( "No trigger configuration loaded, skipping trigger" );
bacbe0fd 213 return kFALSE;
214 }
215
216 TTree *tree = runLoader->TreeCT();
217 if( !tree ) {
51f6d619 218 AliError( "No folder with trigger loaded, skipping trigger" );
a5a091ce 219 return kFALSE;
220 }
221
222 TStopwatch stopwatch;
223 stopwatch.Start();
bacbe0fd 224
01eed601 225 AliInfo( Form(" Triggering Detectors: %s \n", GetDetectors().Data() ) );
226 AliInfo( Form(" Detectors with digits: %s \n", detectors ) );
227
a5a091ce 228 // Process each event
229 for( Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++ ) {
bacbe0fd 230 runLoader->GetEvent( iEvent );
a5a091ce 231 // Get detectors involve
232 TString detStr = GetDetectors();
8480396b 233 TString detWithDigits = detectors;
a5a091ce 234 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
235 // Reset Mask
236 fClassMask = 0;
895affe8 237 fClusterMask = 0;
238 // Reset configuration object (inputs and classes)
239 fConfiguration->Reset();
bacbe0fd 240 TObjArray trgdetArray; // use as garbage collector
a5a091ce 241 for( Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++ ) {
242 AliModule* det = (AliModule*) detArray->At( iDet );
243 if( !det || !det->IsActive() ) continue;
8480396b 244 if( IsSelected(det->GetName(), detStr) &&
245 IsSelected(det->GetName(), detWithDigits) ) {
bacbe0fd 246
01eed601 247 AliDebug(1,Form("Triggering from digits for %s", det->GetName() ) );
a5a091ce 248 AliTriggerDetector* trgdet = det->CreateTriggerDetector();
a4d25339 249 trgdet->AssignInputs(fConfiguration->GetInputs());
a5a091ce 250 TStopwatch stopwatchDet;
251 stopwatchDet.Start();
252 trgdet->Trigger();
01eed601 253 AliDebug(1, Form("Execution time for %s: R:%.2fs C:%.2fs",
a5a091ce 254 det->GetName(), stopwatchDet.RealTime(), stopwatchDet.CpuTime() ) );
bacbe0fd 255
bacbe0fd 256 trgdetArray.AddLast( trgdet );
257
258 // Write trigger detector in Event folder in Digits file
259 TString loadername = det->GetName();
260 loadername.Append( "Loader" );
261 AliLoader * loader = runLoader->GetLoader( loadername );
262 if( loader ) {
263 AliDataLoader * dataLoader = loader->GetDigitsDataLoader();
264 if( !dataLoader->IsFileOpen() ) {
265 if( dataLoader->OpenFile( "UPDATE" ) ) {
266 AliWarning( Form( "\n\nCan't write trigger for %s\n", det->GetName() ) );
267 }
268 }
269 dataLoader->Cd();
270 if( gFile && !gFile->IsWritable() ) {
271 gFile->ReOpen( "UPDATE" );
272 dataLoader->Cd();
273 }
274 trgdet->Write( "Trigger", TObject::kOverwrite );
275 dataLoader->CloseFile();
276 }
277 else AliWarning( Form( "Not loader found for %s", det->GetName() ) );
a5a091ce 278 }
279 }
280
281 // Check trigger conditions and create the trigger class mask
51f6d619 282 TriggerClasses();
d3f1f232 283 // Calculate trigger Input pattern
284 TriggerInputs();
bacbe0fd 285
a5a091ce 286 // Clear trigger detectors
287 trgdetArray.SetOwner();
288 trgdetArray.Delete();
289
290 if( (detStr.CompareTo( "ALL" ) != 0) && !detStr.IsNull() ) {
291 AliError( Form("the following detectors were not found: %s",
292 detStr.Data()));
e229562b 293 //JF return kFALSE;
a5a091ce 294 }
295
bacbe0fd 296 // Save trigger mask
297 tree->Fill();
73bbf779 298 AliDebug(1, Form("Event:%d Class Mask:0x%llX", iEvent,fClassMask ) );
a5a091ce 299 } // end event loop
a5a091ce 300
bacbe0fd 301 Reset();
302// cout << endl << " Print " << endl;
303// Print();
304
305 // Write
306 runLoader->WriteTrigger( "OVERWRITE" );
a5a091ce 307
bacbe0fd 308 return kTRUE;
309}
d3f1f232 310//----------------------------------------------------------------------------
311void AliCentralTrigger::TriggerInputs()
312{
313 // Find which inputs are in configuration
314 // and calculate input pattern
315 fL0TriggerInputs=0;
316 fL1TriggerInputs=0;
317 fL2TriggerInputs=0;
318 if(fConfiguration){
319 const TObjArray& inputsArray = fConfiguration->GetInputs();
320 Int_t ninputs = inputsArray.GetEntriesFast();
321 for( Int_t j=0; j<ninputs; j++ ) {
322 AliTriggerInput* input = (AliTriggerInput*)inputsArray.At( j );
323 if(input->GetValue()){
324 UChar_t level=input->GetLevel();
325 if(level == 0) fL0TriggerInputs |= (input->GetMask());
326 else if(level == 1) fL1TriggerInputs |= (input->GetMask());
327 else if(level == 2) fL2TriggerInputs |= (input->GetMask());
328 else{
329 AliError(Form("Unknown input level:%c:",level));
330 }
331 }
332 }
333 }
334}
a5a091ce 335//_____________________________________________________________________________
51f6d619 336ULong64_t AliCentralTrigger::TriggerClasses()
a5a091ce 337{
51f6d619 338 // Check trigger conditions and create the trigger class
339 // and trigger cluster masks
7e88424f 340 fClassMask = 0;
341 fClusterMask = 0;
51f6d619 342 if (fConfiguration) {
343 const TObjArray& classesArray = fConfiguration->GetClasses();
344 Int_t nclasses = classesArray.GetEntriesFast();
345 for( Int_t j=0; j<nclasses; j++ ) {
346 AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
347 trclass->Trigger( fConfiguration->GetInputs(), fConfiguration->GetFunctions() );
348 fClassMask |= trclass->GetValue();
7e88424f 349 if (trclass->GetStatus()) {
350 AliTriggerCluster *trclust = trclass->GetCluster();
351 fClusterMask |= AliDAQ::DetectorPattern(trclust->GetDetectorsInCluster());
352 }
51f6d619 353 }
354 }
355 return fClassMask;
a5a091ce 356}
357//_____________________________________________________________________________
51f6d619 358TObjArray* AliCentralTrigger::GetFiredClasses() const
a5a091ce 359{
360 // return only the true conditions
361
362 TObjArray* result = new TObjArray();
363
51f6d619 364 if (fConfiguration) {
365 const TObjArray& classesArray = fConfiguration->GetClasses();
366 Int_t nclasses = classesArray.GetEntriesFast();
367 for( Int_t j=0; j<nclasses; j++ ) {
368 AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
369 if( trclass->GetStatus() ) result->AddLast( trclass );
370 }
a5a091ce 371 }
372
373 return result;
374}
375
a5a091ce 376//_____________________________________________________________________________
377void AliCentralTrigger::Print( const Option_t* ) const
378{
379 // Print
380 cout << "Central Trigger: " << endl;
381 cout << " Trigger Class Mask: 0x" << hex << fClassMask << dec << endl;
51f6d619 382 if (fConfiguration) fConfiguration->Print();
a5a091ce 383 cout << endl;
384}
385
386
387//////////////////////////////////////////////////////////////////////////////
388// Helper method
389
390//_____________________________________________________________________________
391Bool_t AliCentralTrigger::IsSelected( TString detName, TString& detectors ) const
392{
393 // check whether detName is contained in detectors
394 // if yes, it is removed from detectors
395
396 // check if all detectors are selected
397 if( (detectors.CompareTo("ALL") == 0 ) ||
398 detectors.BeginsWith("ALL ") ||
399 detectors.EndsWith(" ALL") ||
400 detectors.Contains(" ALL ") ) {
401 detectors = "ALL";
402 return kTRUE;
403 }
404
405 // search for the given detector
406 Bool_t result = kFALSE;
407 if( (detectors.CompareTo( detName ) == 0) ||
408 detectors.BeginsWith( detName+" " ) ||
409 detectors.EndsWith( " "+detName ) ||
410 detectors.Contains( " "+detName+" " ) ) {
411 detectors.ReplaceAll( detName, "" );
412 result = kTRUE;
413 }
414
415 // clean up the detectors string
416 while( detectors.Contains(" ") ) detectors.ReplaceAll( " ", " " );
417 while( detectors.BeginsWith(" ") ) detectors.Remove( 0, 1 );
418 while( detectors.EndsWith(" ") ) detectors.Remove( detectors.Length()-1, 1 );
419
420 return result;
421}
67327b72 422
423//_____________________________________________________________________________
7e88424f 424Bool_t AliCentralTrigger::CheckTriggeredDetectors() const
67327b72 425{
426 // Check the trigger mask, finds which trigger classes
427 // have been fired, load the corresponding trigger clusters and
428 // finally makes a list of the detectors that have been readout
7e88424f 429 // for each particular event. This list is then compared to the
430 // one stored in fClusterMask. Return value:
431 // true = two lists are equal
432 // false = two lists are not equal meaning wrong trigger config
433 // is loaded.
67327b72 434
435 if (!fConfiguration) {
7e88424f 436 AliError("The trigger confiration has not yet been loaded! Cross-check is not possible!");
437 return kFALSE;
67327b72 438 }
7e88424f 439 else {
67327b72 440
7e88424f 441 // Make a cross-check so that to exclude wrong trigger configuration used
442 // Loop over the trigger classes
443 UInt_t clusterMask = 0;
444 const TObjArray& classesArray = fConfiguration->GetClasses();
445 Int_t nclasses = classesArray.GetEntriesFast();
446 for( Int_t j=0; j<nclasses; j++ ) {
447 AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
448 if (trclass->GetMask() & fClassMask) { // class was fired
449 AliTriggerCluster *trclust = trclass->GetCluster();
450 clusterMask |= AliDAQ::DetectorPattern(trclust->GetDetectorsInCluster());
67327b72 451 }
452 }
7e88424f 453 // Compare the stored cluster mask with the one
454 // that we get from trigger classes
7e88424f 455 if (clusterMask != fClusterMask) {
454d6738 456 if ((clusterMask & fClusterMask) == clusterMask) {
457 AliInfo(Form("Cluster mask from trigger classes (%x) and from data (%x) differ. Concurrent DAQ run(s) could be the reason.",
458 (UInt_t)clusterMask,(UInt_t)fClusterMask));
459 return kTRUE;
460 }
461 else {
462 AliError(Form("Wrong cluster mask from trigger classes (%x), expecting (%x)! Loaded trigger configuration is possibly wrong!",
463 (UInt_t)clusterMask,(UInt_t)fClusterMask));
464 return kFALSE;
465 }
7e88424f 466 }
67327b72 467 }
468
7e88424f 469 return kTRUE;
67327b72 470}