#!/usr/bin/env python

# Copyright (C) 2013-2019 Ian W. Harry, Alex Nitz, Marton Tapai
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
"""
Program for running multi-detector workflow analysis through coincidence and
then generate post-processing and plots.
"""
import pycbc
import pycbc.version
__author__  = "Alex Nitz <alex.nitz@ligo.org>"
__version__ = pycbc.version.git_verbose_msg
__date__    = pycbc.version.date
__program__ = "pycbc_offline"

import sys
import socket
import pycbc.events, pycbc.workflow as wf
import os, argparse, ConfigParser, logging
from ligo import segments
import numpy, lal, datetime, itertools
from pycbc.results import create_versioning_page, static_table, layout
from pycbc.results.versioning import save_fig_with_metadata
from pycbc.results.metadata import html_escape


def symlink_path(f, path):
    if f is None:
        return
    try:
        os.symlink(f.storage_path, os.path.join(path, f.name))
    except OSError:
        pass

def symlink_result(f, rdir_path):
    symlink_path(f, rdir[rdir_path])


# Log to the screen until we know where the output file is
logging.basicConfig(format='%(asctime)s:%(levelname)s : %(message)s',
    level=logging.INFO)

parser = argparse.ArgumentParser(description=__doc__[1:])
parser.add_argument('--version', action='version', version=__version__)
parser.add_argument('--workflow-name', default='my_unamed_run')
parser.add_argument("-d", "--output-dir", default=None,
                    help="Path to output directory.")
wf.add_workflow_command_line_group(parser)
args = parser.parse_args()

wf.makedir(args.output_dir)

container = wf.Workflow(args, args.workflow_name)
workflow = wf.Workflow(args, args.workflow_name + '-main')
finalize_workflow = wf.Workflow(args, args.workflow_name + '-finalization')

os.chdir(args.output_dir)

rdir = layout.SectionNumber('results', ['analysis_time',
                                 'detector_sensitivity',
                                 'single_triggers',
                                 'coincident_triggers',
                                 'injections',
                                 'search_sensitivity',
                                 'open_box_result',
                                 'workflow',
                                 ])

wf.makedir(rdir.base)
wf.makedir(rdir['workflow'])

wf_log_file = wf.File(workflow.ifos, 'workflow-log', workflow.analysis_time,
                      extension='.txt',
                      directory=rdir['workflow'])

logging.basicConfig(format='%(asctime)s:%(levelname)s : %(message)s',
                    filename=wf_log_file.storage_path,
                    level=logging.INFO,
                    filemode='w')

logfile = logging.FileHandler(filename=wf_log_file.storage_path,mode='w')
logfile.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s:%(levelname)s : %(message)s')
logfile.setFormatter(formatter)
logging.getLogger('').addHandler(logfile)
logging.info("Created log file %s" % wf_log_file.storage_path)

# put start / end time at top of summary page
time = workflow.analysis_time
s, e = int(time[0]), int(time[1])
s_utc = str(datetime.datetime(*lal.GPSToUTC(s)[0:6]))
e_utc = str(datetime.datetime(*lal.GPSToUTC(e)[0:6]))
time_str = '<center><p><b>GPS Interval [%s,%s). ' %(s,e)
time_str += 'UTC Interval %s - %s. ' %(s_utc, e_utc)
time_str += 'Interval duration = %.3f days.</b></p></center>'\
                                                         %(float(e-s)/86400.0,)
time_file = wf.File(workflow.ifos, 'time', workflow.analysis_time,
                                           extension='.html',
                                           directory=rdir.base)
kwds = { 'title' : 'Search Workflow Duration (Wall Clock Time)',
        'caption' : "Wall clock start and end times for this invocation of "
                    "the workflow. The command line button shows the "
                    "arguments used to invoke the workflow creation script.",
        'cmd' :' '.join(sys.argv), }
save_fig_with_metadata(time_str, time_file.storage_path, **kwds)

# Get segments and find the data locations
wf.makedir(rdir['analysis_time/segment_data'])
science_veto_name = 'segments-science-veto'
primary_veto_name = 'segments-final-veto-group'
secondary_vetoes_name = 'segments-veto-groups'
nonscience_veto_names = [primary_veto_name, secondary_vetoes_name]

science_seg_file, sci_segs, sci_seg_name = wf.get_science_segments(workflow,
                                            rdir['analysis_time/segment_data'])

runtime_names=[science_veto_name]
in_workflow_names = nonscience_veto_names
veto_cat_files = wf.get_files_for_vetoes(workflow,
                                         rdir['analysis_time/segment_data'],
                                         runtime_names=runtime_names,
                                         in_workflow_names=in_workflow_names)

sci_ok_seg_file, sci_ok_segs, sci_ok_seg_name = wf.get_analyzable_segments(\
                                            workflow, sci_segs, veto_cat_files,
                                            rdir['analysis_time/segment_data'])

datafind_files, analyzable_file, analyzable_segs, analyzable_name = \
                                           wf.setup_datafind_workflow(workflow,
                                                     sci_ok_segs, "datafind",
                                                     seg_file=science_seg_file)

cum_veto_files, veto_names, ind_cats = wf.get_cumulative_veto_group_files(\
                                            workflow, 'segments-veto-groups',
                                            veto_cat_files,
                                            rdir['analysis_time/segment_data'],
                                            execute_now=False)

final_veto_file, final_veto_name, ind_cats = \
                                   wf.get_cumulative_veto_group_files(workflow,
                                            'segments-final-veto-group',
                                            veto_cat_files,
                                            rdir['analysis_time/segment_data'],
                                            execute_now=False)

# Precalculated PSDs
precalc_psd_files = wf.setup_psd_workflow(workflow, analyzable_segs,
                                            datafind_files, "psdfiles")

# Template bank stuff
hdfbank = wf.setup_tmpltbank_workflow(workflow, analyzable_segs,
                                      datafind_files, output_dir="bank",
                                      psd_files=precalc_psd_files,
                                      return_format='hdf')

splitbank_files_fd = wf.setup_splittable_workflow(workflow, hdfbank,
                                                  out_dir="bank",
                                                  tags=['full_data'])

bank_plot = wf.make_template_plot(workflow, hdfbank[0],
                                  rdir['coincident_triggers'])

######################## Setup the FULL DATA run ##############################
tag = output_dir = "full_data"

# setup the matchedfilter jobs
ind_insps = insps = wf.setup_matchedfltr_workflow(workflow, analyzable_segs,
                                   datafind_files, splitbank_files_fd,
                                   output_dir, tags = [tag])

insps = wf.merge_single_detector_hdf_files(workflow, hdfbank[0],
                                           insps, output_dir, tags=[tag])

# setup sngl trigger distribution fitting jobs
# 'statfiles' is list of files used in calculating coinc statistic
statfiles = []
statfiles += wf.setup_trigger_fitting(workflow, insps, hdfbank,
                                      final_veto_file, final_veto_name)

# Set up the multi-ifo coinc jobs
# bg_files contains coinc results using vetoes from cum_veto_files
# final_bg_files contains coinc results using vetoes final_veto_files
# ifo_ids will store an (integer) index for each ifo in the precedence list
full_insps = insps
ctags = [tag]
bg_files = []
final_bg_files = {}
ifo_ids = {}

# Get the ifo precedence values
ifo_precedence_list = workflow.cp.get_opt_tags('workflow-coincidence', 'timeslide-precedence', ctags)
for ifo, _ in zip(*insps.categorize_by_attr('ifo')):
    ifo_ids[ifo] = ifo_precedence_list.index(ifo)

# Generate the possible detector combinations from 2 detectors
# up to the number of trigger files
for i in range(2, len(insps)+1):
    combinations = itertools.combinations(ifo_ids.keys(), i)
    for ifocomb in combinations:
        inspcomb = wf.select_files_by_ifo_combination(ifocomb, insps)
        pivot_ifo, fixed_ifo, ordered_ifo_list = wf.get_ordered_ifo_list(ifocomb, ifo_ids)

        # Create coinc tag, and set up the coinc job for the combination
        coinctag = '{}det_'.format(len(ifocomb)) + ordered_ifo_list
        ctagcomb = [tag, 'full', coinctag]
        bg_files += wf.setup_multiifo_interval_coinc(workflow, hdfbank, inspcomb, statfiles,
                               cum_veto_files, veto_names,
                               output_dir, pivot_ifo, fixed_ifo, tags=ctagcomb)
        final_bg_files[ordered_ifo_list] = wf.setup_multiifo_interval_coinc(workflow,
                                                                            hdfbank,
                                                                            inspcomb,
                                                                            statfiles,
                                                                            final_veto_file,
                                                                            final_veto_name,
                                                                            output_dir,
                                                                            pivot_ifo,
                                                                            fixed_ifo,
                                                                            tags=ctagcomb)

combctags = [tag]
final_bg_file_list = wf.FileList()
for key in final_bg_files:
    final_bg_file_list += final_bg_files[key][0][1]
combined_bg_file = wf.setup_multiifo_combine_statmap(workflow,
                                                     final_bg_file_list,
                                                     output_dir,
                                                     tags=combctags)

censored_veto = wf.make_foreground_censored_veto(workflow,
                       combined_bg_file, final_veto_file[0], final_veto_name[0],
                       'closed_box', 'segments')

# Calculate the inspiral psds and make plots
psd_files = []
trig_generated_name = 'TRIGGERS_GENERATED'
trig_generated_segs = {}
data_analysed_name = 'DATA_ANALYSED'
data_analysed_segs = {}
insp_files_seg_dict = segments.segmentlistdict()

for ifo, files in zip(*ind_insps.categorize_by_attr('ifo')):
    trig_generated_segs[ifo] = segments.segmentlist([f.segment for f in files])
    data_analysed_segs[ifo] = \
        segments.segmentlist([f.metadata['data_seg'] for f in files])

    # Remove duplicates from splitbank
    trig_generated_segs[ifo] = \
        segments.segmentlist(set(trig_generated_segs[ifo]))
    data_analysed_segs[ifo] = \
        segments.segmentlist(set(data_analysed_segs[ifo]))

    insp_files_seg_dict[ifo + ":" + trig_generated_name] = \
                                                       trig_generated_segs[ifo]
    insp_files_seg_dict[ifo + ":" + data_analysed_name] = \
                                                        data_analysed_segs[ifo]

    if datafind_files:
        frame_files = datafind_files.find_output_with_ifo(ifo)
    else:
        frame_files = None
    psd_files += [wf.setup_psd_calculate(workflow, frame_files, ifo,
              data_analysed_segs[ifo], data_analysed_name, 'psds')]

insp_files_seg_file = wf.SegFile.from_segment_list_dict('INSP_SEGMENTS',
                 insp_files_seg_dict, valid_segment=workflow.analysis_time,
                 extension='xml', directory=rdir['analysis_time/segment_data'])

################### Range, spectrum and segments plots #######################

s = wf.make_spectrum_plot(workflow, psd_files, rdir['detector_sensitivity'],
                          precalc_psd_files=precalc_psd_files)
r = wf.make_range_plot(workflow, psd_files, rdir['detector_sensitivity'],
                       require='summ')
r2 = wf.make_range_plot(workflow, psd_files, rdir['detector_sensitivity'],
                        exclude='summ')

det_summ = [(s, r[0] if len(r) != 0 else None)]
layout.two_column_layout(rdir['detector_sensitivity'],
                         det_summ + list(layout.grouper(r2, 2)))

# do plotting of segments / veto times
for ifo, files in zip(*ind_cats.categorize_by_attr('ifo')):
    wf.make_segments_plot(workflow, files, rdir['analysis_time/segments'],
                          tags=['%s_VETO_SEGMENTS' % ifo])

wf.make_segments_plot(workflow, [insp_files_seg_file],
                      rdir['analysis_time/segments'],
                      tags=[trig_generated_name])
wf.make_segments_plot(workflow, [sci_ok_seg_file],
                      rdir['analysis_time/segments'],
                      tags=['SCIENCE_MINUS_CAT1'])
wf.make_gating_plot(workflow, full_insps, rdir['analysis_time/gating'],
                    tags=['full_data'])

# make segment table and plot for summary page
curr_files = [science_seg_file, sci_ok_seg_file, analyzable_file,
              insp_files_seg_file]
curr_names = [sci_seg_name, sci_ok_seg_name, analyzable_name,
              trig_generated_name]
seg_summ_table = wf.make_seg_table\
    (workflow, curr_files, curr_names, rdir['analysis_time/segments'],
     ['SUMMARY'], title_text='Input and output',
     description='This shows the total amount of input data, analyzable data, '
                 'and the time for which triggers are produced.')
seg_summ_plot = wf.make_seg_plot(workflow, curr_files,
                                rdir['analysis_time/segments'],
                                curr_names, ['SUMMARY'])

curr_files = [insp_files_seg_file] + final_veto_file + cum_veto_files
# Add in singular veto files
curr_files = curr_files + veto_cat_files + [science_seg_file]
curr_names = [trig_generated_name + '&' + veto_name
              for veto_name in veto_names+final_veto_name]
# And SCIENCE - CAT 1 vetoes explicitly.
curr_names += [sci_seg_name + '&' + 'VETO_CAT1']

veto_summ_table = wf.make_seg_table\
    (workflow, curr_files, curr_names, rdir['analysis_time/segments'],
     ['VETO_SUMMARY'], title_text='Time removed by vetoes',
     description='This shows the time removed from the output time by the '
                 'vetoes applied to the triggers.')

# make veto definer table
vetodef_table = wf.make_veto_table(workflow, rdir['analysis_time/veto_definer'])
layout.single_layout(rdir['analysis_time/veto_definer'], ([vetodef_table]))

#################### Plotting on FULL_DATA results ##########################
##################### SINGLES plots first ###################################

snrchi = wf.make_snrchi_plot(workflow, insps, censored_veto,
                            'closed_box', rdir['single_triggers'], tags=[tag])
layout.group_layout(rdir['single_triggers'], snrchi)

hist_summ = []
for insp in full_insps:
    outdir = rdir['single_triggers/%s_binned_triggers' % insp.ifo]
    wf.make_singles_plot(workflow, [insp], hdfbank[0], censored_veto,
                         'closed_box', outdir, tags=[tag])
    # make non-summary hists using the bank file
    # currently, none of these are made
    outdir = rdir['single_triggers/%s_trigger_histograms' % insp.ifo]
    wf.make_single_hist(workflow, insp, censored_veto, 'closed_box', outdir,
                        bank_file=hdfbank[0], exclude='summ', tags=[tag])
    # make summary hists for all templates together
    # currently, 2 per ifo: snr and newsnr
    outdir = rdir['single_triggers/%s_trigger_histograms' % insp.ifo]
    allhists = wf.make_single_hist(workflow, insp, censored_veto, 'closed_box',
                                   outdir, require='summ', tags=[tag])
    # make hists of newsnr split up by parameter
    # currently, 1 per ifo split by template duration
    outdir = rdir['single_triggers/%s_binned_histograms' % insp.ifo]
    binhists = wf.make_binned_hist(workflow, insp, final_veto_file[0],
                                   'closed_box', outdir, hdfbank[0],
                                   tags=[tag])
    # put raw SNR and binned newsnr hist in summary
    hist_summ += list(layout.grouper([allhists[0], binhists[0]], 2))

if workflow.cp.has_option_tags('workflow-matchedfilter',
                                   'plot-throughput', tags=[tag]):
    wf.make_throughput_plot(workflow, full_insps, rdir['workflow/throughput'],
                            tags=['full_data'])

# Run minifollowups on loudest sngl detector events
excl_subsecs = set([])

for insp_file in full_insps:
    for tag in insp_file.tags:
        excl_subsecs.add(tag)

for insp_file in full_insps:
    curr_ifo = insp_file.ifo
    for subsec in workflow.cp.get_subsections('workflow-sngl_minifollowups'):
        if subsec in excl_subsecs:
            continue
        sec_name = 'workflow-sngl_minifollowups-{}'.format(subsec)
        dir_str = workflow.cp.get(sec_name, 'section-header')
        currdir = rdir['single_triggers/{}_{}'.format(curr_ifo, dir_str)]
        wf.setup_single_det_minifollowups\
            (workflow, insp_file, hdfbank[0], insp_files_seg_file,
             data_analysed_name, trig_generated_name, 'daxes', currdir,
             veto_file=censored_veto, veto_segment_name='closed_box',
             tags=insp_file.tags + [subsec])

##################### COINC FULL_DATA plots ###################################

# Main results with combined file (we mix open and closed box here, but
# separate them in the result page)

# FIXME: COMMENTED OUT JOBS ARE FAILING ... NEED FIXING!!
#        (Currently that's most of the jobs :-( )
#snrifar = wf.make_snrifar_plot(workflow, combined_bg_file,
#                               rdir['open_box_result'],
#                               tags=combined_bg_file.tags)
#snrifar_cb = wf.make_snrifar_plot(workflow, combined_bg_file,
#                                  rdir['coincident_triggers'], closed_box=True,
#                                  tags=combined_bg_file.tags + ['closed'])
#ratehist = wf.make_snrratehist_plot(workflow, combined_bg_file,
#                                    rdir['open_box_result'],
#                                    tags=combined_bg_file.tags)
#snrifar_ifar = wf.make_snrifar_plot(workflow, combined_bg_file,
#                                    rdir['open_box_result/significance'],
#                                    cumulative=False,
#                                    tags=combined_bg_file.tags + ['ifar'])
#ifar_ob = wf.make_ifar_plot(workflow, combined_bg_file,
#                            rdir['open_box_result/significance'],
#                            tags=combined_bg_file.tags + ['open_box'])
#ifar_cb = wf.make_ifar_plot(workflow, combined_bg_file,
#                            rdir['coincident_triggers'],
#                            tags=combined_bg_file.tags + ['closed_box'])
#table = wf.make_foreground_table(workflow, combined_bg_file,
#                                 hdfbank[0], rdir['open_box_result'],
#                                 singles=insps,  extension='.html',
#                                 tags=["html"])
#symlink_result(snrifar, 'open_box_result/significance')
#symlink_result(ratehist, 'open_box_result/significance')
#symlink_result(table, 'open_box_result/significance')

# Set html pages
#main_page = [(snrifar, ratehist),(table,)]
#layout.two_column_layout(rdir['open_box_result'], main_page)

#detailed_page = [(snrifar, ratehist), (snrifar_ifar, ifar_ob), (table,)]
#layout.two_column_layout(rdir['open_box_result/significance'], detailed_page)

#closed_page = [(snrifar_cb, ifar_cb), (bank_plot,)]
#layout.two_column_layout(rdir['coincident_triggers'], closed_page)

# run minifollowups on the output of the loudest events
mfup_dir = rdir['open_box_result/loudest_events_followup']
wf.setup_foreground_minifollowups(workflow, combined_bg_file,
                                  full_insps,  hdfbank[0], insp_files_seg_file,
                                  data_analysed_name, trig_generated_name,
                                  'daxes', mfup_dir,
                                  tags=combined_bg_file.tags)

# Sub-pages for each ifo combination

for key in final_bg_files:
    # FIXME: Stop obfuscating this file!
    bg_file = final_bg_files[key][0][1][0]
    open_dir = rdir['open_box_result/{}_coincidences'.format(key)]
    closed_dir = rdir['coincident_triggers/{}_coincidences'.format(key)]
    snrifar = wf.make_snrifar_plot(workflow, bg_file, open_dir,
                                   tags=bg_file.tags)
    snrifar_cb = wf.make_snrifar_plot(workflow, bg_file, closed_dir,
                                      closed_box=True,
                                      tags=bg_file.tags + ['closed'])
    ratehist = wf.make_snrratehist_plot(workflow, bg_file, open_dir,
                                        tags=bg_file.tags)
    snrifar_ifar = wf.make_snrifar_plot(workflow, bg_file, open_dir,
                                        cumulative=False,
                                        tags=bg_file.tags + ['ifar'])
    #ifar_ob = wf.make_ifar_plot(workflow, bg_file, open_dir,
    #                            tags=bg_file.tags + ['open_box'])
    #ifar_cb = wf.make_ifar_plot(workflow, bg_file, closed_dir,
    #                            tags=bg_file.tags + ['closed_box'])
    #table = wf.make_foreground_table(workflow, bg_file, hdfbank[0], open_dir,
    #                                 singles=insps,  extension='.html',
    #                                 tags=["html"])

    #detailed_page = [(snrifar, ratehist), (snrifar_ifar, ifar_ob), (table,)]
    # FIXME: NEED TO ADD NOT WORKING PLOTS, AS ABOVE
    detailed_page = [(snrifar, ratehist), (snrifar_ifar,)]
    layout.two_column_layout(open_dir, detailed_page)

    #closed_page = [(snrifar_cb, ifar_cb)]
    closed_page = [(snrifar_cb,)]
    layout.two_column_layout(closed_dir, closed_page)


############################## Setup the injection runs #######################

splitbank_files_inj = wf.setup_splittable_workflow(workflow, hdfbank,
                                                   out_dir="bank",
                                                   tags=['injections'])

# setup the injection files
inj_files, inj_tags = wf.setup_injection_workflow(workflow,
                                                  output_dir="inj_files")

inj_coincs = wf.FileList()

found_inj_dict ={}
insps_dict = {}
small_inj_file_dict = {}

files_for_combined_injfind = []
for inj_file, tag in zip(inj_files, inj_tags):
    ctags = [tag, 'injections']
    output_dir = '%s_coinc' % tag

    if workflow.cp.has_option_tags('workflow-injections',
                                   'compute-optimal-snr', tags=ctags):
        optimal_snr_file = wf.compute_inj_optimal_snr(
                workflow, inj_file, psd_files, 'inj_files', tags=ctags)
        file_for_injfind = optimal_snr_file
    else:
        file_for_injfind = inj_file

    if workflow.cp.has_option_tags('workflow-injections', 'inj-cut', tags=ctags):
        file_for_vetoes = wf.cut_distant_injections(
                workflow, file_for_injfind, 'inj_files', tags=ctags)
    else:
        file_for_vetoes = inj_file

    files_for_combined_injfind.append(file_for_injfind)

    if workflow.cp.has_option_tags('workflow-injections', 'strip-injections',
                                   tags=ctags):
        small_inj_file = wf.veto_injections(workflow, file_for_vetoes,
                             insp_files_seg_file, trig_generated_name,
                             "inj_files", tags=ctags)
    else:
        small_inj_file = file_for_vetoes

    # setup the matchedfilter jobs
    insps = wf.setup_matchedfltr_workflow(workflow, analyzable_segs,
                                         datafind_files, splitbank_files_inj,
                                         output_dir, tags=ctags,
                                         injection_file=small_inj_file)

    insps = wf.merge_single_detector_hdf_files(workflow, hdfbank[0],
                                               insps, output_dir, tags=ctags)
    # multiifo coincidence for injections
    inj_coinc = {}
    for i in range(2, len(insps)+1):
        combinations = itertools.combinations(ifo_ids.keys(), i)
        for ifocomb in combinations:
            inspcomb = wf.select_files_by_ifo_combination(ifocomb, insps)
            pivot_ifo, fixed_ifo, ordered_ifo_list = \
                wf.get_ordered_ifo_list(ifocomb, ifo_ids)

            # Create coinc tag, and set up the coinc job for the combination
            coinctag = '{}det_'.format(len(ifocomb)) + ordered_ifo_list
            ctagcomb = [tag, 'injections', coinctag]
            curr_out = wf.setup_multiifo_interval_coinc_inj\
                (workflow, hdfbank, full_insps, inspcomb, statfiles,
                 final_bg_files[ordered_ifo_list][0][1],
                 final_veto_file[0], final_veto_name[0],
                 output_dir, pivot_ifo, fixed_ifo, tags=ctagcomb)
            inj_coinc[ordered_ifo_list] = curr_out
    
    combctags = [tag, 'injections']
    final_inj_bg_file_list = wf.FileList()
    for key in inj_coinc:
        final_inj_bg_file_list += [inj_coinc[key]]
        
    combined_inj_bg_file = wf.setup_multiifo_combine_statmap(workflow,
                                                     final_inj_bg_file_list,
                                                     output_dir,
                                                     tags=combctags)
    
    # FIXME: Should this be censored_veto
    found_inj = wf.find_injections_in_hdf_coinc\
        (workflow, [combined_inj_bg_file], [file_for_injfind],
         final_veto_file[0], final_veto_name[0], output_dir, tags=combctags)
    
    inj_coincs += [combined_inj_bg_file]

    # Set files for plots
    found_inj_dict[tag] = found_inj
    insps_dict[tag] = insps
    small_inj_file_dict[tag] = small_inj_file

# Make combined injection file
# FIXME: Should this be censored_veto?
if len(files_for_combined_injfind) > 0:
    found_inj_comb = wf.find_injections_in_hdf_coinc\
        (workflow, inj_coincs, files_for_combined_injfind, final_veto_file[0],
         final_veto_name[0], 'allinj', tags=['ALLINJ'])


############################ Injection plots #################################

# Per injection run plots
for inj_file, tag in zip(inj_files, inj_tags):
    s = []
    found_inj = found_inj_dict[tag]
    insps = insps_dict[tag]
    small_inj_file = small_inj_file_dict[tag]
    injdir = rdir['injections/%s' % tag]
    sensdir = rdir['search_sensitivity/%s' % tag]

    #foundmissed/sensitivity plots
    #s = wf.make_sensitivity_plot(workflow, found_inj, sensdir,
    #                             exclude=['all', 'summ'], require='sub',
    #                             tags=ctags)
    f = wf.make_foundmissed_plot(workflow, found_inj, injdir,
                                 exclude=['all', 'summ'], require='sub',
                                 tags=[tag])

    # FIXME: It's not clear to me that this does anything??
    # Extra foundmissed/sensitivity plots
    #wf.make_sensitivity_plot(workflow, found_inj, sensdir,
    #                         exclude=['all', 'summ', 'sub'], tags=ctags)
    wf.make_foundmissed_plot(workflow, found_inj, injdir,
                             exclude=['all', 'summ', 'sub'], tags=[tag])

    #found_table = wf.make_inj_table(workflow, found_inj, injdir,
    #                                singles=insps, tags=[tag + 'found'])
    missed_table = wf.make_inj_table(workflow, found_inj, injdir,
                                     missed=True, tags=[tag + 'missed'])

    for i in range(2, len(insps)+1):
        combinations = itertools.combinations(ifo_ids.keys(), i)
        for ifocomb in combinations:
            inspcomb = wf.select_files_by_ifo_combination(ifocomb, insps)
            fdinspcmb = wf.select_files_by_ifo_combination(ifocomb, full_insps)
            _, _, ordered_ifo_list = wf.get_ordered_ifo_list(ifocomb, ifo_ids)

            for inj_insp, trig_insp in zip(inspcomb, fdinspcmb):
                final_bg_file = final_bg_files[ordered_ifo_list][0][1][0]
                curr_tags = [tag, ordered_ifo_list]
                #f += wf.make_coinc_snrchi_plot(workflow, found_inj, inj_insp,
                #                               final_bg_file, trig_insp,
                #                               injdir, tags=curr_tags)

    # Make pages from plots
    inj_layout = list(layout.grouper(f, 2)) + [(missed_table,)]
    layout.two_column_layout(rdir['injections/%s' % tag], inj_layout)

    if len(s) > 0:
        layout.group_layout(rdir['search_sensitivity/%s' % tag], s)

    # Minifollowups
    curr_dir_nam = 'injections/followup_of_{}'.format(tag)
    if workflow.cp.has_option_tags('workflow-injection_minifollowups',
                                   'subsection-suffix', tags=[tag]):
        suf_str = workflow.cp.get_opt_tags('workflow-injection_minifollowups',
                                           'subsection-suffix', tags=[tag])
        curr_dir_nam += '_' + suf_str
    currdir = rdir[curr_dir_nam]
    #wf.setup_injection_minifollowups(workflow, found_inj, small_inj_file,
    #                                 insps,  hdfbank[0], insp_files_seg_file,
    #                                 data_analysed_name, trig_generated_name,
    #                                 'daxes', currdir, tags=[tag])

    # If option given, make throughput plots
    if workflow.cp.has_option_tags('workflow-matchedfilter',
                                   'plot-throughput', tags=[tag]):
        wf.make_throughput_plot(workflow, insps, rdir['workflow/throughput'],
                                tags=[tag])


############################ Finalization ####################################

# Create the final log file
log_file_html = wf.File(workflow.ifos, 'WORKFLOW-LOG', workflow.analysis_time,
                                           extension='.html',
                                           directory=rdir['workflow'])

# Create a page to contain a dashboard link
dashboard_file = wf.File(workflow.ifos, 'DASHBOARD', workflow.analysis_time,
                                           extension='.html',
                                           directory=rdir['workflow'])
dashboard_str = """<center><p style="font-size:20px"><b><a href="PEGASUS_DASHBOARD_URL" target="_blank">Pegasus Dashboard Page</a></b></p></center>"""
kwds = { 'title' : 'Pegasus Dashboard',
         'caption' : "Link to Pegasus Dashboard",
         'cmd' : "PYCBC_SUBMIT_DAX_ARGV", }
save_fig_with_metadata(dashboard_str, dashboard_file.storage_path, **kwds)

# Create pages for the submission script to write data
wf.makedir(rdir['workflow/dax'])
wf.makedir(rdir['workflow/input_map'])
wf.makedir(rdir['workflow/output_map'])
wf.makedir(rdir['workflow/planning'])

wf.make_results_web_page(finalize_workflow, os.path.join(os.getcwd(),
rdir.base))

container += workflow
container += finalize_workflow

import Pegasus.DAX3 as dax
dep = dax.Dependency(parent=workflow.as_job, child=finalize_workflow.as_job)
container._adag.addDependency(dep)

container.save()

# Protect the open box results folder
# os.chmod(rdir['open_box_result'], 0700)
logging.info("Written dax.")

# Close the log and flush to the html file
logging.shutdown()
with open (wf_log_file.storage_path, "r") as logfile:
    logdata=logfile.read()
log_str = """
<p>Workflow generation script created workflow in output directory: %s</p>
<p>Workflow name is: %s</p>
<p>Workflow generation script run on host: %s</p>
<pre>%s</pre>
""" % (os.getcwd(), args.workflow_name, socket.gethostname(), logdata)
kwds = { 'title' : 'Workflow Generation Log',
         'caption' : "Log of the workflow script %s" % sys.argv[0],
         'cmd' :' '.join(sys.argv), }
save_fig_with_metadata(log_str, log_file_html.storage_path, **kwds)
layout.single_layout(rdir['workflow'], ([dashboard_file,log_file_html]))
