Coverity 16571
[u/mrichter/AliRoot.git] / STEER / AliTriggerBCMask.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 ///////////////////////////////////////////////////////////////////////////////
17 //
18 // This class which defines the trigger bunch-crossing mask
19 //
20 //
21 ///////////////////////////////////////////////////////////////////////////////
22 #include <Riostream.h>
23 #include <TObjArray.h>
24 #include <TObjString.h>
25
26 #include "AliTriggerBCMask.h"
27 #include "AliLog.h"
28
29 ClassImp(AliTriggerBCMask)
30
31 //_____________________________________________________________________________
32 AliTriggerBCMask::AliTriggerBCMask():
33   TNamed()
34 {
35   // Default constructor
36   for (Int_t i = 0; i < kNBytesPerBCMask; i++) fBCMask[i] = 0;
37 }
38
39 //_____________________________________________________________________________
40 AliTriggerBCMask::AliTriggerBCMask( TString & name ):
41   TNamed( name, name )
42 {
43   // Constructor
44   for (Int_t i = 0; i < kNBytesPerBCMask; i++) fBCMask[i] = 255;
45 }
46
47 //_____________________________________________________________________________
48 AliTriggerBCMask::AliTriggerBCMask( TString & name, TString & mask ):
49   TNamed( name, mask )
50 {
51   // Constructor
52   CreateMask(mask);
53 }
54
55 //_____________________________________________________________________________
56 AliTriggerBCMask::AliTriggerBCMask( const char* name, const char* mask ):
57   TNamed( name, mask )
58 {
59   // Constructor
60   SetMask(mask);
61 }
62
63 //_____________________________________________________________________________
64 AliTriggerBCMask::~AliTriggerBCMask() 
65
66   // Destructor
67 }
68 //_____________________________________________________________________________
69 AliTriggerBCMask::AliTriggerBCMask( const AliTriggerBCMask& mask ):
70   TNamed( mask )
71 {
72    // Copy constructor
73   for (Int_t i = 0; i < kNBytesPerBCMask; i++) fBCMask[i] = mask.fBCMask[i];
74 }
75
76 //______________________________________________________________________________
77 AliTriggerBCMask& AliTriggerBCMask::operator=(const AliTriggerBCMask& mask)
78 {
79    // AliTriggerBCMask assignment operator.
80
81    if (this != &mask) {
82       TNamed::operator=(mask);
83       for (Int_t i = 0; i < kNBytesPerBCMask; i++) fBCMask[i] = mask.fBCMask[i];
84    }
85    return *this;
86 }
87
88 //_____________________________________________________________________________
89 Bool_t AliTriggerBCMask::GetMask( UShort_t index) const
90 {
91   // Return true or false whenever the mask is active
92   // for the bunch-crossing # = index
93   UShort_t position = index/8;
94   if (position >= kNBytesPerBCMask) return kFALSE;
95   UChar_t offset = index%8;
96   return (fBCMask[position] & (0x1 << offset));
97 }
98
99 //_____________________________________________________________________________
100 void AliTriggerBCMask::Print( const Option_t* opt) const
101 {
102    // Print
103   cout << "Trigger bunch-crossing mask:" << endl;
104   cout << "  Name:                      " << GetName() << endl;
105   cout << "  Mask:                      " << GetTitle() << endl;
106
107   if (strcmp(opt,"bits") == 0) {
108     cout << "  Bits:                      " << endl;
109     for (UShort_t i = 0; i < kNBits; i++) {
110       if (GetMask(i)) {
111         cout << "1";
112       }
113       else {
114         cout << "0";
115       }
116     }
117     cout << endl;
118   }
119 }
120
121 Bool_t AliTriggerBCMask::SetMask (const char *mask)
122 {
123   // Wrapper used in pileup generators
124   // Call directly CreateMask method.
125   SetTitle(mask);
126   return CreateMask(fTitle);
127 }
128
129 //_____________________________________________________________________________
130 Bool_t AliTriggerBCMask::CreateMask(TString &mask)
131 {
132   // (re)creates the bc mask bit pattern
133   // according to the bc string.
134   // The string has the following syntax:
135   //   "25L 25(2H2LH 3(23HL))"
136   //        - H/h -> 1  L/l -> 0
137   //        - spaces, new lines are white characters
138   // The method returns kTRUE in case of successful
139   // parsing and kFALSE otherwise.
140
141   for (Int_t i = 0; i < kNBytesPerBCMask; i++) fBCMask[i] = 255;
142
143   mask.ReplaceAll("("," ( ");
144   mask.ReplaceAll(")"," ) ");
145   mask.ReplaceAll("H"," H ");
146   mask.ReplaceAll("h"," H ");
147   mask.ReplaceAll("L"," L ");
148   mask.ReplaceAll("l"," L ");
149   TObjArray *tokens = mask.Tokenize(" \t");
150   if (tokens->GetEntriesFast() == 0) {
151     delete tokens;
152     return kTRUE;
153   }
154
155   TBits bits(kNBits);
156   Int_t index = 0, ibit = 0, level = 0;
157   if ((!Bcm2Bits(tokens,index,bits,ibit,level)) ||
158       (index != tokens->GetEntriesFast())) {
159     AliError("Invalid bunch-crossing mask syntax. Empty mask produced.");
160     delete tokens;
161     return kFALSE;
162   }
163
164   delete tokens;
165
166   if (ibit != kNBits) {
167     AliError(Form("Incomplete bunch-crossing mask. Only the first %d bits are filled.",ibit));
168     return kFALSE;
169   }
170
171   bits.Get(fBCMask);
172
173   return kTRUE;
174 }
175
176 Bool_t AliTriggerBCMask::Bcm2Bits(TObjArray *tokens, Int_t &index, TBits &bits, Int_t &ibit, Int_t &level) const
177 {
178
179   level++;
180   Int_t repetion = 1;
181
182   while(1) {
183     if (index == tokens->GetEntriesFast()) {
184       if (level > 1) {
185         AliError("Missing )");
186         return kFALSE;
187       }
188       break;
189     }
190     TString st = ((TObjString*)tokens->At(index))->String();
191     if (st.CompareTo("H") == 0) {
192       for (Int_t i = 0; i < repetion; i++) bits.SetBitNumber(ibit++,kTRUE);
193       repetion = 1;
194       index++;
195     }
196     else if (st.CompareTo("L") == 0) {
197       for (Int_t i = 0; i < repetion; i++) bits.SetBitNumber(ibit++,kFALSE);
198       repetion = 1;
199       index++;
200     }
201     else if (st.IsDigit()) {
202       repetion = st.Atoi();
203       index++;
204     }
205     else if (st.CompareTo("(") == 0) {
206       index++;
207       Int_t ibit1 = ibit;
208       if (!Bcm2Bits(tokens,index,bits,ibit,level)) {
209         return kFALSE;
210       }
211       Int_t ibit2 = ibit;
212       for (Int_t i = 0; i < (repetion-1); i++) {
213         for (Int_t j = ibit1; j < ibit2; j++) {
214           bits.SetBitNumber(ibit++,bits.TestBitNumber(j));
215         }
216       }
217       repetion = 1;
218     }
219     else if (st.CompareTo(")") == 0) {
220       index++;
221       if (level <= 1) {
222         AliError("Incorrectly placed )");
223         return kFALSE;
224       }
225       break;
226     }
227     else {
228       AliError(Form("Incorrect BC mask field: %s",st.Data()));
229       return kFALSE;
230     }
231   }
232   level--;
233   return kTRUE;
234
235 }
236