Newer
Older
////////////////////////////////////////////////////////////////////////
//
// THcHelicity
//
// Helicity of the beam in delayed mode using quartets
// +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 "THaHelicityDet.h"
#include "hcana/Logger.h"
using namespace std;
//_____________________________________________________________________________

Sylvester Joosten
committed
THcHelicity::THcHelicity(const char* name, const char* description, THaApparatus* app)
: THaHelicityDet(name, description, app), fnQrt(-1), fHelDelay(8),

Sylvester Joosten
committed
fMAXBIT(30) {
// for( Int_t i = 0; i < NHIST; ++i )
// fHisto[i] = 0;
// memset(fHbits, 0, sizeof(fHbits));
}
//_____________________________________________________________________________
THcHelicity::THcHelicity()
: 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;
fQuadPattern[0] = fQuadPattern[1] = fQuadPattern[2] = fQuadPattern[3] = 0;
fQuadPattern[4] = fQuadPattern[5] = fQuadPattern[6] = fQuadPattern[7] = 0;
fHelperHistory = 0;
fHelperQuartetHistory = 0;
fScalerSeed = 0;
fNBits = 0;
lastispos = 0;
fLastReportedHelicity = kUnknown;
fFixFirstCycle = kFALSE;
fHaveQRT = kFALSE;
fNQRTProblems = 0;
fPeriodCheck = 0.0;
fCycle = 0.0;
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
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"},
{"pcheck", "Period check", "fPeriodCheck"},
{"cycle", "Helicity Cycle", "fCycle"},
{"qrt", "Last cycle of quartet", "fQrt"},
{0}};
_logger->info("Calling THcHelicity DefineVarsFromList");
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;
//_____________________________________________________________________________
void THcHelicity::SetHelicityScaler(THcHelicityScaler* f) {
fglHelicityScaler = f;
fHelicityHistory = fglHelicityScaler->GetHelicityHistoryP();
//_____________________________________________________________________________

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.");
fReportedHelicity = (fIsHelp ? (fIsHelm ? kUnknown : kPlus) : (fIsHelm ? kMinus : kUnknown));
fMPS = fIsMPS ? 1 : 0;
fQrt = fIsQrt ? 1 : 0; // Last of quartet
if (fglHelicityScaler) {
Int_t nhelev = fglHelicityScaler->GetNevents();
Int_t ncycles = fglHelicityScaler->GetNcycles();
if (nhelev > 0) {
for (Int_t i = 0; i < nhelev; i++) {
fScaleQuartet = (fHelicityHistory[i] & 2) != 0;
Int_t ispos = fHelicityHistory[i] & 1;
if (fScaleQuartet) {
fScalerSeed = ((fScalerSeed << 1) | ispos) & 0x3FFFFFFF;
}
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) {
fPeriodCheck = fmod(fTITime / fTIPeriod, 1.0);
fCycle = (fTITime / fTIPeriod);

Sylvester Joosten
committed
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;
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
} 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;
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) {
for (Int_t i = 0; i < quartets_missed; i++) { // Advance the seeds.
// cout << "Advancing seed A " << fNBits << endl;
fRingSeed_reported = RanBit30(fRingSeed_reported);
fRingSeed_actual = RanBit30(fRingSeed_actual);
}
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;
}
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
if (fIsNewCycle) {
// cout << "Scaler Seed " << bitset<32>(fScalerSeed) << endl;
// Int_t predictedScalerSeed = RanBit30(fScalerSeed);
// cout << "Predct Seed " << bitset<32>(predictedScalerSeed) << endl;
// cout << "Event Seed " << bitset<32>(fRingSeed_reported) << endl;
fQuartet[3] = fQuartet[2];
fQuartet[2] = fQuartet[1];
fQuartet[1] = fQuartet[0];
fQuartet[0] = fReportedHelicity;
fNCycle++;
// cout << "XX: " << fNCycle << " " << fReportedHelicity << " " << fIsQrt <<endl;
if (fIsQrt) { //
fNLastQuartet = fNQuartet;
fNQuartet = (fNCycle - fFirstCycle) / 4;
if (fHaveQRT) { // Should already have phase set
if ((fNCycle - fFirstCycle) % 4 != 0) { // Test if first in a quartet
fNQRTProblems++;
if (fNQRTProblems > 10) {
cout << "QRT Problem resetting" << endl;
fHaveQRT = kFALSE;
fFoundQuartet = kFALSE;
fNQRTProblems = 0;
} else {
cout << "Ignored " << fNQRTProblems << " problems" << endl;
}
} else {
fNQRTProblems = 0;
}
}
if (!fHaveQRT) {
fHaveQRT = kTRUE;
fFoundQuartet = kTRUE;
fFirstCycle = fNCycle; //
fNQuartet = (fNCycle - fFirstCycle) / 4;
fNLastQuartet = fNQuartet - 1; // Make sure LoadHelicity uses
fNBits = 0;
fNQRTProblems = 0;
cout << "Phase found from QRT signal" << endl;
cout << "fFirstcycle = " << fFirstCycle << endl;
}
} else {
if (fHaveQRT) { // Using qrt signal.
fNLastQuartet = fNQuartet;
fNQuartet = (fNCycle - fFirstCycle) / 4;
if ((fNCycle - fFirstCycle) % 4 == 0) { // Shouldn't happen
fNQRTProblems++;
if (fNQRTProblems > 10) {
cout << "Shouldn't happen, cycle=" << fNCycle << "/" << fFirstCycle << endl;
fHaveQRT = kFALSE; // False until a new QRT seen
fNBits = 0; // Reset
fNLastQuartet = fNQuartet; // Make sure LoadHelicity does not use
} else {
cout << "Ignored " << fNQRTProblems << " problems" << endl;
}
}
} else { // Presumable pre qrt signal data
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;
cout << "Quartet potentially found, starting at cycle " << fFirstCycle << endl;
fNQuartet = (fNCycle - fFirstCycle) / 4;
fNLastQuartet = fNQuartet - 1; // Make sure LoadHelicity uses
fFoundQuartet = kTRUE;
}
} else {
if (fNCycle - fFirstCycle > 4) { // Not at start of run. Reset
cout << "Lost quartet sync at cycle " << fNCycle << endl;
cout << fQuartet[0] << " " << fQuartet[1] << " " << fQuartet[2] << " "
<< fQuartet[3] << endl;
fFirstCycle +=
4 * ((fNCycle - fFirstCycle) / 4); // Update, but don't change phase
}
fFoundQuartet = kFALSE;
fNBits = 0;
cout << "Searching for first of a quartet at cycle "
<< " " << fFirstCycle << endl;
cout << fQuartet[0] << " " << fQuartet[1] << " " << fQuartet[2] << " "
<< fQuartet[3] << endl;
fFirstCycle++;
}
} else {
fNLastQuartet = fNQuartet;
fNQuartet = (fNCycle - fFirstCycle) / 4;
}
}
}
// Load the actual helicity. Calibrate if not calibrated.
fActualHelicity = kUnknown;
// Here if we know we missed some earlier in the quartet, we need
// to make sure we get here and call LoadHelicity for the missing
// Cycles, reducing the missed count for each extra loadhelicity
// call that we make.
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;
// if(!fFixFirstCycle) {
if (fNQuartet - fNLastQuartet > 1) { // If we missed a quartet
if (fNBits < fMAXBIT) { // and we haven't gotten the seed, start over
cout << "fNBits = 0, missedcycles=" << missedcycles << " " << fNLastQuartet << " "
<< fNQuartet << endl;
fNBits = 0;
return;
}
// }
if (!fFoundQuartet) { // Wait until we have found quad phase before starting
return; // to calibrate
// LoadHelicity is called first event of each cycle.
// But only do it's thing if it is first cycle of quartet.
// Need to instead have it do it's thing on the first event of a quartet.
// But only for seed building. Current logic is OK once seed is found.
if (fNBits < fMAXBIT) {
if (fNQuartet != fNLastQuartet) {
// Sanity check fNQuartet == fNLastQuartet+1
if (fNBits == 0) {
cout << "Start calibrating at cycle " << cyclecount << endl;
fRingSeed_reported = 0;
if ((fReportedHelicity == kPlus && (quartetphase == 0 || quartetphase == 3)) ||
(fReportedHelicity == kMinus && (quartetphase == 1 || quartetphase == 2))) {
fRingSeed_reported = ((fRingSeed_reported << 1) | 1) & 0x3FFFFFFF;
// cout << " " << fNQuartet << " 1" << endl;
fRingSeed_reported = (fRingSeed_reported << 1) & 0x3FFFFFFF;
// cout << " " << fNQuartet << " 0" << endl;
if (fReportedHelicity == kUnknown) {
fNBits = 0;
fRingSeed_reported = 0;
} else if (fNBits == fMAXBIT) {
cout << "Seed Found " << bitset<32>(fRingSeed_reported) << " at cycle " << cyclecount
<< " with first cycle " << fFirstCycle << endl;
if (fglHelicityScaler) {
cout << "Scaler Seed " << bitset<32>(fScalerSeed) << endl;
}
Int_t backseed = GetSeed30(fRingSeed_reported);
cout << "Seed at cycle " << fFirstCycle << " should be " << hex << backseed << dec << endl;
// Create the "actual seed"
fRingSeed_actual = fRingSeed_reported;
for (Int_t i = 0; i < fHelDelay / 4; i++) {
fRingSeed_actual = RanBit30(fRingSeed_actual);
}
fActualHelicity = kUnknown;
} // Need to change this to build seed even when not at start of quartet
} else {
// If quartetphase !=, the seeds will alread have been advanced
// except that we won't have made the initial
// cout << "Advancing seed B " << fNBits << endl;
fRingSeed_reported = RanBit30(fRingSeed_reported);
fRingSeed_actual = RanBit30(fRingSeed_actual);
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) {
cout << "Helicity prediction failed " << fReportedHelicity << " " << fPredictedHelicity
<< " " << fActualHelicity << endl;
cout << bitset<32>(fRingSeed_reported) << " " << bitset<32>(fRingSeed_actual) << endl;
fNBits = 0; // Need to reaquire seed
fActualHelicity = kUnknown;
fPredictedHelicity = kUnknown;
fQuartetStartHelicity = fActualHelicity;
fQuartetStartPredictedHelicity = fPredictedHelicity;
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)