diff --git a/coa_detection/in_silico_mixture.py b/coa_detection/in_silico_mixture.py
new file mode 100644
index 0000000000000000000000000000000000000000..8c1611ef46ab45a41742d6350836ba8dddbef018
--- /dev/null
+++ b/coa_detection/in_silico_mixture.py
@@ -0,0 +1,74 @@
+from coa_detection.AbfData import AbfData
+from pathlib import Path
+import numpy as np
+import random
+import matplotlib.pyplot as plt
+
+
+class InSilicoGenerator:
+    def __init__(self, file_list):
+        """Generate in silico squiggles of a ratio that you determine yourself
+        :param file_list: List of abf files
+        """
+        self.coa4 = []
+        self.coa5 = []
+        self.coa6 = []
+        self.load_abfs(file_list)
+        self.squiggle_length = 60*50000  # 50 khz for 60 seconds
+        self.squiggle = np.empty(self.squiggle_length)
+        self.squiggle[:] = np.nan
+        self.all_coas = [self.coa4, self.coa5, self.coa6]
+        #  In the ground truth vector:
+        # -4, -5, -6 are negatives for coa4, 5, 6
+        #  4,  5,  6 are positives for coa4, 5, 6
+        self.ground_truth_vector = np.empty_like(self.squiggle)
+
+    def load_abfs(self, file_list):
+        for file in file_list:
+            if 'A4' in file.name:
+                self.coa4.append(AbfData(file))
+            elif 'A5' in file.name:
+                self.coa5.append(AbfData(file))
+            elif 'A6' in file.name:
+                self.coa6.append(AbfData(file))
+
+    def fill_squiggle(self, coa4_ratio, coa5_ratio, coa6_ratio, unfiltered=True):
+        """
+        :param coa4_ratio: number of coa4 events
+        :param coa5_ratio: number of coa5 events
+        :param coa6_ratio: number of coa6 events
+        """
+        current_index = 0
+        # Just start with some noise first
+        while current_index < len(self.squiggle):
+            fragment_width = random.randint(100, 3000)
+            coa_type = random.choice(self.all_coas)
+            fragment_id = 1  # TODO base this on coa type that is chosen
+            coa_object = random.choice(coa_type)
+            positive_example = random.choice([True, False])
+            if current_index + fragment_width > self.squiggle_length:
+                # Edge case: always fill final bit of squiggle with noise
+                positive_example = False
+                fragment_width = self.squiggle_length - current_index
+            if positive_example:
+                squiggle_fragment = coa_object.get_pos(fragment_width,
+                                                       unfiltered=unfiltered)  # TODO this might not match up with real data
+            else:
+                squiggle_fragment = coa_object.get_neg(fragment_width,
+                                                       unfiltered=unfiltered)
+                fragment_id *= -1
+            end_index = current_index + fragment_width
+            self.squiggle[current_index:end_index] = squiggle_fragment
+            self.ground_truth_vector[current_index:end_index] = fragment_id
+            current_index += fragment_width
+        return self.squiggle, self.ground_truth_vector
+
+
+if __name__ == '__main__':
+    files = [Path(r"/mnt/c/Users/benno/Downloads/zooi/+120mV_cOA4.abf"),
+             Path(r"/mnt/c/Users/benno/Downloads/zooi/+120mV_cOA5.abf"),
+             Path(r"/mnt/c/Users/benno/Downloads/zooi/+120mV_cOA6.abf")]
+    generator = InSilicoGenerator(files)
+    simulated_squiggle, ground_truth = generator.fill_squiggle(1, 2, 3)
+    plt.plot(simulated_squiggle)
+    plt.show()