diff --git a/gracedb/api/v1/events/views.py b/gracedb/api/v1/events/views.py index 14c7e9444da7852eb1b985d55ea101d64f37f8cf..c7ead4b47379271f6bd92af025e6955eb1e82d9e 100644 --- a/gracedb/api/v1/events/views.py +++ b/gracedb/api/v1/events/views.py @@ -1599,6 +1599,10 @@ class VOEventList(APIView): CoincComment = request.data.get('CoincComment', None) ProbHasNS = request.data.get('ProbHasNS', None) ProbHasRemnant = request.data.get('ProbHasRemnant', None) + BNS = request.data.get('BNS', None) + NSBH = request.data.get('NSBH', None) + BBH = request.data.get('BBH', None) + Terrestrial = request.data.get('Terrestrial', None) if (skymap_filename and not skymap_type) or (skymap_type and not skymap_filename): msg = "Both or neither of skymap_time and skymap_filename must be specified." @@ -1619,7 +1623,9 @@ class VOEventList(APIView): skymap_filename = skymap_filename, skymap_type = skymap_type, skymap_image_filename = skymap_image_filename, internal = internal, open_alert=open_alert, hardware_inj=hardware_inj, - CoincComment=CoincComment, ProbHasNS=ProbHasNS, ProbHasRemnant=ProbHasRemnant) + CoincComment=CoincComment, ProbHasNS=ProbHasNS, + ProbHasRemnant=ProbHasRemnant, BNS=BNS, NSBH=NSBH, BBH=BBH, + Terrestrial=Terrestrial) except VOEventBuilderException, e: msg = "Problem building VOEvent: %s" % str(e) diff --git a/gracedb/api/v1/superevents/serializers.py b/gracedb/api/v1/superevents/serializers.py index 31fbed00f0ce01739059e3f2d439a9295b7b0351..e4a688408f950f6b1b2d8d16089050138f663455 100644 --- a/gracedb/api/v1/superevents/serializers.py +++ b/gracedb/api/v1/superevents/serializers.py @@ -564,6 +564,14 @@ class SupereventVOEventSerializer(serializers.ModelSerializer): max_value=1, required=False) ProbHasRemnant = serializers.FloatField(write_only=True, min_value=0, max_value=1, required=False) + BNS = serializers.FloatField(write_only=True, min_value=0, max_value=1, + required=False) + NSBH = serializers.FloatField(write_only=True, min_value=0, max_value=1, + required=False) + BBH = serializers.FloatField(write_only=True, min_value=0, max_value=1, + required=False) + Terrestrial = serializers.FloatField(write_only=True, min_value=0, + max_value=1, required=False) class Meta: model = VOEvent @@ -571,7 +579,8 @@ class SupereventVOEventSerializer(serializers.ModelSerializer): 'issuer', 'filename', 'N', 'links', 'skymap_type', 'skymap_filename', 'skymap_image_filename', 'internal', 'open_alert', 'hardware_inj', 'CoincComment', 'ProbHasNS', - 'ProbHasRemnant', 'superevent', 'user') + 'ProbHasRemnant', 'BNS', 'NSBH', 'BBH', 'Terrestrial', + 'superevent', 'user') def __init__(self, *args, **kwargs): super(SupereventVOEventSerializer, self).__init__(*args, **kwargs) diff --git a/gracedb/api/v1/superevents/tests/test_access.py b/gracedb/api/v1/superevents/tests/test_access.py index 303c9a84131e0e9d304604aef29088b138068057..bfd0b22500923c8da6f038d43bcd63aee5f29bf9 100644 --- a/gracedb/api/v1/superevents/tests/test_access.py +++ b/gracedb/api/v1/superevents/tests/test_access.py @@ -2438,6 +2438,9 @@ class TestSupereventVOEventList(SupereventSetup, GraceDbApiTestBase): 'open_alert': False, 'hardware_inj': False, 'CoincComment': False, + 'ProbHasRemnant': 0.5, + 'BBH': 0.2, + 'Terrestrial': 0.9, } def test_internal_user_get_voevent_list(self): diff --git a/gracedb/events/buildVOEvent.py b/gracedb/events/buildVOEvent.py index ddb120c4b0e078eb0f66123735912fb0be7e51f7..5086fe9a0e23fc560c8a99d7c7356a05f147e8c3 100644 --- a/gracedb/events/buildVOEvent.py +++ b/gracedb/events/buildVOEvent.py @@ -51,8 +51,9 @@ def get_voevent_type(short_name): def buildVOEvent(event, serial_number, voevent_type, request=None, skymap_filename=None, skymap_type=None, skymap_image_filename=None, internal=True, - open_alert=False, hardware_inj=False, CoincComment=False, ProbHasNS=None, - ProbHasRemnant=None): + open_alert=False, hardware_inj=False, CoincComment=False, + ProbHasNS=None, ProbHasRemnant=None, BNS=None, NSBH=None, + BBH=None, Terrestrial=None): # XXX Branson commenting out. Reed's MDC events do not have FAR for some reason. # if not event.far: @@ -314,6 +315,12 @@ def buildVOEvent(event, serial_number, voevent_type, request=None, skymap_filena # Analysis specific attributes if voevent_type != 'retraction': + classification_group = Group('Classification', Description=["Source " + "classification: binary neutron star (BNS), neutron star-black" + "hole (NSBH), binary black hole (BBH), or terrestrial (noise)"]) + properties_group = Group('Properties', Description=["Qualitative " + "properties of the source, conditioned on the assumption that the " + "signal is an astrophysical compact binary merger"]) if isinstance(event,CoincInspiralEvent) and voevent_type != 'retraction': # get mchirp and mass mchirp = float(event.mchirp) @@ -322,37 +329,44 @@ def buildVOEvent(event, serial_number, voevent_type, request=None, skymap_filena eta = pow((mchirp/mass),5.0/3.0) # EM-Bright mass classifier information for CBC event candidates - if ProbHasNS!=None: - w.add_Param(Param(name="ProbHasNS", - dataType="float", - ucd="stat.probability", - unit="", - value=ProbHasNS, - Description=["Probability that at least one object in the binary is less than 3 solar masses"])) - - if ProbHasRemnant!=None: - w.add_Param(Param(name="ProbHasRemnant", - dataType="float", - ucd="stat.probability", - unit="", - value=ProbHasRemnant, - Description=["Probability that there is matter in the surroundings of the central object"])) - -# XXX -# w.add_Param(Param(name="ChirpMass", -# dataType="float", -# ucd="phys.mass", -# unit="solar mass", -# value=mchirp, -# Description=["Estimated CBC chirp mass"])) - -# XXX -# w.add_Param(Param(name="Eta", -# dataType="float", -# ucd="phys.mass;arith.factor", -# unit="", -# value=eta, -# Description=["Estimated ratio of reduced mass to total mass"])) + if ProbHasNS is not None: + properties_group.add_Param(Param(name="HasNS", + dataType="float", ucd="stat.probability", unit="", + value=ProbHasNS, Description=["Probability that at least " + "one object in the binary has a mass that is less than " + "3 solar masses"])) + + if ProbHasRemnant is not None: + properties_group.add_Param(Param(name="HasRemnant", + dataType="float", ucd="stat.probability", + unit="", value=ProbHasRemnant, + Description=["Probability that a nonzero mass was ejected " + "outside the central remnant object"])) + + if BNS is not None: + classification_group.add_Param(Param(name="BNS", + dataType="float", ucd="stat.probability", + unit="", value=BNS, Description=["Probability that the " + "source is a binary neutron star merger"])) + + if NSBH is not None: + classification_group.add_Param(Param(name="NSBH", + dataType="float", ucd="stat.probability", + unit="", value=NSBH, Description=["Probability that the " + "source is a neutron star - black hole merger"])) + + if BBH is not None: + classification_group.add_Param(Param(name="BBH", + dataType="float", ucd="stat.probability", + unit="", value=BBH, Description=["Probability that the " + "source is a binary black hole merger"])) + + if Terrestrial is not None: + classification_group.add_Param(Param(name="Terrestrial", + dataType="float", ucd="stat.probability", + unit="", value=Terrestrial, Description=["Probability " + "that the source is terrestrial (i.e., a background noise " + "fluctuation or a glitch)"])) # build up MaxDistance. event.singleinspiral_set.all()? # Each detector calculates an effective distance assuming the inspiral is @@ -452,6 +466,9 @@ def buildVOEvent(event, serial_number, voevent_type, request=None, skymap_filena pass else: pass + # Add Groups to What block + w.add_Group(classification_group) + w.add_Group(properties_group) v.set_What(w) diff --git a/gracedb/superevents/buildVOEvent.py b/gracedb/superevents/buildVOEvent.py index 2e374bd83e8591f4e54acdb909868023638832e7..40d7ab9794e482d011056ee17af0a4692e961743 100644 --- a/gracedb/superevents/buildVOEvent.py +++ b/gracedb/superevents/buildVOEvent.py @@ -54,7 +54,8 @@ def get_voevent_type(short_name): def construct_voevent_file(superevent, voevent, request=None, skymap_filename=None, skymap_type=None, skymap_image_filename=None, internal=True, open_alert=False, hardware_inj=False, CoincComment=False, - ProbHasNS=None, ProbHasRemnant=None): + ProbHasNS=None, ProbHasRemnant=None, BNS=None, NSBH=None, BBH=None, + Terrestrial=None): # Set preferred_event as event to be used in most of this event = superevent.preferred_event @@ -302,6 +303,12 @@ def construct_voevent_file(superevent, voevent, request=None, # Analysis specific attributes if voevent_type != 'retraction': + classification_group = Group('Classification', Description=["Source " + "classification: binary neutron star (BNS), neutron star-black" + "hole (NSBH), binary black hole (BBH), or terrestrial (noise)"]) + properties_group = Group('Properties', Description=["Qualitative " + "properties of the source, conditioned on the assumption that the " + "signal is an astrophysical compact binary merger"]) if isinstance(event, CoincInspiralEvent) and voevent_type != 'retraction': # get mchirp and mass mchirp = float(event.mchirp) @@ -310,21 +317,44 @@ def construct_voevent_file(superevent, voevent, request=None, eta = pow((mchirp/mass),5.0/3.0) # EM-Bright mass classifier information for CBC event candidates - if ProbHasNS!=None: - w.add_Param(Param(name="ProbHasNS", - dataType="float", - ucd="stat.probability", - unit="", - value=ProbHasNS, - Description=["Probability that at least one object in the binary is less than 3 solar masses"])) - - if ProbHasRemnant!=None: - w.add_Param(Param(name="ProbHasRemnant", - dataType="float", - ucd="stat.probability", - unit="", - value=ProbHasRemnant, - Description=["Probability that there is matter in the surroundings of the central object"])) + if ProbHasNS is not None: + properties_group.add_Param(Param(name="HasNS", + dataType="float", ucd="stat.probability", unit="", + value=ProbHasNS, Description=["Probability that at least " + "one object in the binary has a mass that is less than " + "3 solar masses"])) + + if ProbHasRemnant is not None: + properties_group.add_Param(Param(name="HasRemnant", + dataType="float", ucd="stat.probability", + unit="", value=ProbHasRemnant, + Description=["Probability that a nonzero mass was ejected " + "outside the central remnant object"])) + + if BNS is not None: + classification_group.add_Param(Param(name="BNS", + dataType="float", ucd="stat.probability", + unit="", value=BNS, Description=["Probability that the " + "source is a binary neutron star merger"])) + + if NSBH is not None: + classification_group.add_Param(Param(name="NSBH", + dataType="float", ucd="stat.probability", + unit="", value=NSBH, Description=["Probability that the " + "source is a neutron star - black hole merger"])) + + if BBH is not None: + classification_group.add_Param(Param(name="BBH", + dataType="float", ucd="stat.probability", + unit="", value=BBH, Description=["Probability that the " + "source is a binary black hole merger"])) + + if Terrestrial is not None: + classification_group.add_Param(Param(name="Terrestrial", + dataType="float", ucd="stat.probability", + unit="", value=Terrestrial, Description=["Probability " + "that the source is terrestrial (i.e., a background noise " + "fluctuation or a glitch)"])) # build up MaxDistance. event.singleinspiral_set.all()? # Each detector calculates an effective distance assuming the inspiral is @@ -416,6 +446,10 @@ def construct_voevent_file(superevent, voevent, request=None, except Exception as e: logger.exception(e) + # Add Groups to What block + w.add_Group(classification_group) + w.add_Group(properties_group) + v.set_What(w) ############ Wherewhen ############################ diff --git a/gracedb/superevents/utils.py b/gracedb/superevents/utils.py index 9c317e4f41be5c8cd8b79146dd53af13b8da5765..1d667a014bd1924c65488fe4c6b1155f5df0f1dc 100644 --- a/gracedb/superevents/utils.py +++ b/gracedb/superevents/utils.py @@ -560,8 +560,9 @@ def create_emobservation_for_superevent(superevent, submitter, ra_list, def create_voevent_for_superevent(superevent, issuer, voevent_type, skymap_type=None, skymap_filename=None, skymap_image_filename=None, internal=True, open_alert=False, hardware_inj=False, - CoincComment=False, ProbHasNS=None, ProbHasRemnant=None, - add_log_message=True, issue_alert=True): + CoincComment=False, ProbHasNS=None, ProbHasRemnant=None, BNS=None, + NSBH=None, BBH=None, Terrestrial=None, add_log_message=True, + issue_alert=True): # Instantiate VOEvent object voevent = VOEvent.objects.create(superevent=superevent, issuer=issuer, @@ -573,7 +574,8 @@ def create_voevent_for_superevent(superevent, issuer, voevent_type, skymap_image_filename=skymap_image_filename, internal=internal, open_alert=open_alert, hardware_inj=hardware_inj, CoincComment=CoincComment, ProbHasNS=ProbHasNS, - ProbHasRemnant=ProbHasRemnant) + ProbHasRemnant=ProbHasRemnant, BNS=BNS, NSBH=NSBH, BBH=BBH, + Terrestrial=Terrestrial) # Save versioned VOEvent file voevent_display_type = dict(VOEvent.VOEVENT_TYPE_CHOICES) \