Fixing generation of bit mask for TObject::fBits field.
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTTriggerDomain.h
1 //-*- Mode: C++ -*-
2 // $Id$
3 #ifndef ALIHLTTRIGGERDOMAIN_H
4 #define ALIHLTTRIGGERDOMAIN_H
5 /* This file is property of and copyright by the ALICE HLT Project        *
6  * ALICE Experiment at CERN, All rights reserved.                         *
7  * See cxx source for full Copyright notice                               */
8
9 /// @file   AliHLTDomainEntry.h
10 /// @author Artur Szostak <artursz@iafrica.com>
11 /// @date   19 Nov 2008
12 /// @brief  Declaration of the AliHLTTriggerDomain class used to store the set of data block types to readout.
13
14 #include "TObject.h"
15 #include "TClonesArray.h"
16 #include "AliHLTDataTypes.h"
17
18 class AliHLTDomainEntry;
19 class AliHLTReadoutList;
20
21 /**
22  * \class AliHLTTriggerDomain
23  * The trigger domain class is the set of HLT raw data block types that should
24  * be readout and sent to HLTOUT.
25  * It is implemented as a list of domain entries, where each domain entry is
26  * like a rule, or pattern to match against. When trying to decide if a given
27  * data block falls within the trigger domain, i.e. is part of the readout, the
28  * domain entries are applied one after the other from top to bottom. Two kinds
29  * of domain entries, inclusive and exclusive are possible, which indicate if a
30  * data block type or range, is part of the trigger domain or not. As we process
31  * the domain entries we update our decision of whether the data block is part
32  * of the trigger domain or not. If the domain entry is an inclusion then we update
33  * the decision to true, if it is an exclusion then we update the decision to false.
34  * The value of the result after applying the last domain entry then indicates
35  * if the data block is part of the trigger domain or not.
36  * In this way we can specify trigger domains as sets to arbitrary complexity
37  * and manipulate them as mathematical sets accordingly.
38  *
39  * The other feature of the AliHLTTriggerDomain class is that it overloads the
40  * following operators to provide set like behaviour:
41  *   |  this provides the set union operation (The + operator does the same).
42  *   &  this provides the set intersect operation.
43  *   -  this provides the set difference operation.
44  *   ^  this provides an exclusive or (xor) operation. i.e. given two sets A and B
45  *        the result C is given by:
46  *        C = {x : x elf A and not x elf B, or x elf B and not x elf A}
47  *        where 'elf' means "is an element of".
48  *   ~  this returns the set complement.
49  * These operators then allow expressions to be formed from trigger domain objects
50  * which behave like sets.
51  */
52 class AliHLTTriggerDomain : public TObject
53 {
54  public:
55   
56   /**
57    * Default constructor.
58    */
59   AliHLTTriggerDomain();
60   
61   /**
62    * Constructs the trigger domain from a list of domain entries.
63    * \param list  Comma separated list of domain entries of the form xxx:yyy:zzz
64    *    Can optionaly have a '+' or '-' character just in front of the block
65    *    type string, xxx in this case, to indicate inclusive or exclusive entries.
66    * \note If inclusive and exclusive entries are specified then they are applied
67    *    in the order found in the list, from left to right. This means that subsequent
68    *    includes can override previous excludes and visa versa.
69    */
70   AliHLTTriggerDomain(const char* list);
71   
72   /**
73    * Constructor to create a trigger domain from a DDL readout list.
74    * The trigger domain will contain entries of the form "DAQRDOUT:xxxx:yyyy"
75    * where xxxx is the appropriate detector name given by AliDAQ::OnlineName()
76    * and yyyy is the DDL equipment ID number.
77    * \param list  The read out list object
78    */
79   AliHLTTriggerDomain(const AliHLTReadoutList& list);
80   
81   /**
82    * Copy constructor performs a deep copy.
83    * \param domain  The domain entry to copy from.
84    */
85   AliHLTTriggerDomain(const AliHLTTriggerDomain& domain);
86   
87   /**
88    * Default destructor.
89    */
90   virtual ~AliHLTTriggerDomain();
91   
92   /**
93    * Adds entries to the trigger domain to correspond to the DDL readout list.
94    * The trigger domain will contain entries of the form "DAQRDOUT:xxxx:yyyy"
95    * where xxxx is the appropriate detector name given by AliDAQ::OnlineName()
96    * and yyyy is the DDL equipment ID number.
97    * \param list  The readout list object
98    */
99   void Add(const AliHLTReadoutList& list);
100   
101   /**
102    * Adds the given entry to this trigger domain as an inclusive entry.
103    * Existing entries are modified as required to optimise the trigger domain
104    * rule / pattern matching list.
105    * \param entry  The domain entry object to add.
106    * \note The entry.Exclusive() flag is ignored and is treated as if it was kFALSE.
107    */
108   void Add(const AliHLTDomainEntry& entry);
109   
110   /**
111    * Adds the given data type to the trigger domain such that all data blocks
112    * that match this type will form part of the trigger domain.
113    * \param datatype  The data block type and origin to match.
114    */
115   void Add(const AliHLTComponentDataType& datatype);
116   
117   /**
118    * Adds the given data type and origin to the trigger domain such that all data
119    * blocks that match will form part of this trigger domain.
120    * \param blocktype  The data block type string of the data block that must match.
121    *    The value of kAliHLTAnyDataTypeID can be used to specify the 'any' type
122    *    wild card value.
123    * \param origin  The origin of the data block, such as the detector name, that
124    *    must match. The value of kAliHLTDataOriginAny can be used to specify the
125    *    'any' origin wild card value.
126    */
127   void Add(const char* blocktype, const char* origin);
128   
129   /**
130    * Adds the given data type with particular specification bits to the trigger
131    * domain, such that all data blocks that match these will form part of this
132    * trigger domain.
133    * \param datatype  The data block type and origin that must match.
134    * \param spec  The specification bits that must match.
135    */
136   void Add(const AliHLTComponentDataType& datatype, UInt_t spec);
137   
138   /**
139    * Adds the given data type, origin and specification bits of data blocks that
140    * should form part of this trigger domain.
141    * \param blocktype  The data block type string of the data block that must match.
142    *    The value of kAliHLTAnyDataTypeID can be used to specify the 'any' type
143    *    wild card value.
144    * \param origin  The origin of the data block, such as the detector name, that
145    *    must match. The value of kAliHLTDataOriginAny can be used to specify the
146    *    'any' origin wild card value.
147    * \param spec  The specification bits that must match.
148    */
149   void Add(const char* blocktype, const char* origin, UInt_t spec);
150   
151   /**
152    * Removes entries from the trigger domain that correspond to the DDL readout list.
153    * All entries of the form "DAQRDOUT:xxxx:yyyy" are removed, where xxxx is the
154    * appropriate detector name given by AliDAQ::OnlineName() and yyyy is the DDL
155    * equipment ID number, as long as the corresponding bit is set in the readout
156    * list.
157    * \param list  The readout list object
158    */
159   void Remove(const AliHLTReadoutList& list);
160   
161   /**
162    * Removes or modifies all entries from the trigger domain, such that data blocks
163    * that match the given domain entry will not form part of this trigger domain.
164    * Existing entries are modified as required to optimise the trigger domain
165    * rule / pattern matching list.
166    * \param entry  The domain entry object to indicating values that should be removed.
167    * \note The entry.Exclusive() flag is ignored and is treated as if it was kTRUE.
168    */
169   void Remove(const AliHLTDomainEntry& entry);
170   
171   /**
172    * Removes the given data type from the trigger domain, such that all data blocks
173    * that match this type will not form part of the trigger domain.
174    * \param datatype  The data block type and origin that must match the blocks not
175    *    forming part of this trigger domain.
176    */
177   void Remove(const AliHLTComponentDataType& datatype);
178   
179   /**
180    * Removes the given data type and origin from the trigger domain, such that all
181    * data blocks that match these will not form part of the trigger domain.
182    * \param blocktype  The data block type string that must match the data blocks
183    *    not forming part of this trigger domain.
184    *    The value of kAliHLTAnyDataTypeID can be used to specify the 'any' type
185    *    wild card value.
186    * \param origin  The origin string, such as the detector name, that must match
187    *    the data blocks not forming part of this trigger domain.
188    *    The value of kAliHLTDataOriginAny can be used to specify the 'any' origin
189    *    wild card value.
190    */
191   void Remove(const char* blocktype, const char* origin);
192   
193   /**
194    * Removes the given data type with given specification bit from the trigger
195    * domain, such that all data blocks that match these will not form part of the
196    * trigger domain.
197    * \param datatype  The data block type and origin that must match the blocks
198    *    not forming part of this trigger domain.
199    * \param spec  The specification bits that must match for the blocks that do
200    *    not form part of this trigger domain.
201    */
202   void Remove(const AliHLTComponentDataType& datatype, UInt_t spec);
203   
204   /**
205    * Removes the given data type, origin and specification from the trigger domain,
206    * such that all data blocks that match these will not form part of the trigger
207    * domain.
208    * \param blocktype  The data block type string that must match the data blocks
209    *    not forming part of this trigger domain.
210    *    The value of kAliHLTAnyDataTypeID can be used to specify the 'any' type
211    *    wild card value.
212    * \param origin  The origin string, such as the detector name, that must match
213    *    the data blocks not forming part of this trigger domain.
214    *    The value of kAliHLTDataOriginAny can be used to specify the 'any' origin
215    *    wild card value.
216    * \param spec  The specification bits that must match for the blocks that do
217    *    not form part of this trigger domain.
218    */
219   void Remove(const char* blocktype, const char* origin, UInt_t spec);
220   
221   /**
222    * This checks to see if the given entry (or class of entries, if the entry uses
223    * wild card values) is part of the trigger domain.
224    * \param entry  This is the entry to check for.
225    * \return  true if data blocks that match the entry are part of this
226    *    trigger domain and false otherwise.
227    * \note If the block contains the 'any' wild card values for the data type
228    *    origin or specification, then the inclusive domains are treated
229    *    optimistically and the exclusive domains pessimistically. This means that
230    *    the wild card values are assumed to fall within the trigger domain for the
231    *    optimistic case, but fall outside the domain for the pessimistic case.
232    */
233   bool Contains(const AliHLTDomainEntry& entry) const;
234   
235   /**
236    * This checks to see if the given data block should be included in the HLT readout.
237    * \param block  The data block descriptor to check.
238    * \return  true if data block forms part of this trigger domain and should
239    *    be part of the readout and false otherwise.
240    * \note If the block contains the 'any' wild card values for the data type
241    *    or origin, then the inclusive domains are treated optimistically and the
242    *    exclusive domains pessimistically. This means that the wild card values
243    *    are assumed to fall within the trigger domain for the optimistic case,
244    *    but fall outside the domain for the pessimistic case.
245    */
246   bool IncludeInReadout(const AliHLTComponentBlockData* block) const;
247   
248   /**
249    * This checks to see if the given data block should not be included in the
250    * HLT readout.
251    * \param block  The data block descriptor to check.
252    * \return  true if data block does not form part of this trigger domain and
253    *    false otherwise.
254    */
255   bool ExcludeFromReadout(const AliHLTComponentBlockData* block) const
256   {
257     return ! IncludeInReadout(block);
258   }
259   
260   /**
261    * This method removes all entries in the trigger domain list, giving us and
262    * empty trigger domain set.
263    * \param  option  This is passed onto the internal fEntries TClonesArray.
264    * The method is inherited from TObject.
265    */
266   virtual void Clear(Option_t* option = "");
267   
268   /**
269    * Prints all the domain entries in this trigger domain in the order in which
270    * they are applied and if they are inclusive or exclusive.
271    * \param  option  This is not used by this method.
272    * The method is inherited from TObject.
273    */
274   virtual void Print(Option_t* option = "") const;
275
276   /**
277    * Assignment operator performs a deep copy.
278    * \param domain  The domain entry to copy from.
279    * \return  A reference to this object.
280    */
281   AliHLTTriggerDomain& operator = (const AliHLTTriggerDomain& domain);
282   
283   /**
284    * This operator adds all domain entries in <i>domain</i> to this trigger domain
285    * in such a way, so as to effectively perform a set union.
286    * \param domain  The domain object on the right hand side of the operator.
287    * \return  A reference to this object.
288    */
289   AliHLTTriggerDomain& operator |= (const AliHLTTriggerDomain& domain);
290   
291   /**
292    * This operator adds all domain entries in <i>domain</i> that do not exist in
293    * this trigger domain, but removes all entries that do exist, effectively
294    * performing an exclusive or (xor) operation.
295    * i.e. given two sets A and B the result C is given by:
296    *    C = {x : x elf A and not x elf B, or x elf B and not x elf A}
297    * where 'elf' means "is an element of".
298    * \param domain  The domain object on the right hand side of the operator.
299    * \return  A reference to this object.
300    */
301   AliHLTTriggerDomain& operator ^= (const AliHLTTriggerDomain& domain);
302   
303   /**
304    * This operator removes all domain entries from this trigger domain that do
305    * not also exist in <i>domain</i>, effectively performing a set intersect.
306    * \param domain  The domain object on the right hand side of the operator.
307    * \return  A reference to this object.
308    */
309   AliHLTTriggerDomain& operator &= (const AliHLTTriggerDomain& domain)
310   {
311     return this->operator = (*this & domain);
312   }
313   
314   /**
315    * This operator removes all domain entries from this trigger domain that exisit
316    * in <i>domain</i>, effectively implementing a set difference.
317    * \param domain  The domain object on the right hand side of the operator.
318    * \return  A reference to this object.
319    */
320   AliHLTTriggerDomain& operator -= (const AliHLTTriggerDomain& domain);
321   
322   /**
323    * This operator returns the set complement of the trigger domain.
324    * \return  The complement of this trigger domain, such that any data block that
325    *    returns true for AliHLTTriggerDomain::IncludeInReadout() for this trigger
326    *    domain, will return false for the same method call in the returned object.
327    */
328   AliHLTTriggerDomain operator ~ () const;
329   
330   /**
331    * This operator performs a set union between this trigger domain and <i>domain</i>.
332    * \param domain  The domain object on the right hand side of the operator.
333    * \return  a trigger domain object R, such that for each data block D, we will have
334    *    R.IncludeInReadout(D) == this->IncludeInReadout(D) or domain.IncludeInReadout(D)
335    */
336   AliHLTTriggerDomain operator | (const AliHLTTriggerDomain& domain) const
337   {
338     AliHLTTriggerDomain result = *this;
339     return result.operator |= (domain);
340   }
341   
342   /**
343    * This operator performs an exclusive or (xor) like operation between this trigger
344    * domain and <i>domain</i>.
345    * \param domain  The domain object on the right hand side of the operator.
346    * \return  a trigger domain object R, such that for each data block D, we will have
347    *    R.IncludeInReadout(D) == this->IncludeInReadout(D) xor domain.IncludeInReadout(D)
348    */
349   AliHLTTriggerDomain operator ^ (const AliHLTTriggerDomain& domain) const
350   {
351     AliHLTTriggerDomain result = *this;
352     return result.operator ^= (domain);
353   }
354   
355   /**
356    * This operator performs a set intersect operation between this trigger domain
357    * and <i>domain</i>.
358    * \param domain  The domain object on the right hand side of the operator.
359    * \return  a trigger domain object R, such that for each data block D, we will have
360    *    R.IncludeInReadout(D) == this->IncludeInReadout(D) and domain.IncludeInReadout(D)
361    */
362   AliHLTTriggerDomain operator & (const AliHLTTriggerDomain& domain) const;
363   
364   /**
365    * This operator implements the set difference between this trigger domain and
366    * <i>domain</i>.
367    * \param domain  The domain object on the right hand side of the operator.
368    * \return  a trigger domain object R, such that for each data block D, we will have
369    *    R.IncludeInReadout(D) == this->IncludeInReadout(D) and not domain.IncludeInReadout(D)
370    */
371   AliHLTTriggerDomain operator - (const AliHLTTriggerDomain& domain) const
372   {
373     AliHLTTriggerDomain result = *this;
374     return result.operator -= (domain);
375   }
376   
377   /**
378    * Typecase operator to create a DDL readout list object from the trigger domain.
379    */
380   operator AliHLTReadoutList () const;
381
382   /**
383    * access of the individual entries
384    */
385   const AliHLTDomainEntry& operator[](int index) const;
386
387   /** get number of entries in the domain */
388   int GetNofEntries()const  {return fEntries.GetEntriesFast();}
389   
390  private:
391   
392   /**
393    * This method merges the domain entries from <i>domain</i> by copying them into
394    * fEntries, but only the ones not marked for removal in <i>removeDomainEntry</i>.
395    * Any entries that were marked for removal in fEntries are also removed.
396    * \param removeThisEntry  Flags which indicate if the corresponding fEntries[i]
397    *    should be removed.
398    * \param entriesCount The number of entries in <i>removeThisEntry</i>.
399    * \param removeDomainEntry  Flags which indicate if the corresponding domain.fEntries[i]
400    *    was marked for removal or not. If marked for removal then it will not be copied
401    *    into this trigger domain. The size of the array is given by domain.GetEntriesFast().
402    * \param startOfIntersects  This is the start location of the new intersection domain
403    *    entries that were added to fEntries. i.e. fEntries[startOfIntersects] is the
404    *    first new intersect entry.
405    */
406   void MergeEntries(
407       const bool* removeThisEntry, Int_t entriesCount,
408       const bool* removeDomainEntry, Int_t startOfIntersects,
409       const AliHLTTriggerDomain& domain
410     );
411   
412   /**
413    * Goes throught the list of domain entries in fEntries from the first entry
414    * indicated by 'min' to the end of the list and marks for deletion all entries
415    * in fEntries that are subsets of 'entry'.
416    * The entries are marked by setting the 14'th bit in fBits with a call to
417    * AliHLTDomainEntry::SetBit(BIT(14), true).
418    * \param entry  The entry that should be the super set of the entries we mark
419    *    for removal.
420    * \param min  This is the first entry we consider, all the way up to
421    *    fEntries.GetEntriesFast() - 1.
422    */
423   void MarkForDeletionSubsetsOf(const AliHLTDomainEntry& entry, Int_t min);
424   
425   /**
426    * Removes all entries in this trigger domain which were marked for removal.
427    * These are all domain entries that have the 14'th bit set in their fBits field
428    * with a call to AliHLTDomainEntry::SetBit(BIT(14), true).
429    */
430   void RemoveMarkedEntries();
431   
432   /**
433    * Removes any redundant trigger domain entries from the fEntries list.
434    * Entries that are subsets of each other are removed. Also exclusive entries
435    * that are not subsets of any inclusive entry are also removed, because we
436    * implicitly assume a data block does not form part of the trigger domain,
437    * unless explicitly included with an inclusive domain entry. So these kinds
438    * of entries are redundant.
439    */
440   void Optimise();
441   
442   TClonesArray fEntries;  /// The list of domain entries used to decide if a data block forms part of trigger domain set.
443   
444   ClassDef(AliHLTTriggerDomain, 1) // This is a list of internal HLT data block types which should be forwarded for readout.
445
446 };
447
448 #endif // ALIHLTTRIGGERDOMAIN_H
449