diff --git a/miniapp/miniapp.cpp b/miniapp/miniapp.cpp
index f21208874a9f78d30995f4fa590e37c8233a6bf1..960c3ccb4f52d7b27ac186ae9cb3f5f018c8ee7b 100644
--- a/miniapp/miniapp.cpp
+++ b/miniapp/miniapp.cpp
@@ -7,7 +7,6 @@
 
 #include <json/json.hpp>
 
-#include <backends/fvm.hpp>
 #include <common_types.hpp>
 #include <communication/communicator.hpp>
 #include <communication/global_policy.hpp>
@@ -36,7 +35,7 @@ using lowered_cell = fvm::fvm_multicell<gpu::backend>;
 using lowered_cell = fvm::fvm_multicell<multicore::backend>;
 #endif
 using model_type = model<lowered_cell>;
-using sample_trace_type = sample_trace<model_type::time_type, model_type::value_type>;
+using sample_trace_type = sample_trace<model_type::time_type, double>;
 using file_export_type = io::exporter_spike_file<global_policy>;
 void banner();
 std::unique_ptr<recipe> make_recipe(const io::cl_options&, const probe_distribution&);
diff --git a/src/cell_group.hpp b/src/cell_group.hpp
index 229885425818d112b626b61914a3c4e2b514ef7a..2148a0b5bf90f5c86b8f75af691e08069808b1ce 100644
--- a/src/cell_group.hpp
+++ b/src/cell_group.hpp
@@ -63,7 +63,7 @@ public:
 
     void reset() {
         spikes_.clear();
-        clear_events();
+        events_.clear();
         reset_samplers();
         binner_.reset();
         lowered_.reset();
@@ -164,38 +164,18 @@ public:
         return spike_sources_;
     }
 
-    void clear_events() {
-        events_.clear();
-    }
-
     void add_sampler(cell_member_type probe_id, sampler_function s, time_type start_time = 0) {
         auto handle = get_probe_handle(probe_id);
 
-        auto sampler_index = uint32_t(samplers_.size());
+        using size_type = sample_event<time_type>::size_type;
+        auto sampler_index = size_type(samplers_.size());
         samplers_.push_back({handle, probe_id.gid, s});
         sampler_start_times_.push_back(start_time);
         sample_events_.push({sampler_index, start_time});
     }
 
-    void remove_samplers() {
-        sample_events_.clear();
-        samplers_.clear();
-        sampler_start_times_.clear();
-    }
-
-    void reset_samplers() {
-        // clear all pending sample events and reset to start at time 0
-        sample_events_.clear();
-        for(uint32_t i=0u; i<samplers_.size(); ++i) {
-            sample_events_.push({i, sampler_start_times_[i]});
-        }
-    }
-
-    value_type probe(cell_member_type probe_id) const {
-        return lowered_.probe(get_probe_handle(probe_id));
-    }
-
 private:
+
     // gid of first cell in group.
     cell_gid_type gid_base_;
 
@@ -243,8 +223,10 @@ private:
     // Build handle index lookup tables.
     template <typename Cells>
     void build_handle_partitions(const Cells& cells) {
-        auto probe_counts = util::transform_view(cells, [](const cell& c) { return c.probes().size(); });
-        auto target_counts = util::transform_view(cells, [](const cell& c) { return c.synapses().size(); });
+        auto probe_counts =
+            util::transform_view(cells, [](const cell& c) { return c.probes().size(); });
+        auto target_counts =
+            util::transform_view(cells, [](const cell& c) { return c.synapses().size(); });
 
         make_partition(probe_handle_divisions_, probe_counts);
         make_partition(target_handle_divisions_, target_counts);
@@ -277,6 +259,15 @@ private:
     target_handle get_target_handle(cell_member_type target_id) const {
         return target_handles_[handle_partition_lookup(target_handle_divisions_, target_id)];
     }
+
+    void reset_samplers() {
+        // clear all pending sample events and reset to start at time 0
+        sample_events_.clear();
+        using size_type = sample_event<time_type>::size_type;
+        for(size_type i=0; i<samplers_.size(); ++i) {
+            sample_events_.push({i, sampler_start_times_[i]});
+        }
+    }
 };
 
 } // namespace mc
diff --git a/src/event_queue.hpp b/src/event_queue.hpp
index d6573e0fee63c0cf84d3f3d52ef06b996e4850d3..f26a60c52a954c7566d1892647f740e3e26366fb 100644
--- a/src/event_queue.hpp
+++ b/src/event_queue.hpp
@@ -32,8 +32,9 @@ struct postsynaptic_spike_event {
 template <typename Time>
 struct sample_event {
     using time_type = Time;
+    using size_type = std::uint32_t;
 
-    std::uint32_t sampler_index;
+    size_type sampler_index;
     time_type time;
 };
 
diff --git a/src/model.hpp b/src/model.hpp
index ee0a12eb00ce18b2ada44459a5897c731188fe49..99448000254ae4b9f5c79af3257b4120462d5c68 100644
--- a/src/model.hpp
+++ b/src/model.hpp
@@ -22,14 +22,14 @@
 namespace nest {
 namespace mc {
 
+// FIXME: this is going to go
 template <typename Cell>
 class model {
 public:
-    using cell_group_type = cell_group<Cell>;
-    using time_type = typename cell_group_type::time_type;
-    using value_type = typename cell_group_type::value_type;
+    // FIXME: this is an intermediate step to remove the template parameter from model
+    using cell_group_type = cell_group<Cell>; // FIXME
+    using time_type = typename spike::time_type;
     using communicator_type = communication::communicator<communication::global_policy>;
-    using sampler_function = typename cell_group_type::sampler_function;
     using spike_export_function = std::function<void(const std::vector<spike>&)>;
 
     struct probe_record {
@@ -208,12 +208,14 @@ public:
         current_spikes().get().push_back({source, tspike});
     }
 
-    void attach_sampler(cell_member_type probe_id, sampler_function f, time_type tfrom = 0) {
+    template <typename F>
+    void attach_sampler(cell_member_type probe_id, F&& f, time_type tfrom = 0) {
         if (!algorithms::in_interval(probe_id.gid, gid_partition().bounds())) {
             return;
         }
 
-        cell_groups_[gid_partition().index(probe_id.gid)].add_sampler(probe_id, f, tfrom);
+        const auto idx = gid_partition().index(probe_id.gid);
+        cell_groups_[idx].add_sampler(probe_id, std::forward<F>(f), tfrom);
     }
 
     const std::vector<probe_record>& probes() const { return probes_; }