621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778 | def produce_output_coinc(self, row, coincfar):
"""
Construct a full ligolw file object to represent a simulated
recovered event.
Parameters
----------
row (ligolw table row)
A single SimInspiral row corresponding to the injection.
coincfar (float)
FAR value for simulated recovered event associated with
this injection.
Returns
----------
newxmldoc (ligolw file object)
ligo-lw coinc file object with all required tables.
"""
# instantiate relevant lsctables objects
newxmldoc = ligolw.Document()
ligolw_elem = newxmldoc.appendChild(ligolw.LIGO_LW())
new_process_table = ligolw_elem.appendChild(
lsctables.New(lsctables.ProcessTable,
columns=utils.all_process_rows)
)
new_sngl_inspiral_table = ligolw_elem.appendChild(
lsctables.New(lsctables.SnglInspiralTable,
columns=utils.all_sngl_rows)
)
new_coinc_inspiral_table = ligolw_elem.appendChild(
lsctables.New(lsctables.CoincInspiralTable,
columns=utils.all_coinc_rows)
)
new_coinc_event_table = ligolw_elem.appendChild(
lsctables.New(lsctables.CoincTable)
)
new_coinc_map_table = ligolw_elem.appendChild(
lsctables.New(lsctables.CoincMapTable)
)
# simulate SNR time series using interpolated psd object
# measurement_error is set as gaussian but one can switch
# to no noise by measurement_error="zero-noise"
bayestar_sim_list = bayestar_realize_coincs.simulate(
seed=None,
sim_inspiral=row,
psds=self.psds_interp,
responses=self.responses,
locations=self.locations,
measurement_error="gaussian-noise",
f_low=20,
f_high=2048,
)
# get mass parameters
mass1 = max(numpy.random.normal(loc=row.mass1, scale=1.0), 1.1)
mass2 = max(numpy.random.normal(loc=row.mass2, scale=1.0), mass1)
mchirp, eta = self.mc_eta_from_m1_m2(mass1, mass2)
snrs = defaultdict(lambda: 0)
coincsnr = None
# populate process table
process_row_dict = {k: 0 for k in utils.all_process_rows}
process_row_dict.update(
{"process_id": 0, "program": "gstlal_inspiral", "comment": ""}
)
new_process_table.extend([
lsctables.ProcessTable.RowType(**process_row_dict)
])
# populate sngl table, coinc map table, and SNR timeseriess
for event_id, (
ifo, (horizon, abs_snr, arg_snr, toa, snr_series)
) in enumerate(zip(self.ifos, bayestar_sim_list)):
sngl_row_dict = {k: 0 for k in utils.all_sngl_rows}
sngl_row_dict.update(
{
"process_id": 0,
"event_id": event_id,
"end": toa,
"mchirp": mchirp,
"mass1": mass1,
"mass2": mass2,
"eta": eta,
"ifo": ifo,
"snr": abs_snr,
"coa_phase": arg_snr,
}
)
# add to the sngl inspiral table
new_sngl_inspiral_table.extend(
[lsctables.SnglInspiralTable.RowType(**sngl_row_dict)]
)
snrs[ifo] = abs_snr
coinc_map_row_dict = {
"coinc_event_id": 0,
"event_id": event_id,
"table_name": "sngl_inspiral",
}
# add to the coinc map table
new_coinc_map_table.extend(
[lsctables.CoincMapTable.RowType(**coinc_map_row_dict)]
)
# add SNR time series as array objects
elem = lal.series.build_COMPLEX8TimeSeries(snr_series)
elem.appendChild(Param.from_pyvalue("event_id", event_id))
ligolw_elem.appendChild(elem)
# calculate coinc SNR, only proceed if above 4
coincsnr = numpy.linalg.norm([snr for snr in snrs.values() if snr > 4])
if not coincsnr:
logging.debug(f"Coinc SNR {coincsnr} too low to send a message.")
return None
# populate coinc inspiral table
coinc_row_dict = {col: 0 for col in utils.all_coinc_rows}
coincendtime = row.geocent_end_time
coincendtimens = row.geocent_end_time_ns
coinc_row_dict.update(
{
"coinc_event_id": 0,
"snr": coincsnr,
"mass": row.mass1 + row.mass2,
"mchirp": row.mchirp,
"end_time": coincendtime,
"end_time_ns": coincendtimens,
"combined_far": coincfar,
}
)
new_coinc_inspiral_table.extend(
[lsctables.CoincInspiralTable.RowType(**coinc_row_dict)]
)
# populate coinc event table
coinc_event_row_dict = {col: 0 for col in utils.all_coinc_event_rows}
coinc_event_row_dict.update(
{
"coinc_def_id": 0,
"process_id": 0,
"time_slide_id": 0,
"instruments": "H1,L1,V1",
"numevents": len(new_sngl_inspiral_table),
}
)
new_coinc_event_table.extend(
[lsctables.CoincTable.RowType(**coinc_event_row_dict)]
)
# add psd frequeny series
lal.series.make_psd_xmldoc(self.psd, ligolw_elem)
return newxmldoc
|