Changing once more (hopefully we get it correct this time...) the logic to trig the...
[u/mrichter/AliRoot.git] / TRIGGER / AliTrigScheduler.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 // Author: Andrei Gheata, 05/01/2010
18
19 #include "AliTrigScheduler.h"
20
21 #include <TMath.h>
22 #include <TList.h>
23 #include <TObjArray.h>
24 #include "AliTrigScheduledEntry.h"
25
26 ClassImp(AliTrigScheduledGroup)
27
28 //==============================================================================
29 //
30 //   AliTrigScheduledGroup - A group of scheduled entries that will simply be
31 //                           fired-up sequentially. The group delay in global time
32 //                           units is the latest start time of the contained
33 //                           entries. A group has a priority assigned by the
34 //                           owner scheduler object. Groups are fired-up according
35 //                           a programable sequence.
36 //
37 //==============================================================================
38
39 //______________________________________________________________________________
40 AliTrigScheduledGroup::AliTrigScheduledGroup()
41                       :TNamed(),
42                        fPriority(0),
43                        fDelay(0),
44                        fEntries(NULL)
45 {
46 // I/O constructor. 
47 }
48
49 //______________________________________________________________________________
50 AliTrigScheduledGroup::AliTrigScheduledGroup(const char *name, Int_t priority)
51                       :TNamed(name,""),
52                        fPriority(priority),
53                        fDelay(0),
54                        fEntries(new TObjArray())
55 {
56 // Constructor.
57 }
58
59 //______________________________________________________________________________
60 AliTrigScheduledGroup::~AliTrigScheduledGroup()
61 {
62 // Destructor.
63   if (fEntries) delete fEntries;
64 }  
65
66 //______________________________________________________________________________
67 void AliTrigScheduledGroup::AddEntry(AliTrigScheduledEntry *entry)
68 {
69 // Add a scheduled entry to the group. There is no check if an entry was added twice !
70   if (!fEntries) fEntries = new TObjArray();
71   fEntries->Add(entry);
72 }
73
74 //______________________________________________________________________________
75 void AliTrigScheduledGroup::FireUp(Int_t time)
76 {
77 // Fire-up all entries in the group.
78   Int_t nentries = GetNentries();
79   AliTrigScheduledEntry *entry;
80   for (Int_t i=0; i<nentries; i++) {
81     entry = (AliTrigScheduledEntry*)fEntries->At(i);
82     entry->FireUp(time);
83   }
84 }    
85
86 //______________________________________________________________________________
87 Int_t AliTrigScheduledGroup::GetNentries() const
88 {
89 // Get number of scheduled entries in the group.
90   return (fEntries)?fEntries->GetEntriesFast():0;
91 }
92
93 //______________________________________________________________________________
94 void AliTrigScheduledGroup::Print(Option_t *option) const
95 {
96 // Print the group content.
97   Int_t nentries = GetNentries();
98   printf("Group: %s containing %d entries.\n", GetName(), nentries);
99   TString opt(option);
100   opt.ToUpper();
101   // Check if details are requested.
102   if (!opt.Contains("D")) return;
103   for (Int_t i=0; i<nentries; i++) {
104     printf("   %d: ", i);
105     fEntries->At(i)->Print(option);
106   }   
107 }   
108
109 //______________________________________________________________________________
110 void AliTrigScheduledGroup::RemoveEntry(AliTrigScheduledEntry *entry)
111 {
112 // Remove an entry.
113    if (!fEntries) return;
114    fEntries->RecursiveRemove(entry);
115    fEntries->Compress();
116 }
117    
118 ClassImp(AliTrigScheduledSequence)
119
120 //==============================================================================
121 //
122 //   AliTrigScheduledSequence - A programable group sequence. Scheduled groups
123 //                      are owned and controlled by a trigger scheduler. They
124 //                      are fired-up in such a sequence. A sequence supports some
125 //                      default modes but can also be programed manually.
126 //
127 //==============================================================================
128
129 //______________________________________________________________________________
130 AliTrigScheduledSequence::AliTrigScheduledSequence()
131                 :TNamed(),
132                  fScheduler(NULL),
133                  fNgroups(0),
134                  fType(AliTrigScheduledSequence::kDefault),
135                  fArray(NULL)
136 {
137 // I/O constructor
138 }
139
140 //______________________________________________________________________________
141 AliTrigScheduledSequence::AliTrigScheduledSequence(const char *name, AliTrigScheduler *scheduler)
142                 :TNamed(name,""),
143                  fScheduler(scheduler),
144                  fNgroups(scheduler->GetNgroups()),
145                  fType(AliTrigScheduledSequence::kDefault),
146                  fArray(NULL)
147 {
148 // Constructor
149   if (fNgroups) {
150     fArray = new Int_t[fNgroups];
151     for (Int_t i=0; i<fNgroups; i++) fArray[i] = i;
152   }
153 }    
154    
155 //______________________________________________________________________________
156 AliTrigScheduledSequence::~AliTrigScheduledSequence()
157 {
158 // Destructor.
159   if (fArray) delete [] fArray;
160 }  
161
162 //______________________________________________________________________________
163 void AliTrigScheduledSequence::Print(Option_t *) const
164 {
165 // Print the sequence.
166   printf("Sequence: %s scheduled by: %s\n", GetName(), fScheduler->GetName());
167   printf("   type: %d  sequence: ", (Int_t)fType);
168   for (Int_t i=0; i<fNgroups; i++) printf("%d ", fArray[i]);
169   printf("\n");
170 }   
171
172 //______________________________________________________________________________
173 void AliTrigScheduledSequence::SortArray(Int_t *array, Bool_t increasing)
174 {
175 // Sort the internal sequence array.
176   Int_t *ind = new Int_t[fNgroups];
177   TMath::Sort(fNgroups, array, ind, !increasing);
178   memcpy(fArray, ind, fNgroups*sizeof(Int_t));
179   delete [] ind;
180 }
181   
182 //______________________________________________________________________________
183 void AliTrigScheduledSequence::Sort(ESortingType type, Int_t *sequence)
184 {
185   // Sort the group sequence according a predefined type. The sequence
186   // custom input array is considered only for kCustom type.
187   Int_t i;
188   Int_t *array = 0;
189   switch (type) {
190     case AliTrigScheduledSequence::kDefault:
191       // Just ID permutation
192       for (i=0; i<fNgroups; i++) fArray[i] = i;
193       break;
194     case AliTrigScheduledSequence::kTimeInc:
195       // Sort by increasing start time
196       array = new Int_t[fNgroups];
197       for (i=0; i<fNgroups; i++) {
198         array[i] = fScheduler->GetScheduledGroup(i)->GetDelay();
199       }  
200       SortArray(array, kTRUE);
201       break;
202     case AliTrigScheduledSequence::kTimeDec:
203       // Sort by decreasing start time
204       array = new Int_t[fNgroups];
205       for (i=0; i<fNgroups; i++) {
206         array[i] = fScheduler->GetScheduledGroup(i)->GetDelay();
207       }  
208       SortArray(array, kFALSE);
209       break;
210     case AliTrigScheduledSequence::kPriorityInc:
211       // Sort by increasing priority
212       array = new Int_t[fNgroups];
213       for (i=0; i<fNgroups; i++) {
214         array[i] = fScheduler->GetScheduledGroup(i)->GetPriority();
215       }  
216       SortArray(array, kTRUE);
217       break;
218     case AliTrigScheduledSequence::kPriorityDec:
219       // Sort by decreasing priority
220       array = new Int_t[fNgroups];
221       for (i=0; i<fNgroups; i++) {
222         array[i] = fScheduler->GetScheduledGroup(i)->GetPriority();
223       }  
224       SortArray(array, kFALSE);
225       break;
226     case AliTrigScheduledSequence::kCustom:
227       if (!sequence) {
228         Error("Sort", "Sequence array must be provided for custom type");
229         return;
230       }
231       memcpy(fArray, sequence, fNgroups*sizeof(Int_t));
232   }
233   if (array) delete [] array;  
234 }            
235
236 ClassImp(AliTrigScheduler)
237
238 //==============================================================================
239 //   AliTrigScheduler - Device response function scheduler. Every device has a
240 //                      scheduler, but the same scheduler can replay responses of
241 //                      several devices. A scheduler holds groups of scheduled 
242 //                      entries. The groups can be replayed in programable
243 //                      sequences. A default group and sequence are always created.
244 //==============================================================================
245
246 //______________________________________________________________________________
247 AliTrigScheduler::AliTrigScheduler()
248                  :TNamed(),
249                   fNgroups(0),
250                   fGroups(NULL),
251                   fSequences(NULL),
252                   fCurrentSequence(NULL)
253 {
254 // I/O constructor.
255 }
256
257 //______________________________________________________________________________
258 AliTrigScheduler::AliTrigScheduler(const char *name)
259                  :TNamed(name,""),
260                   fNgroups(0),
261                   fGroups(new TObjArray()),
262                   fSequences(new TObjArray()),
263                   fCurrentSequence(NULL)
264 {
265 // Constructor.
266   AddGroup("default");
267   AddSequence("default");
268 }
269
270 //______________________________________________________________________________
271 AliTrigScheduler::~AliTrigScheduler()
272 {
273 // Destructor.
274   if (fGroups) {fGroups->Delete(); delete fGroups;}
275   if (fSequences) {fSequences->Delete(); delete fSequences;}
276 }
277
278 //______________________________________________________________________________
279 void AliTrigScheduler::AddScheduledEntry(AliTrigScheduledEntry *entry, const char *togroup)
280 {
281 // Add a scheduled entry to a given group.
282   AliTrigScheduledGroup *group = GetScheduledGroup(togroup);
283   if (!group) {
284     Error("AddScheduledEntry", "Group %s does not exist in scheduler %s", togroup, GetName());
285     return;
286   }
287   group->AddEntry(entry);
288 }
289
290 //______________________________________________________________________________
291 AliTrigScheduledGroup *AliTrigScheduler::AddGroup(const char *groupname)
292 {
293 // Add a group to the list of groups.
294   if (!fGroups) fGroups = new TObjArray();
295   if (fGroups->FindObject(groupname)) {
296     Error("AddGroup", "Scheduler %s contains already a group named: %s", GetName(), groupname);
297     return NULL;
298   }
299   AliTrigScheduledGroup *group = new AliTrigScheduledGroup(groupname);
300   fGroups->Add(group);
301   return group;
302 }
303
304 //______________________________________________________________________________
305 AliTrigScheduledGroup *AliTrigScheduler::AddGroup(AliTrigScheduledGroup *group)
306 {
307 // Add a group to the list of groups.
308   if (!fGroups) fGroups = new TObjArray();
309   if (fGroups->FindObject(group->GetName())) {
310     Error("AddGroup", "Scheduler %s contains already a group named: %s", GetName(), group->GetName());
311     return NULL;
312   }
313   fGroups->Add(group);
314   return group;
315 }
316
317 //______________________________________________________________________________
318 AliTrigScheduledSequence *AliTrigScheduler::AddSequence(const char *seqname, AliTrigScheduledSequence::ESortingType type, Int_t *sequence)
319 {
320 // Add a sequence to the scheduler. Becomes the current sequence.
321   if (!fSequences) fSequences = new TObjArray();
322   if (fSequences->FindObject(seqname)) {
323     Error("AddSequence", "Scheduler %s contains already a sequence named: %s", GetName(), seqname);
324     return NULL;
325   }
326   AliTrigScheduledSequence *seq = new AliTrigScheduledSequence(seqname, (AliTrigScheduler*)this); 
327   seq->Sort(type, sequence);
328   fCurrentSequence = seq;
329   return seq;
330 }
331
332 //______________________________________________________________________________
333 void AliTrigScheduler::FireUp(Int_t time)
334 {
335 // Fire-up groups in the order given by the current sequence.
336   if (!fCurrentSequence) Fatal("FireUp", "No scheduled sequence booked for scheduler: %s", GetName());
337   Int_t *sequence = fCurrentSequence->GetArray();
338   AliTrigScheduledGroup *group;
339   for (Int_t i=0; i<fNgroups; i++) {
340     group = GetScheduledGroup(sequence[i]);
341     group->FireUp(time);
342   }
343 }
344
345 //______________________________________________________________________________
346 AliTrigScheduledGroup *AliTrigScheduler::GetScheduledGroup(Int_t i) const
347 {
348 // Get i-th registered group (scheduling order does not matter, only group addition order).
349   return (AliTrigScheduledGroup*)fGroups->At(i);
350 }
351
352 //______________________________________________________________________________
353 AliTrigScheduledGroup *AliTrigScheduler::GetScheduledGroup(const char *name) const
354 {
355 // Get a scheduled group by name.
356   return (AliTrigScheduledGroup*)fGroups->FindObject(name);
357 }
358
359 //______________________________________________________________________________
360 void AliTrigScheduler::SetGroupPriority(const char *groupname, Int_t priority)
361 {
362 // Set the priority of a group.
363   AliTrigScheduledGroup *group = GetScheduledGroup(groupname);
364   if (!group) {
365     Error("SetGroupPriority", "Scheduler %s has no group named: %s", GetName(), groupname);
366     return;
367   }
368   group->SetPriority(priority);
369 }
370