From f14d9d2750de86ba621848e3a2c1a880adc5dbd1 Mon Sep 17 00:00:00 2001
From: Brandon Piotrzkowski <piotrzk3@uwm.edu>
Date: Thu, 14 Nov 2019 14:57:53 -0600
Subject: [PATCH] Modify RAVEN VOEvent template

---
 gracedb/annotations/voevent_utils.py          | 91 +++++++++++--------
 gracedb/api/v1/superevents/serializers.py     |  3 +-
 gracedb/events/models.py                      |  3 +
 .../0006_add_raven_voevent_sevent_fields.py   |  5 +
 4 files changed, 63 insertions(+), 39 deletions(-)

diff --git a/gracedb/annotations/voevent_utils.py b/gracedb/annotations/voevent_utils.py
index 904e2d309..9541c0b39 100644
--- a/gracedb/annotations/voevent_utils.py
+++ b/gracedb/annotations/voevent_utils.py
@@ -291,6 +291,7 @@ def construct_voevent_file(obj, voevent, request=None):
         if (is_superevent(obj) and voevent.raven_coinc):
             ext_id = obj.em_type
             ext_event = Event.getByGraceid(ext_id)
+            emcoinc_params = []
 
             ## External GCN ID
             if ext_event.trigger_id:
@@ -301,18 +302,29 @@ def construct_voevent_file(obj, voevent, request=None):
                     dataType="string"
                 )
                 p_extid.Description = ("GCN trigger ID of external event")
-                v.What.append(p_extid)
+                emcoinc_params.append(p_extid)
+
+            ## External IVORN
+            if ext_event.ivorn:
+                p_extivorn = vp.Param(
+                    "External_Ivorn",
+                    value=ext_event.ivorn,
+                    ucd="meta.id",
+                    dataType="string"
+                )
+                p_extivorn.Description = ("IVORN of external event")
+                emcoinc_params.append(p_extivorn)
 
             ## External Pipeline
             if ext_event.pipeline:
                 p_extpipeline = vp.Param(
-                    "External_Alert_Type",
+                    "External_Observatory",
                     value=ext_event.pipeline.name,
                     ucd="meta.code",
                     dataType="string"
                 )
                 p_extpipeline.Description = ("External Observatory")
-                v.What.append(p_extpipeline)
+                emcoinc_params.append(p_extpipeline)
 
             ## External Search
             if ext_event.search:
@@ -323,7 +335,7 @@ def construct_voevent_file(obj, voevent, request=None):
                     dataType="string"
                 )
                 p_extsearch.Description = ("External astrophysical search")
-                v.What.append(p_extsearch)
+                emcoinc_params.append(p_extsearch)
 
             ## Time Difference
             if ext_event.gpstime and obj.t_0:
@@ -336,8 +348,10 @@ def construct_voevent_file(obj, voevent, request=None):
                    #AEP--> figure this out
                    ac=True,
                )
-               p_deltat.Description = ("External astrophysical search")
-               v.What.append(p_deltat)
+               p_deltat.Description = ("Time difference between GW candidate "
+                                       "and external event, centered on the "
+                                       "GW candidate")
+               emcoinc_params.append(p_deltat)
 
             ## Temporal Coinc FAR
             if obj.coinc_far:
@@ -351,8 +365,8 @@ def construct_voevent_file(obj, voevent, request=None):
                     unit="Hz"
                 )
                 p_coincfar.Description = ("Estimated coincidence false alarm "
-                                        "rate in Hz using timing")
-                v.What.append(p_coincfar)
+                                          "rate in Hz using timing")
+                emcoinc_params.append(p_coincfar)
 
             ## Spatial-Temporal Coinc FAR
             ## FIXME: Find a way to supply this value
@@ -367,9 +381,37 @@ def construct_voevent_file(obj, voevent, request=None):
                     unit="Hz"
                 )
                 p_coincfar_space.Description = ("Estimated coincidence false alarm "
-                                        "rate in Hz using timing and sky "
-                                        "position")
-                v.What.append(p_coincfar_space)
+                                                "rate in Hz using timing and sky "
+                                                "position")
+                emcoinc_params.append(p_coincfar_space)
+
+            ## RAVEN combined sky map
+            if voevent.combined_skymap_filename:
+                ## Skymap group
+                ### fits skymap URL
+                fits_skymap_url_comb = build_absolute_uri(
+                    reverse(fits_view_name, args=[graceid,
+                                                  voevent.combined_skymap_filename]),
+                    request
+                )
+                p_fits_url_comb = vp.Param(
+                    "joint_skymap_fits",
+                    value=fits_skymap_url_comb,
+                    ucd="meta.ref.url",
+                    dataType="string"
+                )
+                p_fits_url_comb.Description = "Combined GW-External Sky Map FITS"
+                emcoinc_params.append(p_fits_url_comb)
+
+            ## Create EMCOINC group
+            emcoinc_group = vp.Group(
+                emcoinc_params,
+                name='External Coincidence',
+                type='External Coincidence'  # keep this only for backwards compatibility
+            )
+            emcoinc_group.Description = \
+                ("Properties of joint coincidence found by RAVEN")
+            v.What.append(emcoinc_group)
 
     # initial and update VOEvents must have a skymap.
     # new feature (10/24/2016): preliminary VOEvents can have a skymap,
@@ -401,33 +443,6 @@ def construct_voevent_file(obj, voevent, request=None):
         ### Add to What
         v.What.append(skymap_group)
 
-        ## RAVEN combined sky map
-        if (voevent.combined_skymap_filename and voevent.raven_coinc):
-            ## Skymap group
-            ### fits skymap URL
-            fits_skymap_url_comb = build_absolute_uri(
-                reverse(fits_view_name, args=[graceid,
-                                              combined_skymap_filename]),
-                request
-            )
-            p_fits_url_comb = vp.Param(
-                "skymap_fits",
-                value=fits_skymap_url_comb,
-                ucd="meta.ref.url",
-                dataType="string"
-            )
-            p_fits_url_comb.Description = "Combined GW-External Sky Map FITS"
-
-            ### Create skymap group with params
-            skymap_group_comb = vp.Group(
-                [p_fits_url],
-                name="GW-External_SKYMAP",
-                type="GW-External_SKYMAP",
-            )
-
-            ### Add to What
-            v.What.append(skymap_group_comb)
-
     ## Analysis specific attributes
     if voevent_type != 'retraction':
         ### Classification group (EM-Bright params; CBC only)
diff --git a/gracedb/api/v1/superevents/serializers.py b/gracedb/api/v1/superevents/serializers.py
index 540e63698..352a7a829 100644
--- a/gracedb/api/v1/superevents/serializers.py
+++ b/gracedb/api/v1/superevents/serializers.py
@@ -589,6 +589,7 @@ class SupereventVOEventSerializer(serializers.ModelSerializer):
     combined_skymap_filename = serializers.CharField(required=False)
     delta_t = serializers.FloatField(write_only=True, min_value=-1000,
         max_value=1000, required=False)
+    ivorn = serializers.CharField(required=False)
 
     class Meta:
         model = VOEvent
@@ -602,7 +603,7 @@ class SupereventVOEventSerializer(serializers.ModelSerializer):
 
         raven_fields = ('raven_coinc','ext_gcn', 'ext_pipeline', 'ext_search',
             'time_coinc_far', 'space_coinc_far', 'combined_skymap_filename',
-            'delta_t')
+            'delta_t', 'ivorn')
 
         # Combine the fields:
         fields = fields + raven_fields
diff --git a/gracedb/events/models.py b/gracedb/events/models.py
index 978a35d95..6413e548d 100644
--- a/gracedb/events/models.py
+++ b/gracedb/events/models.py
@@ -1025,6 +1025,9 @@ class VOEventBase(CleanSaveModel):
     delta_t = models.FloatField(null=True, default=None, blank=True,
         validators=[models.fields.validators.MinValueValidator(-1000),
         models.fields.validators.MaxValueValidator(1000)])
+    ivorn = models.CharField(max_length=300, default="", blank=True,
+        editable=False)
+
 
     def fileurl(self):
         # Override this method on derived classes
diff --git a/gracedb/superevents/migrations/0006_add_raven_voevent_sevent_fields.py b/gracedb/superevents/migrations/0006_add_raven_voevent_sevent_fields.py
index 1a8e6b6a8..bbeaac50d 100644
--- a/gracedb/superevents/migrations/0006_add_raven_voevent_sevent_fields.py
+++ b/gracedb/superevents/migrations/0006_add_raven_voevent_sevent_fields.py
@@ -63,4 +63,9 @@ class Migration(migrations.Migration):
             name='time_coinc_far',
             field=models.FloatField(blank=True, default=None, null=True, validators=[django.core.validators.MinValueValidator(0.0)]),
         ),
+        migrations.AddField(
+            model_name='voevent',
+            name='ivorn',
+            field=models.CharField(blank=True, default='', editable=False, max_length=300),
+        ),
     ]
-- 
GitLab