swh:1:snp:3a699297f000109a1bc833f294a54171df990207
Tip revision: 35017d8575078e84d7af6ef003b027ae6c3c7983 authored by Gareth S Davies on 20 July 2020, 13:31:53 UTC
prep for release 1.16.5 (#3386)
prep for release 1.16.5 (#3386)
Tip revision: 35017d8
pycbc_dark_vs_bright_injections
#!/usr/bin/env python
# Copyright (C) 2015 Francesco Pannarale
#
# 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.
"""
Given an xml(.gz) table with CBC injections, this script separates them into:
(1) (potentially) EM bright sources, i.e. BNS + (potentially) bright NSBH;
(2) EM dim sources, i.e. BBH + dark NSBH.
The two sets are stored into two separate output files.
"""
__author__ = "Francesco Pannarale"
__email__ = "francesco.pannarale@ligo.org"
__version__ = "1.1"
__date__ = "28.09.2015"
import argparse
import logging
import numpy
import pycbc
import pycbc.inject
import pycbc.tmpltbank.em_progenitors
from glue.ligolw import utils as ligolw_utils
from glue.ligolw import lsctables
from random import sample
from copy import deepcopy
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('-i', dest='inj_xml', required=True, help='Input LIGOLW injections file.')
parser.add_argument('--output-bright', dest='output_bright', required=True,
help="Output LIGOLW file containing potentially EM bright injections.")
parser.add_argument('--output-dim', dest='output_dim', required=True,
help="Output LIGOLW file containing EM dim injections.")
parser.add_argument('--eos', dest='eos', required=True,
help="Select the EOS to be used for the NS when calculating"
"the remnant disk mass. Only 2H is currently supported.")
parser.add_argument('--ns-bh-boundary', type=float, required=True,
help="Mass boundary between neutron stars and black holes. "
"Components below this mass are considered neutron "
"stars. Components at/above are considered black holes."
"UNITS=Solar mass")
parser.add_argument('--remnant-mass-threshold', type=float, required=True,
help="Setting this filters EM dim NS-BH binaries: if the"
"remnant disk mass does not exceed this value, the NS-BH"
"binary is dropped from the bank. UNITS=Solar mass")
parser.add_argument("-z", "--write-compress", action="store_true", help="Write compressed xml.gz files.")
parser.add_argument("--frame-axis-view", action="store_true",
help="The x, y, z spin components are wrt the line of site.")
parser.add_argument("-v", "--verbose", action="store_true", default=False,
help="Extended standard output.")
parser.add_argument("-k", "--max-keep", type=int, default=None,
help="Upper limit on the number of injections in the "
"bright output file.")
opts = parser.parse_args()
log_fmt = '%(asctime)s %(message)s'
log_date_fmt = '%Y-%m-%d %H:%M:%S'
logging.basicConfig(level=logging.INFO, format=log_fmt, datefmt=log_date_fmt)
if opts.verbose:
logging.info("Loading injections")
injections = pycbc.inject.InjectionSet(opts.inj_xml)
if opts.verbose:
logging.info("Loading neutron star equilibrium configurations")
ns_sequence, max_ns_g_mass = pycbc.tmpltbank.em_progenitors.load_ns_sequence(opts.eos)
# (Potentially) EM bright sources: table and name of the file that will store it
output_bright = opts.output_bright
if opts.write_compress:
if not output_bright.endswith('gz'):
output_bright = output_bright+'.gz'
out_sim_inspiral_bright = lsctables.New(lsctables.SimInspiralTable,
columns=injections.table.columnnames)
if opts.max_keep is not None:
out_sim_inspiral_bright_trimmed = deepcopy(out_sim_inspiral_bright)
# EM dim sources: table and name of the file that will store it
output_dim = opts.output_dim
out_sim_inspiral_dim = deepcopy(out_sim_inspiral_bright)
if opts.write_compress:
if not output_dim.endswith('gz'):
output_dim = output_dim+'.gz'
for i, inj in enumerate(injections.table):
if opts.verbose:
logging.info('%d/%d', i, len(injections.table))
m1 = inj.mass1
m2 = inj.mass2
# BNS are all considered potentially EM bright
if numpy.logical_and(m1 < opts.ns_bh_boundary, m2 < opts.ns_bh_boundary):
out_sim_inspiral_bright.append(inj)
# NSBH systems
elif numpy.logical_not(numpy.logical_and(m1 >= opts.ns_bh_boundary, m2 >= opts.ns_bh_boundary)):
eta = inj.eta
s1x = inj.spin1x
s1y = inj.spin1y
s1z = inj.spin1z
s2x = inj.spin2x
s2y = inj.spin2y
s2z = inj.spin2z
incl = inj.inclination
# 1 = NS, 2 = BH
if m1 < m2:
ns_mass = m1
bh_spin_magnitude = numpy.sqrt(s2x*s2x + s2y*s2y + s2z*s2z)
if opts.frame_axis_view:
# Scalar product between spin and orbital angular momentum
# (the x, y, z spin components are wrt the line of site)
bh_spin_para = s2x*numpy.sin(incl)+s2z*numpy.cos(incl)
else:
# The x, y, z spin components are wrt the orbital angular momentum
bh_spin_para = s2z
bh_spin_inclination = numpy.arccos(bh_spin_para/bh_spin_magnitude)
# 2 = NS, 1 = BH
else:
ns_mass = m2
bh_spin_magnitude = numpy.sqrt(s1x*s1x + s1y*s1y + s1z*s1z)
if opts.frame_axis_view:
# Scalar product between spin and orbital angular momentum
# (the x, y, z spin components are wrt the line of site)
bh_spin_para = s1x*numpy.sin(incl)+s1z*numpy.cos(incl)
else:
# The x, y, z spin components are wrt the orbital angular momentum
bh_spin_para = s1z
bh_spin_inclination = numpy.arccos(bh_spin_para/bh_spin_magnitude)
# remnant_mass is the remnant disk mass, it is compared to the
# threshold set by the user to discriminate dim and bright
remnant_mass = pycbc.tmpltbank.em_progenitors.remnant_mass( \
eta, ns_mass, ns_sequence, bh_spin_magnitude, bh_spin_inclination)
if remnant_mass > opts.remnant_mass_threshold:
out_sim_inspiral_bright.append(inj)
else:
out_sim_inspiral_dim.append(inj)
# BBH are all considered EM dark
else:
out_sim_inspiral_dim.append(inj)
if opts.max_keep is not None and \
len(out_sim_inspiral_bright) > int(opts.max_keep):
out_sim_inspiral_bright_trimmed.extend(sample(out_sim_inspiral_bright,
int(opts.max_keep)))
logging.info("Found %d/%d (potentially) EM bright injections. Trimming to "
"keep only %d. Storing them to %s."
% (len(out_sim_inspiral_bright), len(injections.table),
len(out_sim_inspiral_bright_trimmed),
output_bright))
else:
logging.info("Found %d/%d (potentially) EM bright injections. Storing them"
" to %s." % (len(out_sim_inspiral_bright),
len(injections.table), output_bright))
logging.info("Found %d/%d EM dim injections. Storing them to %s."
% (len(out_sim_inspiral_dim), len(injections.table), output_dim))
if opts.verbose:
logging.info('Writing output')
llw_doc = injections.indoc
llw_root = llw_doc.childNodes[0]
llw_root.removeChild(injections.table)
if opts.max_keep is not None and \
len(out_sim_inspiral_bright) > int(opts.max_keep):
llw_root.appendChild(out_sim_inspiral_bright_trimmed)
ligolw_utils.write_filename(llw_doc, output_bright,
gz=output_bright.endswith('gz'))
llw_root.removeChild(out_sim_inspiral_bright_trimmed)
output_bright = output_bright.replace("POTENTIALLY_BRIGHT",
"POTENTIALLY_BRIGHT_UNTRIMMED")
logging.info(output_bright)
llw_root.appendChild(out_sim_inspiral_bright)
ligolw_utils.write_filename(llw_doc, output_bright,
gz=output_bright.endswith('gz'))
llw_root.removeChild(out_sim_inspiral_bright)
llw_root.appendChild(out_sim_inspiral_dim)
ligolw_utils.write_filename(llw_doc, output_dim,
gz=output_dim.endswith('gz'))
logging.info('Done')