diff --git a/Makefile b/Makefile
index fadfb2944800f96524642667e412b4977efa1e24..422e44b8456bc4d1847309026d5fb6da4dcf2d4b 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,8 @@ SRC  =  src/THcInterface.cxx src/THcParmList.cxx src/THcAnalyzer.cxx \
 	src/THcSignalHit.cxx \
 	src/THcHodoscope.cxx src/THcScintillatorPlane.cxx \
 	src/THcHodoscopeHit.cxx \
-	src/THcDriftChamber.cxx src/THcDriftChamberPlane.cxx \
+	src/THcDC.cxx src/THcDriftChamberPlane.cxx \
+	src/THcDriftChamber.cxx \
 	src/THcRawDCHit.cxx src/THcDCHit.cxx \
 	src/THcDCWire.cxx \
 	src/THcDCLookupTTDConv.cxx src/THcDCTimeToDistConv.cxx \
diff --git a/examples/PARAM/hcana.param b/examples/PARAM/hcana.param
index d7f6f97b403c0daeace562384cbacb2285482767..61d60c67416cd2b92a6e69416e20b1281f30689b 100644
--- a/examples/PARAM/hcana.param
+++ b/examples/PARAM/hcana.param
@@ -14,3 +14,4 @@ hdc_plane_names = "1x1 1y1 1u1 1v1 1y2 1x2 2x1 2y1 2u1 2v1 2y2 2x2"
 
 hcal_layer_names = "1pr 2ta 3ta 4ta"
 
+hhodo_plane_names = "1x 1y 2x 2y"
diff --git a/examples/PARAM/hhodo.param b/examples/PARAM/hhodo.param
index 8a4ba606916588424553151b44d4ccb199bea081..4b7fcf89a862e88c022473c458f697227bee964c 100644
--- a/examples/PARAM/hhodo.param
+++ b/examples/PARAM/hhodo.param
@@ -11,7 +11,7 @@
 ; new variable for picking good hits for tof fitting
 ; this should not be set tight until you are ready to fit
 ; tof and you figured out good values
-htof_tolerance = 50.0
+   htof_tolerance = 3.0
 ;                                                                               
 ; hms_tof_params                                                                
 ; hnum_scin_counters, hhodo_zpos, hhodo_center_coord, hhodo_width               
@@ -127,38 +127,38 @@ htof_tolerance = 50.0
 ; csa 9/8/98 -- I had to hand-twaddle a few of the values                       
 ; based on (relative) offsets of older hhodo.param                              
                                                                                 
-hhodo_pos_time_offset =   5.5391,   0.0000,  -6.8586,   5.1830
-                         -1.2985,  -0.2551,   0.3953,   8.9369
-                          5.0531,   1.4333,  -6.5520,   8.0628
-                          5.5481,  -0.3965,  -3.6470,  12.8933
-                          1.2416,  -7.0707,   9.6246,  10.0208
-                          1.9282,  -0.9275,  -4.1448,   8.2112
-                          6.4910,  -1.5780,   1.8980,   9.6928
-                          4.4770,   1.7009,  -3.8385,   4.7545
-                          2.7533,  -2.7182,  -5.8864,   6.3882
-                          4.3398,   6.1158,  -0.3572,  -0.4308
-                          6.0782,   0.0000,  -7.5343,   0.0000
-                          5.4665,   0.0000,   0.2169,   0.0000
-                          4.1334,   0.0000,   1.3767,   0.0000
-                          1.6088,   0.0000,   2.5930,   0.0000
-                          3.9776,   0.0000,  -5.0340,   0.0000
-                          1.6534,   0.0000,   1.5043,   0.0000
-hhodo_neg_time_offset =  -2.5728,   0.0000,   2.8982,  10.8670
-                         -1.9187,  -2.6479,  10.6272,  13.8790
-                         -4.1126,  -4.5084,   3.9705,  15.5799
-                          0.7699,  -2.3908,  11.7183,  15.1612
-                         -1.2568,  -5.0343,   2.9473,  10.6625
-                         -2.8197,   0.7670,  10.3919,   7.8739
-                          1.2798,  -3.9185,   4.3248,  11.3533
-                         -4.8009,  -0.2453,   9.2837,  11.6355
-                         -6.3004,  -5.7362,   0.8352,  14.9451
-                          1.8476,   6.1209,  11.9751,  15.7375
-                          0.3913,   0.0000,   8.9105,   0.0000
-                         -1.0702,   0.0000,   9.8926,   0.0000
-                         -2.3617,   0.0000,   5.7061,   0.0000
-                         -5.2931,   0.0000,  10.7318,   0.0000
-                          0.0632,   0.0000,   6.6962,   0.0000
-                          6.7208,   0.0000,  13.4108,   0.0000
+hhodo_pos_time_offset =   6.5821,   0.0000,  -6.9727,   4.4189
+                         -1.1011,   0.1270,   0.1930,   8.2907
+                          5.5928,   1.2312,  -7.0087,   8.3756
+                          5.3494,  -0.2264,  -3.9023,  13.4700
+                          1.6938,  -7.1708,   9.2976,   9.9767
+                          1.7531,  -0.9044,  -4.6540,   7.8608
+                          6.9700,  -1.5083,   1.7866,   8.6117
+                          3.3819,   1.8281,  -4.2414,   4.3756
+                          3.4984,  -2.5534,  -6.0882,   5.4043
+                          4.5793,   6.1158,  -0.5954,  -1.3631
+                          6.8272,   0.0000,  -7.6493,  32.1266
+                          5.4571,   2.0212,   0.2085,   0.0000
+                          5.0147,   2.0219,   1.1072,  32.0001
+                          1.4959,   0.0000,   2.4523,   0.0000
+                          6.2602,   0.0000,  -5.1102,  -1.9990
+                          1.6534,   0.0000,   1.2513,   0.0000
+hhodo_neg_time_offset =  -2.4664,   0.0000,   4.1095,  11.9016
+                         -2.0589,  -2.5527,  10.4536,  13.4114
+                         -4.2564,  -3.8944,   3.8712,  15.4475
+                          0.3935,  -2.2300,  11.5590,  14.8406
+                         -1.7111,  -4.8155,   2.8606,  10.2379
+                         -3.0792,   0.6972,  10.1887,   7.8083
+                          1.0046,  -3.6839,   4.2680,  10.9969
+                         -5.2801,   0.9309,   9.1779,  11.4677
+                         -6.4931,  -5.5225,   0.7246,  14.8212
+                          1.6218,   6.1209,  11.8919,  15.5699
+                          0.0703,  -1.9990,   8.8625,   2.0216
+                         -1.3146,   0.0000,   9.8650,   0.0000
+                         -2.9002,   0.0000,   5.6735,   0.0000
+                         -5.6444,   0.0000,  10.7529,   0.0000
+                          0.5662,   0.0000,   6.6559,   2.0115
+                          6.7208,   0.0000,  13.4179,  36.7325
 ;                                                                               
 hhodo_pos_ped_limit = 1000,1000,1000,1000,1000,1000,1000,1000                   
                       1000,1000,1000,1000,1000,1000,1000,1000                   
@@ -178,11 +178,9 @@ hhodo_neg_ped_limit = 1000,1000,1000,1000,1000,1000,1000,1000
                       1000,1000,1000,1000,1000,1000,1000,1000                   
                       1000,1000,1000,1000,1000,1000,1000,1000                   
                                                                                 
-
 ; use htofusinginvadc=1 if want invadc_offset
 ;  invadc_linear, and invadc_adc to be used
 htofusinginvadc=1
-
 hhodo_pos_invadc_offset =    0.00,    0.00,   -7.49,    0.00
                              0.00,   -3.93,   -1.33,    6.35
                             -0.47,   -1.79,   -7.92,    6.66
@@ -251,6 +249,7 @@ hhodo_neg_invadc_linear =   50.00,   50.00,   11.14,   50.00
                             26.89,   50.00,   11.54,   50.00
                             50.00,   50.00,   10.51,   50.00
 
+
 hhodo_pos_invadc_adc=     0.00,     0.00,    24.53,     0.00
                          0.00,    85.08,    40.16,    46.66
                        104.72,    90.39,    48.39,    40.45
@@ -284,48 +283,3 @@ hhodo_neg_invadc_adc=     0.00,     0.00,    33.27,     0.00
                         78.19,     0.00,    51.72,     0.00
                         75.03,     0.00,    49.34,     0.00
                          0.00,     0.00,    53.40,     0.00
-
-hhodo_pos_sigma =  100.00,  100.00,    0.92,  100.00
-                   100.00,    0.55,    0.85,    0.80
-                     0.79,    0.58,    0.80,    0.75
-                     0.68,    0.58,    0.65,    0.79
-                     0.73,    0.58,    0.66,    0.79
-                     0.59,    0.58,    0.65,    0.74
-                     0.59,    0.58,    0.53,    0.76
-                     0.61,    0.57,    0.67,    0.80
-                     0.57,    0.59,    0.64,    0.81
-                     0.61,  100.00,    0.64,    0.76
-                     0.67,  100.00,    0.67,  100.00
-                     0.52,  100.00,    0.61,  100.00
-                     0.56,  100.00,    0.62,  100.00
-                     0.61,  100.00,    0.71,  100.00
-                     0.70,  100.00,    0.74,  100.00
-                   100.00,  100.00,    0.66,  100.00
-
-hhodo_neg_sigma =  100.00,  100.00,    0.92,  100.00
-                   100.00,    0.58,    0.82,    0.80
-                     0.74,    0.57,    0.81,    0.81
-                     0.68,    0.58,    0.72,    0.81
-                   100.00,    0.56,    0.68,    0.88
-                     0.61,    0.54,    0.61,    0.76
-                     0.53,    0.55,    0.53,    0.73
-                     0.58,    0.55,    0.65,    0.80
-                     0.61,    0.56,    0.71,    0.87
-                     0.59,  100.00,    0.69,    0.88
-                   100.00,  100.00,    0.65,  100.00
-                     0.57,  100.00,    0.62,  100.00
-                     0.58,  100.00,    0.57,  100.00
-                     0.59,  100.00,    0.64,  100.00
-                     0.57,  100.00,    0.84,  100.00
-                   100.00,  100.00,    0.73,  100.00
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/hodtest.C b/examples/hodtest.C
index 0a7370289f9f293c9faa1c76b3d9a7bb7ac8a568..982e284adffdc261d98dec97cbf39ec5f105b017 100644
--- a/examples/hodtest.C
+++ b/examples/hodtest.C
@@ -38,7 +38,7 @@
   // Add hodoscope
   HMS->AddDetector( new THcHodoscope("hod", "Hodoscope" ));
   HMS->AddDetector( new THcShower("cal", "Shower" ));
-  HMS->AddDetector( new THcDriftChamber("dc", "Drift Chambers" ));
+  HMS->AddDetector( new THcDC("dc", "Drift Chambers" ));
   THcAerogel* aerogel = new THcAerogel("aero", "Aerogel Cerenkov" );
   HMS->AddDetector( aerogel );
 
@@ -63,7 +63,7 @@
 
   // Eventually need to learn to skip over, or properly analyze
   // the pedestal events
-  run->SetEventRange(1,1000000);//  Physics Event number, does not
+  run->SetEventRange(1,2000);//  Physics Event number, does not
                                 // include scaler or control events
 
   // Define the analysis parameters
diff --git a/examples/hodtest_cuts.def b/examples/hodtest_cuts.def
index be6d4297d79edd4e786eed2d543a2f3c064a2342..f6003c2200a18b2f4d7156e51c0250c8b5ce2b06 100644
--- a/examples/hodtest_cuts.def
+++ b/examples/hodtest_cuts.def
@@ -9,3 +9,9 @@ RawDecode_master  1
 Block: Decode
 Decode_master     !Pedestal_event
 
+Block: CoarseTracking
+CoarseTracking_master !Pedestal_event
+
+Block: CoarseReconstruct
+RawCoarseReconstruct !Pedestal_event
+
diff --git a/examples/output.def b/examples/output.def
index 0e282d441984a9b4f648e231783988f941afd4cc..a8fb8536136ab159c7df20d0efdde3af357b6e76 100644
--- a/examples/output.def
+++ b/examples/output.def
@@ -164,3 +164,9 @@ TH1F hdc2v1_dd 'HDC 2V1 Drift Distance' H.dc.2v1.dist 300 -0.1 0.6
 TH1F hdc2y2_dd 'HDC 2Y2 Drift Distance' H.dc.2y2.dist 300 -0.1 0.6
 TH1F hdc2x2_dd 'HDC 2X2 Drift Distance' H.dc.2x2.dist 300 -0.1 0.6
 
+# Focal Plane times
+TH1F hs1xfptime 'HODO s1x fptime' H.hod.1x.fptime 80 0 80 H.hod.hgoodstarttime
+TH1F hs1yfptime 'HODO s1y fptime' H.hod.1y.fptime 80 0 80 H.hod.hgoodstarttime
+TH1F hs2xfptime 'HODO s2x fptime' H.hod.2x.fptime 80 0 80 H.hod.hgoodstarttime
+TH1F hs2yfptime 'HODO s2y fptime' H.hod.2y.fptime 80 0 80 H.hod.hgoodstarttime
+TH1F starttime  'HODO start time' H.hod.starttime 80 0 80 H.hod.hgoodstarttime
diff --git a/src/HallC_LinkDef.h b/src/HallC_LinkDef.h
index 608c0041beef3679cbdce6befbbf801ca61abd6d..ce520fa067dda33b10aebdad9bebadeb2336f719 100644
--- a/src/HallC_LinkDef.h
+++ b/src/HallC_LinkDef.h
@@ -18,6 +18,7 @@
 #pragma link C++ class THcHodoscope+;
 #pragma link C++ class THcScintillatorPlane+;
 #pragma link C++ class THcHodoscopeHit+;
+#pragma link C++ class THcDC+;
 #pragma link C++ class THcDriftChamber+;
 #pragma link C++ class THcDriftChamberPlane+;
 #pragma link C++ class THcRawDCHit+;
diff --git a/src/THcDC.cxx b/src/THcDC.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e79868cd26090cc462a36fdb37b40d3942064365
--- /dev/null
+++ b/src/THcDC.cxx
@@ -0,0 +1,432 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// THcDC                                                              //
+//                                                                           //
+// Class for a generic hodoscope consisting of multiple                      //
+// planes with multiple paddles with phototubes on both ends.                //
+// This differs from Hall A scintillator class in that it is the whole       //
+// hodoscope array, not just one plane.                                      //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "THcDC.h"
+#include "THaEvData.h"
+#include "THaDetMap.h"
+#include "THcDetectorMap.h"
+#include "THcGlobals.h"
+#include "THcParmList.h"
+#include "VarDef.h"
+#include "VarType.h"
+#include "THaTrack.h"
+#include "TClonesArray.h"
+#include "TMath.h"
+
+#include "THaTrackProj.h"
+
+#include <cstring>
+#include <cstdio>
+#include <cstdlib>
+#include <iostream>
+
+using namespace std;
+
+//_____________________________________________________________________________
+THcDC::THcDC(
+ const char* name, const char* description,
+				  THaApparatus* apparatus ) :
+  THaTrackingDetector(name,description,apparatus)
+{
+  // Constructor
+
+  //  fTrackProj = new TClonesArray( "THaTrackProj", 5 );
+  fNPlanes = 0;			// No planes until we make them
+
+}
+
+//_____________________________________________________________________________
+void THcDC::Setup(const char* name, const char* description)
+{
+
+  char prefix[2];
+  char parname[100];
+
+  THaApparatus *app = GetApparatus();
+  if(app) {
+    cout << app->GetName() << endl;
+  } else {
+    cout << "No apparatus found" << endl;
+  }
+
+  prefix[0]=tolower(app->GetName()[0]);
+  prefix[1]='\0';
+
+  string planenamelist;
+  DBRequest list[]={
+    {"dc_num_planes",&fNPlanes, kInt},
+    {"dc_num_chambers",&fNChambers, kInt},
+    {"dc_tdc_time_per_channel",&fNSperChan, kDouble},
+    {"dc_wire_velocity",&fWireVelocity,kDouble},
+    {"dc_plane_names",&planenamelist, kString},
+    {0}
+  };
+
+  gHcParms->LoadParmValues((DBRequest*)&list,prefix);
+  cout << planenamelist << endl;
+  cout << "Drift Chambers: " <<  fNPlanes << " planes in " << fNChambers << " chambers" << endl;
+
+  vector<string> plane_names = vsplit(planenamelist);
+
+  if(plane_names.size() != (UInt_t) fNPlanes) {
+    cout << "ERROR: Number of planes " << fNPlanes << " doesn't agree with number of plane names " << plane_names.size() << endl;
+    // Should quit.  Is there an official way to quit?
+  }
+  fPlaneNames = new char* [fNPlanes];
+  for(Int_t i=0;i<fNPlanes;i++) {
+    fPlaneNames[i] = new char[plane_names[i].length()];
+    strcpy(fPlaneNames[i], plane_names[i].c_str());
+  }
+
+  char *desc = new char[strlen(description)+100];
+  fPlanes = new THcDriftChamberPlane* [fNPlanes];
+
+  for(Int_t i=0;i<fNPlanes;i++) {
+    strcpy(desc, description);
+    strcat(desc, " Plane ");
+    strcat(desc, fPlaneNames[i]);
+
+    fPlanes[i] = new THcDriftChamberPlane(fPlaneNames[i], desc, i+1, this);
+    cout << "Created Drift Chamber Plane " << fPlaneNames[i] << ", " << desc << endl;
+
+  }
+  fChambers = new THcDriftChamber* [fNChambers];
+  for(Int_t i=0;i<fNChambers;i++) {
+    sprintf(desc,"%s Chamber %d",description, i+1);
+
+    // Should construct a better chamber name
+    fChambers[i] = new THcDriftChamber(desc, desc, i+1, this);
+    cout << "Created Drift Chamber " << i+1 << ", " << desc << endl;
+    
+    
+  }
+}
+
+//_____________________________________________________________________________
+THcDC::THcDC( ) :
+  THaTrackingDetector()
+{
+  // Constructor
+}
+
+//_____________________________________________________________________________
+THaAnalysisObject::EStatus THcDC::Init( const TDatime& date )
+{
+  static const char* const here = "Init()";
+
+  Setup(GetName(), GetTitle());	// Create the subdetectors here
+  
+  // Should probably put this in ReadDatabase as we will know the
+  // maximum number of hits after setting up the detector map
+  THcHitList::InitHitList(fDetMap, "THcRawDCHit", 1000);
+
+  EStatus status;
+  // This triggers call of ReadDatabase and DefineVariables
+  if( (status = THaTrackingDetector::Init( date )) )
+    return fStatus=status;
+
+  // Initialize planes and add them to chambers
+  for(Int_t ip=0;ip<fNPlanes;ip++) {
+    if((status = fPlanes[ip]->Init( date ))) {
+      return fStatus=status;
+    } else {
+      Int_t chamber=fNChamber[ip];
+      fChambers[chamber-1]->AddPlane(fPlanes[ip]);
+    }
+  }
+  // Initialize chambers
+  for(Int_t ic=0;ic<fNChambers;ic++) {
+    if((status = fChambers[ic]->Init ( date ))) {
+      return fStatus=status;
+    }
+  }
+
+  // Replace with what we need for Hall C
+  //  const DataDest tmp[NDEST] = {
+  //    { &fRTNhit, &fRANhit, fRT, fRT_c, fRA, fRA_p, fRA_c, fROff, fRPed, fRGain },
+  //    { &fLTNhit, &fLANhit, fLT, fLT_c, fLA, fLA_p, fLA_c, fLOff, fLPed, fLGain }
+  //  };
+  //  memcpy( fDataDest, tmp, NDEST*sizeof(DataDest) );
+
+  // Will need to determine which apparatus it belongs to and use the
+  // appropriate detector ID in the FillMap call
+  char EngineDID[4];
+
+  EngineDID[0] = toupper(GetApparatus()->GetName()[0]);
+  EngineDID[1] = 'D';
+  EngineDID[2] = 'C';
+  EngineDID[3] = '\0';
+  
+  if( gHcDetectorMap->FillMap(fDetMap, EngineDID) < 0 ) {
+    Error( Here(here), "Error filling detectormap for %s.", 
+	     EngineDID);
+      return kInitError;
+  }
+
+  return fStatus = kOK;
+}
+
+//_____________________________________________________________________________
+Int_t THcDC::ReadDatabase( const TDatime& date )
+{
+  // Read this detector's parameters from the database file 'fi'.
+  // This function is called by THaDetectorBase::Init() once at the
+  // beginning of the analysis.
+  // 'date' contains the date/time of the run being analyzed.
+
+  //  static const char* const here = "ReadDatabase()";
+  char prefix[2];
+  char parname[100];
+
+  // Read data from database 
+  // Pull values from the THcParmList instead of reading a database
+  // file like Hall A does.
+
+  // We will probably want to add some kind of method to gHcParms to allow
+  // bulk retrieval of parameters of interest.
+
+  // Will need to determine which spectrometer in order to construct
+  // the parameter names (e.g. hscin_1x_nr vs. sscin_1x_nr)
+
+  prefix[0]=tolower(GetApparatus()->GetName()[0]);
+
+  prefix[1]='\0';
+
+  fXCenter = new Double_t [fNChambers];
+  fYCenter = new Double_t [fNChambers];
+  fMinHits = new Int_t [fNChambers];
+  fMaxHits = new Int_t [fNChambers];
+  fMinCombos = new Int_t [fNChambers];
+  fSpace_Point_Criterion2 = new Double_t [fNChambers];
+
+  fTdcWinMin = new Int_t [fNPlanes];
+  fTdcWinMax = new Int_t [fNPlanes];
+  fCentralTime = new Int_t [fNPlanes];
+  fNWires = new Int_t [fNPlanes];
+  fNChamber = new Int_t [fNPlanes]; // Which chamber is this plane
+  fWireOrder = new Int_t [fNPlanes]; // Wire readout order
+  fDriftTimeSign = new Int_t [fNPlanes];
+
+  fZPos = new Double_t [fNPlanes];
+  fAlphaAngle = new Double_t [fNPlanes];
+  fBetaAngle = new Double_t [fNPlanes];
+  fGammaAngle = new Double_t [fNPlanes];
+  fPitch = new Double_t [fNPlanes];
+  fCentralWire = new Double_t [fNPlanes];
+  fPlaneTimeZero = new Double_t [fNPlanes];
+  fSigma = new Double_t [fNPlanes];
+
+  DBRequest list[]={
+    {"dc_tdc_time_per_channel",&fNSperChan, kDouble},
+    {"dc_wire_velocity",&fWireVelocity,kDouble},
+
+    {"dc_xcenter", fXCenter, kDouble, fNChambers},
+    {"dc_ycenter", fYCenter, kDouble, fNChambers},
+    {"min_hit", fMinHits, kInt, fNChambers},
+    {"max_pr_hits", fMaxHits, kInt, fNChambers},
+    {"min_combos", fMinCombos, kInt, fNChambers},
+    {"space_point_criterion", fSpace_Point_Criterion2, kDouble, fNChambers},
+
+    {"dc_tdc_min_win", fTdcWinMin, kInt, fNPlanes},
+    {"dc_tdc_max_win", fTdcWinMax, kInt, fNPlanes},
+    {"dc_central_time", fCentralTime, kInt, fNPlanes},
+    {"dc_nrwire", fNWires, kInt, fNPlanes},
+    {"dc_chamber_planes", fNChamber, kInt, fNPlanes},
+    {"dc_wire_counting", fWireOrder, kInt, fNPlanes},
+    {"dc_drifttime_sign", fDriftTimeSign, kInt, fNPlanes},
+
+    {"dc_zpos", fZPos, kDouble, fNPlanes},
+    {"dc_alpha_angle", fAlphaAngle, kDouble, fNPlanes},
+    {"dc_beta_angle", fBetaAngle, kDouble, fNPlanes},
+    {"dc_gamma_angle", fGammaAngle, kDouble, fNPlanes},
+    {"dc_pitch", fPitch, kDouble, fNPlanes},
+    {"dc_central_wire", fCentralWire, kDouble, fNPlanes},
+    {"dc_plane_time_zero", fPlaneTimeZero, kDouble, fNPlanes},
+    {"dc_sigma", fSigma, kDouble, fNPlanes},
+    {0}
+  };
+  gHcParms->LoadParmValues((DBRequest*)&list,prefix);
+
+  cout << "Plane counts:";
+  for(Int_t i=0;i<fNPlanes;i++) {
+    cout << " " << fNWires[i];
+  }
+  cout << endl;
+
+  fIsInit = true;
+
+  return kOK;
+}
+
+//_____________________________________________________________________________
+Int_t THcDC::DefineVariables( EMode mode )
+{
+  // Initialize global variables and lookup table for decoder
+
+  if( mode == kDefine && fIsSetup ) return kOK;
+  fIsSetup = ( mode == kDefine );
+
+  // Register variables in global list
+
+  RVarDef vars[] = {
+    { "nhit", "Number of DC hits",  "fNhits" },
+    { 0 }
+  };
+  return DefineVarsFromList( vars, mode );
+
+}
+
+//_____________________________________________________________________________
+THcDC::~THcDC()
+{
+  // Destructor. Remove variables from global list.
+
+  if( fIsSetup )
+    RemoveVariables();
+  if( fIsInit )
+    DeleteArrays();
+  if (fTrackProj) {
+    fTrackProj->Clear();
+    delete fTrackProj; fTrackProj = 0;
+  }
+}
+
+//_____________________________________________________________________________
+void THcDC::DeleteArrays()
+{
+  // Delete member arrays. Used by destructor.
+
+  delete [] fNWires;  fNWires = NULL;
+  //  delete [] fSpacing;  fSpacing = NULL;
+  //  delete [] fCenter;   fCenter = NULL; // This 2D. What is correct way to delete?
+
+  //  delete [] fRA_c;    fRA_c    = NULL;
+  //  delete [] fRA_p;    fRA_p    = NULL;
+  //  delete [] fRA;      fRA      = NULL;
+  //  delete [] fLA_c;    fLA_c    = NULL;
+  //  delete [] fLA_p;    fLA_p    = NULL;
+  //  delete [] fLA;      fLA      = NULL;
+  //  delete [] fRT_c;    fRT_c    = NULL;
+  //  delete [] fRT;      fRT      = NULL;
+  //  delete [] fLT_c;    fLT_c    = NULL;
+  //  delete [] fLT;      fLT      = NULL;
+  
+  //  delete [] fRGain;   fRGain   = NULL;
+  //  delete [] fLGain;   fLGain   = NULL;
+  //  delete [] fRPed;    fRPed    = NULL;
+  //  delete [] fLPed;    fLPed    = NULL;
+  //  delete [] fROff;    fROff    = NULL;
+  //  delete [] fLOff;    fLOff    = NULL;
+  //  delete [] fTWalkPar; fTWalkPar = NULL;
+  //  delete [] fTrigOff; fTrigOff = NULL;
+
+  //  delete [] fHitPad;  fHitPad  = NULL;
+  //  delete [] fTime;    fTime    = NULL;
+  //  delete [] fdTime;   fdTime   = NULL;
+  //  delete [] fYt;      fYt      = NULL;
+  //  delete [] fYa;      fYa      = NULL;
+}
+
+//_____________________________________________________________________________
+inline 
+void THcDC::ClearEvent()
+{
+  // Reset per-event data.
+  fNhits = 0;
+
+  for(Int_t i=0;i<fNChambers;i++) {
+    fChambers[i]->Clear();
+  }
+
+  
+  //  fTrackProj->Clear();
+}
+
+//_____________________________________________________________________________
+Int_t THcDC::Decode( const THaEvData& evdata )
+{
+
+  ClearEvent();
+
+  // Get the Hall C style hitlist (fRawHitList) for this event
+  fNhits = THcHitList::DecodeToHitList(evdata);
+
+  // Let each plane get its hits
+  Int_t nexthit = 0;
+  for(Int_t ip=0;ip<fNPlanes;ip++) {
+    nexthit = fPlanes[ip]->ProcessHits(fRawHitList, nexthit);
+  }
+
+  // Let each chamber get its hits
+  for(Int_t ic=0;ic<fNChambers;ic++) {
+    fChambers[ic]->ProcessHits();
+  }
+#if 0
+  // fRawHitList is TClones array of THcRawDCHit objects
+  for(Int_t ihit = 0; ihit < fNRawHits ; ihit++) {
+    THcRawDCHit* hit = (THcRawDCHit *) fRawHitList->At(ihit);
+    //    cout << ihit << " : " << hit->fPlane << ":" << hit->fCounter << " : "
+    //	 << endl;
+    for(Int_t imhit = 0; imhit < hit->fNHits; imhit++) {
+      //      cout << "                     " << imhit << " " << hit->fTDC[imhit]
+      //	   << endl;
+    }
+  }
+  //  cout << endl;
+#endif
+
+  return fNhits;
+}
+
+//_____________________________________________________________________________
+Int_t THcDC::ApplyCorrections( void )
+{
+  return(0);
+}
+
+//_____________________________________________________________________________
+Int_t THcDC::CoarseTrack( TClonesArray& /* tracks */ )
+{
+  // Calculation of coordinates of particle track cross point with scint
+  // plane in the detector coordinate system. For this, parameters of track 
+  // reconstructed in THaVDC::CoarseTrack() are used.
+  //
+  // Apply corrections and reconstruct the complete hits.
+  //
+  //  static const Double_t sqrt2 = TMath::Sqrt(2.);
+  for(Int_t i=0;i<fNChambers;i++) {
+
+    fChambers[i]->FindSpacePoints();
+    fChambers[i]->CorrectHitTimes();
+  }
+
+  ApplyCorrections();
+
+  return 0;
+}
+
+//_____________________________________________________________________________
+Int_t THcDC::FineTrack( TClonesArray& tracks )
+{
+  // Reconstruct coordinates of particle track cross point with scintillator
+  // plane, and copy the data into the following local data structure:
+  //
+  // Units of measurements are meters.
+
+  // Calculation of coordinates of particle track cross point with scint
+  // plane in the detector coordinate system. For this, parameters of track 
+  // reconstructed in THaVDC::FineTrack() are used.
+
+  return 0;
+}
+
+ClassImp(THcDC)
+////////////////////////////////////////////////////////////////////////////////
diff --git a/src/THcDC.h b/src/THcDC.h
new file mode 100644
index 0000000000000000000000000000000000000000..7a69711388ef1c5685a7dd47174e4060e39868ce
--- /dev/null
+++ b/src/THcDC.h
@@ -0,0 +1,150 @@
+#ifndef ROOT_THcDC
+#define ROOT_THcDC
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// THcDC                                                           //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "THaTrackingDetector.h"
+#include "THcHitList.h"
+#include "THcRawDCHit.h"
+#include "THcDriftChamberPlane.h"
+#include "THcDriftChamber.h"
+#include "TMath.h"
+
+//class THaScCalib;
+class TClonesArray;
+
+class THcDC : public THaTrackingDetector, public THcHitList {
+
+public:
+  THcDC( const char* name, const char* description = "",
+		   THaApparatus* a = NULL );
+  virtual ~THcDC();
+
+  virtual Int_t      Decode( const THaEvData& );
+  virtual EStatus    Init( const TDatime& run_time );
+  virtual Int_t      CoarseTrack( TClonesArray& tracks );
+  virtual Int_t      FineTrack( TClonesArray& tracks );
+  
+  virtual Int_t      ApplyCorrections( void );
+
+  //  Int_t GetNHits() const { return fNhit; }
+  
+  Int_t GetNTracks() const { return fTrackProj->GetLast()+1; }
+  const TClonesArray* GetTrackHits() const { return fTrackProj; }
+
+  Int_t GetNWires(Int_t plane) const { return fNWires[plane-1];}
+  Int_t GetNChamber(Int_t plane) const { return fNChamber[plane-1];}
+  Int_t GetWireOrder(Int_t plane) const { return fWireOrder[plane-1];}
+  Int_t GetPitch(Int_t plane) const { return fPitch[plane-1];}
+  Int_t GetCentralWire(Int_t plane) const { return fCentralWire[plane-1];}
+  Int_t GetTdcWinMin(Int_t plane) const { return fTdcWinMin[plane-1];}
+  Int_t GetTdcWinMax(Int_t plane) const { return fTdcWinMax[plane-1];}
+
+  Double_t GetZPos(Int_t plane) const { return fZPos[plane-1];}
+  Double_t GetAlphaAngle(Int_t plane) const { return fAlphaAngle[plane-1];}
+  Double_t GetBetaAngle(Int_t plane) const { return fBetaAngle[plane-1];}
+  Double_t GetGammaAngle(Int_t plane) const { return fGammaAngle[plane-1];}
+
+  Int_t GetMinHits(Int_t chamber) const { return fMinHits[chamber-1];}
+  Int_t GetMaxHits(Int_t chamber) const { return fMaxHits[chamber-1];}
+  Int_t GetMinCombos(Int_t chamber) const { return fMinCombos[chamber-1];}
+  Double_t GetSpacePointCriterion(Int_t chamber) const { return TMath::Sqrt(fSpace_Point_Criterion2[chamber-1]);}
+  Double_t GetCentralTime(Int_t plane) const { return fCentralTime[plane-1];}
+  Int_t GetDriftTimeSign(Int_t plane) const { return fDriftTimeSign[plane-1];}
+
+  Double_t GetPlaneTimeZero(Int_t plane) const { return fPlaneTimeZero[plane-1];}
+  Double_t GetSigma(Int_t plane) const { return fSigma[plane-1];}
+
+  Double_t GetNSperChan() const { return fNSperChan;}
+
+  Double_t GetCenter(Int_t plane) const {
+    Int_t chamber = GetNChamber(plane)-1;
+    return
+      fXCenter[chamber]*sin(fAlphaAngle[plane-1]) +
+      fYCenter[chamber]*cos(fAlphaAngle[plane-1]);
+  }
+  //  friend class THaScCalib;
+
+  THcDC();  // for ROOT I/O
+protected:
+
+  // Calibration
+
+  // Per-event data
+  Int_t fNhits;
+
+  // Potential Hall C parameters.  Mostly here for demonstration
+  Int_t fNPlanes;
+  char** fPlaneNames;
+  Int_t fNChambers;
+
+  Double_t fNSperChan;		/* TDC bin size */
+  Double_t fWireVelocity;
+
+  // Each of these will be dimensioned with the number of chambers
+  Double_t* fXCenter;
+  Double_t* fYCenter;
+  Int_t* fMinHits;
+  Int_t* fMaxHits;
+  Int_t* fMinCombos;
+  Double_t* fSpace_Point_Criterion2;
+
+  // Each of these will be dimensioned with the number of planes
+  // A THcDCPlane class object will need to access the value for
+  // its plane number.  Should we have a Get method for each or 
+  Int_t* fTdcWinMin;
+  Int_t* fTdcWinMax;
+  Int_t* fCentralTime;
+  Int_t* fNWires;		// Number of wires per plane
+  Int_t* fNChamber;
+  Int_t* fWireOrder;
+  Int_t* fDriftTimeSign;
+
+  Double_t* fZPos;
+  Double_t* fAlphaAngle;
+  Double_t* fBetaAngle;
+  Double_t* fGammaAngle;
+  Double_t* fPitch;
+  Double_t* fCentralWire;
+  Double_t* fPlaneTimeZero;
+  Double_t* fSigma;
+
+  THcDriftChamberPlane** fPlanes; // List of plane objects
+  THcDriftChamber** fChambers; // List of chamber objects
+
+  TClonesArray*  fTrackProj;  // projection of track onto scintillator plane
+                              // and estimated match to TOF paddle
+  // Useful derived quantities
+  // double tan_angle, sin_angle, cos_angle;
+  
+  //  static const char NDEST = 2;
+  //  struct DataDest {
+  //    Int_t*    nthit;
+  //    Int_t*    nahit;
+  //    Double_t*  tdc;
+  //    Double_t*  tdc_c;
+  //    Double_t*  adc;
+  //    Double_t*  adc_p;
+  //    Double_t*  adc_c;
+  //    Double_t*  offset;
+  //    Double_t*  ped;
+  //    Double_t*  gain;
+  //  } fDataDest[NDEST];     // Lookup table for decoder
+
+  void           ClearEvent();
+  void           DeleteArrays();
+  virtual Int_t  ReadDatabase( const TDatime& date );
+  virtual Int_t  DefineVariables( EMode mode = kDefine );
+
+  void Setup(const char* name, const char* description);
+
+  ClassDef(THcDC,0)   // Drift Chamber class
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/src/THcDCHit.cxx b/src/THcDCHit.cxx
index 0484b1ad39d1f2d1ee0171dfe0d2f5194f6a0ce0..3b1523c444ce0d4088ab5b422359d7e3d1cfd9ac 100644
--- a/src/THcDCHit.cxx
+++ b/src/THcDCHit.cxx
@@ -9,10 +9,31 @@
 #include "THcDCHit.h"
 #include "THcDCTimeToDistConv.h"
 
+#include <iostream>
+
+using std::cout;
+using std::endl;
+
 ClassImp(THcDCHit)
 
 const Double_t THcDCHit::kBig = 1.e38; // Arbitrary large value
 
+//_____________________________________________________________________________
+void THcDCHit::Print( Option_t* opt ) const
+{
+  // Print hit info
+
+  cout << "Hit: wire=" << GetWireNum()
+       << "/" << (fWirePlane ? fWirePlane->GetName() : "??")
+       << " wpos="     << GetPos()
+       << " time="     << GetTime()
+       << " drift="    << GetDist();
+  //       << " res="      << GetResolution()
+    //       << " z="        << GetZ()
+  if( *opt != 'C' )
+    cout << endl;
+}
+
 //_____________________________________________________________________________
 Double_t THcDCHit::ConvertTimeToDist()
 {
@@ -51,15 +72,17 @@ Int_t THcDCHit::Compare( const TObject* obj ) const
  
   Int_t myWireNum = fWire->GetNum();
   Int_t hitWireNum = hit->GetWire()->GetNum();
-  // Compare wire numbers
+  Int_t myPlaneNum = GetPlaneNum();
+  Int_t hitPlaneNum = hit->GetPlaneNum();
+  if (myPlaneNum < hitPlaneNum) return -1;
+  if (myPlaneNum > hitPlaneNum) return 1;
+  // If planes are the same, compare wire numbers
   if (myWireNum < hitWireNum) return -1;
   if (myWireNum > hitWireNum) return  1;
-  if (myWireNum == hitWireNum) {
-    // If wire numbers are the same, compare times
-    Double_t hitTime = hit->GetTime();
-    if (fTime < hitTime) return -1;
-    if (fTime > hitTime) return  1;
-  }
+  // If wire numbers are the same, compare times
+  Double_t hitTime = hit->GetTime();
+  if (fTime < hitTime) return -1;
+  if (fTime > hitTime) return  1;
   return 0;
 }
 
diff --git a/src/THcDCHit.h b/src/THcDCHit.h
index 79f88e7123f7a8d39d805719e7ce2b74ec831316..e32cc6159bd9590170df39d4ebb15a175aebcec3 100644
--- a/src/THcDCHit.h
+++ b/src/THcDCHit.h
@@ -9,20 +9,26 @@
 
 #include "TObject.h"
 #include "THcDCWire.h"
+#include "THcDriftChamberPlane.h"
+#include "THcDriftChamber.h"
 #include <cstdio>
 
 class THcDCHit : public TObject {
 
 public:
-  THcDCHit( THcDCWire* wire=NULL, Int_t rawtime=0, Double_t time=0.0 ) : 
-    fWire(wire), fRawTime(rawtime), fTime(time), fDist(0.0), ftrDist(kBig) {
+ THcDCHit( THcDCWire* wire=NULL, Int_t rawtime=0, Double_t time=0.0,
+	   THcDriftChamberPlane* wp=0) : 
+  fWire(wire), fRawTime(rawtime), fTime(time), fWirePlane(wp),
+    fDist(0.0), ftrDist(kBig) {
       ConvertTimeToDist();
+      fCorrected = 0;
     }
   virtual ~THcDCHit() {}
 
   virtual Double_t ConvertTimeToDist();
   Int_t  Compare ( const TObject* obj ) const;
   Bool_t IsSortable () const { return kTRUE; }
+  virtual void Print( Option_t* opt="" ) const;
   
   // Get and Set Functions
   THcDCWire* GetWire() const { return fWire; }
@@ -31,24 +37,40 @@ public:
   Double_t GetTime()    const { return fTime; }
   Double_t GetDist()    const { return fDist; }
   Double_t GetPos()     const { return fWire->GetPos(); } //Position of hit wire
+  Double_t GetCoord()   const { return fCoord; }
   Double_t GetdDist()   const { return fdDist; }
+  Int_t    GetCorrectedStatus() const { return fCorrected; }
+
+  THcDriftChamberPlane* GetWirePlane() const { return fWirePlane; }
+  
 
   void     SetWire(THcDCWire * wire) { fWire = wire; }
   void     SetRawTime(Int_t time)     { fRawTime = time; }
   void     SetTime(Double_t time)     { fTime = time; }
   void     SetDist(Double_t dist)     { fDist = dist; }
+  void     SetLeftRight(Int_t lr)   { fCoord = GetPos() + lr*fDist;}
   void     SetdDist(Double_t ddist)   { fdDist = ddist; }
   void     SetFitDist(Double_t dist)  { ftrDist = dist; }
+  Int_t    GetPlaneNum() const { return fWirePlane->GetPlaneNum(); }
+  Int_t    GetPlaneIndex() const { return fWirePlane->GetPlaneIndex(); }
+  Int_t    GetChamberNum() const { return fWirePlane->GetChamberNum(); }
+  void     SetCorrectedStatus(Int_t c) { fCorrected = c; }
   
 protected:
   static const Double_t kBig;  //!
   
-  THcDCWire* fWire;     // Wire on which the hit occurred
+  THcDCWire*  fWire;     // Wire on which the hit occurred
   Int_t       fRawTime;  // TDC value (channels)
   Double_t    fTime;     // Time corrected for time offset of wire (s)
+  THcDriftChamberPlane* fWirePlane; //! Pointer to parent wire plane
   Double_t    fDist;     // (Perpendicular) Drift Distance
+  Double_t    fCoord;    // Actual coordinate of hit
   Double_t    fdDist;    // uncertainty in fDist (for chi2 calc)
   Double_t    ftrDist;   // (Perpendicular) distance from the track
+  Int_t       fCorrected; // Has this hit been corrected?
+
+  THcDriftChamber* fChamber; //! Pointer to parent wire plane
+
   
  private:
   THcDCHit( const THcDCHit& );
diff --git a/src/THcDriftChamber.cxx b/src/THcDriftChamber.cxx
index 1d53b20c58f52e7465596ea9240a58bd1755eb6b..59312b75dd42c826c949ed2d2169f33224831529 100644
--- a/src/THcDriftChamber.cxx
+++ b/src/THcDriftChamber.cxx
@@ -1,18 +1,17 @@
 ///////////////////////////////////////////////////////////////////////////////
 //                                                                           //
-// THcDriftChamber                                                              //
+// THcDriftChamber                                                           //
 //                                                                           //
-// Class for a generic hodoscope consisting of multiple                      //
-// planes with multiple paddles with phototubes on both ends.                //
-// This differs from Hall A scintillator class in that it is the whole       //
-// hodoscope array, not just one plane.                                      //
+// Subdetector class to hold a bunch of planes constituting a chamber        //
+// This class will be created by the THcDC class which will also create      //
+// the plane objects.                                                        //
+// The THcDC class will then pass this class a list of the planes.           //
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "THcDriftChamber.h"
-#include "THaEvData.h"
-#include "THaDetMap.h"
-#include "THcDetectorMap.h"
+#include "THcDC.h"
+#include "THcDCHit.h"
 #include "THcGlobals.h"
 #include "THcParmList.h"
 #include "VarDef.h"
@@ -20,6 +19,7 @@
 #include "THaTrack.h"
 #include "TClonesArray.h"
 #include "TMath.h"
+#include "TVectorD.h"
 
 #include "THaTrackProj.h"
 
@@ -27,20 +27,23 @@
 #include <cstdio>
 #include <cstdlib>
 #include <iostream>
+#include <iomanip>
 
 using namespace std;
 
 //_____________________________________________________________________________
 THcDriftChamber::THcDriftChamber(
  const char* name, const char* description,
-				  THaApparatus* apparatus ) :
-  THaTrackingDetector(name,description,apparatus)
+ const Int_t chambernum, THaDetectorBase* parent ) :
+  THaSubDetector(name,description,parent)
 {
   // Constructor
 
   //  fTrackProj = new TClonesArray( "THaTrackProj", 5 );
   fNPlanes = 0;			// No planes until we make them
 
+  fChamberNum = chambernum;
+
 }
 
 //_____________________________________________________________________________
@@ -48,7 +51,6 @@ void THcDriftChamber::Setup(const char* name, const char* description)
 {
 
   char prefix[2];
-  char parname[100];
 
   THaApparatus *app = GetApparatus();
   if(app) {
@@ -60,181 +62,153 @@ void THcDriftChamber::Setup(const char* name, const char* description)
   prefix[0]=tolower(app->GetName()[0]);
   prefix[1]='\0';
 
-  string planenamelist;
-  DBRequest list[]={
-    {"dc_num_planes",&fNPlanes, kInt},
-    {"dc_num_chambers",&fNChambers, kInt},
-    {"dc_tdc_time_per_channel",&fNSperChan, kDouble},
-    {"dc_wire_velocity",&fWireVelocity,kDouble},
-    {"dc_plane_names",&planenamelist, kString},
-    {0}
-  };
-
-  gHcParms->LoadParmValues((DBRequest*)&list,prefix);
-  cout << planenamelist << endl;
-  cout << "Drift Chambers: " <<  fNPlanes << " planes in " << fNChambers << " chambers" << endl;
-
-  vector<string> plane_names = vsplit(planenamelist);
-
-  if(plane_names.size() != (UInt_t) fNPlanes) {
-    cout << "ERROR: Number of planes " << fNPlanes << " doesn't agree with number of plane names " << plane_names.size() << endl;
-    // Should quit.  Is there an official way to quit?
-  }
-  fPlaneNames = new char* [fNPlanes];
-  for(Int_t i=0;i<fNPlanes;i++) {
-    fPlaneNames[i] = new char[plane_names[i].length()];
-    strcpy(fPlaneNames[i], plane_names[i].c_str());
-  }
-
-  char *desc = new char[strlen(description)+100];
-  fPlanes = new THcDriftChamberPlane* [fNPlanes];
-
-  for(Int_t i=0;i<fNPlanes;i++) {
-    strcpy(desc, description);
-    strcat(desc, " Plane ");
-    strcat(desc, fPlaneNames[i]);
-
-    fPlanes[i] = new THcDriftChamberPlane(fPlaneNames[i], desc, i+1, this);
-    cout << "Created Drift Chamber Plane " << fPlaneNames[i] << ", " << desc << endl;
-
-  }
-    
 }
 
 //_____________________________________________________________________________
 THcDriftChamber::THcDriftChamber( ) :
-  THaTrackingDetector()
+  THaSubDetector()
 {
   // Constructor
 }
 
+//_____________________________________________________________________________
+Int_t THcDriftChamber::Decode( const THaEvData& evdata )
+{
+  cout << "THcDriftChamber::Decode called" << endl;
+  return 0;
+}
+
 //_____________________________________________________________________________
 THaAnalysisObject::EStatus THcDriftChamber::Init( const TDatime& date )
 {
-  static const char* const here = "Init()";
+  //  static const char* const here = "Init()";
 
-  Setup(GetName(), GetTitle());	// Create the subdetectors here
+  Setup(GetName(), GetTitle());
   
-  // Should probably put this in ReadDatabase as we will know the
-  // maximum number of hits after setting up the detector map
-  THcHitList::InitHitList(fDetMap, "THcRawDCHit", 1000);
-
   EStatus status;
   // This triggers call of ReadDatabase and DefineVariables
-  if( (status = THaTrackingDetector::Init( date )) )
+  if( (status = THaSubDetector::Init( date )) )
     return fStatus=status;
 
-  for(Int_t ip=0;ip<fNPlanes;ip++) {
-    if((status = fPlanes[ip]->Init( date ))) {
-      return fStatus=status;
-    }
-  }
-
-  // Replace with what we need for Hall C
-  //  const DataDest tmp[NDEST] = {
-  //    { &fRTNhit, &fRANhit, fRT, fRT_c, fRA, fRA_p, fRA_c, fROff, fRPed, fRGain },
-  //    { &fLTNhit, &fLANhit, fLT, fLT_c, fLA, fLA_p, fLA_c, fLOff, fLPed, fLGain }
-  //  };
-  //  memcpy( fDataDest, tmp, NDEST*sizeof(DataDest) );
-
-  // Will need to determine which apparatus it belongs to and use the
-  // appropriate detector ID in the FillMap call
-  char EngineDID[4];
+  return fStatus = kOK;
+}
 
-  EngineDID[0] = toupper(GetApparatus()->GetName()[0]);
-  EngineDID[1] = 'D';
-  EngineDID[2] = 'C';
-  EngineDID[3] = '\0';
-  
-  if( gHcDetectorMap->FillMap(fDetMap, EngineDID) < 0 ) {
-    Error( Here(here), "Error filling detectormap for %s.", 
-	     EngineDID);
-      return kInitError;
+void THcDriftChamber::AddPlane(THcDriftChamberPlane *plane)
+{
+  cout << "Added plane " << plane->GetPlaneNum() << " to chamber " << fChamberNum << endl;
+  plane->SetPlaneIndex(fNPlanes);
+  fPlanes[fNPlanes] = plane;
+
+  // HMS Specific
+  // Check if this is a Y Plane
+  if(plane->GetPlaneNum() == YPlaneNum) {
+    YPlaneInd = fNPlanes;
+  } else if (plane->GetPlaneNum() == YPlanePNum) {
+    YPlanePInd = fNPlanes;
   }
+  fNPlanes++;
 
-  return fStatus = kOK;
+  return;
 }
 
 //_____________________________________________________________________________
 Int_t THcDriftChamber::ReadDatabase( const TDatime& date )
 {
-  // Read this detector's parameters from the database file 'fi'.
-  // This function is called by THaDetectorBase::Init() once at the
-  // beginning of the analysis.
-  // 'date' contains the date/time of the run being analyzed.
 
-  //  static const char* const here = "ReadDatabase()";
+  cout << "THcDriftChamber::ReadDatabase()" << endl;
   char prefix[2];
-  char parname[100];
-
-  // Read data from database 
-  // Pull values from the THcParmList instead of reading a database
-  // file like Hall A does.
-
-  // We will probably want to add some kind of method to gHcParms to allow
-  // bulk retrieval of parameters of interest.
-
-  // Will need to determine which spectrometer in order to construct
-  // the parameter names (e.g. hscin_1x_nr vs. sscin_1x_nr)
-
   prefix[0]=tolower(GetApparatus()->GetName()[0]);
-
   prefix[1]='\0';
-
-  fXCenter = new Double_t [fNChambers];
-  fYCenter = new Double_t [fNChambers];
-
-  fTdcWinMin = new Int_t [fNPlanes];
-  fTdcWinMax = new Int_t [fNPlanes];
-  fCentralTime = new Int_t [fNPlanes];
-  fNWires = new Int_t [fNPlanes];
-  fNChamber = new Int_t [fNPlanes]; // Which chamber is this plane
-  fWireOrder = new Int_t [fNPlanes]; // Wire readout order
-  fDriftTimeSign = new Int_t [fNPlanes];
-
-  fZPos = new Double_t [fNPlanes];
-  fAlphaAngle = new Double_t [fNPlanes];
-  fBetaAngle = new Double_t [fNPlanes];
-  fGammaAngle = new Double_t [fNPlanes];
-  fPitch = new Double_t [fNPlanes];
-  fCentralWire = new Double_t [fNPlanes];
-  fPlaneTimeZero = new Double_t [fNPlanes];
-
-
   DBRequest list[]={
-    {"dc_tdc_time_per_channel",&fNSperChan, kDouble},
-    {"dc_wire_velocity",&fWireVelocity,kDouble},
-
-    {"dc_xcenter", fXCenter, kDouble, fNChambers},
-    {"dc_ycenter", fYCenter, kDouble, fNChambers},
-
-    {"dc_tdc_min_win", fTdcWinMin, kInt, fNPlanes},
-    {"dc_tdc_max_win", fTdcWinMax, kInt, fNPlanes},
-    {"dc_central_time", fCentralTime, kInt, fNPlanes},
-    {"dc_nrwire", fNWires, kInt, fNPlanes},
-    {"dc_chamber_planes", fNChamber, kInt, fNPlanes},
-    {"dc_wire_counting", fWireOrder, kInt, fNPlanes},
-    {"dc_drifttime_sign", fDriftTimeSign, kInt, fNPlanes},
-
-    {"dc_zpos", fZPos, kDouble, fNPlanes},
-    {"dc_alpha_angle", fAlphaAngle, kDouble, fNPlanes},
-    {"dc_beta_angle", fBetaAngle, kDouble, fNPlanes},
-    {"dc_gamma_angle", fGammaAngle, kDouble, fNPlanes},
-    {"dc_pitch", fPitch, kDouble, fNPlanes},
-    {"dc_central_wire", fCentralWire, kDouble, fNPlanes},
-    {"dc_plane_time_zero", fPlaneTimeZero, kDouble, fNPlanes},
+    {"_remove_sppt_if_one_y_plane",&fRemove_Sppt_If_One_YPlane, kInt},
+    {"dc_wire_velocity", &fWireVelocity, kDouble},
+    {"SmallAngleApprox", &fSmallAngleApprox, kInt},
+    {"stub_max_xpdiff", &fStubMaxXPDiff, kDouble},
     {0}
   };
   gHcParms->LoadParmValues((DBRequest*)&list,prefix);
 
-  cout << "Plane counts:";
-  for(Int_t i=0;i<fNPlanes;i++) {
-    cout << " " << fNWires[i];
+  // Get parameters parent knows about
+  THcDC* fParent;
+  fParent = (THcDC*) GetParent();
+  fMinHits = fParent->GetMinHits(fChamberNum);
+  fMaxHits = fParent->GetMaxHits(fChamberNum);
+  fMinCombos = fParent->GetMinCombos(fChamberNum);
+
+  cout << "Chamber " << fChamberNum << "  Min/Max: " << fMinHits << "/" << fMaxHits << endl;
+
+  fSpacePointCriterion = fParent->GetSpacePointCriterion(fChamberNum); 
+  fSpacePointCriterion2 = fSpacePointCriterion*fSpacePointCriterion;
+
+  // HMS Specific
+  // Hard code Y plane numbers.  Should be able to get from wire angle
+  if(fChamberNum == 1) {
+    YPlaneNum = 2;
+    YPlanePNum = 5;
+  } else {
+    YPlaneNum = 8;
+    YPlanePNum = 11;
+  }
+    
+  // Generate the HAA3INV matrix for all the acceptable combinations
+  // of hit planes.  Try to make it as generic as possible 
+  // pindex=0 -> Plane 1 missing, pindex5 -> plane 6 missing.  Won't 
+  // replicate the exact values used in the ENGINE, because the engine
+  // had one big list of matrices for both chambers, while here we will
+  // have a list just for one chamber.  Also, call pindex, pmindex as
+  // we tend to use pindex as a plane index.
+  fCosBeta = new Double_t [fNPlanes];
+  fSinBeta = new Double_t [fNPlanes];
+  fTanBeta = new Double_t [fNPlanes];
+  fSigma = new Double_t [fNPlanes];
+  fPsi0 = new Double_t [fNPlanes];
+  fStubCoefs = new Double_t* [fNPlanes];
+  Int_t allplanes=0;
+  for(Int_t ip=0;ip<fNPlanes;ip++) {
+    fCosBeta[ip] = TMath::Cos(fPlanes[ip]->GetBeta());
+    fSinBeta[ip] = TMath::Sin(fPlanes[ip]->GetBeta());
+    fTanBeta[ip] = fSinBeta[ip]/fCosBeta[ip];
+    fSigma[ip] = fPlanes[ip]->GetSigma();
+    fPsi0[ip] = fPlanes[ip]->GetPsi0();
+    fStubCoefs[ip] = fPlanes[ip]->GetStubCoef();
+    allplanes |= 1<<ip;
+  }
+  // Unordered map introduced in C++-11
+  // Can use unordered_map if using C++-11
+  // May not want to use map a all for performance, but using it now
+  // for code clarity
+  for(Int_t ipm1=0;ipm1<fNPlanes+1;ipm1++) { // Loop over missing plane1
+    for(Int_t ipm2=ipm1;ipm2<fNPlanes+1;ipm2++) {
+      if(ipm1==ipm2 && ipm1<fNPlanes) continue;
+      TMatrixDSym* AA3 = new TMatrixDSym(3);
+      for(Int_t i=0;i<3;i++) {
+	for(Int_t j=i;j<3;j++) {
+	  (*AA3)[j][i] = 0.0;
+	  for(Int_t ip=0;ip<fNPlanes;ip++) {
+	    if(ipm1 != ip && ipm2 != ip) {
+	      (*AA3)[j][i] += fStubCoefs[ip][i]*fStubCoefs[ip][j];
+	    }
+	  }
+	}
+      }
+      // Use the bit pattern of missing planes as an hash index.
+      // Perhaps it is more efficient to just use a regular array instead of map
+      Int_t bitpat = allplanes & ~(1<<ipm1) & ~(1<<ipm2);
+      // Should check that it is invertable
+      AA3->Invert();
+      fAA3Inv[bitpat] = AA3;
+    }
+  }
+
+#if 0  
+  for(map<int,TMatrixDSym*>::iterator pm=fHaa3map.begin();
+      pm != fHaa3map.end(); pm++) {
+    cout << setbase(8) << pm->first << endl;
+    fAA3Inv[pm->first]->Print();
   }
-  cout << endl;
+#endif
 
   fIsInit = true;
-
   return kOK;
 }
 
@@ -249,165 +223,863 @@ Int_t THcDriftChamber::DefineVariables( EMode mode )
   // Register variables in global list
 
   //  RVarDef vars[] = {
-  //    { "nlthit", "Number of Left paddles TDC times",  "fLTNhit" },
-  //    { "nrthit", "Number of Right paddles TDC times", "fRTNhit" },
-  //    { "nlahit", "Number of Left paddles ADCs amps",  "fLANhit" },
-  //    { "nrahit", "Number of Right paddles ADCs amps", "fRANhit" },
-  //    { "lt",     "TDC values left side",              "fLT" },
-  //    { "lt_c",   "Corrected times left side",         "fLT_c" },
-  //    { "rt",     "TDC values right side",             "fRT" },
-  //    { "rt_c",   "Corrected times right side",        "fRT_c" },
-  //    { "la",     "ADC values left side",              "fLA" },
-  //    { "la_p",   "Corrected ADC values left side",    "fLA_p" },
-  //    { "la_c",   "Corrected ADC values left side",    "fLA_c" },
-  //    { "ra",     "ADC values right side",             "fRA" },
-  //    { "ra_p",   "Corrected ADC values right side",   "fRA_p" },
-  //    { "ra_c",   "Corrected ADC values right side",   "fRA_c" },
-  //    { "nthit",  "Number of paddles with l&r TDCs",   "fNhit" },
-  //    { "t_pads", "Paddles with l&r coincidence TDCs", "fHitPad" },
-  //    { "y_t",    "y-position from timing (m)",        "fYt" },
-  //    { "y_adc",  "y-position from amplitudes (m)",    "fYa" },
-  //    { "time",   "Time of hit at plane (s)",          "fTime" },
-  //    { "dtime",  "Est. uncertainty of time (s)",      "fdTime" },
-  //    { "dedx",   "dEdX-like deposited in paddle",     "fAmpl" },
-  //    { "troff",  "Trigger offset for paddles",        "fTrigOff"},
-  //    { "trn",    "Number of tracks for hits",         "GetNTracks()" },
-  //    { "trx",    "x-position of track in det plane",  "fTrackProj.THaTrackProj.fX" },
-  //    { "try",    "y-position of track in det plane",  "fTrackProj.THaTrackProj.fY" },
-  //    { "trpath", "TRCS pathlen of track to det plane","fTrackProj.THaTrackProj.fPathl" },
-  //    { "trdx",   "track deviation in x-position (m)", "fTrackProj.THaTrackProj.fdX" },
-  //    { "trpad",  "paddle-hit associated with track",  "fTrackProj.THaTrackProj.fChannel" },
+  //    { "nhit", "Number of DC hits",  "fNhits" },
   //    { 0 }
   //  };
   //  return DefineVarsFromList( vars, mode );
   return kOK;
-}
 
-//_____________________________________________________________________________
-THcDriftChamber::~THcDriftChamber()
+}
+void THcDriftChamber::ProcessHits( void)
 {
-  // Destructor. Remove variables from global list.
+  // Make a list of hits for whole chamber
+  fNhits = 0;
 
-  if( fIsSetup )
-    RemoveVariables();
-  if( fIsInit )
-    DeleteArrays();
-  if (fTrackProj) {
-    fTrackProj->Clear();
-    delete fTrackProj; fTrackProj = 0;
+  for(Int_t ip=0;ip<fNPlanes;ip++) {
+    TClonesArray* hitsarray = fPlanes[ip]->GetHits();
+    for(Int_t ihit=0;ihit<fPlanes[ip]->GetNHits();ihit++) {
+      fHits[fNhits++] = static_cast<THcDCHit*>(hitsarray->At(ihit));
+    }
   }
+  //  cout << "ThcDriftChamber::ProcessHits() " << fNhits << " hits" << endl;
 }
 
-//_____________________________________________________________________________
-void THcDriftChamber::DeleteArrays()
+
+Int_t THcDriftChamber::FindSpacePoints( void )
 {
-  // Delete member arrays. Used by destructor.
+  // Following h_pattern_recognition.f, but just for one chamber
 
-  delete [] fNWires;  fNWires = NULL;
-  //  delete [] fSpacing;  fSpacing = NULL;
-  //  delete [] fCenter;   fCenter = NULL; // This 2D. What is correct way to delete?
-
-  //  delete [] fRA_c;    fRA_c    = NULL;
-  //  delete [] fRA_p;    fRA_p    = NULL;
-  //  delete [] fRA;      fRA      = NULL;
-  //  delete [] fLA_c;    fLA_c    = NULL;
-  //  delete [] fLA_p;    fLA_p    = NULL;
-  //  delete [] fLA;      fLA      = NULL;
-  //  delete [] fRT_c;    fRT_c    = NULL;
-  //  delete [] fRT;      fRT      = NULL;
-  //  delete [] fLT_c;    fLT_c    = NULL;
-  //  delete [] fLT;      fLT      = NULL;
-  
-  //  delete [] fRGain;   fRGain   = NULL;
-  //  delete [] fLGain;   fLGain   = NULL;
-  //  delete [] fRPed;    fRPed    = NULL;
-  //  delete [] fLPed;    fLPed    = NULL;
-  //  delete [] fROff;    fROff    = NULL;
-  //  delete [] fLOff;    fLOff    = NULL;
-  //  delete [] fTWalkPar; fTWalkPar = NULL;
-  //  delete [] fTrigOff; fTrigOff = NULL;
-
-  //  delete [] fHitPad;  fHitPad  = NULL;
-  //  delete [] fTime;    fTime    = NULL;
-  //  delete [] fdTime;   fdTime   = NULL;
-  //  delete [] fYt;      fYt      = NULL;
-  //  delete [] fYa;      fYa      = NULL;
+  // Code below is specifically for HMS chambers with Y and Y' planes
+
+  Int_t yplane_hitind=0;
+  Int_t yplanep_hitind=0;
+
+  fNSpacePoints=0;
+  fEasySpacePoint = 0;
+  // Should really build up array of hits
+  if(fNhits >= fMinHits && fNhits < fMaxHits) {
+    /* Has this list of hits already been cut the way it should have at this point? */
+    
+    for(Int_t ihit=0;ihit<fNhits;ihit++) {
+      THcDCHit* thishit = fHits[ihit];
+      Int_t ip=thishit->GetPlaneNum();  // This is the absolute plane mumber
+      if(ip==YPlaneNum) yplane_hitind = ihit;
+      if(ip==YPlanePNum) yplanep_hitind = ihit;
+    }
+    // fPlanes is the array of planes for this chamber.
+    //    cout << fPlanes[YPlaneInd]->GetNHits() << " "
+    //	 << fPlanes[YPlanePInd]->GetNHits() << " " << endl;
+    if (fPlanes[YPlaneInd]->GetNHits() == 1 && fPlanes[YPlanePInd]->GetNHits() == 1) {
+      cout << fHits[yplane_hitind]->GetWireNum() << " "
+	   << fHits[yplane_hitind]->GetPos() << " "
+	   << fHits[yplanep_hitind]->GetWireNum() << " "
+	   << fHits[yplanep_hitind]->GetPos() << " " 
+	   << fSpacePointCriterion << endl;
+    }
+    if(fPlanes[YPlaneInd]->GetNHits() == 1 && fPlanes[YPlanePInd]->GetNHits() == 1
+       && TMath::Abs(fHits[yplane_hitind]->GetPos() - fHits[yplanep_hitind]->GetPos())
+       < fSpacePointCriterion
+       && fNhits <= 6) {	// An easy case, probably one hit per plane
+      fEasySpacePoint = FindEasySpacePoint(yplane_hitind, yplanep_hitind);
+    }
+    if(!fEasySpacePoint) {	// It's not easy
+      FindHardSpacePoints();
+    }
+
+    // We have our space points for this chamber
+    cout << fNSpacePoints << " Space Points found" << endl;
+    if(fNSpacePoints > 0) {
+      if(fRemove_Sppt_If_One_YPlane == 1) {
+	// The routine is specific to HMS
+	Int_t ndest=DestroyPoorSpacePoints();
+	cout << ndest << " Poor space points destroyed" << endl;
+	// Loop over space points and remove those with less than 4 planes
+	// hit and missing hits in Y,Y' planes
+      }
+      if(fNSpacePoints == 0) cout << "DestroyPoorSpacePoints() killed SP" << endl;
+      Int_t nadded=SpacePointMultiWire();
+      if (nadded) cout << nadded << " Space Points added with SpacePointMultiWire()" << endl;
+      ChooseSingleHit();
+      SelectSpacePoints();
+      if(fNSpacePoints == 0) cout << "SelectSpacePoints() killed SP" << endl;
+    }
+    cout << fNSpacePoints << " Space Points remain" << endl;
+    // Add these space points to the total list of space points for the
+    // the DC package.  Do this in THcDC.cxx.
+#if 0
+    for(Int_t ip=0;ip<fNPlanes;ip++) {
+      Int_t np = fPlanes[ip]->GetPlaneNum(); // Actuall plane number of this plane
+      // (0-11) or (1-12)?
+      TClonesArray* fHits = fPlanes[ip]->GetHits();
+
+      for(Int_t ihit=0;ihit<fNhits;ihit++) { // Looping over all hits in all planes of the chamber
+	THcDCHit* hit = static_cast<THcDCHit*>(fHits->At(ihit));
+	// 
+
+      }
+    }
+#endif
+  }
+  return(fNSpacePoints);
 }
 
 //_____________________________________________________________________________
-inline 
-void THcDriftChamber::ClearEvent()
+// HMS Specific
+Int_t THcDriftChamber::FindEasySpacePoint(Int_t yplane_hitind,Int_t yplanep_hitind)
 {
-  // Reset per-event data.
+  // Simplified HMS find_space_point routing.  It is given all y hits and
+  // checks to see if all x-like hits are close enough together to make
+  // a space point.
+
+  Int_t easy_space_point=0;
+  cout << "Doing Find Easy Space Point" << endl;
+  Double_t yt = (fHits[yplane_hitind]->GetPos() + fHits[yplanep_hitind]->GetPos())/2.0;
+  Double_t xt = 0.0;
+  Int_t num_xhits = 0;
+  Double_t x_pos[MAX_HITS_PER_POINT];
+
+  for(Int_t ihit=0;ihit<fNhits;ihit++) {
+    THcDCHit* thishit = fHits[ihit];
+    if(ihit!=yplane_hitind && ihit!=yplanep_hitind) { // x-like hit
+      // ysp and xsp are from h_generate_geometry
+      x_pos[ihit] = (thishit->GetPos()
+		     -yt*thishit->GetWirePlane()->GetYsp())
+	/thishit->GetWirePlane()->GetXsp();
+      xt += x_pos[ihit];
+      num_xhits++;
+    } else {
+      x_pos[ihit] = 0.0;
+    }
+  }
+  xt = (num_xhits>0?xt/num_xhits:0.0);
+  cout << "xt=" << xt << endl;
+  easy_space_point = 1; // Assume we have an easy space point
+  // Rule it out if x points don't cluster well enough
+  for(Int_t ihit=0;ihit<fNhits;ihit++) {
+    cout << "Hit " << ihit << " " << x_pos[ihit] << " " << xt << endl;
+    if(ihit!=yplane_hitind && ihit!=yplanep_hitind) { // x-like hit
+      if(TMath::Abs(xt-x_pos[ihit]) >= fSpacePointCriterion)
+	{ easy_space_point=0; break;}
+    }
+  }
+  if(easy_space_point) {	// Register the space point
+    cout << "Easy Space Point " << xt << " " << yt << endl;
+    fNSpacePoints = 1;
+    fSpacePoints[0].x = xt;
+    fSpacePoints[0].y = yt;
+    fSpacePoints[0].nhits = fNhits;
+    fSpacePoints[0].ncombos = 0; // No combos
+    for(Int_t ihit=0;ihit<fNhits;ihit++) {
+      THcDCHit* thishit = fHits[ihit];
+      fSpacePoints[0].hits[ihit] = thishit;
+    }
+  }
+  return(easy_space_point);
+}
 
-  fTrackProj->Clear();
+//_____________________________________________________________________________
+// Generic
+Int_t THcDriftChamber::FindHardSpacePoints()
+{
+  Int_t MAX_NUMBER_PAIRS=1000; // Where does this get set?
+  struct Pair {
+    THcDCHit* hit1;
+    THcDCHit* hit2;
+    Double_t x, y;
+  };
+  Pair pairs[MAX_NUMBER_PAIRS];
+  //	
+  Int_t ntest_points=0;
+  for(Int_t ihit1=0;ihit1<fNhits-1;ihit1++) {
+    THcDCHit* hit1=fHits[ihit1];
+    THcDriftChamberPlane* plane1 = hit1->GetWirePlane();
+    for(Int_t ihit2=ihit1+1;ihit2<fNhits;ihit2++) {
+      if(ntest_points < MAX_NUMBER_PAIRS) {
+	THcDCHit* hit2=fHits[ihit2];
+	THcDriftChamberPlane* plane2 = hit2->GetWirePlane();
+	Double_t determinate = plane1->GetXsp()*plane2->GetYsp()
+	  -plane1->GetYsp()*plane2->GetXsp();
+	if(TMath::Abs(determinate) > 0.3) { // 0.3 is sin(alpha1-alpha2)=sin(17.5)
+	  pairs[ntest_points].hit1 = hit1;
+	  pairs[ntest_points].hit2 = hit2;
+	  pairs[ntest_points].x = (hit1->GetPos()*plane2->GetYsp()
+				   - hit2->GetPos()*plane1->GetYsp())
+	    /determinate;
+	  pairs[ntest_points].y = (hit2->GetPos()*plane1->GetXsp()
+				   - hit1->GetPos()*plane2->GetXsp())
+	    /determinate;
+	  ntest_points++;
+	}
+      }
+    }
+  }
+  Int_t ncombos=0;
+  struct Combo {
+    Pair* pair1;
+    Pair* pair2;
+  };
+  Combo combos[10*MAX_NUMBER_PAIRS];
+  for(Int_t ipair1=0;ipair1<ntest_points-1;ipair1++) {
+    for(Int_t ipair2=ipair1+1;ipair2<ntest_points;ipair2++) {
+      if(ncombos < 10*MAX_NUMBER_PAIRS) {
+	Double_t dist2 = pow(pairs[ipair1].x - pairs[ipair2].x,2)
+	  + pow(pairs[ipair1].y - pairs[ipair2].y,2);
+	if(dist2 <= fSpacePointCriterion2) {
+	  combos[ncombos].pair1 = &pairs[ipair1];
+	  combos[ncombos].pair2 = &pairs[ipair2];
+	  ncombos++;
+	}
+      }
+    }
+  }
+  // Loop over all valid combinations and build space points
+  for(Int_t icombo=0;icombo<ncombos;icombo++) {
+    THcDCHit* hits[4];
+    hits[0]=combos[icombo].pair1->hit1;
+    hits[1]=combos[icombo].pair1->hit2;
+    hits[2]=combos[icombo].pair2->hit1;
+    hits[3]=combos[icombo].pair2->hit2;
+    // Get Average Space point xt, yt
+    Double_t xt = (combos[icombo].pair1->x + combos[icombo].pair2->x)/2.0;
+    Double_t yt = (combos[icombo].pair1->y + combos[icombo].pair2->y)/2.0;
+    // Loop over space points
+    if(fNSpacePoints > 0) {
+      Int_t add_flag=1;
+      for(Int_t ispace=0;ispace<fNSpacePoints;ispace++) {
+	if(fSpacePoints[ispace].nhits > 0) {
+	  Double_t sqdist_test = pow(xt - fSpacePoints[ispace].x,2) +
+	    pow(yt - fSpacePoints[ispace].y,2);
+	  // I (who is I) want to be careful if sqdist_test is bvetween 1 and
+	  // 3 fSpacePointCriterion2.  Let me ignore not add a new point the
+	  if(sqdist_test < 3*fSpacePointCriterion2) {
+	    add_flag = 0;	// do not add a new space point
+	  }
+	  if(sqdist_test < fSpacePointCriterion2) {
+	    // This is a real match
+	    // Add the new hits to the existing space point
+	    Int_t iflag[4];
+	    iflag[0]=0;iflag[1]=0;iflag[2]=0;iflag[3]=0;
+	    // Find out which of the four hits in the combo are already
+	    // in the space point under consideration so that we don't
+	    // add duplicate hits to the space point
+	    for(Int_t isp_hit=0;isp_hit<fSpacePoints[ispace].nhits;isp_hit++) {
+	      for(Int_t icm_hit=0;icm_hit<4;icm_hit++) { // Loop over combo hits
+		if(fSpacePoints[ispace].hits[isp_hit]==hits[icm_hit]) {
+		  iflag[icm_hit] = 1;
+		}
+	      }
+	    }
+	    // Remove duplicated pionts in the combo so we don't add
+	    // duplicate hits to the space point
+	    for(Int_t icm1=0;icm1<3;icm1++) {
+	      for(Int_t icm2=icm1+1;icm2<4;icm2++) {
+		if(hits[icm1]==hits[icm2]) {
+		  iflag[icm2] = 1;
+		}
+	      }
+	    }
+	    // Add the unique combo hits to the space point
+	    for(Int_t icm=0;icm<4;icm++) {
+	      if(iflag[icm]==0) {
+		fSpacePoints[ispace].hits[fSpacePoints[ispace].nhits++] = hits[icm];
+	      }
+	    }
+	    fSpacePoints[ispace].ncombos++;
+	    // Terminate loop since this combo can only belong to one space point
+	    break;
+	  }
+	}
+      }// End of loop over existing space points
+      // Create a new space point if more than 2*space_point_criteria
+      if(fNSpacePoints < MAX_SPACE_POINTS) {
+	if(add_flag) {
+	  fSpacePoints[fNSpacePoints].nhits=2;
+	  fSpacePoints[fNSpacePoints].ncombos=1;
+	  fSpacePoints[fNSpacePoints].hits[0]=hits[0];
+	  fSpacePoints[fNSpacePoints].hits[1]=hits[1];
+	  fSpacePoints[fNSpacePoints].x = xt;
+	  fSpacePoints[fNSpacePoints].y = yt;
+	  if(hits[0] != hits[2] && hits[1] != hits[2]) {
+	    fSpacePoints[fNSpacePoints].hits[fSpacePoints[fNSpacePoints].nhits++] = hits[2];
+	  }
+	  if(hits[0] != hits[3] && hits[1] != hits[3]) {
+	    fSpacePoints[fNSpacePoints].hits[fSpacePoints[fNSpacePoints].nhits++] = hits[3];
+	  }
+	  fNSpacePoints++;
+	}
+      }
+    } else {// Create first space point
+      // This duplicates code above.  Need to see if we can restructure
+      // to avoid
+      fSpacePoints[fNSpacePoints].nhits=2;
+      fSpacePoints[fNSpacePoints].ncombos=1;
+      fSpacePoints[fNSpacePoints].hits[0]=hits[0];
+      fSpacePoints[fNSpacePoints].hits[1]=hits[1];
+      fSpacePoints[fNSpacePoints].x = xt;
+      fSpacePoints[fNSpacePoints].y = yt;
+      if(hits[0] != hits[2] && hits[1] != hits[2]) {
+	fSpacePoints[fNSpacePoints].hits[fSpacePoints[fNSpacePoints].nhits++] = hits[2];
+      }
+      if(hits[0] != hits[3] && hits[1] != hits[3]) {
+	fSpacePoints[fNSpacePoints].hits[fSpacePoints[fNSpacePoints].nhits++] = hits[3];
+      }
+      fNSpacePoints++;
+    }//End check on 0 space points
+  }//End loop over combos
+  return(fNSpacePoints);
 }
 
 //_____________________________________________________________________________
-Int_t THcDriftChamber::Decode( const THaEvData& evdata )
+// HMS Specific?
+Int_t THcDriftChamber::DestroyPoorSpacePoints()
 {
+  Int_t nhitsperplane[fNPlanes];
 
-  // Get the Hall C style hitlist (fRawHitList) for this event
-  Int_t nhits = THcHitList::DecodeToHitList(evdata);
+  Int_t spacepointsgood[fNSpacePoints];
+  Int_t ngood=0;
 
-  // Let each plane get its hits
-  Int_t nexthit = 0;
-  for(Int_t ip=0;ip<fNPlanes;ip++) {
-    nexthit = fPlanes[ip]->ProcessHits(fRawHitList, nexthit);
+  for(Int_t i=0;i<fNSpacePoints;i++) {
+    spacepointsgood[i] = 0;
+  }
+  for(Int_t isp=0;isp<fNSpacePoints;isp++) {
+    Int_t nplanes_hit = 0;
+    for(Int_t ip=0;ip<fNPlanes;ip++) {
+      nhitsperplane[ip] = 0;
+    }
+    // Count # hits in each plane for this space point
+    for(Int_t ihit=0;ihit<fSpacePoints[isp].nhits;ihit++) {
+      THcDCHit* hit=fSpacePoints[isp].hits[ihit];
+      // hit_order(hit) = ihit;
+      Int_t ip = hit->GetPlaneIndex();
+      nhitsperplane[ip]++;
+    }
+    // Count # planes that have hits
+    for(Int_t ip=0;ip<fNPlanes;ip++) {
+      if(nhitsperplane[ip] > 0) {
+	nplanes_hit++;
+      }
+    }
+    if(nplanes_hit >= fMinHits && nhitsperplane[YPlaneInd]>0
+       && nhitsperplane[YPlanePInd] > 0) {
+      spacepointsgood[ngood++] = isp; // Build list of good points
+    } else {
+      //      cout << "Missing Y-hit!!";
+    }
   }
 
-#if 0
-  // fRawHitList is TClones array of THcRawDCHit objects
-  for(Int_t ihit = 0; ihit < fNRawHits ; ihit++) {
-    THcRawDCHit* hit = (THcRawDCHit *) fRawHitList->At(ihit);
-    //    cout << ihit << " : " << hit->fPlane << ":" << hit->fCounter << " : "
-    //	 << endl;
-    for(Int_t imhit = 0; imhit < hit->fNHits; imhit++) {
-      //      cout << "                     " << imhit << " " << hit->fTDC[imhit]
-      //	   << endl;
+  // Remove the bad space points
+  Int_t nremoved=fNSpacePoints-ngood;
+  fNSpacePoints = ngood;
+  for(Int_t isp=0;isp<fNSpacePoints;isp++) { // New index num ber
+    Int_t osp=spacepointsgood[isp]; // Original index number
+    if(osp > isp) {
+      // Does this work, or do we have to copy each member?
+      // If it doesn't we should overload the = operator
+      fSpacePoints[isp] = fSpacePoints[osp];
     }
   }
-  //  cout << endl;
+  return nremoved;
+}
+    
+//_____________________________________________________________________________
+// HMS Specific?
+  /*
+   Purpose and Methods :  This routine loops over space points and 
+                          looks at all hits in the space
+                          point. If more than 1 hit is in the same 
+                          plane then the space point is cloned with
+                          all combinations of 1 wire per plane.  The 
+                          requirements for cloning are:  1) at least 
+                          4 planes fire, and 2) no more than 6 planes 
+                          have multiple hits.      
+  */
+Int_t THcDriftChamber::SpacePointMultiWire()
+{
+  Int_t nhitsperplane[fNPlanes];
+  THcDCHit* hits_plane[fNPlanes][MAX_HITS_PER_POINT];
+
+  Int_t nsp_check;
+  Int_t nplanes_single;
+
+  Int_t nsp_tot=fNSpacePoints;
+
+  for(Int_t isp=0;isp<fNSpacePoints;isp++) {
+    Int_t nplanes_hit = 0;	// Number of planes with hits
+    Int_t nplanes_mult = 0;	// Number of planes with multiple hits
+    Int_t nsp_new = 1;
+    Int_t newsp_num=0;
+
+    for(Int_t ip=0;ip<fNPlanes;ip++) {
+      nhitsperplane[ip] = 0;
+    }
+    // Sort Space Points hits by plane
+    for(Int_t ihit=0;ihit<fSpacePoints[isp].nhits;ihit++) { // All hits in SP
+      THcDCHit* hit=fSpacePoints[isp].hits[ihit];
+      //      hit_order Make a hash
+      // hash(hit) = ihit;
+      Int_t ip = hit->GetPlaneIndex();
+      hits_plane[ip][nhitsperplane[ip]++] = hit;
+    }
+    for(Int_t ip=0;ip<fNPlanes;ip++) {
+      if(nhitsperplane[ip] > 0) {
+	nplanes_hit++;
+	nsp_new *= nhitsperplane[ip];
+	if(nhitsperplane[ip] > 1) nplanes_mult++;
+      }
+    }
+    --nsp_new;
+    nsp_check=nsp_tot + nsp_new;
+    nplanes_single = nplanes_hit - nplanes_mult;
+    
+    // Check if cloning conditions are met
+    Int_t ntot = 0;
+    if(nplanes_hit >= 4 && nplanes_mult < 4 && nplanes_mult >0
+       && nsp_check < 20) {
+      
+      // Order planes by decreasing # of hits
+      
+      Int_t maxplane[fNPlanes];
+      for(Int_t ip=0;ip<fNPlanes;ip++) {
+	maxplane[ip] = ip;
+      }
+      // Sort by decreasing # of hits
+      for(Int_t ip1=0;ip1<fNPlanes-1;ip1++) {
+	for(Int_t ip2=ip1+1;ip2<fNPlanes;ip2++) {
+	  if(nhitsperplane[maxplane[ip2]] > nhitsperplane[maxplane[ip1]]) {
+	    Int_t temp = maxplane[ip1];
+	    maxplane[ip1] = maxplane[ip2];
+	    maxplane[ip2] = temp;
+	  }
+	}
+      }
+
+      // First fill clones with 1 hit each from the 3 planes with the most hits
+      for(Int_t n1=0;n1<nhitsperplane[maxplane[0]];n1++) {
+	for(Int_t n2=0;n2<nhitsperplane[maxplane[1]];n2++) {
+	  for(Int_t n3=0;n3<nhitsperplane[maxplane[2]];n3++) {
+	    ntot++;
+	    newsp_num = nsp_tot + ntot - 2; // ntot will be 2 for first new
+	    if(n1==0 && n2==0 && n3==0) newsp_num = isp; // Copy over original SP
+	    fSpacePoints[newsp_num].x = fSpacePoints[isp].x;
+	    fSpacePoints[newsp_num].y = fSpacePoints[isp].y;
+	    fSpacePoints[newsp_num].nhits = nplanes_hit;
+	    fSpacePoints[newsp_num].ncombos = fSpacePoints[isp].ncombos;
+	    fSpacePoints[newsp_num].hits[0] = hits_plane[maxplane[0]][n1];
+	    fSpacePoints[newsp_num].hits[1] = hits_plane[maxplane[1]][n2];
+	    fSpacePoints[newsp_num].hits[2] = hits_plane[maxplane[2]][n3];
+	    fSpacePoints[newsp_num].hits[3] = hits_plane[maxplane[3]][0];
+	    if(nhitsperplane[maxplane[4]] == 1)
+	      fSpacePoints[newsp_num].hits[4] = hits_plane[maxplane[4]][0];
+	    if(nhitsperplane[maxplane[5]] == 1)
+	      fSpacePoints[newsp_num].hits[5] = hits_plane[maxplane[5]][0];
+	  }
+	}
+      }
+#if 0
+      // Loop over clones and order hits in the same way as parent SP
+      // Why do we have to order the hits.
+      for(Int_t i=0;i<ntot;i++) {
+	Int_t newsp_num= nsp_tot + i;
+	if(i == 1) newsp_num = isp;
+	for(Int_t j=0;j<nplanes_hit;j++) {
+	  for(Int_t k=0;k<nplanes_hit;k++) {
+	    THcDCHit* hit1 = fSpacePointHits[newsp_num][j];
+	    THcDCHit* hit2 = fSpacePointHits[newsp_num][k];
+	    if(hit_order(hit1) > hit_order(hit2)) {
+	      THcDCHit* temp = fSpacePoints[newsp_num].hits[k];
+	      fSpacePoints[newsp_num].hits[k] = fSpacePoints[newsp_num].hits[j];
+	      fSpacePoints[newsp_num].hits[j] = temp;
+	    }
+	  }
+	}
+      }
 #endif
+      nsp_tot += (ntot-1);
+    } else {
+      ntot=1;
+    }
+  }
+  assert (nsp_tot > 0);
+  Int_t nadded=0;
+  if(nsp_tot <= 20) {
+    nadded = nsp_tot - fNSpacePoints;
+    fNSpacePoints = nsp_tot;
+  }
 
-  return nhits;
+  // In Fortran, fill in zeros.
+  return(nadded);
 }
 
 //_____________________________________________________________________________
-Int_t THcDriftChamber::ApplyCorrections( void )
+// HMS Specific?
+void THcDriftChamber::ChooseSingleHit()
 {
-  return(0);
+  // Look at all hits in a space point.  If two hits are in the same plane,
+  // reject the one with the longer drift time.
+  Int_t goodhit[MAX_HITS_PER_POINT];
+
+  for(Int_t isp=0;isp<fNSpacePoints;isp++) {
+    Int_t startnum = fSpacePoints[isp].nhits;
+    
+    for(Int_t ihit=0;ihit<startnum;ihit++) {
+      goodhit[ihit] = 1;
+    }
+    // For each plane, mark all hits longer than the shortest drift time
+    for(Int_t ihit1=0;ihit1<startnum-1;ihit1++) {
+      THcDCHit* hit1 = fSpacePoints[isp].hits[ihit1];
+      Int_t plane1=hit1->GetPlaneIndex();
+      Double_t tdrift1 = hit1->GetTime();
+      for(Int_t ihit2=ihit1+1;ihit2<startnum;ihit2++) {
+	THcDCHit* hit2 = fSpacePoints[isp].hits[ihit2];
+	Int_t plane2=hit2->GetPlaneIndex();
+	Double_t tdrift2 = hit2->GetTime();
+	if(plane1 == plane2) {
+	  if(tdrift1 > tdrift2) {
+	    goodhit[ihit1] = 0;
+	  } else {
+	    goodhit[ihit2] = 0;
+	  }
+	}
+      }
+    }
+    // Gather the remaining hits
+    Int_t finalnum = 0;
+    for(Int_t ihit=0;ihit<startnum;ihit++) {
+      if(goodhit[ihit] > 0) {	// Keep this hit
+	if (ihit > finalnum) {	// Move hit 
+	  fSpacePoints[isp].hits[finalnum++] = fSpacePoints[isp].hits[ihit];
+	} else {
+	  finalnum++;
+	}
+      }
+    }
+    fSpacePoints[isp].nhits = finalnum;
+  }
 }
+//_____________________________________________________________________________
+// Generic
+void THcDriftChamber::SelectSpacePoints()
+//    This routine goes through the list of space_points and space_point_hits
+//    found by find_space_points and only accepts those with 
+//    number of hits > min_hits
+//    number of combinations > min_combos
+{
+  Int_t sp_count=0;
+  for(Int_t isp=0;isp<fNSpacePoints;isp++) {
+    // Include fEasySpacePoint because ncombos not filled in
+    if(fSpacePoints[isp].ncombos >= fMinCombos || fEasySpacePoint) {
+      if(fSpacePoints[isp].nhits >= fMinHits) {
+	fSpacePoints[sp_count++] = fSpacePoints[isp];
+      }
+    }
+  }
+  fNSpacePoints = sp_count;
+}
+
+void THcDriftChamber::CorrectHitTimes()
+{
+  // Use the rough hit positions in the chambers to correct the drift time
+  // for hits in the space points.
+
+  // Assume all wires for a plane are read out on the same side (l/r or t/b).
+  // If the wire is closer to horizontal, read out left/right.  If nearer
+  // vertical, assume top/bottom.  (Note, this is not always true for the
+  // SOS u and v planes.  They have 1 card each on the side, but the overall
+  // time offset per card will cancel much of the error caused by this.  The
+  // alternative is to check by card, rather than by plane and this is harder.
+  for(Int_t isp=0;isp<fNSpacePoints;isp++) {
+    Double_t x = fSpacePoints[isp].x;
+    Double_t y = fSpacePoints[isp].y;
+    for(Int_t ihit=0;ihit<fSpacePoints[isp].nhits;ihit++) {
+      THcDCHit* hit = fSpacePoints[isp].hits[ihit];
+      THcDriftChamberPlane* plane=hit->GetWirePlane();
+
+      // How do we know this correction only gets applied once?  Is
+      // it determined that a given hit can only belong to one space point?
+      Double_t time_corr = plane->GetReadoutX() ?
+	y*plane->GetReadoutCorr()/fWireVelocity :
+	x*plane->GetReadoutCorr()/fWireVelocity;
+      
+      //      cout << "Correcting hit " << hit << " " << plane->GetPlaneNum() << " " << isp << "/" << ihit << "  " << x << "," << y << endl;
+      // Fortran ENGINE does not do this check, so hits can get "corrected"
+      // multiple times if they belong to multiple space points.
+      // To reproduce the precise ENGINE behavior, remove this if condition.
+      if(! hit->GetCorrectedStatus()) {
+	hit->SetTime(hit->GetTime() - plane->GetCentralTime()
+		     + plane->GetDriftTimeSign()*time_corr);
+	hit->ConvertTimeToDist();
+	hit->SetCorrectedStatus(1);
+      }
+    }
+  }
+}	   
+UInt_t THcDriftChamber::Count1Bits(UInt_t x)
+// From "Hacker's Delight"
+{
+   x = x - ((x >> 1) & 0x55555555);
+   x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
+   x = x + (x >> 8);
+   x = x + (x >> 16);
+   return x & 0x0000003F;
+}
+
+//_____________________________________________________________________________
+// HMS Specific
+void THcDriftChamber::LeftRight()
+{
+  // For each space point,
+  // Fit stubs to all possible left-right combinations of drift distances
+  // and choose the set with the minimum chi**2.
+
+  for(Int_t isp=0; isp<fNSpacePoints; isp++) {
+    // Build a bit pattern of which planes are hit
+    Int_t nhits = fSpacePoints[isp].nhits;
+    UInt_t bitpat  = 0;		// Bit pattern of which planes are hit
+    Double_t minchi2 = 1.0e10;
+    Double_t tmp_minchi2;
+    Double_t minxp = 0.25;
+    Int_t hasy1 = -1;
+    Int_t hasy2 = -1;
+    Int_t plusminusknown[nhits];
+    Int_t plusminusbest[nhits];
+    Int_t plusminus[nhits];	// ENGINE makes this array float.  Why?
+    Int_t tmp_plusminus[nhits];
+    Int_t plane_list[nhits];
+    Double_t stub[4];
+    Double_t tmp_stub[4];
+
+    if(nhits < 0) {
+      cout << "THcDriftChamber::LeftRight() nhits < 0" << endl;
+    } else if (nhits==0) {
+      cout << "THcDriftChamber::LeftRight() nhits = 0" << endl;
+    }
+    for(Int_t ihit=0;ihit < nhits;ihit++) {
+      THcDCHit* hit = fSpacePoints[isp].hits[ihit];
+      Int_t pindex = hit->GetPlaneIndex();
+      plane_list[ihit] = pindex;
+
+      bitpat |= 1<<pindex;
+
+      plusminusknown[ihit] = 0;
 
+      if(pindex == YPlaneInd) hasy1 = ihit;
+      if(pindex == YPlanePInd) hasy2 = ihit;
+    }
+    Int_t smallAngOK = (hasy1>=0) && (hasy2>=0);
+    if(fSmallAngleApprox !=0 && smallAngOK) { // to small Angle L/R for Y,Y' planes
+      if(fSpacePoints[isp].hits[hasy1]->GetPos() <=
+	 fSpacePoints[isp].hits[hasy2]->GetPos()) {
+	plusminusknown[hasy1] = -1;
+	plusminusknown[hasy2] = 1;
+      } else {
+	plusminusknown[hasy1] = 1;
+	plusminusknown[hasy2] = -1;
+      }
+    }
+    if(nhits < 2) {
+      cout << "THcDriftChamber::LeftRight: numhits-2 < 0" << endl;
+    } else if (nhits == 2) {
+      cout << "THcDriftChamber::LeftRight: numhits-2 = 0" << endl;
+    }
+    Int_t nplaneshit = Count1Bits(bitpat);
+    Int_t nplusminus = pow(2,nhits-2);
+    
+    // Use bit value of integer word to set + or -
+    // Loop over all combinations of left right.
+    for(Int_t pmloop=0;pmloop<nplusminus;pmloop++) {
+      Int_t iswhit = 1;
+      for(Int_t ihit=0;ihit<nhits;ihit++) {
+	if(plusminusknown[ihit]!=0) {
+	  plusminus[ihit] = plusminusknown[ihit];
+	} else {
+	  // Max hits per point has to be less than 32.  
+	  if(pmloop & iswhit) {
+	    plusminus[ihit] = 1;
+	  } else {
+	    plusminus[ihit] = -1;
+	  }
+	  iswhit <<= 1;
+	}
+      }
+      if (nplaneshit >= fNPlanes-1) {
+	Double_t chi2 = FindStub(nhits, fSpacePoints[isp].hits,
+				     plane_list, bitpat, plusminus, stub);
+				     
+	//if(debugging)
+	//cout << "pmloop=" << pmloop << " Chi2=" << chi2 << endl;
+	// Take best chi2 IF x' of the stub agrees with x' as expected from x.
+	// Sometimes an incorrect x' gives a good chi2 for the stub, even though it is
+	// not the correct left/right combination for the real track.
+	// Rotate x'(=stub(3)) to hut coordinates and compare to x' expected from x.
+	// THIS ASSUMES STANDARD HMS TUNE!!!!, for which x' is approx. x/875.
+	if(chi2 < minchi2) {
+	  if(stub[2]*fTanBeta[plane_list[0]]==-1.0) {
+	    cout << "THcDriftChamber::LeftRight() Error 3" << endl;
+	  }
+	  Double_t xp_fit=stub[2]-fTanBeta[plane_list[0]]
+	    /(1+stub[2]*fTanBeta[plane_list[0]]);
+	  // Tune depdendent.  Definitely HMS specific
+	  Double_t xp_expect = fSpacePoints[isp].x/875.0;
+	  if(TMath::Abs(xp_fit-xp_expect)<fStubMaxXPDiff) {
+	    minchi2 = chi2;
+	    for(Int_t ihit=0;ihit<nhits;ihit++) {
+	      plusminusbest[ihit] = plusminus[ihit];
+	    }
+	    for(Int_t i=0;i<4;i++) {
+	      fSpacePoints[isp].stub[i] = stub[i];
+	    }
+	  } else {		// Record best stub failing angle cut
+	    tmp_minchi2 = chi2;
+	    for(Int_t ihit=0;ihit<nhits;ihit++) {
+	      tmp_plusminus[ihit] = plusminus[ihit];
+	    }
+	    for(Int_t i=0;i<4;i++) {
+	      tmp_stub[i] = stub[i];
+	    }
+	  }
+	}
+      } else if (nplaneshit >= fNPlanes-2) { // Two planes missing
+	Double_t chi2 = FindStub(nhits, fSpacePoints[isp].hits,
+				     plane_list, bitpat, plusminus, stub); 
+	//if(debugging)
+	//cout << "pmloop=" << pmloop << " Chi2=" << chi2 << endl;
+	// Isn't this a bad idea, doing == with reals
+	if(stub[2]*fTanBeta[plane_list[0]] == -1.0) {
+	  cout << "THcDriftChamber::LeftRight() Error 3" << endl;
+	}
+	Double_t xp_fit=stub[2]-fTanBeta[plane_list[0]]
+	  /(1+stub[2]*fTanBeta[plane_list[0]]);
+	if(TMath::Abs(xp_fit) <= minxp) {
+	  minxp = TMath::Abs(xp_fit);
+	  minchi2 = chi2;
+	  for(Int_t ihit=0;ihit<nhits;ihit++) {
+	    plusminusbest[ihit] = plusminus[ihit];
+	  }
+	  for(Int_t i=0;i<4;i++) {
+	    fSpacePoints[isp].stub[i] = stub[i];
+	  }
+	}
+      } else {
+	cout << "Insufficient planes hit in THcDriftChamber::LeftRight()" << bitpat <<endl;
+      }
+    } // End loop of pm combinations
+
+    if(minchi2 > 9.9e9) {	// No track passed angle cut
+      minchi2 = tmp_minchi2;
+      for(Int_t ihit=0;ihit<nhits;ihit++) {
+	plusminusbest[ihit] = tmp_plusminus[ihit];
+      }
+      for(Int_t i=0;i<4;i++) {
+	fSpacePoints[isp].stub[i] = tmp_stub[i];
+      }
+      
+    }
+
+    // Calculate final coordinate based on plusminusbest
+    // Update the hit positions in the space points
+    for(Int_t ihit; ihit<nhits; ihit++) {
+      fSpacePoints[isp].hits[ihit]->SetLeftRight(plusminusbest[ihit]);
+    }
+
+    // Stubs are calculated in rotated coordinate system
+    // (I think this rotates in case chambers not perpendicular to central ray)
+    Int_t pindex=plane_list[0];
+    if(fSpacePoints[isp].stub[2] - fTanBeta[pindex] == -1.0) {
+      cout << "THcDriftChamber::LeftRight(): stub3 error" << endl;
+    }
+    stub[2] = (fSpacePoints[isp].stub[2] - fTanBeta[pindex])
+      / (1.0 + fSpacePoints[isp].stub[2]*fTanBeta[pindex]);
+    if(fSpacePoints[isp].stub[2]*fSinBeta[pindex] ==  -fCosBeta[pindex]) {
+      cout << "THcDriftChamber::LeftRight(): stub4 error" << endl;
+    }
+    stub[3] = fSpacePoints[isp].stub[3]
+      / (fSpacePoints[isp].stub[2]*fSinBeta[pindex]+fCosBeta[pindex]);
+    stub[0] = fSpacePoints[isp].stub[0]*fCosBeta[pindex]
+      - fSpacePoints[isp].stub[0]*stub[2]*fSinBeta[pindex];
+    stub[1] = fSpacePoints[isp].stub[1]
+      - fSpacePoints[isp].stub[1]*stub[3]*fSinBeta[pindex];
+    for(Int_t i=0;i<4;i++) {
+      fSpacePoints[isp].stub[i] = stub[i];
+    }
+  }
+  // Option to print stubs
+}
+    //    if(fAA3Inv.find(bitpat) != fAAInv.end()) { // Valid hit combination
 //_____________________________________________________________________________
-Int_t THcDriftChamber::CoarseTrack( TClonesArray& /* tracks */ )
+Double_t THcDriftChamber::FindStub(Int_t nhits, THcDCHit** hits,
+				       Int_t* plane_list, UInt_t bitpat,
+				       Int_t* plusminus, Double_t* stub)
 {
-  // Calculation of coordinates of particle track cross point with scint
-  // plane in the detector coordinate system. For this, parameters of track 
-  // reconstructed in THaVDC::CoarseTrack() are used.
-  //
-  // Apply corrections and reconstruct the complete hits.
-  //
-  //  static const Double_t sqrt2 = TMath::Sqrt(2.);
+  // For a given combination of L/R, fit a stub to the space point
+  Double_t zeros[] = {0.0,0.0,0.0};
+  TVectorD TT; TT.Use(3, zeros);
+  TVectorD dstub;
+  Double_t dpos[3];
   
-  ApplyCorrections();
+  for(Int_t ihit=0;ihit<nhits; ihit++) {
+    dpos[ihit] = hits[ihit]->GetPos() + plusminus[ihit]*hits[ihit]->GetdDist()
+      - fPsi0[plane_list[ihit]];
+    for(Int_t index=0;index<3;index++) {
+      TT[index]+= dpos[ihit]*fStubCoefs[plane_list[ihit]][index]
+	/fSigma[plane_list[ihit]];
+    }
+  }
+  dstub = (*fAA3Inv[bitpat]) * TT;
+
+  // Calculate Chi2.  Remember one power of sigma is in fStubCoefs
+  stub[0] = dstub[0];
+  stub[1] = dstub[1];
+  stub[2] = dstub[2];
+  stub[3] = 0.0;
+  Double_t chi2=0.0;
+  for(Int_t ihit=0;ihit<nhits; ihit++) {
+    chi2 += pow( dpos[ihit]/fSigma[plane_list[ihit]]
+		 - fStubCoefs[plane_list[ihit]][0]*stub[0]
+		 - fStubCoefs[plane_list[ihit]][1]*stub[1]
+		 - fStubCoefs[plane_list[ihit]][2]*stub[2]
+		 , 2);
+  }
+  return(chi2);
+}
 
-  return 0;
+//_____________________________________________________________________________
+THcDriftChamber::~THcDriftChamber()
+{
+  // Destructor. Remove variables from global list.
+
+  if( fIsSetup )
+    RemoveVariables();
+  if( fIsInit )
+    DeleteArrays();
+  if (fTrackProj) {
+    fTrackProj->Clear();
+    delete fTrackProj; fTrackProj = 0;
+  }
 }
 
 //_____________________________________________________________________________
-Int_t THcDriftChamber::FineTrack( TClonesArray& tracks )
+void THcDriftChamber::DeleteArrays()
 {
-  // Reconstruct coordinates of particle track cross point with scintillator
-  // plane, and copy the data into the following local data structure:
-  //
-  // Units of measurements are meters.
+  // Delete member arrays. Used by destructor.
 
-  // Calculation of coordinates of particle track cross point with scint
-  // plane in the detector coordinate system. For this, parameters of track 
-  // reconstructed in THaVDC::FineTrack() are used.
+}
 
-  return 0;
+//_____________________________________________________________________________
+inline 
+void THcDriftChamber::Clear( const Option_t* )
+{
+  // Reset per-event data.
+  //  fNhits = 0;
+
+  //  fTrackProj->Clear();
+  fNhits = 0;
+
+}
+
+//_____________________________________________________________________________
+Int_t THcDriftChamber::ApplyCorrections( void )
+{
+  return(0);
 }
 
 ClassImp(THcDriftChamber)
diff --git a/src/THcDriftChamber.h b/src/THcDriftChamber.h
index a973c466a25804993d2e8c3576d05cefd9c1eb56..db307dd06bfab3b204bf482e8c3820351d03da0b 100644
--- a/src/THcDriftChamber.h
+++ b/src/THcDriftChamber.h
@@ -7,52 +7,44 @@
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "THaTrackingDetector.h"
-#include "THcHitList.h"
-#include "THcRawDCHit.h"
+#include "THaSubDetector.h"
 #include "THcDriftChamberPlane.h"
-#include "TMath.h"
+#include "TClonesArray.h"
+#include "TMatrixDSym.h"
+
+#include <map>
+
+#define MAX_SPACE_POINTS 50
+#define MAX_HITS_PER_POINT 20
+
+//#include "TMath.h"
 
 //class THaScCalib;
 class TClonesArray;
 
-class THcDriftChamber : public THaTrackingDetector, public THcHitList {
+class THcDriftChamber : public THaSubDetector {
 
 public:
-  THcDriftChamber( const char* name, const char* description = "",
-		   THaApparatus* a = NULL );
+  THcDriftChamber( const char* name, const char* description, Int_t chambernum,
+		   THaDetectorBase* parent = NULL );
   virtual ~THcDriftChamber();
 
-  virtual Int_t      Decode( const THaEvData& );
+  virtual Int_t Decode( const THaEvData& );
   virtual EStatus    Init( const TDatime& run_time );
-  virtual Int_t      CoarseTrack( TClonesArray& tracks );
-  virtual Int_t      FineTrack( TClonesArray& tracks );
   
+  virtual void       AddPlane(THcDriftChamberPlane *plane);
   virtual Int_t      ApplyCorrections( void );
+  virtual void       ProcessHits( void );
+  virtual Int_t      FindSpacePoints( void ) ;
+  virtual void       CorrectHitTimes( void ) ;
+
+  virtual void   Clear( Option_t* opt="" );
 
   //  Int_t GetNHits() const { return fNhit; }
   
   Int_t GetNTracks() const { return fTrackProj->GetLast()+1; }
   const TClonesArray* GetTrackHits() const { return fTrackProj; }
 
-  Int_t GetNWires(Int_t plane) const { return fNWires[plane-1];}
-  Int_t GetNChamber(Int_t plane) const { return fNChamber[plane-1];}
-  Int_t GetWireOrder(Int_t plane) const { return fWireOrder[plane-1];}
-  Int_t GetPitch(Int_t plane) const { return fPitch[plane-1];}
-  Int_t GetCentralWire(Int_t plane) const { return fCentralWire[plane-1];}
-  Int_t GetTdcWinMin(Int_t plane) const { return fTdcWinMin[plane-1];}
-  Int_t GetTdcWinMax(Int_t plane) const { return fTdcWinMax[plane-1];}
-
-  Double_t GetPlaneTimeZero(Int_t plane) const { return fPlaneTimeZero[plane-1];}
-
-  Double_t GetNSperChan() const { return fNSperChan;}
-
-  Double_t GetCenter(Int_t plane) const {
-    Int_t chamber = GetNChamber(plane)-1;
-    return
-      fXCenter[chamber]*sin(fAlphaAngle[plane-1]) +
-      fYCenter[chamber]*cos(fAlphaAngle[plane-1]);
-  }
   //  friend class THaScCalib;
 
   THcDriftChamber();  // for ROOT I/O
@@ -61,65 +53,75 @@ protected:
   // Calibration
 
   // Per-event data
+  Int_t fNhits;
 
-  // Potential Hall C parameters.  Mostly here for demonstration
-  Int_t fNPlanes;
-  char** fPlaneNames;
-  Int_t fNChambers;
+  Int_t fNPlanes;		// Number of planes in the chamber
 
-  Double_t fNSperChan;		/* TDC bin size */
-  Double_t fWireVelocity;
+  Int_t fChamberNum;
 
-  // Each of these will be dimensioned with the number of chambers
-  Double_t* fXCenter;
-  Double_t* fYCenter;
-
-  // Each of these will be dimensioned with the number of planes
-  // A THcDriftChamberPlane class object will need to access the value for
-  // its plane number.  Should we have a Get method for each or 
-  Int_t* fTdcWinMin;
-  Int_t* fTdcWinMax;
-  Int_t* fCentralTime;
-  Int_t* fNWires;		// Number of wires per plane
-  Int_t* fNChamber;
-  Int_t* fWireOrder;
-  Int_t* fDriftTimeSign;
-
-  Double_t* fZPos;
-  Double_t* fAlphaAngle;
-  Double_t* fBetaAngle;
-  Double_t* fGammaAngle;
-  Double_t* fPitch;
-  Double_t* fCentralWire;
-  Double_t* fPlaneTimeZero;
-
-  THcDriftChamberPlane** fPlanes; // List of plane objects
+  // HMS Specific
+  Int_t YPlaneInd; 		// Index of Yplane for this chamber
+  Int_t YPlanePInd; 		// Index of Yplanep for this chamber
+  Int_t YPlaneNum;		// Absolute plane number of Yplane
+  Int_t YPlanePNum;		// Absolute plane number of Yplanep
+
+  // Parameters 
+  Int_t fMinHits; 		// Minimum hits required to do something
+  Int_t fMaxHits; 		// Maximum required to do something
+  Int_t fMinCombos;             // Minimum # pairs in a space point
+  Int_t fRemove_Sppt_If_One_YPlane;
+  Double_t fWireVelocity;
+  Int_t fSmallAngleApprox;
+  Double_t fStubMaxXPDiff;
+
+  Double_t fXCenter;
+  Double_t fYCenter;
+  Double_t fSpacePointCriterion;
+  Double_t fSpacePointCriterion2;
+  Double_t* fSinBeta;
+  Double_t* fCosBeta;
+  Double_t* fTanBeta;
+  Double_t* fSigma;
+  Double_t* fPsi0;
+  Double_t** fStubCoefs;
+
+  THcDriftChamberPlane* fPlanes[20]; // List of plane objects
 
   TClonesArray*  fTrackProj;  // projection of track onto scintillator plane
                               // and estimated match to TOF paddle
-  // Useful derived quantities
-  // double tan_angle, sin_angle, cos_angle;
-  
-  //  static const char NDEST = 2;
-  //  struct DataDest {
-  //    Int_t*    nthit;
-  //    Int_t*    nahit;
-  //    Double_t*  tdc;
-  //    Double_t*  tdc_c;
-  //    Double_t*  adc;
-  //    Double_t*  adc_p;
-  //    Double_t*  adc_c;
-  //    Double_t*  offset;
-  //    Double_t*  ped;
-  //    Double_t*  gain;
-  //  } fDataDest[NDEST];     // Lookup table for decoder
-
-  void           ClearEvent();
+  //  void           ClearEvent();
   void           DeleteArrays();
   virtual Int_t  ReadDatabase( const TDatime& date );
   virtual Int_t  DefineVariables( EMode mode = kDefine );
 
   void Setup(const char* name, const char* description);
+  Int_t      FindEasySpacePoint(Int_t yplane_hitind, Int_t yplanep_hitind);
+  Int_t      FindHardSpacePoints(void);
+  Int_t      DestroyPoorSpacePoints(void);
+  Int_t      SpacePointMultiWire(void);
+  void       ChooseSingleHit(void);
+  void       SelectSpacePoints(void);
+  UInt_t     Count1Bits(UInt_t x);
+  void       LeftRight(void);
+  Double_t   FindStub(Int_t nhits, THcDCHit** hits, Int_t* plane_list,
+			  UInt_t bitpat, Int_t* plusminus, Double_t* stub);
+
+  THcDCHit* fHits[10000];	/* All hits for this chamber */
+  // A simple structure until we figure out what we are doing.
+  struct SpacePoint {
+    Double_t x;
+    Double_t y;
+    Int_t nhits;
+    Int_t ncombos;
+    THcDCHit* hits[MAX_HITS_PER_POINT];
+    Double_t stub[4];
+  };
+  SpacePoint fSpacePoints[MAX_SPACE_POINTS];
+  Int_t fNSpacePoints;
+  Int_t fEasySpacePoint;	/* This event is an easy space point */
+
+  Double_t* stubcoef[4]; 
+  std::map<int,TMatrixDSym*> fAA3Inv;
 
   ClassDef(THcDriftChamber,0)   // Drift Chamber class
 };
diff --git a/src/THcDriftChamberPlane.cxx b/src/THcDriftChamberPlane.cxx
index 816d27a650ea46865c1bd42f0655f5751de1ae1d..bd708bf6c51a7557ef3d09880390f5ab2c637586 100644
--- a/src/THcDriftChamberPlane.cxx
+++ b/src/THcDriftChamberPlane.cxx
@@ -14,7 +14,7 @@
 #include "THcGlobals.h"
 #include "THcParmList.h"
 #include "THcHitList.h"
-#include "THcDriftChamber.h"
+#include "THcDC.h"
 #include "THcHodoscope.h"
 #include "TClass.h"
 
@@ -97,11 +97,11 @@ Int_t THcDriftChamberPlane::ReadDatabase( const TDatime& date )
   gHcParms->LoadParmValues((DBRequest*)&list,prefix);
 
   // Retrieve parameters we need from parent class
-  THcDriftChamber* fParent;
+  THcDC* fParent;
 
-  fParent = (THcDriftChamber*) GetParent();
+  fParent = (THcDC*) GetParent();
   // These are single variables here, but arrays in THcDriftChamber.
-  fNChamber = fParent->GetNChamber(fPlaneNum);
+  fChamberNum = fParent->GetNChamber(fPlaneNum);
   fNWires = fParent->GetNWires(fPlaneNum);
   fWireOrder = fParent->GetWireOrder(fPlaneNum);
   fPitch = fParent->GetPitch(fPlaneNum);
@@ -110,10 +110,72 @@ Int_t THcDriftChamberPlane::ReadDatabase( const TDatime& date )
   fTdcWinMax = fParent->GetTdcWinMax(fPlaneNum);
   fPlaneTimeZero = fParent->GetPlaneTimeZero(fPlaneNum);
   fCenter = fParent->GetCenter(fPlaneNum);
+  fCentralTime = fParent->GetCentralTime(fPlaneNum);
+  fDriftTimeSign = fParent->GetDriftTimeSign(fPlaneNum);
+  fSigma = fParent->GetSigma(fPlaneNum);
 
   fNSperChan = fParent->GetNSperChan();
 
-  cout << fPlaneNum << " " << fNWires << endl;
+  // Calculate Geometry Constants
+  // Do we want to move all this to the Chamber of DC Package leve
+  // as that is where these things will be needed?
+  Double_t z0 = fParent->GetZPos(fPlaneNum);
+  Double_t alpha = fParent->GetAlphaAngle(fPlaneNum);
+  Double_t beta = fParent->GetBetaAngle(fPlaneNum);
+  fBeta = beta;
+  Double_t gamma = fParent->GetGammaAngle(fPlaneNum);
+  Double_t cosalpha = TMath::Cos(alpha);
+  Double_t sinalpha = TMath::Sin(alpha);
+  Double_t cosbeta = TMath::Cos(beta);
+  Double_t sinbeta = TMath::Sin(beta);
+  Double_t cosgamma = TMath::Cos(gamma);
+  Double_t singamma = TMath::Sin(gamma);
+
+  Double_t hzchi = -cosalpha*sinbeta + sinalpha*cosbeta*singamma;
+  Double_t hzpsi =  sinalpha*sinbeta + cosalpha*cosbeta*singamma;
+  Double_t hxchi = -cosalpha*cosbeta - sinalpha*sinbeta*singamma;
+  Double_t hxpsi =  sinalpha*cosbeta - cosalpha*sinbeta*singamma;
+  Double_t hychi =  sinalpha*cosgamma;
+  Double_t hypsi =  cosalpha*cosgamma;
+  Double_t stubxchi = -cosalpha;
+  Double_t stubxpsi = sinalpha;
+  Double_t stubychi = sinalpha;
+  Double_t stubypsi = cosalpha;
+
+  if(cosalpha <= 0.707) { // x-like wire, need dist from x=0 line
+    fReadoutX = 1;
+    fReadoutCorr = 1/sinalpha;
+  } else {
+    fReadoutX = 0;
+    fReadoutCorr = 1/cosalpha;
+  }
+
+  Double_t sumsqupsi = hzpsi*hzpsi+hxpsi*hxpsi+hypsi*hypsi;
+  Double_t sumsquchi = hzchi*hzchi+hxchi*hxchi+hychi*hychi;
+  Double_t sumcross = hzpsi*hzchi + hxpsi*hxchi + hypsi*hychi;
+  Double_t denom1 = sumsqupsi*sumsquchi-sumcross*sumcross;
+  fPsi0 = (-z0*hzpsi*sumsquchi
+		    +z0*hzchi*sumcross) / denom1;
+  Double_t hchi0 = (-z0*hzchi*sumsqupsi
+		    +z0*hzpsi*sumcross) / denom1;
+  Double_t hphi0 = TMath::Sqrt(pow(z0+hzpsi*fPsi0+hzchi*hchi0,2)
+			       + pow(hxpsi*fPsi0+hxchi*hchi0,2)
+			       + pow(hypsi*fPsi0+hychi*hchi0,2) );
+  if(z0 < 0.0) hphi0 = -hphi0;
+  
+  Double_t denom2 = stubxpsi*stubychi - stubxchi*stubypsi;
+
+  // Why are there 4, but only 3 used?
+  fStubCoef[0] = stubychi/(fSigma*denom2);   // sin(a)/sigma
+  fStubCoef[1] = -stubxchi/(fSigma*denom2);   // cos(a)/sigma
+  fStubCoef[2] = hphi0*fStubCoef[0];     // z0*sin(a)/sig
+  fStubCoef[3] = hphi0*fStubCoef[1];     // z0*cos(a)/sig
+
+  fXsp = hychi/denom2;		// sin(a)
+  fYsp = -hxchi/denom2;		// cos(a)
+
+
+  cout << fPlaneNum << " " << fNWires << " " << fWireOrder << endl;
 
   fTTDConv = new THcDCLookupTTDConv(DriftMapFirstBin,fPitch/2,DriftMapBinSize,
 				    NumDriftMapBins,DriftMap);
@@ -242,7 +304,7 @@ Int_t THcDriftChamberPlane::ProcessHits(TClonesArray* rawhits, Int_t nexthit)
 	    - rawtdc*fNSperChan + fPlaneTimeZero;
 	  // How do we get this start time from the hodoscope to here
 	  // (or at least have it ready by coarse process)
-	  new( (*fHits)[nextHit++] ) THcDCHit(wire, rawtdc, time);
+	  new( (*fHits)[nextHit++] ) THcDCHit(wire, rawtdc, time, this);
 	}
 	wire_last = wireNum;
       }
diff --git a/src/THcDriftChamberPlane.h b/src/THcDriftChamberPlane.h
index 7307a4acf649f75679223878d27d2607747c3798..475e9bc9d1d4038a4f1f8bede46e535f41d940b0 100644
--- a/src/THcDriftChamberPlane.h
+++ b/src/THcDriftChamberPlane.h
@@ -48,6 +48,24 @@ class THcDriftChamberPlane : public THaSubDetector {
   { assert( i>=1 && i<=GetNWires() );
     return (THcDCWire*)fWires->UncheckedAt(i-1); }
 
+  Int_t         GetNHits() const { return fHits->GetLast()+1; }
+  TClonesArray* GetHits()  const { return fHits; }
+
+  Int_t        GetPlaneNum() const { return fPlaneNum; }
+  Int_t        GetChamberNum() const { return fChamberNum; }
+  void         SetPlaneIndex(Int_t index) { fPlaneIndex = index; }
+  Int_t        GetPlaneIndex() { return fPlaneIndex; }
+  Double_t     GetXsp() const { return fXsp; }
+  Double_t     GetYsp() const { return fYsp; }
+  Int_t        GetReadoutX() { return fReadoutX; }
+  Double_t     GetReadoutCorr() { return fReadoutCorr; }
+  Double_t     GetCentralTime() { return fCentralTime; }
+  Int_t        GetDriftTimeSign() { return fDriftTimeSign; }
+  Double_t     GetBeta() { return fBeta; }
+  Double_t     GetSigma() { return fSigma; }
+  Double_t     GetPsi0() { return fPsi0; }
+  Double_t*    GetStubCoef() { return fStubCoef; }
+
  protected:
 
   TClonesArray* fParentHitList;
@@ -56,7 +74,8 @@ class THcDriftChamberPlane : public THaSubDetector {
   TClonesArray* fWires;
 
   Int_t fPlaneNum;
-  Int_t fNChamber;
+  Int_t fPlaneIndex;		/* Index of this plane within it's chamber */
+  Int_t fChamberNum;
   Int_t fNWires;
   Int_t fWireOrder;
   Int_t fTdcWinMin;
@@ -64,6 +83,17 @@ class THcDriftChamberPlane : public THaSubDetector {
   Double_t fPitch;
   Double_t fCentralWire;
   Double_t fPlaneTimeZero;
+  Double_t fXsp;
+  Double_t fYsp;
+  Double_t fSigma;
+  Double_t fPsi0;
+  Double_t fStubCoef[4];
+  Double_t fBeta;
+
+  Int_t fReadoutX;
+  Double_t fReadoutCorr;
+  Double_t fCentralTime;
+  Int_t fDriftTimeSign;
 
   Double_t fCenter;
 
diff --git a/src/THcHodoscope.cxx b/src/THcHodoscope.cxx
index 4d09ccf2560968b566b79fcccd8ae438bc95ae92..4a7f365f3cb78d3258b051d56060fe427bcde181 100644
--- a/src/THcHodoscope.cxx
+++ b/src/THcHodoscope.cxx
@@ -73,15 +73,29 @@ void THcHodoscope::Setup(const char* name, const char* description)
   prefix[0]=tolower(GetApparatus()->GetName()[0]);
   prefix[1]='\0';
 
+  string planenamelist;
   DBRequest listextra[]={
     {"hodo_num_planes", &fNPlanes, kInt},
+    {"hodo_plane_names",&planenamelist, kString},
     {0}
   };
-  fNPlanes = 4; 		// Default if not defined
+  //fNPlanes = 4; 		// Default if not defined
   gHcParms->LoadParmValues((DBRequest*)&listextra,prefix);
   
-  // Plane names
+  cout << "Plane Name List : " << planenamelist << endl;
+
+  vector<string> plane_names = vsplit(planenamelist);
+  // Plane names  
+  if(plane_names.size() != (UInt_t) fNPlanes) {
+    cout << "ERROR: Number of planes " << fNPlanes << " doesn't agree with number of plane names " << plane_names.size() << endl;
+    // Should quit.  Is there an official way to quit?
+  }
   fPlaneNames = new char* [fNPlanes];
+  for(Int_t i=0;i<fNPlanes;i++) {
+    fPlaneNames[i] = new char[plane_names[i].length()];
+    strcpy(fPlaneNames[i], plane_names[i].c_str());
+  }
+  /*  fPlaneNames = new char* [fNPlanes];
   for(Int_t i=0;i<fNPlanes;i++) {fPlaneNames[i] = new char[3];}
   // Should get the plane names from parameters.  
   // could try this: grep _zpos PARAM/hhodo.pos | sed 's/\_/\ /g' | awk '{print $2}'
@@ -89,16 +103,15 @@ void THcHodoscope::Setup(const char* name, const char* description)
   strcpy(fPlaneNames[1],"1y");
   strcpy(fPlaneNames[2],"2x");
   strcpy(fPlaneNames[3],"2y");
-
+  */
   // Probably shouldn't assume that description is defined
-  char* desc = new char[strlen(description)+50];
+  char* desc = new char[strlen(description)+100];
   fPlanes = new THcScintillatorPlane* [fNPlanes];
   for(Int_t i=0;i < fNPlanes;i++) {
     strcpy(desc, description);
     strcat(desc, " Plane ");
     strcat(desc, fPlaneNames[i]);
-    fPlanes[i] = new THcScintillatorPlane(fPlaneNames[i], desc, i+1,fNPlanes, this); 
-    //fPlanes[i] = new THcScintillatorPlane(fPlaneNames[i], desc, i+1, this); 
+    fPlanes[i] = new THcScintillatorPlane(fPlaneNames[i], desc, i+1,fNPlanes,this); // Number planes starting from zero!!
     cout << "Created Scintillator Plane " << fPlaneNames[i] << ", " << desc << endl;
   }
 }
@@ -304,7 +317,7 @@ Int_t THcHodoscope::ReadDatabase( const TDatime& date )
   strcpy(parname,prefix);
   strcat(parname,"scin_");
   Int_t plen=strlen(parname);
-
+  cout << " readdatabse hodo fnplanes = " << fNPlanes << endl;
   fNPaddle = new Int_t [fNPlanes];
   //  fSpacing = new Double_t [fNPlanes];
   //fCenter = new Double_t* [fNPlanes];
@@ -393,6 +406,11 @@ Int_t THcHodoscope::ReadDatabase( const TDatime& date )
     {"hodo_pos_ped_limit",&fHodoPosPedLimit[0],kInt,fMaxHodoScin},
     {"hodo_neg_ped_limit",&fHodoNegPedLimit[0],kInt,fMaxHodoScin},
     {"tofusinginvadc",&fTofUsingInvAdc,kInt},
+    {0}
+  };
+  gHcParms->LoadParmValues((DBRequest*)&list,prefix);
+  if (fTofUsingInvAdc) {
+  DBRequest list2[]={
     {"hodo_pos_invadc_offset",&fHodoPosInvAdcOffset[0],kDouble,fMaxHodoScin},
     {"hodo_neg_invadc_offset",&fHodoNegInvAdcOffset[0],kDouble,fMaxHodoScin},
     {"hodo_pos_invadc_linear",&fHodoPosInvAdcLinear[0],kDouble,fMaxHodoScin},
@@ -401,7 +419,8 @@ Int_t THcHodoscope::ReadDatabase( const TDatime& date )
     {"hodo_neg_invadc_adc",&fHodoNegInvAdcAdc[0],kDouble,fMaxHodoScin},
     {0}
   };
-  gHcParms->LoadParmValues((DBRequest*)&list,prefix);
+  gHcParms->LoadParmValues((DBRequest*)&list2,prefix);
+  };
   if (fDebug >=1) {
     cout <<"******* Testing Hodoscope Parameter Reading ***\n";
     cout<<"StarTimeCenter = "<<fStartTimeCenter<<endl;
@@ -455,7 +474,9 @@ Int_t THcHodoscope::DefineVariables( EMode mode )
     //...
     //    hnegtdc4 HMS s2y- TDC hits
 
-  //  RVarDef vars[] = {
+  RVarDef vars[] = {
+    {"starttime","Hodoscope Start Time","fStartTime"},
+    {"hgoodstarttime","Hodoscope Good Start Time","fGoodStartTime"},
   //    { "nlthit", "Number of Left paddles TDC times",  "fLTNhit" },
   //    { "nrthit", "Number of Right paddles TDC times", "fRTNhit" },
   //    { "nlahit", "Number of Left paddles ADCs amps",  "fLANhit" },
@@ -484,10 +505,10 @@ Int_t THcHodoscope::DefineVariables( EMode mode )
   //    { "trpath", "TRCS pathlen of track to det plane","fTrackProj.THaTrackProj.fPathl" },
   //    { "trdx",   "track deviation in x-position (m)", "fTrackProj.THaTrackProj.fdX" },
   //    { "trpad",  "paddle-hit associated with track",  "fTrackProj.THaTrackProj.fChannel" },
-  //    { 0 }
-  //  };
-  //  return DefineVarsFromList( vars, mode );
-  return kOK;
+        { 0 }
+   };
+  return DefineVarsFromList( vars, mode );
+  //  return kOK;
 }
 
 //_____________________________________________________________________________
@@ -594,6 +615,7 @@ Int_t THcHodoscope::Decode( const THaEvData& evdata )
   Int_t nexthit = 0;
   Int_t nfptimes=0;
 
+  fStartTime=0;
   for(Int_t ip=0;ip<fNPlanes;ip++) {
     //    nexthit = fPlanes[ip]->ProcessHits(fRawHitList, nexthit);
     // GN: select only events that have reasonable TDC values to start with
@@ -601,9 +623,8 @@ Int_t THcHodoscope::Decode( const THaEvData& evdata )
     nexthit = fPlanes[ip]->ProcessHits(fRawHitList,nexthit);
     if (fPlanes[ip]->GetNScinHits()>0) {
       fPlanes[ip]->PulseHeightCorrection();
-      ///cout <<"Plane "<<ip<<" number of fpTimes = "<<fPlanes[ip]->GetFpTimeHits()<<endl;
-      for (Int_t ifptimes=0;ifptimes<fPlanes[ip]->GetFpTimeHits();ifptimes++) {
-	fStartTime=fStartTime+fPlanes[ip]->GetFpTime(ifptimes);
+      if (TMath::Abs(fPlanes[ip]->GetFpTime()-fStartTimeCenter)<=fStartTimeSlop) {
+	fStartTime=fStartTime+fPlanes[ip]->GetFpTime();
 	nfptimes++;
       }
     }
diff --git a/src/THcScintillatorPlane.cxx b/src/THcScintillatorPlane.cxx
index f1ccda77f1890d99e1453e9b6928a2275943c675..6595540b5371e11414e1b3a713e0194211f108c6 100644
--- a/src/THcScintillatorPlane.cxx
+++ b/src/THcScintillatorPlane.cxx
@@ -36,13 +36,16 @@ THcScintillatorPlane::THcScintillatorPlane( const char* name,
   fNegTDCHits = new TClonesArray("THcSignalHit",16);
   fPosADCHits = new TClonesArray("THcSignalHit",16);
   fNegADCHits = new TClonesArray("THcSignalHit",16);
+  frPosTDCHits = new TClonesArray("THcSignalHit",16);
+  frNegTDCHits = new TClonesArray("THcSignalHit",16);
+  frPosADCHits = new TClonesArray("THcSignalHit",16);
+  frNegADCHits = new TClonesArray("THcSignalHit",16);
   fPlaneNum = planenum;
   fTotPlanes = planenum;
   fNScinHits = 0; 
   //
   fMaxHits=53;
-  fpTimeHits=0;
-  fpTime = new Double_t [fMaxHits];
+  fpTime = -1.e5;
 }
 //______________________________________________________________________________
 THcScintillatorPlane::THcScintillatorPlane( const char* name, 
@@ -57,13 +60,16 @@ THcScintillatorPlane::THcScintillatorPlane( const char* name,
   fNegTDCHits = new TClonesArray("THcSignalHit",16);
   fPosADCHits = new TClonesArray("THcSignalHit",16);
   fNegADCHits = new TClonesArray("THcSignalHit",16);
+  frPosTDCHits = new TClonesArray("THcSignalHit",16);
+  frNegTDCHits = new TClonesArray("THcSignalHit",16);
+  frPosADCHits = new TClonesArray("THcSignalHit",16);
+  frNegADCHits = new TClonesArray("THcSignalHit",16);
   fPlaneNum = planenum;
   fTotPlanes = totplanes;
   fNScinHits = 0;
   //
   fMaxHits=53;
-  fpTimeHits=0;
-  fpTime = new Double_t [fMaxHits];
+  fpTime = -1.e5;
 
 }
 
@@ -75,7 +81,10 @@ THcScintillatorPlane::~THcScintillatorPlane()
   delete fNegTDCHits;
   delete fPosADCHits;
   delete fNegADCHits;
-  delete fpTime;
+  delete frPosTDCHits;
+  delete frNegTDCHits;
+  delete frPosADCHits;
+  delete frNegADCHits;
 }
 
 //______________________________________________________________________________
@@ -144,14 +153,14 @@ Int_t THcScintillatorPlane::ReadDatabase( const TDatime& date )
   //
   // Based on the signs of these quantities in the .pos file the correspondence 
   // should be bot=>left  and top=>right when comparing x and y-type scintillators
-  char *tmpleft, *tmpright;
+  char tmpleft[6], tmpright[6];
   if (fPlaneNum==1 || fPlaneNum==3) {
-    tmpleft="left";
-    tmpright="right";
+    strcpy(tmpleft,"left");
+    strcpy(tmpright,"right");
   } 
   else {
-    tmpleft="bot";
-    tmpright="top";
+    strcpy(tmpleft,"bot");
+    strcpy(tmpright,"top");
   }
 
   Double_t tmpdouble[fTotPlanes];
@@ -210,13 +219,15 @@ Int_t THcScintillatorPlane::DefineVariables( EMode mode )
   // Register variables in global list
   RVarDef vars[] = {
     {"postdchits", "List of Positive TDC hits", 
-     "fPosTDCHits.THcSignalHit.GetPaddleNumber()"},
+     "frPosTDCHits.THcSignalHit.GetPaddleNumber()"},
     {"negtdchits", "List of Negative TDC hits", 
-     "fNegTDCHits.THcSignalHit.GetPaddleNumber()"},
+     "frNegTDCHits.THcSignalHit.GetPaddleNumber()"},
     {"posadchits", "List of Positive ADC hits", 
-     "fPosADCHits.THcSignalHit.GetPaddleNumber()"},
+     "frPosADCHits.THcSignalHit.GetPaddleNumber()"},
     {"negadchits", "List of Negative ADC hits", 
-     "fNegADCHits.THcSignalHit.GetPaddleNumber()"},
+     "frNegADCHits.THcSignalHit.GetPaddleNumber()"},
+    {"fptime", "Time at focal plane", 
+     "GetFpTime()"},
     { 0 }
   };
 
@@ -232,6 +243,10 @@ void THcScintillatorPlane::Clear( Option_t* )
   fNegTDCHits->Clear();
   fPosADCHits->Clear();
   fNegADCHits->Clear();
+  frPosTDCHits->Clear();
+  frNegTDCHits->Clear();
+  frPosADCHits->Clear();
+  frNegADCHits->Clear();
 }
 
 //_____________________________________________________________________________
@@ -271,6 +286,16 @@ Int_t THcScintillatorPlane::ProcessHits(TClonesArray* rawhits, Int_t nexthit)
   // if the actual ADC is larger than the pedestal value we subtract!!
 
   Double_t mintdc, maxtdc;
+  //raw
+  Int_t nrPosTDCHits=0;
+  Int_t nrNegTDCHits=0;
+  Int_t nrPosADCHits=0;
+  Int_t nrNegADCHits=0;
+  frPosTDCHits->Clear();
+  frNegTDCHits->Clear();
+  frPosADCHits->Clear();
+  frNegADCHits->Clear();
+  //stripped
   Int_t nPosTDCHits=0;
   Int_t nNegTDCHits=0;
   Int_t nPosADCHits=0;
@@ -280,7 +305,6 @@ Int_t THcScintillatorPlane::ProcessHits(TClonesArray* rawhits, Int_t nexthit)
   fNegTDCHits->Clear();
   fPosADCHits->Clear();
   fNegADCHits->Clear();
-
   Int_t nrawhits = rawhits->GetLast()+1;
   // cout << "THcScintillatorPlane::ProcessHits " << fPlaneNum << " " << nexthit << "/" << nrawhits << endl;
   mintdc=((THcHodoscope *)GetParent())->GetTdcMin();
@@ -291,34 +315,28 @@ Int_t THcScintillatorPlane::ProcessHits(TClonesArray* rawhits, Int_t nexthit)
     if(hit->fPlane > fPlaneNum) {
       break;
     }
-
+    Int_t padnum=hit->fCounter;
+    Int_t index=padnum-1;
+    if (hit->fTDC_pos > 0) ((THcSignalHit*) frPosTDCHits->ConstructedAt(nrPosTDCHits++))->Set(padnum, hit->fTDC_pos);
+    if (hit->fTDC_neg > 0) ((THcSignalHit*) frNegTDCHits->ConstructedAt(nrNegTDCHits++))->Set(padnum, hit->fTDC_neg);
+    if ((hit->fADC_pos-fPosPed[index]) >= 50) ((THcSignalHit*) frPosADCHits->ConstructedAt(nrPosADCHits++))->Set(padnum, hit->fADC_pos-fPosPed[index]);
+    if ((hit->fADC_neg-fNegPed[index]) >= 50) ((THcSignalHit*) frNegADCHits->ConstructedAt(nrNegADCHits++))->Set(padnum, hit->fADC_neg-fNegPed[index]);
     // check TDC values
     if (((hit->fTDC_pos >= mintdc) && (hit->fTDC_pos <= maxtdc)) ||
 	((hit->fTDC_neg >= mintdc) && (hit->fTDC_neg <= maxtdc))) {
-
       //TDC positive hit
       THcSignalHit *sighit = (THcSignalHit*) fPosTDCHits->ConstructedAt(nPosTDCHits++);
-      sighit->Set(hit->fCounter, hit->fTDC_pos);
+      sighit->Set(padnum, hit->fTDC_pos);
       // TDC negative hit
       THcSignalHit *sighit2 = (THcSignalHit*) fNegTDCHits->ConstructedAt(nNegTDCHits++);
-      sighit2->Set(hit->fCounter, hit->fTDC_neg);
+      sighit2->Set(padnum, hit->fTDC_neg);
       // ADC positive hit
-      /// if(hit->fADC_pos >  0) {
-	THcSignalHit *sighit3 = (THcSignalHit*) fPosADCHits->ConstructedAt(nPosADCHits++);
-	sighit3->Set(hit->fCounter, hit->fADC_pos-fPosPed[ihit]);
-	///} else {
-	///  cout<<"Skipping ADC_pos "<<hit->fADC_pos<<endl;
-	/// }
+      THcSignalHit *sighit3 = (THcSignalHit*) fPosADCHits->ConstructedAt(nPosADCHits++);
+      sighit3->Set(padnum, hit->fADC_pos-fPosPed[index]);
       // ADC negative hit
-	///      if(hit->fADC_neg >  0) {   
-	// cout <<"adc neg hit!!\n";
-	THcSignalHit *sighit4 = (THcSignalHit*) fNegADCHits->ConstructedAt(nNegADCHits++);
-	sighit4->Set(hit->fCounter, hit->fADC_neg-fNegPed[ihit]);
-	///} else {
-	///cout<<"Skipping ADC_neg "<<hit->fADC_neg<<endl;
-	///}
-      //      cout <<"test "<<fNHits<<endl;
-      fNScinHits=fNScinHits++;
+      THcSignalHit *sighit4 = (THcSignalHit*) fNegADCHits->ConstructedAt(nNegADCHits++);
+      sighit4->Set(padnum, hit->fADC_neg-fNegPed[index]);      
+      fNScinHits++;
     }
     else {
       //cout <<"pos TDC "<<hit->fTDC_pos<<" "<<mintdc<<" "<<maxtdc<<endl;
@@ -364,7 +382,7 @@ Int_t THcScintillatorPlane::PulseHeightCorrection()
   for (i=0;i<200;i++) {
     timehist[i]=0;
   }
-  for (i=0;i<53;i++) {
+  for (i=0;i<fMaxHits;i++) {
     keep_pos[i]=kFALSE;
     keep_neg[i]=kFALSE;
     two_good_times[i]=kFALSE;
@@ -376,8 +394,8 @@ Int_t THcScintillatorPlane::PulseHeightCorrection()
   toftolerance=((THcHodoscope *)GetParent())->GetTofTolerance();
   //  hbeta_pcent=(TH((THcHodoscope *)GetParent())->GetParent()
   // Horrible hack until I find out where to get the central beta from momentum!! GN
-  hbeta_pcent=0.99776;
-
+  hbeta_pcent=1.0;
+  fpTime=-1e5;
   for (i=0;i<fNScinHits;i++) {
     if ((((THcSignalHit*) fPosTDCHits->At(i))->GetData()>=mintdc) &&
 	(((THcSignalHit*) fPosTDCHits->At(i))->GetData()<=maxtdc) &&
@@ -385,18 +403,29 @@ Int_t THcScintillatorPlane::PulseHeightCorrection()
 	(((THcSignalHit*) fNegTDCHits->At(i))->GetData()<=maxtdc)) {
 	  pos_ph[i]=((THcSignalHit*) fPosADCHits->At(i))->GetData();
 	  postime[i]=((THcSignalHit*) fPosTDCHits->At(i))->GetData()*tdctotime;
-	  j=((THcSignalHit*)fPosTDCHits->At(i))->GetPaddleNumber();
+	  j=((THcSignalHit*)fPosTDCHits->At(i))->GetPaddleNumber()-1;
 	  index=((THcHodoscope *)GetParent())->GetScinIndex(fPlaneNum-1,j);
 	  postime[i]=postime[i]-((THcHodoscope *)GetParent())->GetHodoPosPhcCoeff(index)*
 	    TMath::Sqrt(TMath::Max(0.,(pos_ph[i]/((THcHodoscope *)GetParent())->GetHodoPosMinPh(index)-1)));
 	  postime[i]=postime[i]-((THcHodoscope *)GetParent())->GetHodoPosTimeOffset(index);
+
 	  neg_ph[i]=((THcSignalHit*) fNegADCHits->At(i))->GetData();
 	  negtime[i]=((THcSignalHit*) fNegTDCHits->At(i))->GetData()*tdctotime;
-	  j=((THcSignalHit*)fNegTDCHits->At(i))->GetPaddleNumber();
+	  j=((THcSignalHit*)fNegTDCHits->At(i))->GetPaddleNumber()-1;
 	  index=((THcHodoscope *)GetParent())->GetScinIndex(fPlaneNum-1,j);
 	  negtime[i]=negtime[i]-((THcHodoscope *)GetParent())->GetHodoNegPhcCoeff(index)*
 	    TMath::Sqrt(TMath::Max(0.,(neg_ph[i]/((THcHodoscope *)GetParent())->GetHodoNegMinPh(index)-1)));
 	  negtime[i]=negtime[i]-((THcHodoscope *)GetParent())->GetHodoNegTimeOffset(index);
+
+	  // ***************
+	  ///	  cout <<"hcana i = "<<i<<endl;
+	  ///  cout <<"hcana tdc_pos = "<<((THcSignalHit*) fPosTDCHits->At(i))->GetData()<<endl;
+	  ///cout <<"hcana pos_ph = "<<pos_ph[i]<<endl;
+	  //	  cout <<"hcana pos_phc_coeff = "<<((THcHodoscope *)GetParent())->GetHodoPosPhcCoeff(index)<<endl;
+	  //	  cout <<"hcana postime = "<<postime[i]<<endl;
+	  //cout <<"hcana negtime = "<<negtime[i]<<endl;
+	  //*************
+
 	  // Find hit position.  If postime larger, then hit was nearer negative side.
 	  dist_from_center=0.5*(negtime[i]-postime[i])*((THcHodoscope *)GetParent())->GetHodoVelLight(index);
 	  scint_center=0.5*(fPosLeft+fPosRight);
@@ -405,6 +434,7 @@ Int_t THcScintillatorPlane::PulseHeightCorrection()
 	  hit_position=TMath::Max(hit_position,fPosRight);
 	  postime[i]=postime[i]-(fPosLeft-hit_position)/((THcHodoscope *)GetParent())->GetHodoVelLight(index);
 	  negtime[i]=negtime[i]-(hit_position-fPosRight)/((THcHodoscope *)GetParent())->GetHodoVelLight(index);
+
 	  time_pos[i]=postime[i]-(fZpos+(j%2)*fDzpos)/(29.979*hbeta_pcent);
 	  time_neg[i]=negtime[i]-(fZpos+(j%2)*fDzpos)/(29.979*hbeta_pcent);
 	  nfound++;
@@ -421,7 +451,7 @@ Int_t THcScintillatorPlane::PulseHeightCorrection()
     }
   }
   // Find the bin with most hits
-  jmax=-1;
+  jmax=0;
   maxhit=0;
   for (i=0;i<200;i++) {
     if (timehist[i]>maxhit) {
@@ -451,14 +481,13 @@ Int_t THcScintillatorPlane::PulseHeightCorrection()
       two_good_times[i]=kTRUE;
     }
   } // end of loop that finds tube setting time
-  fpTimeHits=0;
   for (i=0;i<fNScinHits;i++) {
     if (two_good_times[i]) { // both tubes fired
       // correct time for everything except veloc. correction in order
       // to find hit location from difference in TDC.
       pos_ph[i]=((THcSignalHit*) fPosADCHits->At(i))->GetData();
       postime[i]=((THcSignalHit*) fPosTDCHits->At(i))->GetData()*tdctotime;
-      j=((THcSignalHit*)fPosTDCHits->At(i))->GetPaddleNumber();
+      j=((THcSignalHit*)fPosTDCHits->At(i))->GetPaddleNumber()-1;
       index=((THcHodoscope *)GetParent())->GetScinIndex(fPlaneNum-1,j);
       postime[i]=postime[i]-((THcHodoscope *)GetParent())->GetHodoPosPhcCoeff(index)*
 	TMath::Sqrt(TMath::Max(0.,(pos_ph[i]/((THcHodoscope *)GetParent())->GetHodoPosMinPh(index)-1)));
@@ -466,7 +495,7 @@ Int_t THcScintillatorPlane::PulseHeightCorrection()
       //
       neg_ph[i]=((THcSignalHit*) fNegADCHits->At(i))->GetData();
       negtime[i]=((THcSignalHit*) fNegTDCHits->At(i))->GetData()*tdctotime;
-      j=((THcSignalHit*)fNegTDCHits->At(i))->GetPaddleNumber();
+      j=((THcSignalHit*)fNegTDCHits->At(i))->GetPaddleNumber()-1;
       index=((THcHodoscope *)GetParent())->GetScinIndex(fPlaneNum-1,j);
       negtime[i]=negtime[i]-((THcHodoscope *)GetParent())->GetHodoNegPhcCoeff(index)*
 	TMath::Sqrt(TMath::Max(0.,(neg_ph[i]/((THcHodoscope *)GetParent())->GetHodoNegMinPh(index)-1)));
@@ -480,13 +509,10 @@ Int_t THcScintillatorPlane::PulseHeightCorrection()
       postime[i]=postime[i]-(fPosLeft-hit_position)/((THcHodoscope *)GetParent())->GetHodoVelLight(index);
       negtime[i]=negtime[i]-(hit_position-fPosRight)/((THcHodoscope *)GetParent())->GetHodoVelLight(index);
       scin_corrected_time[i]=0.5*(postime[i]+negtime[i]);
-      fpTime[i]=scin_corrected_time[i]-(fZpos+(j%2)*fDzpos)/(29.979*hbeta_pcent);
-      ///   cout <<"fptime ["<<i<<"]= "<<fpTime[i]<<endl;
-      fpTimeHits++;
+      fpTime=scin_corrected_time[i]-(fZpos+(j%2)*fDzpos)/(29.979*hbeta_pcent);
     }
     else { // only one tube fired
       scin_corrected_time[i]=0.0; // not a very good "flag" but there is the logical two_good_hits...
-      fpTime[i]=0.0; // NOTE: we're not incrementing fpTimeHits. In principle these two lines might be deleted
     }
   }
   // Start time calculation, assume xp=yp=0 radians. project all
@@ -552,7 +578,7 @@ void THcScintillatorPlane::CalculatePedestals( )
     fNegPed[i] = ((Double_t) fNegPedSum[i]) / TMath::Max(1, fNegPedCount[i]);
     fNegThresh[i] = fNegPed[i] + 15;
 
-    //    cout << i+1 << " " << fPosPed[i] << " " << fNegPed[i] << endl;
+    //    cout <<"Pedestals "<< i+1 << " " << fPosPed[i] << " " << fNegPed[i] << endl;
   }
   //  cout << " " << endl;
   
diff --git a/src/THcScintillatorPlane.h b/src/THcScintillatorPlane.h
index f47b1ebdd721d7c954a84663b42abb492e349230..cb832fa7dd0975bf1eb0d064e6e6cb91a2e60cfb 100644
--- a/src/THcScintillatorPlane.h
+++ b/src/THcScintillatorPlane.h
@@ -53,13 +53,16 @@ class THcScintillatorPlane : public THaSubDetector {
   Double_t GetPosRight();
   Double_t GetPosOffset();
   Double_t GetPosCenter(Int_t PaddleNo); // here we're counting from zero!
-  Double_t GetFpTime(Int_t index) { return fpTime[index];};
-  Int_t GetFpTimeHits() { return fpTimeHits;};
+  Double_t GetFpTime() { return fpTime;};
 
   TClonesArray* fParentHitList;
 
  protected:
 
+  TClonesArray* frPosTDCHits;
+  TClonesArray* frNegTDCHits;
+  TClonesArray* frPosADCHits;
+  TClonesArray* frNegADCHits;
   TClonesArray* fPosTDCHits;
   TClonesArray* fNegTDCHits;
   TClonesArray* fPosADCHits;
@@ -103,8 +106,8 @@ class THcScintillatorPlane : public THaSubDetector {
   Double_t *fNegThresh;
 
   //
-  Int_t fpTimeHits; // number of entries in *fpTime
-  Double_t   *fpTime; // array with fpTimes for this scintillator plane
+  Double_t   fpTime; // the original code only has one fpTime per plane!
+
 
   virtual Int_t  ReadDatabase( const TDatime& date );
   virtual Int_t  DefineVariables( EMode mode = kDefine );
diff --git a/src/THcSignalHit.h b/src/THcSignalHit.h
index da9d27bbacafefd96e8c1d401a2fd860adcfcb2e..6af80a6e68a203261d306336022d015a237a71cf 100644
--- a/src/THcSignalHit.h
+++ b/src/THcSignalHit.h
@@ -22,6 +22,8 @@ class THcSignalHit : public TObject {
 
   virtual void Set(Int_t paddle, Int_t data)
   { fPaddleNumber=paddle; fData=data; }
+  virtual void Set(Int_t paddle, Double_t data)
+  { fPaddleNumber=paddle; fData=data; }
 
  private:
   Int_t fPaddleNumber;