diff --git a/SConscript.py b/SConscript.py
index fa43727beb7376c8dfe3449b8f9a9db4a6d4cc11..fc1f30932bc7a53dc21b3cd882f9625c53986400 100644
--- a/SConscript.py
+++ b/SConscript.py
@@ -11,17 +11,18 @@ Import ('pbaseenv')
 roothcdict = pbaseenv.subst('$HC_DIR')+'/HallCDict.C'
 roothcobj = pbaseenv.subst('$HC_SRC')+'/HallCDict.so'
 hcheaders = Split("""
-	src/THcInterface.h src/THcParmList.h src/THcAnalyzer.h src/THcHallCSpectrometer.h 
-	src/THcDetectorMap.h src/THcRawHit.h src/THcHitList.h src/THcSignalHit.h src/THcHodoscope.h 
+	src/THcInterface.h src/THcParmList.h src/THcAnalyzer.h src/THcHallCSpectrometer.h
+	src/THcDetectorMap.h src/THcRawHit.h src/THcHitList.h src/THcSignalHit.h src/THcHodoscope.h
 	src/THcScintillatorPlane.h src/THcRawHodoHit.h src/THcHodoHit.h
-        src/THcDC.h src/THcDriftChamberPlane.h 
-	src/THcDriftChamber.h src/THcRawDCHit.h src/THcDCHit.h src/THcDCWire.h src/THcSpacePoint.h 
-	src/THcDCLookupTTDConv.h src/THcDCTimeToDistConv.h src/THcShower.h src/THcShowerPlane.h 
+        src/THcDC.h src/THcDriftChamberPlane.h
+	src/THcDriftChamber.h src/THcRawDCHit.h src/THcDCHit.h src/THcDCWire.h src/THcSpacePoint.h
+	src/THcDCLookupTTDConv.h src/THcDCTimeToDistConv.h src/THcShower.h src/THcShowerPlane.h
         src/THcShowerArray.h src/THcShowerHit.h
 	src/THcRawShowerHit.h src/THcAerogel.h src/THcAerogelHit.h src/THcCherenkov.h src/THcCherenkovHit.h
         src/THcGlobals.h src/THcDCTrack.h src/THcFormula.h
         src/THcRaster.h src/THcRasteredBeam.h src/THcRasterRawHit.h src/THcScalerEvtHandler.h
         src/THcHodoEff.h
+	src/THcTrigApp.h src/THcTrigDet.h src/THcTrigRawHit.h
 	src/HallC_LinkDef.h
 	""")
 pbaseenv.RootCint(roothcdict,hcheaders)
diff --git a/src/HallC_LinkDef.h b/src/HallC_LinkDef.h
index 25a875f665fc0104a0612967e123eb30e4044a55..682a69e6d9590d6b433dcb5ea79dfde027d123d6 100644
--- a/src/HallC_LinkDef.h
+++ b/src/HallC_LinkDef.h
@@ -58,4 +58,8 @@
 #pragma link C++ class THcScalerEvtHandler+;
 #pragma link C++ class THcHodoEff+;
 
+#pragma link C++ class THcTrigApp+;
+#pragma link C++ class THcTrigDet+;
+#pragma link C++ class THcTrigRawHit+;
+
 #endif
diff --git a/src/SConscript.py b/src/SConscript.py
index d811643ddd219f57af6b62f6077b73acc94d830d..121b711c47203f1456fddb0d88c204e834e101a3 100644
--- a/src/SConscript.py
+++ b/src/SConscript.py
@@ -27,6 +27,7 @@ THcCherenkov.cxx THcCherenkovHit.cxx \
 THcFormula.cxx \
 THcRaster.cxx THcRasteredBeam.cxx THcRasterRawHit.cxx \
 THcScalerEvtHandler.cxx \
+THcTrigApp.cxx THcTrigDet.cxx THcTrigRawHit.cxx
 THcHodoEff.cxx
 """)
 
@@ -55,4 +56,3 @@ Clean(srclib,localmajorcleantarget)
 
 #baseenv.Install('../',srclib)
 #baseenv.Alias('install',['../'])
-
diff --git a/src/THcTrigApp.cxx b/src/THcTrigApp.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5bdc6112e11836795cbf52bfe9d9c8c3efc598da
--- /dev/null
+++ b/src/THcTrigApp.cxx
@@ -0,0 +1,105 @@
+/**
+\class THcTrigApp
+\ingroup Base
+
+\brief A mock spectrometer to hold all trigger related data.
+
+This class behaves as a spectrometer apparatus, but it does not correspond to
+any physical spectrometer in the hall. Its purpose is to gather all the trigger
+related data.
+
+Use only with THcTrigDet class.
+*/
+
+/**
+\fn THcTrigApp::THcTrigApp(const char* name, const char* description)
+
+\brief A constructor.
+
+\param[in] name Name of the apparatus. Is typically "T".
+\param[in] description Description of the apparatus.
+*/
+
+/**
+\fn virtual THcTrigApp::~THcTrigApp()
+
+\brief A destructor.
+*/
+
+/**
+\fn Int_t THcTrigApp::Reconstruct()
+
+\brief Does nothing and returns 0.
+
+This function is usually responsible for reconstructing the event from the
+detectors in the spectrometer. Since this is a mock apparatus, we have a mock
+reconstruction.
+*/
+
+/**
+\fn std::string THcTrigApp::GetKwPrefix()
+
+\brief Returns prefix used for parameters in `param` files.
+
+All the parameters read by this apparatus are prefixed with the returned string.
+*/
+
+#include "THcTrigApp.h"
+
+#include "TDatime.h"
+
+#include "THcGlobals.h"
+#include "THcParmList.h"
+
+
+THcTrigApp::THcTrigApp(const char* name, const char* description)
+:
+  THaApparatus(name, description),
+  fKwPrefix("")
+{
+  // Construct the kwPrefix here. Better place would be in `Setup` method.
+  string kwPrefix = name;
+  transform(kwPrefix.begin(), kwPrefix.end(), kwPrefix.begin(), ::tolower);
+  fKwPrefix = kwPrefix;
+}
+
+
+THcTrigApp::~THcTrigApp() {}
+
+
+Int_t THcTrigApp::Reconstruct() {
+  // Don't need reconstruction here.
+  return 0;
+}
+
+
+std::string THcTrigApp::GetKwPrefix() {
+  return fKwPrefix;
+}
+
+
+Int_t THcTrigApp::ReadRunDatabase(const TDatime& date) {
+  return kOK;
+}
+
+
+Int_t THcTrigApp::ReadDatabase(const TDatime& date) {
+  return kOK;
+}
+
+
+Int_t THcTrigApp::DefineVariables(THaAnalysisObject::EMode mode) {
+  if (mode == kDefine && fIsSetup) return kOK;
+  fIsSetup = (mode == kDefine);
+
+  std::vector<RVarDef> vars;
+  vars.push_back({0});
+
+  return DefineVarsFromList(vars.data(), mode);
+}
+
+
+THcTrigApp::THcTrigApp() {}
+
+
+ClassImp(THcTrigApp)
diff --git a/src/THcTrigApp.h b/src/THcTrigApp.h
new file mode 100644
index 0000000000000000000000000000000000000000..ed25818fab554ee6a88ea63347a87762e9c81c3f
--- /dev/null
+++ b/src/THcTrigApp.h
@@ -0,0 +1,36 @@
+#ifndef ROOT_THcTrigApp
+#define ROOT_THcTrigApp
+
+#include <string>
+#include <vector>
+
+#include "THaAnalysisObject.h"
+#include "THaApparatus.h"
+
+
+class TDatime;
+
+
+class THcTrigApp : public THaApparatus {
+  public:
+    THcTrigApp(const char* name, const char* description);
+    virtual ~THcTrigApp();
+
+    virtual Int_t Reconstruct();
+
+    std::string GetKwPrefix();
+
+  protected:
+    virtual Int_t ReadRunDatabase(const TDatime& date);
+    virtual Int_t ReadDatabase(const TDatime& date);
+    virtual Int_t DefineVariables(EMode mode=kDefine);
+
+    std::string fKwPrefix;
+
+  private:
+    THcTrigApp();
+    ClassDef(THcTrigApp, 0);
+};
+
+
+#endif  // ROOT_THcTrigApp
diff --git a/src/THcTrigDet.cxx b/src/THcTrigDet.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..791d866b6b3d3b1a72db8b0172ccc74a5d49ab4e
--- /dev/null
+++ b/src/THcTrigDet.cxx
@@ -0,0 +1,218 @@
+/**
+\class THcTrigDet
+\ingroup Detectors
+
+\brief A mock detector to hold trigger related data.
+
+This class behaves as a detector, but it does not correspond to any physical
+detector in the hall. Its purpose is to gather all the trigger related data
+comming from a specific source, like HMS.
+
+Use only with THcTrigApp class.
+
+Note: not yet finalized!
+*/
+
+/**
+\fn THcTrigDet::THcTrigDet(
+  const char* name, const char* description="",
+  THaApparatus* app=NULL)
+
+\brief A constructor.
+
+\param[in] name Name of the apparatus. Is typically named after spectrometer
+  whose trigger data is collecting; like "HMS".
+\param[in] description Description of the apparatus.
+\param[in] app The parent apparatus pointer.
+*/
+
+/**
+\fn virtual THcTrigDet::~THcTrigDet()
+
+\brief A destructor.
+*/
+
+/**
+\fn virtual THaAnalysisObject::EStatus THcTrigDet::Init(const TDatime& date)
+
+\brief Initializes the detector variables.
+
+\param[in] date Time of the current run.
+*/
+
+/**
+\fn virtual void THcTrigDet::Clear(Option_t* opt="")
+
+\brief Clears variables before next event.
+
+\param[in] opt Maybe used in base clas...
+*/
+
+/**
+\fn Int_t THcTrigDet::Decode(const THaEvData& evData)
+
+\brief Decodes and processes events.
+
+\param[in] evData Raw data to decode.
+*/
+
+#include "THcTrigDet.h"
+
+#include "TDatime.h"
+
+#include "THaApparatus.h"
+#include "THaEvData.h"
+
+#include "THcDetectorMap.h"
+#include "THcGlobals.h"
+#include "THcParmList.h"
+#include "THcTrigApp.h"
+#include "THcTrigRawHit.h"
+
+
+THcTrigDet::THcTrigDet() {}
+
+
+THcTrigDet::THcTrigDet(
+  const char* name, const char* description, THaApparatus* app
+) :
+  THaDetector(name, description, app), THcHitList(),
+  fKwPrefix(""),
+  fNumAdc(0), fNumTdc(0), fAdcNames(), fTdcNames(),
+  fAdcVals(), fTdcVals()
+{}
+
+
+THcTrigDet::~THcTrigDet() {}
+
+
+THaAnalysisObject::EStatus THcTrigDet::Init(const TDatime& date) {
+  // Call `Setup` before everything else.
+  Setup(GetName(), GetTitle());
+
+  // Initialize all variables.
+  for (int i=0; i<fMaxAdcChannels; ++i) fAdcVals[i] = -1.0;
+  for (int i=0; i<fMaxTdcChannels; ++i) fTdcVals[i] = -1.0;
+
+  // Call initializer for base class.
+  // This also calls `ReadDatabase` and `DefineVariables`.
+  EStatus status = THaDetector::Init(date);
+  if (status) {
+    fStatus = status;
+    return fStatus;
+  }
+
+  // Initialize hitlist part of the class.
+  InitHitList(fDetMap, "THcTrigRawHit", 100);
+
+  // Fill in detector map.
+  string EngineDID = string(GetApparatus()->GetName()).substr(0, 1) + GetName();
+  transform(EngineDID.begin(), EngineDID.end(), EngineDID.begin(), ::toupper);
+  if (gHcDetectorMap->FillMap(fDetMap, EngineDID.c_str()) < 0) {
+    static const char* const here = "Init()";
+    Error(Here(here), "Error filling detectormap for %s.", EngineDID.c_str());
+    return kInitError;
+  }
+
+  fStatus = kOK;
+  return fStatus;
+}
+
+
+void THcTrigDet::Clear(Option_t* opt) {
+  // Reset all data.
+  for (int i=0; i<fNumAdc; ++i) fAdcVals[i] = 0.0;
+  for (int i=0; i<fNumTdc; ++i) fTdcVals[i] = 0.0;
+}
+
+
+Int_t THcTrigDet::Decode(const THaEvData& evData) {
+  // Decode raw data for this event.
+  Int_t numHits = DecodeToHitList(evData);
+
+  // Process each hit and fill variables.
+  Int_t iHit = 0;
+  while (iHit < numHits) {
+    THcTrigRawHit* hit = dynamic_cast<THcTrigRawHit*>(fRawHitList->At(iHit));
+
+    if (hit->fPlane == 1) fAdcVals[hit->fCounter-1] = hit->GetData(0);
+    else if (hit->fPlane == 2) fTdcVals[hit->fCounter-1] = hit->GetData(1);
+    else {
+      throw std::out_of_range(
+        "`THcTrigDet::Decode`: only planes `1` and `2` available!"
+      );
+    }
+
+    ++iHit;
+  }
+
+  return 0;
+}
+
+
+void THcTrigDet::Setup(const char* name, const char* description) {
+  // Prefix for parameters in `param` file.
+  string kwPrefix = string(GetApparatus()->GetName()) + "_" + name;
+  transform(kwPrefix.begin(), kwPrefix.end(), kwPrefix.begin(), ::tolower);
+  fKwPrefix = kwPrefix;
+}
+
+
+Int_t THcTrigDet::ReadDatabase(const TDatime& date) {
+  std::string adcNames, tdcNames;
+
+  DBRequest list[] = {
+    {"_numAdc", &fNumAdc, kInt},  // Number of ADC channels.
+    {"_numTdc", &fNumTdc, kInt},  // Number of TDC channels.
+    {"_adcNames", &adcNames, kString},  // Names of ADC channels.
+    {"_tdcNames", &tdcNames, kString},  // Names of TDC channels.
+    {0}
+  };
+  gHcParms->LoadParmValues(list, fKwPrefix.c_str());
+
+  // Split the names to std::vector<std::string>.
+  fAdcNames = vsplit(adcNames);
+  fTdcNames = vsplit(tdcNames);
+
+  return kOK;
+}
+
+
+Int_t THcTrigDet::DefineVariables(THaAnalysisObject::EMode mode) {
+  if (mode == kDefine && fIsSetup) return kOK;
+  fIsSetup = (mode == kDefine);
+
+  std::vector<RVarDef> vars;
+
+  // Push the variable names for ADC channels.
+  std::vector<std::string> varNamesAdc(fNumAdc);
+  std::vector<std::string> varTitlesAdc(fNumAdc);
+  for (int i=0; i<fNumAdc; ++i) {
+    varNamesAdc.at(i) = "fAdcVals[" + to_string(i) + "]";
+    varTitlesAdc.at(i) = fAdcNames.at(i) + "_adc";
+    vars.push_back({
+      varTitlesAdc.at(i).c_str(),
+      varTitlesAdc.at(i).c_str(),
+      varNamesAdc.at(i).c_str()
+    });
+  }
+  // Push the variable names for TDC channels.
+  std::vector<std::string> varNamesTdc(fNumTdc);
+  std::vector<std::string> varTitlesTdc(fNumTdc);
+  for (int i=0; i<fNumTdc; ++i) {
+    varNamesTdc.at(i) = "fTdcVals[" + to_string(i) + "]";
+    varTitlesTdc.at(i) = fTdcNames.at(i) + "_tdc";
+    vars.push_back({
+      varTitlesTdc.at(i).c_str(),
+      varTitlesTdc.at(i).c_str(),
+      varNamesTdc.at(i).c_str()
+    });
+  }
+
+  vars.push_back({0});
+
+  return DefineVarsFromList(vars.data(), mode);
+}
+
+
+ClassImp(THcTrigDet)
diff --git a/src/THcTrigDet.h b/src/THcTrigDet.h
new file mode 100644
index 0000000000000000000000000000000000000000..3b44bd9b07f0790d6b9fbdeb77e738416362fb82
--- /dev/null
+++ b/src/THcTrigDet.h
@@ -0,0 +1,54 @@
+#ifndef ROOT_THcTrigDet
+#define ROOT_THcTrigDet
+
+#include <string>
+#include <vector>
+
+#include "THaDetector.h"
+#include "THcHitList.h"
+
+class TDatime;
+
+class THaApparatus;
+class THaEvData;
+
+
+class THcTrigDet : public THaDetector, public THcHitList {
+  public:
+    THcTrigDet(
+      const char* name, const char* description="",
+      THaApparatus* app=NULL
+    );
+    ~THcTrigDet();
+
+    virtual EStatus Init(const TDatime& date);
+
+    virtual void Clear(Option_t* opt="");
+    Int_t Decode(const THaEvData& evData);
+
+  protected:
+    void Setup(const char* name, const char* description);
+    virtual Int_t ReadDatabase(const TDatime& date);
+    virtual Int_t DefineVariables(EMode mode=kDefine);
+
+    std::string fKwPrefix;
+
+    Int_t fNumAdc;
+    Int_t fNumTdc;
+
+    std::vector<std::string> fAdcNames;
+    std::vector<std::string> fTdcNames;
+
+    static const int fMaxAdcChannels = 100;
+    static const int fMaxTdcChannels = 100;
+
+    Double_t fAdcVals[fMaxAdcChannels];
+    Double_t fTdcVals[fMaxTdcChannels];
+
+  private:
+    THcTrigDet();
+    ClassDef(THcTrigDet, 0);
+};
+
+
+#endif  // ROOT_THcTrigDet
diff --git a/src/THcTrigRawHit.cxx b/src/THcTrigRawHit.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..62065d4fda71ed481251169a56bf912c14625664
--- /dev/null
+++ b/src/THcTrigRawHit.cxx
@@ -0,0 +1,116 @@
+/**
+\class THcTrigRawHit
+\ingroup DetSupport
+
+\brief Class representing a single raw hit for the THcTrigDet.
+
+Contains plane, counter and an ADC or a TDC value.
+
+Note: not yet finalized!
+*/
+
+#include "THcTrigRawHit.h"
+
+#include <stdexcept>
+
+
+THcTrigRawHit::THcTrigRawHit(
+  Int_t plane, Int_t counter
+) :
+  THcRawHit(plane, counter),
+  fAdcVal(), fTdcVal(), fNumAdcSamples(0), fNumTdcSamples(0),
+  fAdcReferenceTime(0), fTdcReferenceTime(0),
+  fHasAdcRef(kFALSE), fHasTdcRef(kFALSE)
+{}
+
+
+THcTrigRawHit& THcTrigRawHit::operator=(const THcTrigRawHit& right) {
+  // Call base class assignment operator.
+  THcRawHit::operator=(right);
+
+  for (UInt_t i=0; i<fNumAdcSamples; ++i) fAdcVal[i] = right.fAdcVal[i];
+  for (UInt_t i=0; i<fNumTdcSamples; ++i) fTdcVal[i] = right.fTdcVal[i];
+
+  fNumAdcSamples = right.fNumAdcSamples;
+  fNumTdcSamples = right.fNumTdcSamples;
+
+  fAdcReferenceTime = right.fAdcReferenceTime;
+  fTdcReferenceTime = right.fTdcReferenceTime;
+  fHasAdcRef = right.fHasAdcRef;
+  fHasTdcRef = right.fHasTdcRef;
+
+  return *this;
+}
+
+
+THcTrigRawHit::~THcTrigRawHit() {}
+
+
+void THcTrigRawHit::Clear(Option_t* opt) {
+  fNumAdcSamples = 0;
+  fNumTdcSamples = 0;
+  fHasAdcRef = kFALSE;
+  fHasTdcRef = kFALSE;
+}
+
+
+void THcTrigRawHit::SetData(Int_t signal, Int_t data) {
+  // TODO: check if signal matches plane.
+  // Signal 0 is ADC.
+  if (signal == 0) {
+    if (fNumAdcSamples >= fMaxAdcSamples) {
+      throw std::out_of_range(
+        "`THcTrigRawHit::SetData`: too many samples for ADC signal!"
+      );
+    }
+    fAdcVal[fNumAdcSamples] = data;
+    ++fNumAdcSamples;
+  }
+  // Signal 1 is TDC.
+  else if (signal == 1) {
+    if (fNumTdcSamples >= fMaxTdcSamples) {
+      throw std::out_of_range(
+        "`THcTrigRawHit::SetData`: too many samples for TDC signal!"
+      );
+    }
+    fTdcVal[fNumTdcSamples] = data;
+    ++fNumTdcSamples;
+  }
+  else throw std::out_of_range("`THcTrigRawHit::SetData`: only signals `0` and `1` available!");
+}
+
+
+void THcTrigRawHit::SetReference(Int_t signal, Int_t reference) {
+
+  if (signal == 0) fAdcReferenceTime = reference;
+  else if (signal == 1) fTdcReferenceTime = reference;
+  else throw std::out_of_range("`THcTrigRawHit::SetReference`: only signals `0` and `1` available!");
+}
+
+
+Int_t THcTrigRawHit::GetData(Int_t signal) {
+  // TODO: expand this. Maybe add new methods.
+  // For now only returns first value.
+  if (signal == 0) return fAdcVal[0];
+  else if (signal == 1) return fTdcVal[0];
+  else throw std::out_of_range("`THcTrigRawHit::GetData`: only signals `0` and `1` available!");
+}
+
+
+Int_t THcTrigRawHit::GetReference(Int_t signal) {
+  // Reference time.
+  if (signal == 0) return fAdcReferenceTime;
+  else if (signal == 1) return fTdcReferenceTime;
+  else throw std::out_of_range("`THcTrigRawHit::GetReference`: only signals `0` and `1` available!");
+}
+
+
+Bool_t THcTrigRawHit::HasReference(Int_t signal) {
+  // Reference time.
+  if (signal == 0) return fHasAdcRef;
+  else if (signal == 1) return fHasTdcRef;
+  else throw std::out_of_range("`THcTrigRawHit::HasReference`: only signals `0` and `1` available!");
+}
+
+
+ClassImp(THcTrigRawHit)
diff --git a/src/THcTrigRawHit.h b/src/THcTrigRawHit.h
new file mode 100644
index 0000000000000000000000000000000000000000..996ea999c9580ca7746ad09d81f3252d684edf47
--- /dev/null
+++ b/src/THcTrigRawHit.h
@@ -0,0 +1,42 @@
+#ifndef ROOT_THcTrigRawHit
+#define ROOT_THcTrigRawHit
+
+
+#include "THcRawHit.h"
+
+
+class THcTrigRawHit : public THcRawHit {
+  public:
+    THcTrigRawHit(Int_t plane=0, Int_t counter=0);
+    THcTrigRawHit& operator=(const THcTrigRawHit& right);
+    virtual ~THcTrigRawHit();
+
+    virtual void Clear(Option_t* opt="");
+
+    void SetData(Int_t signal, Int_t data);
+    void SetReference(Int_t signal, Int_t reference);
+    Int_t GetData(Int_t signal);
+    Int_t GetReference(Int_t signal);
+    Bool_t HasReference(Int_t signal);
+
+  protected:
+    static const Int_t fMaxAdcSamples = 160;
+    static const Int_t fMaxTdcSamples = 16;
+    static const Int_t fNumPlanes = 2;
+
+    Int_t fAdcVal[fMaxAdcSamples];
+    Int_t fTdcVal[fMaxTdcSamples];
+    UInt_t fNumAdcSamples;
+    UInt_t fNumTdcSamples;
+
+    Int_t fAdcReferenceTime;
+    Int_t fTdcReferenceTime;
+    Bool_t fHasAdcRef;
+    Bool_t fHasTdcRef;
+
+  private:
+    ClassDef(THcTrigRawHit, 0);
+};
+
+
+#endif  // ROOT_THcTrigRawHit