diff --git a/src/THcDC.h b/src/THcDC.h
index 7cc5269cd067dba5268b0a03e551284d1d12ccfa..2c1153a27d01dfc68e906d1e7b29be8f0d1d55b8 100644
--- a/src/THcDC.h
+++ b/src/THcDC.h
@@ -45,7 +45,7 @@ public:
 
   //  Int_t GetNHits() const { return fNhit; }
 
-  //  Int_t GetNTracks() const { return fNDCTracks; }
+  Int_t GetNTracks() const { return fNDCTracks; }
   //  const TClonesArray* GetTrackHits() const { return fTrackProj; }
   void SetFocalPlaneBestTrack(Int_t golden_track_index); // Called in THcHallCSpectrometer:
 
@@ -75,6 +75,8 @@ public:
   Int_t GetVersion() const {return fVersion;}
 
 
+
+
   Double_t GetPlaneTimeZero(Int_t plane) const { return fPlaneTimeZero[plane-1];}
   Double_t GetSigma(Int_t plane) const { return fSigma[plane-1];}
   Int_t GetFixPropagationCorrectionFlag() const {return fFixPropagationCorrection;}
@@ -92,6 +94,7 @@ public:
   //  friend class THaScCalib;
 
   THcDC();  // for ROOT I/O
+
 protected:
   Int_t fdebuglinkstubs;
   Int_t fdebugprintrawdc;
@@ -199,6 +202,15 @@ protected:
   // Intermediate structure for building
   static const UInt_t MAXTRACKS = 10;
 
+public:
+  THcDriftChamberPlane* GetPlane(unsigned int i_plane) {
+    if(i_plane < fNPlanes) {
+      return fPlanes[i_plane];
+    }
+    return nullptr;
+  }
+
+protected:
   std::vector<THcDriftChamberPlane*> fPlanes; // List of plane objects
   std::vector<THcDriftChamber*> fChambers; // List of chamber objects
 
diff --git a/src/THcHodoscope.cxx b/src/THcHodoscope.cxx
index 1e54a6fe66b4be85c1f0fc43f0b6b83bed3ceef7..92a3f8ce36a83e167ebfdedb316491d001589939 100644
--- a/src/THcHodoscope.cxx
+++ b/src/THcHodoscope.cxx
@@ -36,12 +36,16 @@ hodoscope array, not just one plane.
 #include "THaTrackProj.h"
 #include <vector>
 
+#include <algorithm>
 #include <cstring>
 #include <cstdio>
 #include <cstdlib>
 #include <iostream>
 #include <iomanip>
 #include <fstream>
+#include <array>
+
+#include "hcana/helpers.hxx"
 
 using namespace std;
 using std::vector;
@@ -1450,23 +1454,18 @@ Int_t THcHodoscope::CoarseProcess( TClonesArray& tracks )
 //
 void THcHodoscope::TrackEffTest(void)
 {
-  Double_t PadLow[4];
-  Double_t PadHigh[4];
+  //Double_t PadLow[4];
+  //Double_t PadHigh[4];
   // assume X planes are 0,2 and Y planes are 1,3
-  PadLow[0]=fxLoScin[0];
-  PadLow[2]=fxLoScin[1];
-  PadLow[1]=fyLoScin[0];
-  PadLow[3]=fyLoScin[1];
-  PadHigh[0]=fxHiScin[0];
-  PadHigh[2]=fxHiScin[1];
-  PadHigh[1]=fyHiScin[0];
-  PadHigh[3]=fyHiScin[1];
-  //
-  Double_t PadPosLo[4];
-  Double_t PadPosHi[4];
+  std::array<int,4> PadLow = {fxLoScin[0], fyLoScin[0], fxLoScin[1], fyLoScin[1]};
+  std::array<int,4> PadHigh = {fxHiScin[0], fyHiScin[0], fxHiScin[1], fyHiScin[1]};
+  
+  std::array<double,4> PadPosLo;
+  std::array<double,4> PadPosHi;
+
   for (Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ){
-    Double_t lowtemp=fPlanes[ip]->GetPosCenter(PadLow[ip]-1)+ fPlanes[ip]->GetPosOffset();
-    Double_t hitemp=fPlanes[ip]->GetPosCenter(PadHigh[ip]-1)+ fPlanes[ip]->GetPosOffset();
+    Double_t lowtemp = fPlanes[ip]->GetPosCenter(PadLow[ip] - 1) + fPlanes[ip]->GetPosOffset();
+    Double_t hitemp  = fPlanes[ip]->GetPosCenter(PadHigh[ip] - 1) + fPlanes[ip]->GetPosOffset();
     if (lowtemp < hitemp) {
       PadPosLo[ip]=lowtemp;
       PadPosHi[ip]=hitemp;
@@ -1476,84 +1475,234 @@ void THcHodoscope::TrackEffTest(void)
     }
   }  
   //
-  const Int_t MaxNClus=5;
-  std::vector<Int_t > iw(MaxNClus,0);
-  std::vector<Double_t > dw(MaxNClus,0);
+  const Int_t           MaxNClus = 5;
+  std::vector<Int_t>    iw(MaxNClus, 0);
+  std::vector<Double_t> dw(MaxNClus, 0);
   for(Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ) {
     fNClust.push_back(0);
     fClustSize.push_back(iw);
     fClustPos.push_back(dw);
   }
+
+  //{
+  //  std::vector<int>  test_vector = {1,2,5,6,7, 9,10, 20};
+  //  auto test_res = hcana::find_discontinuity(test_vector);
+  //  std::cout << " find_discontinuity    test: " << *test_res << "\n";
+  //  std::cout << " count_discontinuities test: " << hcana::count_discontinuities(test_vector)
+  //            << "\n";
+  //  auto cont_ranges  = hcana::get_discontinuities(test_vector);
+  //  int ir = 0;
+  //    std::cout << "ranges: \n";
+  //  for(auto r : cont_ranges) {
+  //    for(auto v = r.first; v< r.second; v++) {
+  //      std::cout << *v << " ";
+  //    }
+  //    std::cout << "\n";
+  //  }
+  //}
+  //{
+  //  std::vector<int>  test_vector = {0,2,4,8,10,12,13, 16,18,20,23};
+  //  auto              test_res    = hcana::find_discontinuity(
+  //      test_vector, [](const int& x1, const int& x2) { return x1 + 2 == x2; });
+  //  std::cout << " find_discontinuity test2: " << *test_res << "\n";
+  //  std::cout << " count_discontinuities test2: "
+  //            << hcana::count_discontinuities(
+  //                   test_vector, [](const int& x1, const int& x2) { return x1 + 2 == x2; })
+  //            << "\n";
+  //}
+
+  using hit_iter = std::vector<THcHodoHit*>::iterator;
+  using HitRangeVector = typename std::vector<std::pair<hit_iter, hit_iter>>;
+  using ClusterPositions = typename std::vector<double>;
+  std::vector<std::vector<THcHodoHit*>> hit_vecs;
+  std::vector<HitRangeVector>           hit_clusters;
+  std::vector<ClusterPositions>         pos_clusters;
+  std::vector<std::vector<int>>         good_clusters;
+  std::array<int,4>                     n_good_clusters;
+  // Loop over each plane
   for (Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ){
+
+    // Get the hit array
     TClonesArray* hodoHits = fPlanes[ip]->GetHits();
-    Int_t prev_padnum=-100;
+
+    // Create vector for good hits.
+    hit_vecs.push_back(std::vector<THcHodoHit*>());
     for (Int_t iphit = 0; iphit < fPlanes[ip]->GetNScinHits(); iphit++ ){
       THcHodoHit *hit = (THcHodoHit*)hodoHits->At(iphit);
-      Int_t padnum  = hit->GetPaddleNumber();
+      // keep only those with "two good times"
       if ( hit->GetTwoGoodTimes() ) {
-	if ( padnum==prev_padnum+1 ) {
-	  fClustSize[ip][fNClust[ip]-1]=fClustSize[ip][fNClust[ip]-1]+1;
-	  fClustPos[ip][fNClust[ip]-1]=fClustPos[ip][fNClust[ip]-1]+fPlanes[ip]->GetPosCenter(padnum-1)+ fPlanes[ip]->GetPosOffset();
-	  //  cout << "Add to cluster  pl = " << ip+1 << " hit = " << iphit << " pad = " << padnum << " clus =  " << fNClust[ip] << " cl size = " << fClustSize[ip][fNClust[ip]-1] << " pos " << fPlanes[ip]->GetPosCenter(padnum-1)+ fPlanes[ip]->GetPosOffset() << endl;
-	} else {
-	  if (fNClust[ip]<MaxNClus) fNClust[ip]++;
-	  fClustSize[ip][fNClust[ip]-1]=1;
-	  fClustPos[ip][fNClust[ip]-1]=fPlanes[ip]->GetPosCenter(padnum-1)+ fPlanes[ip]->GetPosOffset();
-	  //  cout << " New clus pl = " << ip+1 << " hit = " << iphit << " pad = " << padnum << " clus = " << fNClust[ip] << " cl size = " << fClustSize[ip][fNClust[ip]] << " pos " << fPlanes[ip]->GetPosCenter(padnum-1)+ fPlanes[ip]->GetPosOffset() << endl;
-	}
-	prev_padnum=padnum;
+        hit_vecs[ip].push_back(hit);
       }
     }
-  }
-  //
-  Bool_t inside_bound[4]={kFALSE,kFALSE,kFALSE,kFALSE};
-  for(Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ) {	 
-    for(Int_t ic = 0; ic <fNClust[ip] ; ic++ ) {
-      fClustPos[ip][ic]=fClustPos[ip][ic]/fClustSize[ip][ic];
-      inside_bound[ip] = fClustPos[ip][ic]>=PadPosLo[ip] &&  fClustPos[ip][ic]<=PadPosHi[ip];
-      //cout << "plane = " << ip+1 << " Cluster = " << ic+1 << " size = " << fClustSize[ip][ic]<< " pos = " << fClustPos[ip][ic] << " inside = " << inside_bound[ip] << " lo = " << PadPosLo[ip]<< " hi = " << PadPosHi[ip]<< endl;
+
+    // Cluster (group adjacent) hits 
+    if( hit_vecs[ip].size() > 0 ) {
+      auto& hv = hit_vecs[ip];
+      hcana::sort(hv, [](const THcHodoHit* h1, const THcHodoHit* h2) {
+            return h1->GetPaddleNumber() < h2->GetPaddleNumber();
+      });
+
+      // get the clusters for this layer
+      hit_clusters.push_back(
+          hcana::get_discontinuities(hv, [](const THcHodoHit* h1, const THcHodoHit* h2) {
+            return h1->GetPaddleNumber() + 1 == h2->GetPaddleNumber();
+          }));
+    } else {
+      hit_clusters.push_back( HitRangeVector{} );
+    } 
+
+    // Calculate each cluster's mean position (in one coordinate)
+    ClusterPositions clust_positions;
+    std::vector<int> clust_bound;
+    for(auto& r : hit_clusters.back()) {
+      double a_pos  = 0.0;
+      int    n_hit = 0;
+      for(auto chit = r.first; chit < r.second; chit++) {
+        a_pos += fPlanes[ip]->GetPosCenter((*chit)->GetPaddleNumber()-1) + fPlanes[ip]->GetPosOffset();
+        n_hit++;
+      }
+      // take the average position
+      double avg_pos = a_pos / double(n_hit);
+      // Calculate if it is the bound by the upper and lower limits where we expect
+      // full tracks to be reconstructed.
+      int is_bound = int((avg_pos >= PadPosLo[ip]) &&  (avg_pos <= PadPosHi[ip]));
+      clust_bound.push_back(is_bound);
+      if(is_bound) {
+      // we are only interested in clusters positioned inthe "sweet spot"
+        clust_positions.push_back(avg_pos);
+        n_good_clusters[ip]++;
+        if (n_hit > 10) {
+          _logger->warn("cluster in hodoscope track efficiency has {} hits", n_hit);
+        }
+      }
     }
+    pos_clusters.push_back(clust_positions);
+    good_clusters.push_back(clust_bound);
+    //_logger->info("{} clusters in Hod plane {}", hit_clusters.back().size(), ip );
   }
-  //
-  Int_t good_for_track_test[4]={0,0,0,0};
-  Int_t sum_good_track_test=0;
-  for(Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ) {
-    if (fNClust[ip]==1 && inside_bound[ip] && fClustSize[ip][0]<=2) good_for_track_test[ip]=1;
-    //cout << " good for track = " << good_for_track_test[ip] << endl;
-    sum_good_track_test+=good_for_track_test[ip];
-  }	 
-  //
-  Double_t trackeff_scint_ydiff_max= 10. ;
-  Double_t trackeff_scint_xdiff_max= 10. ;
-  Bool_t xdiffTest=kFALSE;
-  Bool_t ydiffTest=kFALSE;
-  fGoodScinHits = 0;
-  if (fTrackEffTestNScinPlanes == 4) {
-    if (fTrackEffTestNScinPlanes==sum_good_track_test) {
-      xdiffTest= TMath::Abs(fClustPos[0][0]-fClustPos[2][0])<trackeff_scint_xdiff_max;
-      ydiffTest= TMath::Abs(fClustPos[1][0]-fClustPos[3][0])<trackeff_scint_ydiff_max;
-      if (xdiffTest && ydiffTest) fGoodScinHits = 1;
+
+  bool has_both_x_clusters          = (n_good_clusters[0] > 0) && (n_good_clusters[2] > 0);
+  bool has_both_y_clusters          = (n_good_clusters[1] > 0) && (n_good_clusters[3] > 0);
+  bool at_least_one_good_x_clusters = (n_good_clusters[0] > 0) || (n_good_clusters[2] > 0);
+  bool at_least_one_good_y_clusters = (n_good_clusters[1] > 0) || (n_good_clusters[3] > 0);
+  bool good_x_match = false;
+  bool good_y_match = false;
+
+  // Superficial matching. Find out if clusters in front and back could possibly belong to the same
+  // track. This done by checking to see if the position differences  are less than 10 cm;
+  // ie, |x1-x2|<10  or |y1-y2| <10
+  // TODO do actual matching with tracks elsewhere
+  if(has_both_x_clusters) {
+    for(auto x1_pos : pos_clusters[0] ) {
+      for(auto x2_pos : pos_clusters[2] ) {
+        if( std::abs(x1_pos-x2_pos) < 10.0) {
+          good_x_match = true;
+          break;
+        }
+      }
     }
   }
-  //
-  if (fTrackEffTestNScinPlanes == 3) {
-    if (fTrackEffTestNScinPlanes==sum_good_track_test) {
-      if(good_for_track_test[0]==1&&good_for_track_test[2]==1) {
-	xdiffTest= TMath::Abs(fClustPos[0][0]-fClustPos[2][0])<trackeff_scint_xdiff_max;
-	ydiffTest=kTRUE;
-      }
-      if (good_for_track_test[1]==1&&good_for_track_test[3]==1) {
-	xdiffTest=kTRUE;
-	ydiffTest= TMath::Abs(fClustPos[1][0]-fClustPos[3][0])<trackeff_scint_ydiff_max;
+  if(has_both_y_clusters) {
+    for(auto y1_pos : pos_clusters[1] ) {
+      for(auto y2_pos : pos_clusters[3] ) {
+        if( std::abs(y1_pos-y2_pos) < 10.0) {
+          good_y_match = true;
+          break;
+        }
       }
-      if (xdiffTest && ydiffTest) fGoodScinHits = 1;
-    }
-    if (sum_good_track_test==4) {
-      xdiffTest= TMath::Abs(fClustPos[0][0]-fClustPos[2][0])<trackeff_scint_xdiff_max;
-      ydiffTest= TMath::Abs(fClustPos[1][0]-fClustPos[3][0])<trackeff_scint_ydiff_max;
-      if (xdiffTest && ydiffTest) fGoodScinHits = 1;
     }
   }
+
+  fGoodScinHits = 0;
+  // (2+2) 4 good hits 
+  if( good_y_match &&  good_x_match )  {
+    fGoodScinHits = 1;
+  }
+  // (2+1) 3 good hits
+  if( at_least_one_good_y_clusters &&  good_x_match )  {
+    fGoodScinHits = 1;
+  }
+  // (1+2) 3 good hits
+  if( at_least_one_good_x_clusters &&  good_y_match )  {
+    fGoodScinHits = 1;
+  }
+
+
+  //for (Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ){
+  //  //std::cout << ip << " " << fPlanes[ip]->GetHits()->GetEntries() << " hits\n" ;
+  //  TClonesArray* hodoHits    = fPlanes[ip]->GetHits();
+  //  Int_t         prev_padnum = -100;
+
+  //  for (Int_t iphit = 0; iphit < fPlanes[ip]->GetNScinHits(); iphit++ ){
+  //    THcHodoHit *hit = (THcHodoHit*)hodoHits->At(iphit);
+  //    Int_t padnum  = hit->GetPaddleNumber();
+  //    if ( hit->GetTwoGoodTimes() ) {
+  //      if ( padnum==prev_padnum+1 ) {
+  //        fClustSize[ip][fNClust[ip]-1]=fClustSize[ip][fNClust[ip]-1]+1;
+  //        fClustPos[ip][fNClust[ip]-1]=fClustPos[ip][fNClust[ip]-1]+fPlanes[ip]->GetPosCenter(padnum-1)+ fPlanes[ip]->GetPosOffset();
+  //        //  cout << "Add to cluster  pl = " << ip+1 << " hit = " << iphit << " pad = " << padnum << " clus =  " << fNClust[ip] << " cl size = " << fClustSize[ip][fNClust[ip]-1] << " pos " << fPlanes[ip]->GetPosCenter(padnum-1)+ fPlanes[ip]->GetPosOffset() << endl;
+  //      } else {
+  //        if (fNClust[ip]<MaxNClus) fNClust[ip]++;
+  //        fClustSize[ip][fNClust[ip]-1]=1;
+  //        fClustPos[ip][fNClust[ip]-1]=fPlanes[ip]->GetPosCenter(padnum-1)+ fPlanes[ip]->GetPosOffset();
+  //        //  cout << " New clus pl = " << ip+1 << " hit = " << iphit << " pad = " << padnum << " clus = " << fNClust[ip] << " cl size = " << fClustSize[ip][fNClust[ip]] << " pos " << fPlanes[ip]->GetPosCenter(padnum-1)+ fPlanes[ip]->GetPosOffset() << endl;
+  //      }
+  //      prev_padnum=padnum;
+  //    }
+  //  }
+  //}
+  //
+  //Bool_t inside_bound[4]={kFALSE,kFALSE,kFALSE,kFALSE};
+  //for(Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ) {	 
+  //  for(Int_t ic = 0; ic <fNClust[ip] ; ic++ ) {
+  //    fClustPos[ip][ic]=fClustPos[ip][ic]/fClustSize[ip][ic];
+  //    inside_bound[ip] = fClustPos[ip][ic]>=PadPosLo[ip] &&  fClustPos[ip][ic]<=PadPosHi[ip];
+  //    //cout << "plane = " << ip+1 << " Cluster = " << ic+1 << " size = " << fClustSize[ip][ic]<< " pos = " << fClustPos[ip][ic] << " inside = " << inside_bound[ip] << " lo = " << PadPosLo[ip]<< " hi = " << PadPosHi[ip]<< endl;
+  //  }
+  //}
+  //
+  //std::array<int,4> good_for_track_test = {0,0,0,0};
+  //Int_t sum_good_track_test=0;
+  //for(Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ) {
+  //  if (fNClust[ip]==1 && inside_bound[ip] && fClustSize[ip][0]<=2) good_for_track_test[ip]=1;
+  //  //cout << " good for track = " << good_for_track_test[ip] << endl;
+  //  sum_good_track_test+=good_for_track_test[ip];
+  //}	 
+
+  // these should be input parameters
+  //Double_t trackeff_scint_ydiff_max= 10. ;
+  //Double_t trackeff_scint_xdiff_max= 10. ;
+
+  //Bool_t xdiffTest=kFALSE;
+  //Bool_t ydiffTest=kFALSE;
+
+  //fGoodScinHits = 0;
+  //if (fTrackEffTestNScinPlanes == 4) {
+  //  if (fTrackEffTestNScinPlanes==sum_good_track_test) {
+  //    xdiffTest= TMath::Abs(fClustPos[0][0]-fClustPos[2][0])<trackeff_scint_xdiff_max;
+  //    ydiffTest= TMath::Abs(fClustPos[1][0]-fClustPos[3][0])<trackeff_scint_ydiff_max;
+  //    if (xdiffTest && ydiffTest) fGoodScinHits = 1;
+  //  }
+  //}
+  ////
+  //if (fTrackEffTestNScinPlanes == 3) {
+  //  if (fTrackEffTestNScinPlanes==sum_good_track_test) {
+  //    if(good_for_track_test[0]==1&&good_for_track_test[2]==1) {
+  //      xdiffTest= TMath::Abs(fClustPos[0][0]-fClustPos[2][0])<trackeff_scint_xdiff_max;
+  //      ydiffTest=kTRUE;
+  //    }
+  //    if (good_for_track_test[1]==1&&good_for_track_test[3]==1) {
+  //      xdiffTest=kTRUE;
+  //      ydiffTest= TMath::Abs(fClustPos[1][0]-fClustPos[3][0])<trackeff_scint_ydiff_max;
+  //    }
+  //    if (xdiffTest && ydiffTest) fGoodScinHits = 1;
+  //  }
+  //  if (sum_good_track_test==4) {
+  //    xdiffTest= TMath::Abs(fClustPos[0][0]-fClustPos[2][0])<trackeff_scint_xdiff_max;
+  //    ydiffTest= TMath::Abs(fClustPos[1][0]-fClustPos[3][0])<trackeff_scint_ydiff_max;
+  //    if (xdiffTest && ydiffTest) fGoodScinHits = 1;
+  //  }
+  //}
   //       
   //	cout << " good scin = " << fGoodScinHits << " " << sum_good_track_test << " " << xdiffTest  << " " << ydiffTest<< endl;
   //cout << " ************" << endl;
diff --git a/src/THcHodoscope.h b/src/THcHodoscope.h
index 10e9861240827b41e5306d1827272dd3b587bf4f..af69735f31aefc615043adac1fe2f1f6c207c837 100644
--- a/src/THcHodoscope.h
+++ b/src/THcHodoscope.h
@@ -135,8 +135,16 @@ public:
   friend class THaScCalib;
 
   THcHodoscope();  // for ROOT I/O
+
+  Int_t        fGoodScinHits = 0; // Used to indicate hodoscope had good hits that can be used for defining efficiencies
+
 protected:
 
+
+  // TODO: clean up this class
+  // Way too many data members!!!!!
+  // Get rid of junk!
+
   THcCherenkov* fCherenkov;
 
   Int_t fTDC_RefTimeCut;
@@ -223,8 +231,6 @@ protected:
   TClonesArray*  fTrackProj;  // projection of track onto scintillator plane
                               // and estimated match to TOF paddle
 
-  //--------------------------   Ahmed   -----------------------------
-
 
   Int_t        fCheckEvent;
   Int_t        fEventType;
@@ -247,7 +253,6 @@ protected:
   Int_t        fdebugprintscinraw;
   Int_t        fTestSum;
   Int_t        fTrackEffTestNScinPlanes;
-  Int_t        fGoodScinHits;
   Int_t*       fxLoScin;
   Int_t*       fxHiScin;
   Int_t*       fyLoScin;