Added methods for finding a given module in the DDL map (F. Prino)
[u/mrichter/AliRoot.git] / STEER / AliCentralTrigger.cxx
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 //                                                                           //
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                           //
27 //           Get the inputs                                                  //
28 //           Check the trigger classes                                       //
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>
39 #include <TFile.h>
40 #include <TTree.h>
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"
49 #include "AliTriggerConfiguration.h"
50 #include "AliTriggerClass.h"
51 #include "AliTriggerCluster.h"
52 #include "AliCentralTrigger.h"
53 #include "AliDetectorEventHeader.h"
54 #include "AliHeader.h"
55
56 #include "AliCDBManager.h"
57 #include "AliCDBPath.h"
58 #include "AliCDBEntry.h"
59
60 ClassImp( AliCentralTrigger )
61
62 //_____________________________________________________________________________
63 AliCentralTrigger::AliCentralTrigger() :
64    TObject(),
65    fClassMask(0),
66    fClusterMask(0),
67    fConfiguration(NULL)
68 {
69    // Default constructor
70 }
71
72 //_____________________________________________________________________________
73 AliCentralTrigger::AliCentralTrigger( TString & config ) :
74    TObject(),
75    fClassMask(0),
76    fClusterMask(0),
77    fConfiguration(NULL)
78 {
79    // Default constructor
80    LoadConfiguration( config );
81 }
82
83 //_____________________________________________________________________________
84 AliCentralTrigger::~AliCentralTrigger()
85 {
86   // Destructor
87   DeleteConfiguration();
88 }
89
90 //_____________________________________________________________________________
91 void AliCentralTrigger::DeleteConfiguration()
92 {
93   // Delete the active configuration
94   fClassMask = 0;
95   fClusterMask = 0;
96   if (fConfiguration) delete fConfiguration;
97 }
98
99 //_____________________________________________________________________________
100 void AliCentralTrigger::Reset()
101 {
102    // Reset Class Mask and classes
103    fClassMask = 0;
104    fClusterMask = 0;
105
106    if (fConfiguration) {
107      const TObjArray& classesArray = fConfiguration->GetClasses();
108      Int_t nclasses = classesArray.GetEntriesFast();
109      for( Int_t j=0; j<nclasses; j++ ) {
110        AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
111        trclass->Reset();
112      }
113    }
114 }
115
116 //_____________________________________________________________________________
117 void AliCentralTrigger::MakeBranch( TString name, TTree * tree )
118 {
119    // Make a branch to store only trigger class mask event by event
120
121    if( tree )  {
122       AliDebug( 1, "Got Tree from folder." );
123       TBranch* branch = tree->GetBranch( name );
124       if( branch == 0x0 ) {
125          AliDebug( 1, "Creating new branch" );
126          branch = tree->Branch( name, &(this->fClassMask), "fClassMask/l" );
127          branch->SetAutoDelete( kFALSE );
128       }
129       else {
130          AliDebug( 1, "Got Branch from Tree" );
131          branch->SetAddress( &(this->fClassMask) );
132       }
133    }
134 }
135
136 //_____________________________________________________________________________
137 Bool_t AliCentralTrigger::LoadConfiguration( TString & config )
138 {
139    // Load one and only one pre-created COnfiguration from database/file that match
140    // with the input string 'config'
141    // Ej: "p-p", "Pb-Pb" or "p-p-DIMUON CALIBRATION-CENTRAL-BARREL"
142
143    // Delete the active configuration, if any
144   DeleteConfiguration();
145
146    // Load the selected configuration
147    if (!config.IsNull()) {
148      fConfiguration = AliTriggerConfiguration::LoadConfiguration( config );
149      if(fConfiguration)
150        return kTRUE;
151      else {
152        AliError( Form( "Valid TriggerConfiguration (%s) is not found ! Disabling the trigger simulation !", config.Data() ) );
153        return kFALSE;
154      }
155    }
156    else {
157      // Load one and only one trigger descriptor from CDB
158      AliInfo( "GETTING TRIGGER DESCRIPTORS FROM CDB!!!" );
159  
160      AliCDBPath path( "GRP", "CTP", "Config" );
161         
162      AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
163      if( !entry ) AliFatal( "Couldn't load trigger description data from CDB!" );
164
165      fConfiguration = (AliTriggerConfiguration *)entry->GetObject();
166      if(fConfiguration)
167        return kTRUE;
168      else {
169        AliError( "No valid configuration is found in the CDB ! Disabling the trigger simulation !" );
170        return kFALSE;
171      }
172    }
173 }
174
175 //_____________________________________________________________________________
176 TString AliCentralTrigger::GetDetectors()
177 {
178    // return TString with the detectors (modules) to be used for triggering
179
180    TString result;
181
182    if (fConfiguration)
183      result = fConfiguration->GetTriggeringModules();
184
185    return result;
186 }
187
188 //_____________________________________________________________________________
189 Bool_t AliCentralTrigger::RunTrigger( AliRunLoader* runLoader, const char *detectors )
190 {
191    // run the trigger
192
193    if( !fConfiguration ) {
194       AliError( "No trigger configuration loaded, skipping trigger" );
195       return kFALSE;
196    }
197
198    TTree *tree = runLoader->TreeCT();
199    if( !tree ) {
200       AliError( "No folder with trigger loaded, skipping trigger" );
201       return kFALSE;
202    }
203
204    TStopwatch stopwatch;
205    stopwatch.Start();
206
207    // Process each event
208    for( Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++ ) {
209       AliInfo( Form("  ***** Processing event %d *****\n", iEvent) );
210       runLoader->GetEvent( iEvent );
211       // Get detectors involve
212       TString detStr = GetDetectors();
213       AliInfo( Form(" Triggering Detectors: %s \n", detStr.Data() ) );
214       TString detWithDigits = detectors;
215       AliInfo( Form(" Detectors with digits: %s \n", detWithDigits.Data() ) );
216       TObjArray* detArray = runLoader->GetAliRun()->Detectors();
217       // Reset Mask
218       fClassMask = 0;
219       fClusterMask = 0;
220       // Reset configuration object (inputs and classes)
221       fConfiguration->Reset();
222       TObjArray trgdetArray; // use as garbage collector
223       for( Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++ ) {
224          AliModule* det = (AliModule*) detArray->At( iDet );
225          if( !det || !det->IsActive() ) continue;
226          if( IsSelected(det->GetName(), detStr) &&
227              IsSelected(det->GetName(), detWithDigits) ) {
228
229             AliInfo( Form("Triggering from digits for %s", det->GetName() ) );
230             AliTriggerDetector* trgdet = det->CreateTriggerDetector();
231             trgdet->CreateInputs(fConfiguration->GetInputs());
232             TStopwatch stopwatchDet;
233             stopwatchDet.Start();
234             trgdet->Trigger();
235             AliInfo( Form("Execution time for %s: R:%.2fs C:%.2fs",
236                      det->GetName(), stopwatchDet.RealTime(), stopwatchDet.CpuTime() ) );
237
238             trgdetArray.AddLast( trgdet );
239
240             // Write trigger detector in Event folder in Digits file
241             TString loadername = det->GetName();
242             loadername.Append( "Loader" );
243             AliLoader * loader = runLoader->GetLoader( loadername );
244             if( loader ) {
245                AliDataLoader * dataLoader = loader->GetDigitsDataLoader();
246                if( !dataLoader->IsFileOpen() ) {
247                   if( dataLoader->OpenFile( "UPDATE" ) ) {
248                      AliWarning( Form( "\n\nCan't write trigger for %s\n", det->GetName() ) );
249                   }
250                }
251                dataLoader->Cd();
252                if( gFile && !gFile->IsWritable() ) {
253                   gFile->ReOpen( "UPDATE" );
254                   dataLoader->Cd();
255                }
256                trgdet->Write( "Trigger", TObject::kOverwrite );
257                dataLoader->CloseFile();
258             }
259             else  AliWarning( Form( "Not loader found for %s", det->GetName() ) );
260          }
261       }
262
263       // Check trigger conditions and create the trigger class mask
264       TriggerClasses();
265
266       // Clear trigger detectors
267       trgdetArray.SetOwner();
268       trgdetArray.Delete();
269
270       if( (detStr.CompareTo( "ALL" ) != 0) && !detStr.IsNull() ) {
271          AliError( Form("the following detectors were not found: %s",
272                    detStr.Data()));
273          //JF return kFALSE;
274       }
275
276       // Save trigger mask
277       tree->Fill();
278       AliInfo( Form("**************** Central Trigger Class Mask:0x%X", fClassMask ) );
279    } // end event loop
280
281    Reset();
282 //   cout << endl <<  " Print " << endl;
283 //   Print();
284
285    // Write
286    runLoader->WriteTrigger( "OVERWRITE" );
287
288    return kTRUE;
289 }
290
291 //_____________________________________________________________________________
292 ULong64_t AliCentralTrigger::TriggerClasses()
293 {
294   // Check trigger conditions and create the trigger class
295   // and trigger cluster masks
296   if (fConfiguration) {
297     const TObjArray& classesArray = fConfiguration->GetClasses();
298     Int_t nclasses = classesArray.GetEntriesFast();
299     for( Int_t j=0; j<nclasses; j++ ) {
300       AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
301       trclass->Trigger( fConfiguration->GetInputs(), fConfiguration->GetFunctions() );
302       fClassMask |= trclass->GetValue();
303       if (trclass->GetStatus())
304         fClusterMask |= (trclass->GetCluster())->GetClusterMask();
305     }
306   }
307   return fClassMask;
308 }
309 //_____________________________________________________________________________
310 TObjArray* AliCentralTrigger::GetFiredClasses() const
311 {
312    // return only the true conditions
313
314    TObjArray* result = new TObjArray();
315
316    if (fConfiguration) {
317      const TObjArray& classesArray = fConfiguration->GetClasses();
318      Int_t nclasses = classesArray.GetEntriesFast();
319      for( Int_t j=0; j<nclasses; j++ ) {
320        AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
321        if( trclass->GetStatus() ) result->AddLast( trclass );
322      }
323    }
324
325    return result;
326 }
327
328 //_____________________________________________________________________________
329 void AliCentralTrigger::Print( const Option_t*  ) const
330 {
331    // Print
332    cout << "Central Trigger: " << endl;
333    cout << "  Trigger Class Mask: 0x" << hex << fClassMask << dec << endl;
334    if (fConfiguration) fConfiguration->Print();
335    cout << endl;
336 }
337
338
339 //////////////////////////////////////////////////////////////////////////////
340 // Helper method
341
342 //_____________________________________________________________________________
343 Bool_t AliCentralTrigger::IsSelected( TString detName, TString& detectors ) const
344 {
345    // check whether detName is contained in detectors
346    // if yes, it is removed from detectors
347
348    // check if all detectors are selected
349    if( (detectors.CompareTo("ALL") == 0 ) ||
350         detectors.BeginsWith("ALL ") ||
351         detectors.EndsWith(" ALL") ||
352         detectors.Contains(" ALL ") ) {
353       detectors = "ALL";
354       return kTRUE;
355    }
356
357    // search for the given detector
358    Bool_t result = kFALSE;
359    if( (detectors.CompareTo( detName ) == 0) ||
360         detectors.BeginsWith( detName+" " ) ||
361         detectors.EndsWith( " "+detName ) ||
362         detectors.Contains( " "+detName+" " ) ) {
363       detectors.ReplaceAll( detName, "" );
364       result = kTRUE;
365    }
366
367    // clean up the detectors string
368    while( detectors.Contains("  ") )  detectors.ReplaceAll( "  ", " " );
369    while( detectors.BeginsWith(" ") ) detectors.Remove( 0, 1 );
370    while( detectors.EndsWith(" ") )   detectors.Remove( detectors.Length()-1, 1 );
371
372    return result;
373 }
374
375 //_____________________________________________________________________________
376 TString AliCentralTrigger::GetTriggeredDetectors() const
377 {
378   // Check the trigger mask, finds which trigger classes
379   // have been fired, load the corresponding trigger clusters and
380   // finally makes a list of the detectors that have been readout
381   // for each particular event
382
383   if (!fConfiguration) {
384     AliError("The trigger confiration has not yet been loaded!");
385     return "";
386   }
387
388   // Now loop over the trigger classes
389   const TObjArray& classesArray = fConfiguration->GetClasses();
390   Int_t nclasses = classesArray.GetEntriesFast();
391   UChar_t clustMask = 0;
392   for( Int_t j=0; j<nclasses; j++ ) {
393     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At( j );
394     if (trclass->GetMask() & fClassMask) { // class was fired
395       AliTriggerCluster *clust = trclass->GetCluster();
396       clustMask |= clust->GetClusterMask();
397     }
398   }
399
400   // Compare the stored cluster mask with the one
401   // that we get from trigger classes
402   // To be enables after we store the cluster mask in the trigger tree
403   //  if (clustMask != fClusterMask)
404   //    AliError(Form("Wrong cluster mask from trigger classes (%x), expecting (%x)!",(UInt_t)clustMask,(UInt_t)fClusterMask));
405
406   // Now loop over clusters and produce the string
407   // with the triggered detectors
408   TString trigDets;
409   const TObjArray& clustArray = fConfiguration->GetClusters();
410   Int_t nclust = clustArray.GetEntriesFast();
411   for( Int_t i=0; i<nclust; i++ ) {
412     AliTriggerCluster* clust = (AliTriggerCluster*)clustArray.At( i );
413     if (clustMask & clust->GetClusterMask()) { // the cluster was fired
414       TString detStr = clust->GetDetectorsInCluster();
415       TObjArray* det = detStr.Tokenize(" ");
416       Int_t ndet = det->GetEntriesFast();
417       for( Int_t j=0; j<ndet; j++ ) {
418         TString &detj = ((TObjString*)det->At(j))->String();
419          if((trigDets.CompareTo(detj) == 0) || 
420             trigDets.BeginsWith(detj) ||
421             trigDets.EndsWith(detj) ||
422             trigDets.Contains( " "+detj+" " )) continue;
423          trigDets.Append( " " );
424          trigDets.Append( detj );
425       }
426     }
427   }
428
429   return trigDets;
430 }