diff --git a/Makefile b/Makefile
index 8965ef476807633dea2e5d9160fb5635dd01aef5..26a08fcae21297e07aca42c1a6f925db8abd82ae 100644
--- a/Makefile
+++ b/Makefile
@@ -13,6 +13,7 @@ SRC  =  src/THcInterface.cxx src/THcParmList.cxx src/THcAnalyzer.cxx \
 	src/THcDCHit.cxx \
 	src/THcHitList.cxx src/THcDetectorMap.cxx src/THcHodoscope.cxx \
 	src/THcHallCSpectrometer.cxx src/THcDriftChamber.cxx \
+	src/THcDriftChamberPlane.cxx \
 	src/THcScintillatorPlane.cxx src/THcSignalHit.cxx \
 	src/THcShower.cxx src/THcShowerHit.cxx src/THcShowerPlane.cxx  
 
diff --git a/examples/hodtest.C b/examples/hodtest.C
index f730a8c5a076e1830498c48a4718cdde398292ea..928ff4d13afae8b2f9d67d1792fce3536955cf70 100644
--- a/examples/hodtest.C
+++ b/examples/hodtest.C
@@ -18,12 +18,12 @@
   // Add hodoscope
   HMS->AddDetector( new THcHodoscope("hod", "Hodoscope" ));
   HMS->AddDetector( new THcShower("Cal", "Shower" ));
-  //  HMS->AddDetector( new THcDriftChamber("dc", "Drift Chambers" ));
+  HMS->AddDetector( new THcDriftChamber("dc", "Drift Chambers" ));
 
   // Set up the analyzer - we use the standard one,
   // but this could be an experiment-specific one as well.
   // The Analyzer controls the reading of the data, executes
-  // tests/cuts, loops over Apparatus's and PhysicsModules,
+  // tests/cuts, loops over Acpparatus's and PhysicsModules,
   // and executes the output routines.
   THcAnalyzer* analyzer = new THcAnalyzer;
   
diff --git a/examples/output.def b/examples/output.def
index 86d1e07957e4dc71f2fec8b47ac4d460036735a3..cf1c55cef0be09ea2ce8b2fa1d2b77bd58cdb9aa 100644
--- a/examples/output.def
+++ b/examples/output.def
@@ -1,6 +1,8 @@
 # See $ANALYZER/examples/output_example.def for examples
 #
+block H.dc.*
 block H.hod.*
+block H.Cal.*
 
 
 # TDC hits per paddle
@@ -23,7 +25,6 @@ TH1F hnegadc3 'HMS s2x- ADC hits' H.hod.2x.negadchits 16 0.5 16.5
 TH1F hposadc4 'HMS s2y+ ADC hits' H.hod.2y.posadchits 10 0.5 10.5
 TH1F hnegadc4 'HMS s2y- ADC hits' H.hod.2y.negadchits 10 0.5 10.5
 
-block H.Cal.*
 # ADC hits per Calorimeter layer
 TH1F chposadc1 'HMS Cal 1z+ ADC hits' H.Cal.1z.posadchits 13 0.5 13.5
 TH1F chnegadc1 'HMS Cal 1z- ADC hits' H.Cal.1z.negadchits 13 0.5 13.5
@@ -31,3 +32,4 @@ TH1F chposadc2 'HMS Cal 2z+ ADC hits' H.Cal.2z.posadchits 13 0.5 13.5
 TH1F chnegadc2 'HMS Cal 2z- ADC hits' H.Cal.2z.negadchits 13 0.5 13.5
 TH1F chposadc3 'HMS Cal 3z+ ADC hits' H.Cal.3z.posadchits 13 0.5 13.5
 TH1F chposadc4 'HMS Cal 4z+ ADC hits' H.Cal.4z.posadchits 13 0.5 13.5
+
diff --git a/src/HallC_LinkDef.h b/src/HallC_LinkDef.h
index d5bbfdd9d41fc8ec7238a2d0d31be55951d5e7f5..dc4d7101faedb04ea68e48b668d946e35920bd83 100644
--- a/src/HallC_LinkDef.h
+++ b/src/HallC_LinkDef.h
@@ -16,6 +16,7 @@
 #pragma link C++ class THcHitList+;
 #pragma link C++ class THcHodoscope+;
 #pragma link C++ class THcDriftChamber+;
+#pragma link C++ class THcDriftChamberPlane+;
 #pragma link C++ class THcDetectorMap+;
 #pragma link C++ class THcHallCSpectrometer+;
 #pragma link C++ class THcScintillatorPlane+;
diff --git a/src/THcDriftChamber.cxx b/src/THcDriftChamber.cxx
index 2e8881df5333d56685e8084833ba368f400d9c54..b69d21243bef7781e2662dd7261958dca01b7d1c 100644
--- a/src/THcDriftChamber.cxx
+++ b/src/THcDriftChamber.cxx
@@ -31,18 +31,69 @@
 using namespace std;
 
 //_____________________________________________________________________________
-THcDriftChamber::THcDriftChamber( const char* name, const char* description,
+THcDriftChamber::THcDriftChamber(
+ const char* name, const char* description,
 				  THaApparatus* apparatus ) :
-  THaNonTrackingDetector(name,description,apparatus)
+  THaTrackingDetector(name,description,apparatus)
 {
   // Constructor
 
-  fTrackProj = new TClonesArray( "THaTrackProj", 5 );
+  //  fTrackProj = new TClonesArray( "THaTrackProj", 5 );
+
+}
+
+//_____________________________________________________________________________
+void THcDriftChamber::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';
+
+  strcpy(parname,prefix);
+  strcat(parname,name); 	// Append "dc"
+  Int_t plen=strlen(parname);
+  cout << "parname=" << parname << endl;
+
+  // Get number of planes and number wires for each plane
+  strcat(parname,"_num_planes");
+  fNPlanes = *(Int_t *)gHcParms->Find(parname)->GetValuePointer();
+
+  parname[plen] = '\0';
+  strcat(parname,"_num_chambers");
+  fNChambers = *(Int_t *)gHcParms->Find(parname)->GetValuePointer();
+
+  fPlaneNames = new char* [fNPlanes];
+
+  char *desc = new char[strlen(description)+100];
+  fPlanes = new THcDriftChamberPlane* [fNPlanes];
+
+  for(Int_t i=0;i<fNPlanes;i++) {
+    fPlaneNames[i] = new char[5];
+    sprintf(fPlaneNames[i],"%d",i+1);
+    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( ) :
-  THaNonTrackingDetector()
+  THaTrackingDetector()
 {
   // Constructor
 }
@@ -52,8 +103,22 @@ THaAnalysisObject::EStatus THcDriftChamber::Init( const TDatime& date )
 {
   static const char* const here = "Init()";
 
-  if( THaNonTrackingDetector::Init( date ) )
-    return fStatus;
+  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, "THcDCHit", 1000);
+
+  EStatus status;
+  // This triggers call of ReadDatabase and DefineVariables
+  if( (status = THaTrackingDetector::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] = {
@@ -62,16 +127,18 @@ THaAnalysisObject::EStatus THcDriftChamber::Init( const TDatime& date )
   //  };
   //  memcpy( fDataDest, tmp, NDEST*sizeof(DataDest) );
 
-  // Should probably put this in ReadDatabase as we will know the
-  // maximum number of hits after setting up the detector map
-
-  THcHitList::InitHitList(fDetMap, "THcDCHit", 1000);
-
   // Will need to determine which apparatus it belongs to and use the
   // appropriate detector ID in the FillMap call
-  if( gHcDetectorMap->FillMap(fDetMap, "HDC") < 0 ) {
+  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.", 
-	     "HSCIN");
+	     EngineDID);
       return kInitError;
   }
 
@@ -87,39 +154,36 @@ Int_t THcDriftChamber::ReadDatabase( const TDatime& date )
   // '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.
 
-  //  DBRequest list[] = {
-  //    { "TDC_offsetsL", fLOff, kDouble, fNelem },
-  //    { "TDC_offsetsR", fROff, kDouble, fNelem },
-  //    { "ADC_pedsL", fLPed, kDouble, fNelem },
-  //    { "ADC_pedsR", fRPed, kDouble, fNelem },
-  //    { "ADC_coefL", fLGain, kDouble, fNelem },
-  //    { "ADC_coefR", fRGain, kDouble, fNelem },
-  //    { "TDC_res",   &fTdc2T },
-  //    { "TransSpd",  &fCn },
-  //    { "AdcMIP",    &fAdcMIP },
-  //    { "NTWalk",    &fNTWalkPar, kInt },
-  //    { "Timewalk",  fTWalkPar, kDouble, 2*fNelem },
-  //    { "ReTimeOff", fTrigOff, kDouble, fNelem },
-  //    { "AvgRes",    &fResolution },
-  //    { "Atten",     &fAttenuation },
-  //    { 0 }
-  //  };
-
   // 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)
 
-  fNPlanes = *(Int_t *)gHcParms->Find("hdc_num_planes")->GetValuePointer();
+  prefix[0]=tolower(GetApparatus()->GetName()[0]);
+
+  prefix[1]='\0';
 
+  strcpy(parname,prefix);
+  strcat(parname,"dc");
+  Int_t plen=strlen(parname);
+
+  // Get number of planes and number wires for each plane
+  strcat(parname,"_num_planes");
+  fNPlanes = *(Int_t *)gHcParms->Find(parname)->GetValuePointer();
+
+  parname[plen]='\0';
+  strcat(parname,"_nrwire");
+  
   fNWires = new Int_t [fNPlanes];
-  Int_t* p= (Int_t *)gHcParms->Find("hdc_nrwire")->GetValuePointer();
+  Int_t* p= (Int_t *)gHcParms->Find(parname)->GetValuePointer();
   for(Int_t i=0;i<fNPlanes;i++) {
     fNWires[i] = p[i];
   }
@@ -241,17 +305,25 @@ Int_t THcDriftChamber::Decode( const THaEvData& evdata )
   // Get the Hall C style hitlist (fRawHitList) for this event
   Int_t nhits = 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);
+  }
+
+#if 0
   // fRawHitList is TClones array of THcDCHit objects
   for(Int_t ihit = 0; ihit < fNRawHits ; ihit++) {
     THcDCHit* hit = (THcDCHit *) fRawHitList->At(ihit);
-    cout << ihit << " : " << hit->fPlane << ":" << hit->fCounter << " : "
-	 << endl;
+    //    cout << ihit << " : " << hit->fPlane << ":" << hit->fCounter << " : "
+    //	 << endl;
     for(Int_t imhit = 0; imhit < hit->fNHits; imhit++) {
-      cout << "                     " << imhit << " " << hit->fTDC[imhit]
-	   << endl;
+      //      cout << "                     " << imhit << " " << hit->fTDC[imhit]
+      //	   << endl;
     }
   }
-  cout << endl;
+  //  cout << endl;
+#endif
 
   return nhits;
 }
@@ -263,7 +335,7 @@ Int_t THcDriftChamber::ApplyCorrections( void )
 }
 
 //_____________________________________________________________________________
-Int_t THcDriftChamber::CoarseProcess( TClonesArray& /* tracks */ )
+Int_t THcDriftChamber::CoarseTrack( TClonesArray& /* tracks */ )
 {
   // Calculation of coordinates of particle track cross point with scint
   // plane in the detector coordinate system. For this, parameters of track 
@@ -279,7 +351,7 @@ Int_t THcDriftChamber::CoarseProcess( TClonesArray& /* tracks */ )
 }
 
 //_____________________________________________________________________________
-Int_t THcDriftChamber::FineProcess( TClonesArray& tracks )
+Int_t THcDriftChamber::FineTrack( TClonesArray& tracks )
 {
   // Reconstruct coordinates of particle track cross point with scintillator
   // plane, and copy the data into the following local data structure:
diff --git a/src/THcDriftChamber.h b/src/THcDriftChamber.h
index b9f7be4e68c9e8ddd9899a9af31cc7ac90237e73..f96363d60e1d3452c4b9ee0f34b6589b24c87fae 100644
--- a/src/THcDriftChamber.h
+++ b/src/THcDriftChamber.h
@@ -7,14 +7,15 @@
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "TClonesArray.h"
-#include "THaNonTrackingDetector.h"
+#include "THaTrackingDetector.h"
 #include "THcHitList.h"
 #include "THcDCHit.h"
+#include "THcDriftChamberPlane.h"
 
-class THaScCalib;
+//class THaScCalib;
+class TClonesArray;
 
-class THcDriftChamber : public THaNonTrackingDetector, public THcHitList {
+class THcDriftChamber : public THaTrackingDetector, public THcHitList {
 
 public:
   THcDriftChamber( const char* name, const char* description = "",
@@ -23,8 +24,8 @@ public:
 
   virtual Int_t      Decode( const THaEvData& );
   virtual EStatus    Init( const TDatime& run_time );
-  virtual Int_t      CoarseProcess( TClonesArray& tracks );
-  virtual Int_t      FineProcess( TClonesArray& tracks );
+  virtual Int_t      CoarseTrack( TClonesArray& tracks );
+  virtual Int_t      FineTrack( TClonesArray& tracks );
   
   virtual Int_t      ApplyCorrections( void );
 
@@ -33,7 +34,7 @@ public:
   Int_t GetNTracks() const { return fTrackProj->GetLast()+1; }
   const TClonesArray* GetTrackHits() const { return fTrackProj; }
   
-  friend class THaScCalib;
+  //  friend class THaScCalib;
 
   THcDriftChamber();  // for ROOT I/O
 protected:
@@ -45,8 +46,12 @@ protected:
 
   // Potential Hall C parameters.  Mostly here for demonstration
   Int_t fNPlanes;
+  char** fPlaneNames;
+  Int_t fNChambers;
   Int_t* fNWires;		// Number of wires per plane
 
+  THcDriftChamberPlane** fPlanes; // List of plane objects
+
   TClonesArray*  fTrackProj;  // projection of track onto scintillator plane
                               // and estimated match to TOF paddle
   // Useful derived quantities
@@ -71,7 +76,9 @@ protected:
   virtual Int_t  ReadDatabase( const TDatime& date );
   virtual Int_t  DefineVariables( EMode mode = kDefine );
 
-  ClassDef(THcDriftChamber,0)   // Generic hodoscope class
+  void Setup(const char* name, const char* description);
+
+  ClassDef(THcDriftChamber,0)   // Drift Chamber class
 };
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/THcDriftChamberPlane.cxx b/src/THcDriftChamberPlane.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1040342149b78125e1d86512623579ff25ca21c8
--- /dev/null
+++ b/src/THcDriftChamberPlane.cxx
@@ -0,0 +1,171 @@
+//*-- Author :
+
+//////////////////////////////////////////////////////////////////////////
+//
+// THcDriftChamberPlane
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "THcDriftChamberPlane.h"
+#include "TClonesArray.h"
+#include "THcSignalHit.h"
+#include "THcGlobals.h"
+#include "THcParmList.h"
+#include "THcHitList.h"
+#include "THcDriftChamber.h"
+
+#include <cstring>
+#include <cstdio>
+#include <cstdlib>
+#include <iostream>
+
+using namespace std;
+
+ClassImp(THcDriftChamberPlane)
+
+//______________________________________________________________________________
+THcDriftChamberPlane::THcDriftChamberPlane( const char* name, 
+					    const char* description,
+					    const Int_t planenum,
+					    THaDetectorBase* parent )
+  : THaSubDetector(name,description,parent)
+{
+  // Normal constructor with name and description
+  fTDCHits = new TClonesArray("THcSignalHit",100);
+  fPlaneNum = planenum;
+}
+
+//______________________________________________________________________________
+THcDriftChamberPlane::~THcDriftChamberPlane()
+{
+  // Destructor
+  delete fTDCHits;
+
+}
+THaAnalysisObject::EStatus THcDriftChamberPlane::Init( const TDatime& date )
+{
+  // Extra initialization for scintillator plane: set up DataDest map
+
+  cout << "THcDriftChamberPlane::Init called " << GetName() << endl;
+
+  if( IsZombie())
+    return fStatus = kInitError;
+
+  // How to get information for parent
+  //  if( GetParent() )
+  //    fOrigin = GetParent()->GetOrigin();
+
+  EStatus status;
+  if( (status=THaSubDetector::Init( date )) )
+    return fStatus = status;
+
+  return fStatus = kOK;
+
+}
+
+//_____________________________________________________________________________
+Int_t THcDriftChamberPlane::ReadDatabase( const TDatime& date )
+{
+
+  // See what file it looks for
+  
+  static const char* const here = "ReadDatabase()";
+  char prefix[2];
+  char parname[100];
+  
+  prefix[0]=tolower(GetParent()->GetPrefix()[0]);
+  prefix[1]='\0';
+
+  // Retrieve parameters we need
+
+  return kOK;
+}
+//_____________________________________________________________________________
+Int_t THcDriftChamberPlane::DefineVariables( EMode mode )
+{
+  // Initialize global variables and lookup table for decoder
+
+  //  cout << "THcDriftChamberPlane::DefineVariables called " << GetName() << endl;
+
+  if( mode == kDefine && fIsSetup ) return kOK;
+  fIsSetup = ( mode == kDefine );
+
+  // Register variables in global list
+  RVarDef vars[] = {
+    {"tdchits", "List of TDC hits", 
+     "fTDCHits.THcSignalHit.GetPaddleNumber()"},
+    { 0 }
+  };
+
+  return DefineVarsFromList( vars, mode );
+}
+
+//_____________________________________________________________________________
+void THcDriftChamberPlane::Clear( Option_t* )
+{
+  //cout << " Calling THcDriftChamberPlane::Clear " << GetName() << endl;
+  // Clears the hit lists
+  fTDCHits->Clear();
+}
+
+//_____________________________________________________________________________
+Int_t THcDriftChamberPlane::Decode( const THaEvData& evdata )
+{
+  // Doesn't actually get called.  Use Fill method instead
+  cout << " Calling THcDriftChamberPlane::Decode " << GetName() << endl;
+
+  return 0;
+}
+//_____________________________________________________________________________
+Int_t THcDriftChamberPlane::CoarseProcess( TClonesArray& tracks )
+{
+ 
+  //  HitCount();
+
+ return 0;
+}
+
+//_____________________________________________________________________________
+Int_t THcDriftChamberPlane::FineProcess( TClonesArray& tracks )
+{
+  return 0;
+}
+Int_t THcDriftChamberPlane::ProcessHits(TClonesArray* rawhits, Int_t nexthit)
+{
+  // Extract the data for this plane from hit list
+  // Assumes that the hit list is sorted by plane, so we stop when the
+  // plane doesn't agree and return the index for the next hit.
+
+  Int_t nTDCHits=0;
+  fTDCHits->Clear();
+
+  Int_t nrawhits = rawhits->GetLast()+1;
+  // cout << "THcDriftChamberPlane::ProcessHits " << fPlaneNum << " " << nexthit << "/" << nrawhits << endl;
+
+  Int_t ihit = nexthit;
+  while(ihit < nrawhits) {
+    THcDCHit* hit = (THcDCHit *) rawhits->At(ihit);
+    if(hit->fPlane > fPlaneNum) {
+      break;
+    }
+    // Just put in the first hit for now
+    if(hit->fNHits > 0) {	// Should always be the case
+#if ROOT_VERSION_CODE >= ROOT_VERSION(5,32,0)      
+      THcSignalHit *sighit = (THcSignalHit*) fTDCHits->ConstructedAt(nTDCHits++);
+#else
+      TObject* obj = (*fTDCHits)[nTDCHits++];
+      R__ASSERT( obj );
+      if(!obj->TestBit (TObject::kNotDeleted))
+	fTDCHitsClass->New(obj);
+      THcSignalHit *sighit = (THcSignalHit*)obj;
+#endif  
+      sighit->Set(hit->fCounter, hit->fTDC[0]);
+    }
+    ihit++;
+  }
+  return(ihit);
+}
+
+    
+  
+  
diff --git a/src/THcDriftChamberPlane.h b/src/THcDriftChamberPlane.h
new file mode 100644
index 0000000000000000000000000000000000000000..29f4bb799abbc484d2f4f88d2caf9bef43dd5d00
--- /dev/null
+++ b/src/THcDriftChamberPlane.h
@@ -0,0 +1,56 @@
+#ifndef ROOT_THcDriftChamberPlane
+#define ROOT_THcDriftChamberPlane
+
+//////////////////////////////////////////////////////////////////////////////
+//                         
+// THcDriftChamberPlane
+//
+// A Hall C scintillator plane
+//
+// May want to later inherit from a THcPlane class if there are similarities
+// in what a plane is shared with other detector types (shower, etc.)
+// 
+//////////////////////////////////////////////////////////////////////////////
+
+#include "THaSubDetector.h"
+#include "TClonesArray.h"
+
+class THaEvData;
+class THaSignalHit;
+
+class THcDriftChamberPlane : public THaSubDetector {
+  
+ public:
+  THcDriftChamberPlane( const char* name, const char* description,
+			Int_t planenum, THaDetectorBase* parent = NULL);
+  virtual ~THcDriftChamberPlane();
+
+  virtual void    Clear( Option_t* opt="" );
+  virtual Int_t Decode( const THaEvData& );
+  virtual EStatus Init( const TDatime& run_time );
+
+  virtual Int_t CoarseProcess( TClonesArray& tracks );
+  virtual Int_t FineProcess( TClonesArray& tracks );
+          Bool_t   IsTracking() { return kFALSE; }
+  virtual Bool_t   IsPid()      { return kFALSE; }
+
+  virtual Int_t ProcessHits(TClonesArray* rawhits, Int_t nexthit);
+
+  Double_t fSpacing;
+
+  TClonesArray* fParentHitList;
+
+ protected:
+
+  TClonesArray* fTDCHits;
+
+  Int_t fPlaneNum;
+
+  virtual Int_t  ReadDatabase( const TDatime& date );
+  virtual Int_t  DefineVariables( EMode mode = kDefine );
+
+  ClassDef(THcDriftChamberPlane,0)
+};
+#endif
+
+