diff --git a/src/THcHelicity.cxx b/src/THcHelicity.cxx
index 6e69e999e2593037f0e9e043e503fd6555ba5971..e48859398c6c84aa062f875d7e1751060a0850cf 100644
--- a/src/THcHelicity.cxx
+++ b/src/THcHelicity.cxx
@@ -289,6 +289,7 @@ Int_t THcHelicity::Decode( const THaEvData& evdata )
   fMPS = fIsMPS?1:0;
   fQrt = fIsQrt?1:0;		// Last of quartet
 
+#if 0
   if(fglHelicityScaler) {
     Int_t nhelev = fglHelicityScaler->GetNevents();
     Int_t ncycles = fglHelicityScaler->GetNcycles();
@@ -323,6 +324,7 @@ Int_t THcHelicity::Decode( const THaEvData& evdata )
       }
     }
   }
+#endif
   
   if(fHelDelay == 0) {		// If no delay actual=reported (but zero if in MPS)
     fActualHelicity = fIsMPS?kUnknown:fReportedHelicity;
diff --git a/src/THcHelicityScaler.cxx b/src/THcHelicityScaler.cxx
index 4c482faa2437c5820df69d5f69a4a76659216bb0..058aa0714ee509efeccc9ecfa5130d95881e77fb 100644
--- a/src/THcHelicityScaler.cxx
+++ b/src/THcHelicityScaler.cxx
@@ -3,28 +3,24 @@
 
 \brief Event handler for Hall C helicity scalers
 
-Scalers not yet implemented.  For now just picks the helicity control
-bits out of the scaler words
-
-~~~
-     gHaEvtHandlers->Add (new THcHelicityScaler("H","HC helicity scalers"));
 ~~~
-To enable debugging you may try this in the setup script
 ~~~
      THcHelcityScaler *hhelscaler = new THcHelicityScaler("H","HC helicity scalers");
-     hscaler->SetDebugFile("HHelScaler.txt");
+     // hscaler->SetDebugFile("HHelScaler.txt");
+     hhelscaler->SetROC(8);   // 5 for HMS defaults to 8 for SHMS
+     hhelscaler->SetBankID(0x9801); // Will default to this
      gHaEvtHandlers->Add (hhelscaler);
 ~~~
 \author  
 */
 
-#include "THaEvtTypeHandler.h"
+//#include "THaEvtTypeHandler.h"
 #include "THcHelicityScaler.h"
 #include "THaCodaData.h"
 #include "THaEvData.h"
-#include "THcParmList.h"
 #include "THcGlobals.h"
 #include "THaGlobals.h"
+#include "THcParmList.h"
 #include "THcHelicity.h"
 #include "TNamed.h"
 #include "TMath.h"
@@ -36,6 +32,7 @@ To enable debugging you may try this in the setup script
 #include <iostream>
 #include <sstream>
 #include <map>
+#include <bitset>
 #include <iterator>
 #include "THaVarList.h"
 #include "VarDef.h"
@@ -55,21 +52,28 @@ static const UInt_t defaultDT = 4;
 
 THcHelicityScaler::THcHelicityScaler(const char *name, const char* description)
   : THaEvtTypeHandler(name,description),
-    fBCM_Gain(0), fBCM_Offset(0), fBCM_delta_charge(0),
     fBankID(9801),
-    evcount(0), evcountR(0.0), ifound(0),
     fUseFirstEvent(kTRUE),
-    fOnlySyncEvents(kFALSE), fOnlyBanks(kFALSE), fDelayedType(-1),
-    fClockChan(-1), fLastClock(0), fClockOverflows(0)
+    fDelayedType(-1),
+    fBCM_Gain(0), fBCM_Offset(0)
 {
-  fRocSet.clear();
+  fROC=-1;
+  fNScalerChannels = 32;
+
+  AddEvtType(1);
+  AddEvtType(2);
+  AddEvtType(4);
+  AddEvtType(5);
+  AddEvtType(6);
+  AddEvtType(7);
+  SetDelayedType(129);
+  
 }
 
 THcHelicityScaler::~THcHelicityScaler()
 {
   delete [] fBCM_Gain;
   delete [] fBCM_Offset;
-  delete [] fBCM_delta_charge;
 
   for( vector<UInt_t*>::iterator it = fDelayedEvents.begin();
        it != fDelayedEvents.end(); ++it )
@@ -81,11 +85,11 @@ Int_t THcHelicityScaler::End( THaRunBase* )
 {
   // Process any delayed events in order received
 
-  cout << "THcHelicityScaler::End Analyzing " << fDelayedEvents.size() << " delayed scaler events" << endl;
-  for(std::vector<UInt_t*>::iterator it = fDelayedEvents.begin();
+  cout << "THcHelicityScaler::End Analyzing " << fDelayedEvents.size() << " delayed helicity scaler events" << endl;
+    for(std::vector<UInt_t*>::iterator it = fDelayedEvents.begin();
       it != fDelayedEvents.end(); ++it) {
     UInt_t* rdata = *it;
-    AnalyzeBuffer(rdata,kFALSE);
+    AnalyzeBuffer(rdata);
   }
 
   for( vector<UInt_t*>::iterator it = fDelayedEvents.begin();
@@ -93,6 +97,71 @@ Int_t THcHelicityScaler::End( THaRunBase* )
     delete [] *it;
   fDelayedEvents.clear();
 
+  //  cout << " -- Helicity Scalers -- " << endl;
+  for(Int_t i=0;i<fNScalerChannels;i++) {
+    if(fScalerSums[i]>0.5) {
+      fAsymmetry[i] = (fHScalers[0][i]-fHScalers[1][i])/fScalerSums[i];
+      fAsymmetryError[i] = 2*TMath::Sqrt(fHScalers[0][i]*fHScalers[1][i]
+					*fScalerSums[i])
+	/(fScalerSums[i]*fScalerSums[i]);
+    } else {
+      fAsymmetry[i] = 0.0;
+      fAsymmetryError[i] = 0.0;
+    }
+    //    printf("%2d %12.0f %12.0f %12.0f %12.8f\n",i,fScalerSums[i],
+    //	   fHScalers[0][i],fHScalers[1][i],
+    //	   fAsymmetry[i]);
+  }
+  //  cout << " ---------------------- " << endl;
+
+  // Compute Charge Asymmetries
+  std::map<std::string, Int_t> bcmindex;
+  bcmindex["BCM1"] = 0;
+  bcmindex["BCM2"] = 2;
+  //  bcmindex["Unser"] = 6;
+  bcmindex["BCM4A"] = 10;
+  bcmindex["BCM4B"] = 4;
+  bcmindex["BCM4C"] = 12;
+  //  bcmindex["1MHz"] = 8;
+  Int_t clockindex=8;
+  Double_t clockfreq=1000000.0;
+  Double_t pclock = fHScalers[0][clockindex];
+  Double_t mclock = fHScalers[1][clockindex];
+  cout << " -- Beam Charge Asymmetries -- " << endl;
+  for(Int_t i=0;i<fNumBCMs;i++) {
+    if(bcmindex.find(fBCM_Name[i]) != bcmindex.end()) {
+      Int_t index=bcmindex[fBCM_Name[i]];
+      Double_t pcounts = fHScalers[0][index];
+      Double_t mcounts = fHScalers[1][index];
+      //      cout << index << " " << fBCM_Name[i] << " " << pcounts << " " << mcounts
+      //	   << " " << fBCM_Gain[i]
+      //      	   << " " << fBCM_Offset[i] << endl;
+      Double_t pcharge = (pcounts - (pclock/clockfreq)*fBCM_Offset[i])
+	/fBCM_Gain[i];
+      Double_t mcharge = (mcounts - (mclock/clockfreq)*fBCM_Offset[i])
+	/fBCM_Gain[i];
+      fCharge[i] = pcharge+mcharge;
+      if(fCharge[i]>0.0) {
+	fChargeAsymmetry[i] = (pcharge-mcharge)/fCharge[i];
+      } else {
+	fChargeAsymmetry[i] = 0.0;
+      }
+      printf("%6s %12.2f %12.8f\n",fBCM_Name[i].c_str(),fCharge[i],fChargeAsymmetry[i]);
+    }
+  }
+  fTime = (pclock+mclock)/clockfreq;
+  if(pclock+mclock>0) {
+    fTimeAsymmetry = (pclock-mclock)/(pclock+mclock);
+  } else {
+    fTimeAsymmetry = 0.0;
+  }
+  printf("TIME(s)%12.2f %12.8f\n",fTime,fTimeAsymmetry);
+  if(fNTriggersPlus+fNTriggersMinus > 0) {
+    fTriggerAsymmetry = ((Double_t) (fNTriggersPlus-fNTriggersMinus))/(fNTriggersPlus+fNTriggersMinus);
+  } else {
+    fTriggerAsymmetry = 0.0;
+  }
+  cout << " ----------------------------- " << endl;
   return 0;
 }
 
@@ -100,9 +169,28 @@ Int_t THcHelicityScaler::End( THaRunBase* )
 Int_t THcHelicityScaler::ReadDatabase(const TDatime& date )
 {
   char prefix[2];
-  prefix[0]='g';
-  prefix[1]='\0';
-
+  prefix[0]='g'; prefix[1]='\0';
+
+  fNumBCMs = 0;
+  string bcm_namelist;
+  DBRequest list[]={
+		    {"NumBCMs",&fNumBCMs, kInt, 0, 1},
+		    {"BCM_Names",     &bcm_namelist,       kString},
+		    {0}
+  };
+  gHcParms->LoadParmValues((DBRequest*)&list, prefix);
+  if(fNumBCMs > 0) {
+    fBCM_Gain = new Double_t[fNumBCMs];
+    fBCM_Offset = new Double_t[fNumBCMs];
+    DBRequest list2[]={
+      {"BCM_Gain",      fBCM_Gain,         kDouble, (UInt_t) fNumBCMs},
+      {"BCM_Offset",     fBCM_Offset,       kDouble,(UInt_t) fNumBCMs},
+      {0}
+    };
+    gHcParms->LoadParmValues((DBRequest*)&list2, prefix);
+    fBCM_Name = vsplit(bcm_namelist);
+  }
+  
   return kOK;
 }
 void THcHelicityScaler::SetDelayedType(int evtype) {
@@ -140,16 +228,16 @@ Int_t THcHelicityScaler::Analyze(THaEvData *evdata)
     if (fDebugFile) *fDebugFile<<"\n\nTHcHelicityScaler :: Debugging event type "<<dec<<evdata->GetEvType()<< " event num = " << evdata->GetEvNum() << endl<<endl;
     evNumber=evdata->GetEvNum();
     Int_t ret;
-    if((ret=AnalyzeBuffer(rdata,fOnlySyncEvents))) {
+    if((ret=AnalyzeBuffer(rdata))) {
       //
     }
     return ret;
   }
 
 }
-Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata, Bool_t onlysync)
+Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata)
 {
-  fNevents = 0;
+  fNTrigsInBuf = 0;
 
   // Parse the data, load local data arrays.
   UInt_t *p = (UInt_t*) rdata;
@@ -158,7 +246,7 @@ Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata, Bool_t onlysync)
   Int_t roc = -1;
   Int_t evlen = *p+1;
 
-  ifound=0;
+  Int_t ifound=0;
   
   while(p<plast) {
     Int_t banklen = *p;
@@ -172,7 +260,7 @@ Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata, Bool_t onlysync)
         roc = (*p>>16) & 0xf;
 	if(fDebugFile) *fDebugFile << "ROC: " << roc << " " << evlen << " " << *(p-1) << hex << " " << *p << dec << endl;
 //		cout << "ROC: " << roc << " " << evlen << " " << *(p-1) << hex << " " << *p << dec << endl;
-	if(fRocSet.find(roc)==fRocSet.end()) { // Not a ROC with helicity scaler
+	if(roc != fROC) { // Not a ROC with helicity scaler
 	  p+=*(p-1)-1;		// Skip to next ROC
 	}
       }
@@ -200,19 +288,18 @@ Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata, Bool_t onlysync)
 
       } else {
 	// This is a helicity scaler bank
-	if (roc == 5) {
-	  Int_t nevents = (banklen-2)/32;
+	if (roc == fROC) {
+	  Int_t nevents = (banklen-2)/fNScalerChannels;
 	  //cout << "# of helicity events in bank:" << " " << nevents << endl;
 	  if (nevents > 100) {
 	    cout << "Error! Beam off for too long" << endl;	
 	  }
-	  fNevents = nevents;
-	  fNcycles += nevents;
-	
+	  
+	  fNTrigsInBuf = 0;
 	  // Save helcitiy and quad info for THcHelicity
 	  for (Int_t iev = 0; iev < nevents; iev++) {  // find number of helicity events in each bank
-	    Int_t nentries = 32*iev+2;
-	    fHelicityHistory[iev] = (p[nentries-1]>>30) & 0x3;
+	    Int_t index = fNScalerChannels*iev+1;
+	    AnalyzeHelicityScaler(p+index);
 	    //	    cout << "H: " << evNumber << endl;
 	  }
 	}
@@ -243,9 +330,6 @@ Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata, Bool_t onlysync)
     *fDebugFile << "   Found flag   =  "<<ifound<<endl;
   }
 
-  // HMS has headers which are different from SOS, but both are
-  // event type 0 and come here.  If you found no headers, return.
-
   if (!ifound) return 0;
 
   return 1;
@@ -253,11 +337,109 @@ Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata, Bool_t onlysync)
  	
 }
 
-//Int_t THcHelicityScaler::AnalyzeHelicityScaler(UInt_t *p)
-//{
-//}
+Int_t THcHelicityScaler::AnalyzeHelicityScaler(UInt_t *p)
+{
+  Int_t hbits = (p[0]>>30) & 0x3; // quartet and helcity bits in scaler word
+  Bool_t isquartet = (hbits&2) != 0;
+  Int_t ispos = hbits&1;
+  Int_t actualhelicity = 0;
+  fHelicityHistory[fNTrigsInBuf] = hbits;
+  fNTrigsInBuf++;
+  fNTriggers++;
+
+  Int_t quartetphase = (fNTriggers-fFirstCycle)%4;
+  if(fFirstCycle >= -10) {
+    if(quartetphase == 0) {
+      Int_t predicted = RanBit30(fRingSeed_reported);
+      fRingSeed_reported = ((fRingSeed_reported<<1) | ispos) & 0x3FFFFFFF;
+      // Check if ringseed_predicted agrees with reported if(fNBits>=30)
+      if(fNBits >= 30 && predicted != fRingSeed_reported) {
+	cout << "THcHelicityScaler: Helicity Prediction Failed" << endl;
+	cout << "Reported  " << bitset<32>(fRingSeed_reported) << endl;
+	cout << "Predicted " << bitset<32>(predicted) << endl;
+      }
+      fNBits++;
+      if(fNBits==30) {
+	cout << "THcHelicityScaler: A " << bitset<32>(fRingSeed_reported) <<
+	  " found at cycle " << fNTriggers << endl;
+      }
+    } else if (quartetphase == 3) {
+      if(!isquartet) {
+	cout << "THcHelicityScaler: Quartet bit expected but not set (" <<
+	  fNTriggers << ")" << endl;
+	fNBits = 0;
+	fRingSeed_reported = 0;
+	fRingSeed_actual = 0;
+	fFirstCycle = -100;
+      }
+    }
+  } else { 			// First cycle not yet identified
+    if(isquartet) { // Helicity and quartet signal for next set of scalers
+      fFirstCycle = fNTriggers - 3;
+      quartetphase = (fNTriggers-fFirstCycle)%4;
+      //// Helicity at start of quartet is same as last of quartet, so we can start filling the seed
+      fRingSeed_reported = ((fRingSeed_reported<<1) | ispos) & 0x3FFFFFFF;
+      fNBits++;
+      if(fNBits==30) {
+	cout << "THcHelicityScaler: B " << bitset<32>(fRingSeed_reported) <<
+	  " found at cycle " << fNTriggers << endl;
+      }
+    }
+  }
 
+  if(fNBits>=30) {
+    fRingSeed_actual = RanBit30(fRingSeed_reported);
+    fRingSeed_actual = RanBit30(fRingSeed_actual);
 
+#define DELAY9
+#ifdef DELAY9
+    if(quartetphase == 3) {
+      fRingSeed_actual = RanBit30(fRingSeed_actual);
+      actualhelicity = (fRingSeed_actual&1)?+1:-1;
+    } else {
+      actualhelicity = (fRingSeed_actual&1)?+1:-1;
+      if(quartetphase == 0 || quartetphase == 1) {
+	actualhelicity = -actualhelicity;
+      }
+    }
+#else
+    actualhelicity = (fRingSeed_actual&1)?+1:-1;
+    if(quartetphase == 1 || quartetphase == 2) {
+      actualhelicity = -actualhelicity;
+    }
+#endif
+  } else {
+    fRingSeed_actual = 0;
+  }
+
+  if(actualhelicity!=0) {
+    Int_t hindex = (actualhelicity>0)?0:1;
+    (actualhelicity>0)?(fNTriggersPlus++):(fNTriggersMinus++);
+    for(Int_t i=0;i<fNScalerChannels;i++) {
+      Int_t count = p[i]&0xFFFFFF; // Bottom 24 bits
+      fHScalers[hindex][i] += count;
+      fScalerSums[i] += count;
+    }
+  }
+  return(0);
+}
+//_____________________________________________________________________________
+Int_t  THcHelicityScaler::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;
+
+  ranseed =  ( (ranseed<<1) | newbit ) & 0x3FFFFFFF;
+
+  return ranseed;
+
+}
+//_____________________________________________________________________________
 THaAnalysisObject::EStatus THcHelicityScaler::Init(const TDatime& date)
 {
   
@@ -277,30 +459,72 @@ THaAnalysisObject::EStatus THcHelicityScaler::Init(const TDatime& date)
     eventtypes.push_back(0);  // Default Event Type
   }
 
-  fRocSet.insert(5);		// List ROCs that have helicity scalers
-  fRocSet.insert(8);		// Should make configurable
+  if(fROC < 0) {
+    fROC = 8;			// Default to SHMS crate
+  }
+
+  fNTriggers = 0;
+  fNTrigsInBuf = 0;
+  fFirstCycle = -100;
+  fRingSeed_reported = 0;
+  fRingSeed_actual = 0;
+  fNBits = 0;
+  fNTriggersPlus = fNTriggersMinus = 0;
+  fHScalers[0] = new Double_t[fNScalerChannels];
+  fHScalers[1] = new Double_t[fNScalerChannels];
+  fScalerSums = new Double_t[fNScalerChannels];
+  fAsymmetry = new Double_t[fNScalerChannels];
+  fAsymmetryError = new Double_t[fNScalerChannels];
+  for(Int_t i=0;i<fNScalerChannels;i++) {
+    fHScalers[0][i] = 0.0;
+    fHScalers[1][i] = 0.0;
+    fScalerSums[0] = 0.0;
+    fAsymmetry[0] = 0.0;
+    fAsymmetryError[0] = 0.0;
+  }
+
+  fCharge = new Double_t[fNumBCMs];
+  fChargeAsymmetry = new Double_t[fNumBCMs];
+
+  fTime = fTimeAsymmetry = 0;
+  fTriggerAsymmetry = 0.0;
+
+  MakeParms();
 
-  fNcycles = 0;
-  fNevents = 0;
-  
   return kOK;
 }
 
-size_t THcHelicityScaler::FindNoCase(const string& sdata, const string& skey)
+void THcHelicityScaler::MakeParms()
 {
-  // Find iterator of word "sdata" where "skey" starts.  Case insensitive.
-  string sdatalc, skeylc;
-  sdatalc = "";  skeylc = "";
-  for (string::const_iterator p =
-	 sdata.begin(); p != sdata.end(); ++p) {
-    sdatalc += tolower(*p);
-  }
-  for (string::const_iterator p =
-	 skey.begin(); p != skey.end(); ++p) {
-    skeylc += tolower(*p);
-  }
-  if (sdatalc.find(skeylc,0) == string::npos) return -1;
-  return sdatalc.find(skeylc,0);
-};
+  /**
+     Put Various helicity scaler results in gHcParms so they can be included in results.
+  */
+  gHcParms->Define(Form("g%s_hscaler_plus[%d]",fName.Data(),fNScalerChannels),
+		   "Plus Helcity Scalers",*(fHScalers[0]));
+  gHcParms->Define(Form("g%s_hscaler_minus[%d]",fName.Data(),fNScalerChannels),
+		   "Minus Helcity Scalers",*(fHScalers[1]));
+  gHcParms->Define(Form("g%s_hscaler_sum[%d]",fName.Data(),fNScalerChannels),
+		   "Helcity Scalers Sum",*fScalerSums);
+  gHcParms->Define(Form("g%s_hscaler_asy[%d]",fName.Data(),fNScalerChannels),
+		   "Helicity Scaler Asymmetry[%d]",*fAsymmetry);
+  gHcParms->Define(Form("g%s_hscaler_asyerr[%d]",fName.Data(),fNScalerChannels),
+		   "Helicity Scaler Asymmetry Error[%d]",*fAsymmetryError);
+  gHcParms->Define(Form("g%s_hscaler_triggers",fName.Data()),
+		   "Total Helicity Scaler Triggers",fNTriggers);
+  gHcParms->Define(Form("g%s_hscaler_triggers_plus",fName.Data()),
+		   "Positive Helicity Scaler Triggers",fNTriggersPlus);
+  gHcParms->Define(Form("g%s_hscaler_triggers_minus",fName.Data()),
+		   "Negative Helicity Scaler Triggers",fNTriggersMinus);
+  gHcParms->Define(Form("g%s_hscaler_charge[%d]",fName.Data(),fNumBCMs),
+		   "Helicity Gated Charge",*fCharge);
+  gHcParms->Define(Form("g%s_hscaler_charge_asy[%d]",fName.Data(),fNumBCMs),
+		   "Helicity Gated Charge Asymmetry",*fChargeAsymmetry);
+  gHcParms->Define(Form("g%s_hscaler_time",fName.Data()),
+		   "Helicity Gated Time (sec)",fTime);
+  gHcParms->Define(Form("g%s_hscaler_time_asy",fName.Data()),
+		   "Helicity Gated Time Asymmetry",fTimeAsymmetry);
+  gHcParms->Define(Form("g%s_hscaler_trigger_asy",fName.Data()),
+		   "Helicity Trigger Asymmetry",fTriggerAsymmetry);
+}
 
 ClassImp(THcHelicityScaler)
diff --git a/src/THcHelicityScaler.h b/src/THcHelicityScaler.h
index d467483469fe74d69251f5e5de30371e4ae38314..8ca54718b77d7f01d9a6dc0d5b1f1932dafbe87e 100644
--- a/src/THcHelicityScaler.h
+++ b/src/THcHelicityScaler.h
@@ -24,64 +24,77 @@ class THcHelicityScaler : public THaEvtTypeHandler {
 
 public:
 
-   THcHelicityScaler(const char*, const char*);
-   virtual ~THcHelicityScaler();
+  THcHelicityScaler(const char*, const char*);
+  virtual ~THcHelicityScaler();
 
-   Int_t Analyze(THaEvData *evdata);
-   Int_t AnalyzeBuffer(UInt_t *rdata, Bool_t onlysync);
-   Int_t AnalyzeHelicityScaler(UInt_t *p);
+  Int_t Analyze(THaEvData *evdata);
+  Int_t AnalyzeBuffer(UInt_t *rdata);
+  Int_t AnalyzeHelicityScaler(UInt_t *p);
 	
-   virtual EStatus Init( const TDatime& run_time);
-   virtual Int_t   ReadDatabase(const TDatime& date );
-   virtual Int_t End( THaRunBase* r=0 );
-
-   virtual void SetUseFirstEvent(Bool_t b = kFALSE) {fUseFirstEvent = b;}
-   virtual void SetDelayedType(int evtype);
-   virtual void SetROC(Int_t roc) {fROC=roc;}
-   virtual void SetBankID(Int_t bankid) {fBankID=bankid;}
-   virtual void SetHelicityDetector(THcHelicity *f) {fglHelicityDetector = f;}
-   virtual Int_t GetNevents() { return fNevents;}
-   virtual Int_t GetNcycles() { return fNcycles;}
-   virtual Int_t GetEvNum() { return evNumber;}
-   virtual Int_t* GetHelicityHistoryP() {return fHelicityHistory;}
+  virtual EStatus Init( const TDatime& run_time);
+  virtual Int_t   ReadDatabase(const TDatime& date );
+  virtual Int_t End( THaRunBase* r=0 );
+
+  virtual void SetUseFirstEvent(Bool_t b = kFALSE) {fUseFirstEvent = b;}
+  virtual void SetDelayedType(int evtype);
+  virtual void SetROC(Int_t roc) {fROC=roc;}
+  virtual void SetBankID(Int_t bankid) {fBankID=bankid;}
+  virtual void SetNScalerChannels(Int_t n) {fNScalerChannels = n;}
+  virtual Int_t GetNevents() { return fNTrigsInBuf;}
+  virtual Int_t GetNcycles() { return fNTriggers;}
+  virtual Int_t GetEvNum() { return evNumber;}
+  virtual Int_t* GetHelicityHistoryP() {return fHelicityHistory;}
+  virtual Int_t GetReportedSeed() {return fRingSeed_reported;}
+  virtual Int_t GetReportedActual() {return fRingSeed_actual;}
+  virtual Bool_t IsSeedGood() {return fNBits>=30;}
 
 private:
 
-   static size_t FindNoCase(const std::string& sdata, const std::string& skey);
-
-   Int_t fNumBCMs;
-   Double_t *fBCM_Gain;
-   Double_t *fBCM_Offset;
-   Double_t *fBCM_delta_charge;
-   
-   Int_t fROC;
-   UInt_t fBankID;
-   // Helicity Scaler variables
-   Int_t fNevents;		/* # of helicity scaler reads in last event */
-   Int_t fNcycles;
-   Int_t fHelicityHistory[200];
-   //
-   Bool_t fUseFirstEvent;
-   Bool_t fOnlySyncEvents;
-   Bool_t fOnlyBanks;
-   Int_t fDelayedType;
-   Int_t fClockChan;
-   UInt_t fLastClock;
-   Int_t fClockOverflows;
-
-   std::vector<UInt_t*> fDelayedEvents;
-   std::set<UInt_t> fRocSet;
-
-   THcHelicityScaler(const THcHelicityScaler& fh);
-   THcHelicityScaler& operator=(const THcHelicityScaler& fh);
-
-   UInt_t evcount;
-   Double_t evcountR;
-   UInt_t evNumber;
-   Int_t ifound;
-   THcHelicity *fglHelicityDetector;
-
-   ClassDef(THcHelicityScaler,0)  // Scaler Event handler
+  Int_t RanBit30(Int_t ranseed);
+  void MakeParms();
+
+  UInt_t fBankID;
+  // Helicity Scaler variables
+  Int_t fNTrigsInBuf;		/* # of helicity scaler reads in last event */
+  Int_t fNTriggers;
+  Int_t fFirstCycle;
+  Int_t fHelicityHistory[200];
+  //
+  Bool_t fUseFirstEvent;
+  Int_t fDelayedType;
+
+  Int_t fRingSeed_reported;
+  Int_t fRingSeed_actual;
+  Int_t fNBits;
+
+  Int_t fNTriggersPlus;
+  Int_t fNTriggersMinus;
+  Double_t* fHScalers[2];
+  Int_t fGateCount[2];
+  Double_t *fScalerSums;
+  Double_t *fAsymmetry;
+  Double_t *fAsymmetryError;
+  Double_t *fCharge;
+  Double_t *fChargeAsymmetry;
+  Double_t fTime;
+  Double_t fTimeAsymmetry;
+  Double_t fTriggerAsymmetry;
+
+  std::vector<UInt_t*> fDelayedEvents;
+  Int_t fROC;
+  Int_t fNScalerChannels;	// Number of scaler channels/event
+
+  Int_t fNumBCMs;
+  Double_t *fBCM_Gain;
+  Double_t *fBCM_Offset;
+  std::vector <std::string> fBCM_Name;
+
+  THcHelicityScaler(const THcHelicityScaler& fh);
+  THcHelicityScaler& operator=(const THcHelicityScaler& fh);
+
+  UInt_t evNumber;
+
+  ClassDef(THcHelicityScaler,0)  // Scaler Event handler
 
 };