Newer
Older
//*-- Author : Julie Roche, November 2010
// this is a modified version of THaGOHelicity.C
////////////////////////////////////////////////////////////////////////
//
// THcHelicity
//
// Helicity of the beam from QWEAK electronics in delayed mode
// +1 = plus, -1 = minus, 0 = unknown
//
// Also supports in-time mode with delay = 0

Sylvester Joosten
committed
//
////////////////////////////////////////////////////////////////////////
#include "THcHelicity.h"

Sylvester Joosten
committed
#include "TH1F.h"
#include "THaApparatus.h"
#include "THaEvData.h"
#include "THcGlobals.h"
#include "THcParmList.h"
#include "TMath.h"
#include <iostream>
using namespace std;
//_____________________________________________________________________________

Sylvester Joosten
committed
THcHelicity::THcHelicity(const char* name, const char* description, THaApparatus* app)
: hcana::ConfigLogging<THaHelicityDet>(name, description, app), fnQrt(-1), fHelDelay(8),
fMAXBIT(30) {
// for( Int_t i = 0; i < NHIST; ++i )
// fHisto[i] = 0;
// memset(fHbits, 0, sizeof(fHbits));
}
//_____________________________________________________________________________
THcHelicity::THcHelicity()

Sylvester Joosten
committed
: hcana::ConfigLogging<THaHelicityDet>(), fnQrt(-1), fHelDelay(8), fMAXBIT(30) {
// Default constructor for ROOT I/O
// for( Int_t i = 0; i < NHIST; ++i )
// fHisto[i] = 0;
}
//_____________________________________________________________________________

Sylvester Joosten
committed
THcHelicity::~THcHelicity() {
DefineVariables(kDelete);
// for( Int_t i = 0; i < NHIST; ++i ) {
// delete fHisto[i];
// }
}
//_____________________________________________________________________________
THaAnalysisObject::EStatus THcHelicity::Init(const TDatime& date) {
// Call `Setup` before everything else.
Setup(GetName(), GetTitle());

Sylvester Joosten
committed
fFirstEvProcessed = kFALSE;
fActualHelicity = kUnknown;
fPredictedHelicity = kUnknown;

Sylvester Joosten
committed
fLastMPSTime = 0;
fFoundMPS = kFALSE;
// Call initializer for base class.
// This also calls `ReadDatabase` and `DefineVariables`.
EStatus status = THaDetector::Init(date);
if (status) {
fStatus = status;
return fStatus;
}

Sylvester Joosten
committed
fDisabled = kFALSE;
fStatus = kOK;
return fStatus;
}
//_____________________________________________________________________________
void THcHelicity::Setup(const char* name, const char* description) {
// Prefix for parameters in `param` file.
string kwPrefix = string(GetApparatus()->GetName()) + "_" + name;
std::transform(kwPrefix.begin(), kwPrefix.end(), kwPrefix.begin(), ::tolower);
fKwPrefix = kwPrefix;
}
//_____________________________________________________________________________

Sylvester Joosten
committed
Int_t THcHelicity::ReadDatabase(const TDatime& date) {
_logger->info("In THcHelicity::ReadDatabase");

Sylvester Joosten
committed
// cout << "In THcHelicity::ReadDatabase" << endl;
// Read general HelicityDet database values (e.g. fSign)
// Int_t st = THaHelicityDet::ReadDatabase( date );
// if( st != kOK )
// return st;
// Read readout parameters (ROC addresses etc.)

Sylvester Joosten
committed
Int_t st = THcHelicityReader::ReadDatabase(GetDBFileName(), GetPrefix(), date, fQWEAKDebug);
if (st != kOK)
return st;

Sylvester Joosten
committed
fSign = 1; // Default helicity sign
fRingSeed_reported_initial = 0; // Initial see that should predict reported

Sylvester Joosten
committed
// helicity of first quartet.
fFirstCycle = -1; // First Cycle that starts a quad (0 to 3)
fFreq = 29.5596;
fHelDelay = 8;
DBRequest list[] = {// {"_hsign", &fSign, kInt, 0, 1},
{"helicity_delay", &fHelDelay, kInt, 0, 1},
{"helicity_freq", &fFreq, kDouble, 0, 1},
// {"helicity_seed", &fRingSeed_reported_initial, kInt, 0, 1},
// {"helicity_cycle", &fFirstCycle, kInt, 0, 1},
{0}};
gHcParms->LoadParmValues(list, "");

Sylvester Joosten
committed
fMAXBIT = 30;

Sylvester Joosten
committed
fTIPeriod = 250000000.0 / fFreq;
// maximum of event in the pattern, for now we are working with quartets

Sylvester Joosten
committed
// Int_t localpattern[4]={1,-1,-1,1};
// careful, the first value here should always +1
// for(int i=0;i<fQWEAKNPattern;i++)
// {
// fPatternSequence.push_back(localpattern[i]);
// }

Sylvester Joosten
committed
HWPIN = kTRUE;

Sylvester Joosten
committed
fQuartet[0] = fQuartet[1] = fQuartet[2] = fQuartet[3] = 0;

Sylvester Joosten
committed
if (fFirstCycle >= 0 && fRingSeed_reported_initial != 0) {
// Set the seed for predicted reported and predicted actual
} else {
// Initialize mode to find quartets and then seed
}

Sylvester Joosten
committed
_logger->info(
"Helicity decoder initialized with frequency of {} Hz and reporting delay of {} cycles.",
fFreq, fHelDelay);
// cout << "Helicity decoder initialized with frequency of " << fFreq
// << " Hz and reporting delay of " << fHelDelay << " cycles." << endl;
return kOK;
}
//_____________________________________________________________________________

Sylvester Joosten
committed
void THcHelicity::MakePrefix() { THaDetector::MakePrefix(); }
//_____________________________________________________________________________

Sylvester Joosten
committed
Int_t THcHelicity::DefineVariables(EMode mode) {
// Initialize global variables
_logger->info("Called THcHelicity::DefineVariables with mode == {}", mode);

Sylvester Joosten
committed
// cout << "Called THcHelicity::DefineVariables with mode == "

Sylvester Joosten
committed
if (mode == kDefine && fIsSetup)
return kOK;
fIsSetup = (mode == kDefine);
// Define standard variables from base class

Sylvester Joosten
committed
THaHelicityDet::DefineVariables(mode);
const RVarDef var[] = {{"nqrt", "position of cycle in quartet", "fnQrt"},
{"hel", "actual helicity for event", "fActualHelicity"},
{"helrep", "reported helicity for event", "fReportedHelicity"},
{"helpred", "predicted reported helicity for event", "fPredictedHelicity"},
{"mps", "In MPS blanking period", "fMPS"},
{0}};
// cout << "Calling THcHelicity DefineVarsFromList" << endl;
_logger->info("Calling THcHelicity DefineVarsFromList");

Sylvester Joosten
committed
return DefineVarsFromList(var, mode);
}
//_____________________________________________________________________________

Sylvester Joosten
committed
void THcHelicity::PrintEvent(Int_t evtnum) {

Sylvester Joosten
committed
cout << " ++++++ THcHelicity::Print ++++++\n";

Sylvester Joosten
committed
cout << " +++++++++++++++++++++++++++++++++++++\n";
return;
}
//_____________________________________________________________________________

Sylvester Joosten
committed
Int_t THcHelicity::Begin(THaRunBase*) {
THcHelicityReader::Begin();
// fHisto[0] = new TH1F("hel.seed","hel.seed",32,-1.5,30.5);
// fHisto[1] = new TH1F("hel.error.code","hel.error.code",35,-1.5,33.5);

Sylvester Joosten
committed
return 0;
}
//_____________________________________________________________________________

Sylvester Joosten
committed
// void THcHelicity::FillHisto()
//{
// fHisto[0]->Fill(fRing_NSeed);
// fHisto[1]->Fill(fErrorCode);
// return;
//}
//_____________________________________________________________________________

Sylvester Joosten
committed
void THcHelicity::SetErrorCode(Int_t error) {
// used as a control for the helciity computation
// 2^0: if the reported number of events in a pattern is larger than fQWEAKNPattern
// 2^1: if the offset between the ring reported value and TIR value is not fOffsetTIRvsRing
// 2^2: if the reported time in the ring is 0
// 2^3: if the predicted reported helicity doesn't match the reported helicity in the ring
// 2^4: if the helicity cannot be computed using the SetHelicity routine
// 2^5: if seed is being gathered

Sylvester Joosten
committed
if (fErrorCode == 0)
fErrorCode = (1 << error);
// only one reported error at the time
return;
}
//_____________________________________________________________________________

Sylvester Joosten
committed
void THcHelicity::Clear(Option_t* opt) {
// Clear event-by-event data
THaHelicityDet::Clear(opt);
THcHelicityReader::Clear(opt);
fEvtype = 0;

Sylvester Joosten
committed
fQrt = 0;
fErrorCode = 0;
return;
}
//_____________________________________________________________________________

Sylvester Joosten
committed
Int_t THcHelicity::Decode(const THaEvData& evdata) {
// Decode Helicity data.
// Return 1 if helicity was assigned, 0 if not, <0 if error.

Sylvester Joosten
committed
Int_t err = ReadData(evdata); // from THcHelicityReader class
if (err) {
Error(Here("THcHelicity::Decode"), "Error decoding helicity data.");

Sylvester Joosten
committed
fReportedHelicity = (fIsHelp ? (fIsHelm ? kUnknown : kPlus) : (fIsHelm ? kMinus : kUnknown));
fMPS = fIsMPS ? 1 : 0;
if (fHelDelay == 0) { // If no delay actual=reported (but zero if in MPS)
fActualHelicity = fIsMPS ? kUnknown : fReportedHelicity;

Sylvester Joosten
committed
if (fDisabled) {
fActualHelicity = kUnknown;
return 0;
}
fEvNumCheck++;
Int_t evnum = evdata.GetEvNum();

Sylvester Joosten
committed
if (fEvNumCheck != evnum) {
_logger->info("THcHelicity: Missed {} events at event {}.", evnum - fEvNumCheck, evnum);
_logger->info(" Disabling helicity decoding for rest of run.");
_logger->info(
" Make sure \"RawDecode_master in cuts file accepts all physics events.");
fDisabled = kTRUE;

Sylvester Joosten
committed
if (fFirstEvProcessed) { // Normal processing
// cout << evnum << " " << fNCycle << " " << fIsMPS << " " << fFoundMPS << " " << fTITime <<
// " "
Int_t missed = 0;
// Double_t elapsed_time = (fTITime - fFirstEvTime)/250000000.0;

Sylvester Joosten
committed
if (fIsMPS) {
fActualHelicity = kUnknown;

Sylvester Joosten
committed
if (fFoundMPS) {
missed = TMath::Nint(fTITime / fTIPeriod - fLastMPSTime / fTIPeriod);
if (missed < 1) { // was <=1
fLastMPSTime = (fTITime + fLastMPSTime + missed * fTIPeriod) / 2;
fIsNewCycle = kTRUE;
fActualHelicity = kUnknown;
fPredictedHelicity = kUnknown;
} else {
fLastMPSTime = (fLastMPSTime + fTITime - missed * fTIPeriod) / 2;
}
// If there is a skip, pass it off to next non MPS event
// Need to also check here for missed MPS's
// cout << "Found MPS" << endl;
// check for Nint((time-last)/period) > 1

Sylvester Joosten
committed
fFoundMPS = kTRUE;
fLastMPSTime = fTITime;

Sylvester Joosten
committed
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
} else if (fFoundMPS) { //
if (fTITime - fLastMPSTime > fTIPeriod) { // We missed MPS periods
missed = TMath::Nint(floor((fTITime - fLastMPSTime) / fTIPeriod));
if (missed > 1) {
// cout << "Missed " << missed << " MPSes" << endl;
Int_t newNCycle = fNCycle + missed - 1; // How many cycles really missed
Int_t quartets_missed = (newNCycle - fFirstCycle) / 4 - (fNCycle - fFirstCycle) / 4;
for (Int_t i = 0; i < quartets_missed; i++) { // Advance the seeds.
fRingSeed_reported = RanBit30(fRingSeed_reported);
fRingSeed_actual = RanBit30(fRingSeed_actual);
}
int quartetphase = (newNCycle - fFirstCycle) % 4;
// cout << " " << fNCycle << " " << newNCycle << " " << fFirstCycle << " " <<
// quartets_missed << " " << quartetphase << endl; cout << "Cycles " << fNCycle << "
// " << newNCycle << " " << fFirstCycle
// << " skipped " << quartets_missed << " quartets" << endl;
fNCycle = newNCycle;
// Need to reset fQuartet to reflect where we are based on the current
// reported helicity. So we don't fail quartet testing.
// But only do this if we are calibrated.
if (fNBits >= fMAXBIT) {
fQuartetStartHelicity = (fRingSeed_actual & 1) ? kPlus : kMinus;
fQuartetStartPredictedHelicity = (fRingSeed_reported & 1) ? kPlus : kMinus;
fActualHelicity = (quartetphase == 0 || quartetphase == 3) ? fQuartetStartHelicity
: -fQuartetStartHelicity;
fPredictedHelicity = (quartetphase == 0 || quartetphase == 3)
? fQuartetStartPredictedHelicity
: -fQuartetStartPredictedHelicity;
if (((fNCycle - fFirstCycle) % 2) == 1) {
fQuartet[0] = fReportedHelicity;
fQuartet[1] = fQuartet[2] = -fQuartet[0];
} else {
fQuartet[0] = fQuartet[1] = -fReportedHelicity;
fQuartet[2] = -fQuartet[1];
}
} else {
fActualHelicity = kUnknown;
fQuartet[0] = fReportedHelicity;
fQuartet[1] = 0;
}
}
fLastMPSTime += missed * fTIPeriod;
fIsNewCycle = kTRUE;
fLastReportedHelicity = fReportedHelicity;
} else { // No missed periods. Get helicities from rings
if (fNBits >= fMAXBIT) {
int quartetphase = (fNCycle - fFirstCycle) % 4;
fQuartetStartHelicity = (fRingSeed_actual & 1) ? kPlus : kMinus;
fQuartetStartPredictedHelicity = (fRingSeed_reported & 1) ? kPlus : kMinus;
fActualHelicity = (quartetphase == 0 || quartetphase == 3) ? fQuartetStartHelicity
: -fQuartetStartHelicity;
fPredictedHelicity = (quartetphase == 0 || quartetphase == 3)
? fQuartetStartPredictedHelicity
: -fQuartetStartPredictedHelicity;
} else {
fActualHelicity = 0;
}

Sylvester Joosten
committed
if (fIsNewCycle) {
fQuartet[3] = fQuartet[2];
fQuartet[2] = fQuartet[1];
fQuartet[1] = fQuartet[0];
fQuartet[0] = fReportedHelicity;
fNCycle++;
if ((fNCycle - fFirstCycle) % 4 == 3) { // Test if last in a quartet
if ((abs(fQuartet[0] + fQuartet[3] - fQuartet[1] - fQuartet[2]) == 4)) {
if (!fFoundQuartet) {
// fFirstCycle = fNCycle - 3;
_logger->info("Quartet potentially found, starting at cycle {} - event {}",
fFirstCycle, evdata.GetEvNum());
// cout << "Quartet potentially found, starting at cycle " << fFirstCycle << " - event
// "
// << evdata.GetEvNum() << endl;
fFoundQuartet = kTRUE;

Sylvester Joosten
committed
}
} else {
if (fNCycle - fFirstCycle > 4) { // Not at start of run. Reset
_logger->warn("Lost quartet sync at cycle {} - event {}", fNCycle, evdata.GetEvNum());
_logger->warn("{} {} {} {}", fQuartet[0], fQuartet[1], fQuartet[2], fQuartet[3]);
// cout << "Lost quartet sync at cycle " << fNCycle << " - event " <<
// evdata.GetEvNum()

Sylvester Joosten
committed
// cout << fQuartet[0] << " " << fQuartet[1] << " " << fQuartet[2] << " " <<
// fQuartet[3]

Sylvester Joosten
committed
fFirstCycle += 4 * ((fNCycle - fFirstCycle) / 4); // Update, but don't change phase
}
fFoundQuartet = kFALSE;

Sylvester Joosten
committed
_logger->info("Searching for first of a quartet at cycle {} - event {}", fFirstCycle,
evdata.GetEvNum());
// cout << "Searching for first of a quartet at cycle "
// << " " << fFirstCycle << " - event " << evdata.GetEvNum() << endl;

Sylvester Joosten
committed
// cout << fQuartet[0] << " " << fQuartet[1] << " " << fQuartet[2] << " " << fQuartet[3]
// << endl;
_logger->info("{} {} {} {}", fQuartet[0], fQuartet[1], fQuartet[2], fQuartet[3]);

Sylvester Joosten
committed
fFirstCycle++;
}
}
// Load the actual helicity. Calibrate if not calibrated.
fActualHelicity = kUnknown;
LoadHelicity(fReportedHelicity, fNCycle, missed);
fLastReportedHelicity = fReportedHelicity;
fIsNewCycle = kFALSE;
// cout << fTITime/250000000.0 << " " << fNCycle << " " << fReportedHelicity << endl;
// cout << fNCycle << ": " << fReportedHelicity << " "
// << fPredictedHelicity << " " << fActualHelicity << endl;
}
// Ignore until a MPS Is found

Sylvester Joosten
committed
} else { // No MPS found yet

Sylvester Joosten
committed
// cout << "Initializing" << endl;
_logger->info("Initializing Helicity");
fLastReportedHelicity = fReportedHelicity;

Sylvester Joosten
committed
fActualHelicity = kUnknown;
fPredictedHelicity = kUnknown;
fFirstEvTime = fTITime;
fLastEvTime = fTITime;
fLastMPSTime = fTITime; // Not necessarily during the MPS
fNCycle = 0;
fFirstEvProcessed = kTRUE;
fFoundMPS = kFALSE;
fFoundQuartet = kFALSE;
fIsNewCycle = kFALSE;
fNBits = 0;

Sylvester Joosten
committed
if (fActualHelicity < -5) {
_logger->info("Actual Helicity never got defined");

Sylvester Joosten
committed
if (fNBits < fMAXBIT) {
if (fActualHelicity == -1 || fActualHelicity == 1) {
cout << "Helicity of " << fActualHelicity << " reported prematurely at cycle " << fNCycle
<< endl;
}
}
fLastActualHelicity = fActualHelicity;
return 0;
}
//_____________________________________________________________________________

Sylvester Joosten
committed
Int_t THcHelicity::End(THaRunBase*) {
// End of run processing. Write histograms.
THcHelicityReader::End();
// for( Int_t i = 0; i < NHIST; ++i )
// fHisto[i]->Write();
return 0;
}
//_____________________________________________________________________________

Sylvester Joosten
committed
void THcHelicity::SetDebug(Int_t level) {
// Set debug level of this detector as well as the THcHelicityReader

Sylvester Joosten
committed
THaHelicityDet::SetDebug(level);
fQWEAKDebug = level;
}
//_____________________________________________________________________________

Sylvester Joosten
committed
void THcHelicity::LoadHelicity(Int_t reportedhelicity, Int_t cyclecount, Int_t missedcycles) {
// static const char* const here = "THcHelicity::LoadHelicity";

Sylvester Joosten
committed
int quartetphase = (cyclecount - fFirstCycle) % 4;
fnQrt = quartetphase;

Sylvester Joosten
committed
if (missedcycles > 1) { // If we missed windows
if (fNBits < fMAXBIT) { // and we haven't gotten the seed, start over
fNBits = 0;
return;
}
}

Sylvester Joosten
committed
if (!fFoundQuartet) { // Wait until we have found quad phase before starting
return; // to calibrate

Sylvester Joosten
committed
if (quartetphase == 0) { // Start of a quad
if (fNBits < fMAXBIT) {
if (fNBits == 0) {
_logger->info("Start calibrating at cycle {}", cyclecount);
// cout << "Start calibrating at cycle " << cyclecount << endl;
fRingSeed_reported = 0;

Sylvester Joosten
committed
if (fReportedHelicity == kPlus) {
fRingSeed_reported = ((fRingSeed_reported << 1) | 1) & 0x3FFFFFFF;

Sylvester Joosten
committed
fRingSeed_reported = (fRingSeed_reported << 1) & 0x3FFFFFFF;

Sylvester Joosten
committed
if (fReportedHelicity == kUnknown) {
fNBits = 0;
fRingSeed_reported = 0;
} else if (fNBits == fMAXBIT) {
_logger->info("Seed Found {} at cycle {} with first cycle {}", fRingSeed_reported,
cyclecount, fFirstCycle);
// cout << "Seed Found " << hex << fRingSeed_reported << dec << " at cycle " << cyclecount
// << " with first cycle " << fFirstCycle << endl;
Int_t backseed = GetSeed30(fRingSeed_reported);
_logger->info("Seed at cycle {} should be {}", fFirstCycle, backseed);
// cout << "Seed at cycle " << fFirstCycle << " should be " << hex << backseed << dec <<
// endl;
}
fActualHelicity = kUnknown;
} else if (fNBits >= fMAXBIT) {
fRingSeed_reported = RanBit30(fRingSeed_reported);

Sylvester Joosten
committed
if (fNBits == fMAXBIT) {
fRingSeed_actual = fRingSeed_reported;
for (Int_t i = 0; i < fHelDelay / 4; i++) {
fRingSeed_actual = RanBit30(fRingSeed_actual);
}
fNBits++;

Sylvester Joosten
committed
fRingSeed_actual = RanBit30(fRingSeed_actual);

Sylvester Joosten
committed
fActualHelicity = (fRingSeed_actual & 1) ? kPlus : kMinus;
fPredictedHelicity = (fRingSeed_reported & 1) ? kPlus : kMinus;
// if(fTITime/250000000.0 > 380.0) cout << fTITime/250000000.0 << " " << fNCycle << " "
// << hex <<
// fRingSeed_reported << " " << fRingSeed_actual << dec
//<< endl;
if (fReportedHelicity != fPredictedHelicity) {
_logger->warn("Helicity prediction failed {} {} {}", fReportedHelicity, fPredictedHelicity,
fActualHelicity);
// cout << "Helicity prediction failed " << fReportedHelicity << " "
// << fPredictedHelicity << " " << fActualHelicity << endl;
// cout << hex << fRingSeed_reported << " " << fRingSeed_actual << dec << endl;
fNBits = 0; // Need to reaquire seed
fActualHelicity = kUnknown;
fPredictedHelicity = kUnknown;

Sylvester Joosten
committed
fQuartetStartHelicity = fActualHelicity;
fQuartetStartPredictedHelicity = fPredictedHelicity;

Sylvester Joosten
committed
} else { // Not the beginning of a quad
if (fNBits >= fMAXBIT) {
fActualHelicity =
(quartetphase == 0 || quartetphase == 3) ? fQuartetStartHelicity : -fQuartetStartHelicity;
fPredictedHelicity = (quartetphase == 0 || quartetphase == 3)
? fQuartetStartPredictedHelicity
: -fQuartetStartPredictedHelicity;
}
}
return;
}
//_____________________________________________________________________________

Sylvester Joosten
committed
Int_t THcHelicity::RanBit30(Int_t ranseed) {
UInt_t bit7 = (ranseed & 0x00000040) != 0;
UInt_t bit28 = (ranseed & 0x08000000) != 0;
UInt_t bit29 = (ranseed & 0x10000000) != 0;
UInt_t bit30 = (ranseed & 0x20000000) != 0;
UInt_t newbit = (bit30 ^ bit29 ^ bit28 ^ bit7) & 0x1;

Sylvester Joosten
committed
if (ranseed <= 0) {
if (fQWEAKDebug > 1)
std::cerr << "ranseed must be greater than zero!"
<< "\n";

Sylvester Joosten
committed
ranseed = ((ranseed << 1) | newbit) & 0x3FFFFFFF;
// here ranseed is changed
if (fQWEAKDebug > 1) {
cout << "THcHelicity::RanBit30, newbit=" << newbit << "\n";
}
return ranseed;
}
//_____________________________________________________________________________

Sylvester Joosten
committed
Int_t THcHelicity::GetSeed30(Int_t currentseed)
/* Back track the seed by 30 samples */
{
#if 1
Int_t seed = currentseed;

Sylvester Joosten
committed
for (Int_t i = 0; i < 30; i++) {
UInt_t bit1 = (seed & 0x00000001) != 0;
UInt_t bit8 = (seed & 0x00000080) != 0;
UInt_t bit29 = (seed & 0x10000000) != 0;
UInt_t bit30 = (seed & 0x20000000) != 0;
UInt_t newbit30 = (bit30 ^ bit29 ^ bit8 ^ bit1) & 0x1;

Sylvester Joosten
committed
seed = (seed >> 1) | (newbit30 << 29);
}
#else
Int_t bits = currentseed;

Sylvester Joosten
committed
Int_t seed = 0;
for (Int_t i = 0; i < 30; i++) {
Int_t val;
// XOR at virtual position 0 and 29

Sylvester Joosten
committed
if (i == 0) {
val = ((bits & (1 << (i))) != 0) ^ ((bits & (1 << (i + 29))) != 0);

Sylvester Joosten
committed
val = ((bits & (1 << (i))) != 0) ^ ((seed & (1 << (i - 1))) != 0);

Sylvester Joosten
committed
if (i <= 1) {
val = ((bits & (1 << (1 - i))) != 0) ^ val;

Sylvester Joosten
committed
val = ((seed & (1 << (i - 2))) != 0) ^ val;

Sylvester Joosten
committed
if (i <= 22) {
val = ((bits & (1 << (i - 22))) != 0) ^ val;

Sylvester Joosten
committed
val = ((seed & (1 << (i - 23))) != 0) ^ val;

Sylvester Joosten
committed
seed |= (val << i);
}
#endif
return seed;
}
ClassImp(THcHelicity)