#include <Riostream.h>
#include <TObjArray.h>
#include <TObjString.h>
#include "AliTriggerBCMask.h"
#include "AliLog.h"
using std::endl;
using std::cout;
ClassImp(AliTriggerBCMask)
AliTriggerBCMask::AliTriggerBCMask():
TNamed()
{
for (Int_t i = 0; i < kNBytesPerBCMask; i++) fBCMask[i] = 0;
}
AliTriggerBCMask::AliTriggerBCMask( TString & name ):
TNamed( name, name )
{
for (Int_t i = 0; i < kNBytesPerBCMask; i++) fBCMask[i] = 255;
}
AliTriggerBCMask::AliTriggerBCMask( TString & name, TString & mask ):
TNamed( name, mask )
{
CreateMask(mask);
}
AliTriggerBCMask::AliTriggerBCMask( const char* name, const char* mask ):
TNamed( name, mask )
{
SetMask(mask);
}
AliTriggerBCMask::~AliTriggerBCMask()
{
}
AliTriggerBCMask::AliTriggerBCMask( const AliTriggerBCMask& mask ):
TNamed( mask )
{
for (Int_t i = 0; i < kNBytesPerBCMask; i++) fBCMask[i] = mask.fBCMask[i];
}
AliTriggerBCMask& AliTriggerBCMask::operator=(const AliTriggerBCMask& mask)
{
if (this != &mask) {
TNamed::operator=(mask);
for (Int_t i = 0; i < kNBytesPerBCMask; i++) fBCMask[i] = mask.fBCMask[i];
}
return *this;
}
Bool_t AliTriggerBCMask::GetMask( UShort_t index) const
{
UShort_t position = index/8;
if (position >= kNBytesPerBCMask) return kFALSE;
UChar_t offset = index%8;
return (fBCMask[position] & (0x1 << offset));
}
void AliTriggerBCMask::Print( const Option_t* opt) const
{
cout << "Trigger bunch-crossing mask:" << endl;
cout << " Name: " << GetName() << endl;
cout << " Mask: " << GetTitle() << endl;
if (strcmp(opt,"bits") == 0) {
cout << " Bits: " << endl;
for (UShort_t i = 0; i < kNBits; i++) {
if (GetMask(i)) {
cout << "1";
}
else {
cout << "0";
}
}
cout << endl;
}
}
Bool_t AliTriggerBCMask::SetMask (const char *mask)
{
SetTitle(mask);
return CreateMask(fTitle);
}
Bool_t AliTriggerBCMask::CreateMask(TString &mask)
{
for (Int_t i = 0; i < kNBytesPerBCMask; i++) fBCMask[i] = 255;
mask.ReplaceAll("("," ( ");
mask.ReplaceAll(")"," ) ");
mask.ReplaceAll("H"," H ");
mask.ReplaceAll("h"," H ");
mask.ReplaceAll("L"," L ");
mask.ReplaceAll("l"," L ");
TObjArray *tokens = mask.Tokenize(" \t");
if (tokens->GetEntriesFast() == 0) {
delete tokens;
return kTRUE;
}
TBits bits(kNBits);
Int_t index = 0, ibit = 0, level = 0;
if ((!Bcm2Bits(tokens,index,bits,ibit,level)) ||
(index != tokens->GetEntriesFast())) {
AliError("Invalid bunch-crossing mask syntax. Empty mask produced.");
delete tokens;
return kFALSE;
}
delete tokens;
if (ibit != kNBits) {
AliError(Form("Incomplete bunch-crossing mask. Only the first %d bits are filled.",ibit));
return kFALSE;
}
bits.Get(fBCMask);
return kTRUE;
}
Bool_t AliTriggerBCMask::Bcm2Bits(TObjArray *tokens, Int_t &index, TBits &bits, Int_t &ibit, Int_t &level) const
{
level++;
Int_t repetion = 1;
while(1) {
if (index == tokens->GetEntriesFast()) {
if (level > 1) {
AliError("Missing )");
return kFALSE;
}
break;
}
TString st = ((TObjString*)tokens->At(index))->String();
if (st.CompareTo("H") == 0) {
for (Int_t i = 0; i < repetion; i++) bits.SetBitNumber(ibit++,kTRUE);
repetion = 1;
index++;
}
else if (st.CompareTo("L") == 0) {
for (Int_t i = 0; i < repetion; i++) bits.SetBitNumber(ibit++,kFALSE);
repetion = 1;
index++;
}
else if (st.IsDigit()) {
repetion = st.Atoi();
index++;
}
else if (st.CompareTo("(") == 0) {
index++;
Int_t ibit1 = ibit;
if (!Bcm2Bits(tokens,index,bits,ibit,level)) {
return kFALSE;
}
Int_t ibit2 = ibit;
for (Int_t i = 0; i < (repetion-1); i++) {
for (Int_t j = ibit1; j < ibit2; j++) {
bits.SetBitNumber(ibit++,bits.TestBitNumber(j));
}
}
repetion = 1;
}
else if (st.CompareTo(")") == 0) {
index++;
if (level <= 1) {
AliError("Incorrectly placed )");
return kFALSE;
}
break;
}
else {
AliError(Form("Incorrect BC mask field: %s",st.Data()));
return kFALSE;
}
}
level--;
return kTRUE;
}
UShort_t AliTriggerBCMask::GetNUnmaskedBCs() const
{
UShort_t nBCs=0;
for (Int_t i=0; i<kNBits; i++){
if (!GetMask(i)) nBCs++;
}
return nBCs;
}