diff --git a/scripts/snr_optimizer/snr_optimizer.sub b/scripts/snr_optimizer/snr_optimizer.sub
new file mode 100644
index 0000000000000000000000000000000000000000..6c4efd68ede87da40b621627b962032bf7c15d5a
--- /dev/null
+++ b/scripts/snr_optimizer/snr_optimizer.sub
@@ -0,0 +1,23 @@
+universe = vanilla
+executable = /usr/local/bin/manifold_cbc_bank_snr_optimizer_online
+arguments = $(channels) --data-source frames --psd-fft-length 4 --seed-bank combined_IMBHreassigned_allskyfull_BANK_idpreserved.h5 --min-mismatch 0.001 --sample-rate 2048 --max-duration 256 --algorithm rectangle $(input) --output-xml-file $(output) --gps-start $(start) --gps-end $(end) --verbose --frame-segments-file segments.xml.gz --frame-segments-name datasegments --ht-gate-threshold 15 --original-template-only --framecache frame.cache --track-psd
+periodic_release = (HoldReasonCode == 5) || ((CurrentTime - EnteredCurrentStatus > 180) && (HoldReasonCode != 34))
+request_cpus = 1
+request_memory = 4000
+request_disk = 1GB
+want_graceful_removal = True
+kill_sig = 15
+accounting_group = ligo.dev.o4.cbc.em.gstlalonline
+accounting_group_user = prathamesh.joshi
+environment = "LAL_DATA_PATH=/cvmfs/oasis.opensciencegrid.org/ligo/sw/pycbc/lalsuite-extra/current/share/lalsimulation X509_USER_PROXY=x509_proxy"
+MY.SingularityImage = "/home/prathamesh.joshi/builds/gstlal-general2"
+transfer_executable = False
+getenv = False
+requirements = has_avx2 && (CpuFamily =?= 6) && (HAS_SINGULARITY=?=True)
+success_exit_code = 0
+output = logs/$(nodename)-$(cluster)-$(process).out
+error = logs/$(nodename)-$(cluster)-$(process).err
+notification = never
+MY.MemoryUsage = ( 4000 ) * 2 / 3
+
+queue
diff --git a/scripts/snr_optimizer/write_dag.py b/scripts/snr_optimizer/write_dag.py
new file mode 100755
index 0000000000000000000000000000000000000000..0bd62d1202eac37d278119c4588adc09e77f152a
--- /dev/null
+++ b/scripts/snr_optimizer/write_dag.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+
+import os
+from ligo.lw import lsctables
+from ligo.lw import utils as ligolw_utils
+from ligo.lw import ligolw
+from ligo.lw import array as ligolw_array
+from ligo.lw import param as ligolw_param
+
+
+
+class LIGOLWContentHandler(ligolw.LIGOLWContentHandler):
+	pass
+ligolw_array.use_in(LIGOLWContentHandler)
+ligolw_param.use_in(LIGOLWContentHandler)
+lsctables.use_in(LIGOLWContentHandler)
+
+path = "/home/gstlalcbc.offline/observing/4/a/injections/rank_RPO4/rank.edward_250118/combined/coincs/"
+output_dir = "optimizer_coincs/"
+channel_dict = {'H1':'--channel-name H1=GDS-CALIB_STRAIN_CLEAN ', 'L1':"--channel-name L1=GDS-CALIB_STRAIN_CLEAN "}
+
+with open("snr_optimizer.dag", 'w') as f:
+	for i, coinc in enumerate(os.listdir(path)):
+		if not coinc.endswith('xml.gz'):
+			print(f"skipping {coinc}")
+			continue
+		coinc_new = output_dir + "/" + coinc
+		coinc = path + coinc
+		coinc_xmldoc = ligolw_utils.load_filename(coinc, contenthandler = LIGOLWContentHandler)
+		coinc_inspiral_table = lsctables.CoincInspiralTable.get_table(coinc_xmldoc)
+
+		sngl_tables = lsctables.SnglInspiralTable.get_table(coinc_xmldoc)
+		channels = []
+		for sngl_row in sngl_tables:
+			channels.append(sngl_row.channel)
+		channels = set(channels)
+
+		coinc_inspiral = coinc_inspiral_table[0] # assume 1
+		tc = coinc_inspiral.end
+		int_tc = int(round(float(tc)))
+		start = int_tc - 5*60
+		end = int_tc + 1*60
+
+		sngl_inspiral_table = lsctables.SnglInspiralTable.get_table(coinc_xmldoc)
+		channels = ""
+		for s in sngl_inspiral_table:
+			channels += channel_dict[s.ifo]
+
+		i = format(i, '05')
+		f.write(f'JOB snr_optimizer.{i} snr_optimizer.sub\n')
+		f.write(f'VARS snr_optimizer.{i} nodename="snr_optimizer_{i}" input="{coinc}" output="{coinc_new}" start="{start}" end="{end}" channels="{channels}"\n')
+		f.write(f'RETRY snr_optimizer.{i} 1\n')