From 3dffd3806896551988a5d74f92fdf4f9d319be90 Mon Sep 17 00:00:00 2001
From: bozianuleon <qzr746@alumni.ku.dk>
Date: Thu, 27 Jan 2022 19:30:11 +0100
Subject: [PATCH 1/4] Stopmuon func in utils, add labels to i3extractor

---
 src/graphnet/data/i3extractor.py | 13 ++++++++++++-
 src/graphnet/data/utils.py       | 29 +++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/src/graphnet/data/i3extractor.py b/src/graphnet/data/i3extractor.py
index 88f38704e..b06d7959d 100644
--- a/src/graphnet/data/i3extractor.py
+++ b/src/graphnet/data/i3extractor.py
@@ -7,7 +7,7 @@ except ImportError:
     print("icecube package not available.")
 
 from abc import abstractmethod
-from .utils import frame_has_key
+from .utils import frame_has_key,muon_stopped
 
 
 class I3Extractor(ABC):
@@ -238,6 +238,17 @@ class I3TruthExtractor(I3Extractor):
                 'interaction_type': interaction_type,
                 'elasticity': elasticity,
             })
+            if abs(output['pid'])==13:
+                output.update({
+                    'track_length': MCInIcePrimary.length,
+                })
+                final_position, stopped = muon_stopped(output)
+                output.update({
+                    'final_position_x': final_position[0],
+                    'final_position_y': final_position[1],
+                    'final_position_z': final_position[2],
+                    'stopped_muon': stopped,
+                })                
 
         return output
 
diff --git a/src/graphnet/data/utils.py b/src/graphnet/data/utils.py
index 57799fc69..05d3c3c9e 100644
--- a/src/graphnet/data/utils.py
+++ b/src/graphnet/data/utils.py
@@ -4,6 +4,7 @@ from glob import glob
 import os
 import numpy as np
 import pandas as pd
+import matplotlib.path as mpath
 from pathlib import Path
 import re
 from typing import List, Tuple
@@ -249,3 +250,31 @@ def frame_has_key(frame, key: str):
         return True
     except:
         return False
+
+def muon_stopped(truth, horizontal_pad = 100, vertical_pad = 100):
+    '''
+    Determine if a simulated muon stops inside the fiducial volume of the IceCube detector as defined in the RIDE study.
+    Vertical and horizontal pad shrink fiducial volume further.
+    Using track length, azimuth and zenith travel from the starting/generation point,
+    also return x,y,z of muon end point (to be reconstructed)
+    '''
+    #to do:remove hard-coded border coords and replace with GCD file contents using string no's
+    border_coords = np.array([(-256.1400146484375, -521.0800170898438), (-132.8000030517578, -501.45001220703125), (-9.13000011444092, -481.739990234375), (114.38999938964844, -461.989990234375), (237.77999877929688, -442.4200134277344), (361.0, -422.8299865722656), (405.8299865722656, -306.3800048828125), (443.6000061035156, -194.16000366210938), (500.42999267578125, -58.45000076293945), (544.0700073242188, 55.88999938964844), (576.3699951171875, 170.9199981689453), (505.2699890136719, 257.8800048828125), (429.760009765625, 351.0199890136719), (338.44000244140625, 463.7200012207031), (224.5800018310547, 432.3500061035156), (101.04000091552734, 412.7900085449219), (22.11000061035156, 509.5), (-101.05999755859375, 490.2200012207031), (-224.08999633789062, 470.8599853515625), (-347.8800048828125, 451.5199890136719), (-392.3800048828125, 334.239990234375), (-437.0400085449219, 217.8000030517578), (-481.6000061035156, 101.38999938964844), (-526.6300048828125, -15.60000038146973), (-570.9000244140625, -125.13999938964844), (-492.42999267578125, -230.16000366210938), (-413.4599914550781, -327.2699890136719), (-334.79998779296875, -424.5)])
+    border_z = [-512.82,524.56]
+    border = mpath.Path(border_coords)
+
+    start_pos = np.array([truth['position_x'],
+                          truth['position_y'],
+                          truth['position_z']])
+                          
+    travel_vec = -1*np.array([truth['track_length']*np.cos(truth['azimuth'])*np.sin(truth['zenith']),
+                           truth['track_length']*np.sin(truth['azimuth'])*np.sin(truth['zenith']),
+                           truth['track_length']*np.cos(truth['zenith'])])
+    
+    end_pos = start_pos+travel_vec
+
+    stopped_xy = border.contains_point((end_pos[0],end_pos[1]),radius=-horizontal_pad) 
+    stopped_z = (end_pos[2] > border_z[0] + vertical_pad) * (end_pos[2] < border_z[1] - vertical_pad) 
+    stopped_muon = stopped_xy * stopped_z 
+
+    return end_pos,stopped_muon
\ No newline at end of file
-- 
GitLab


From 44efd1e2379c2a4946291d346a40481bc42d5f35 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andreas=20S=C3=B8gaard?= <andreas.sogaard@gmail.com>
Date: Thu, 27 Jan 2022 18:32:37 +0000
Subject: [PATCH 2/4] Auto-updating lint badge

---
 misc/badges/pylint.svg | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/misc/badges/pylint.svg b/misc/badges/pylint.svg
index f8f78dd0d..2d83427fd 100644
--- a/misc/badges/pylint.svg
+++ b/misc/badges/pylint.svg
@@ -17,7 +17,7 @@
         <text x="22.0" y="14">pylint</text>
     </g>
     <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
-        <text x="63.0" y="15" fill="#010101" fill-opacity=".3">7.15</text>
-        <text x="62.0" y="14">7.15</text>
+        <text x="63.0" y="15" fill="#010101" fill-opacity=".3">7.06</text>
+        <text x="62.0" y="14">7.06</text>
     </g>
 </svg>
\ No newline at end of file
-- 
GitLab


From d172e5625dd0983cbfddb51506ffaf0f710cd429 Mon Sep 17 00:00:00 2001
From: bozianuleon <qzr746@alumni.ku.dk>
Date: Fri, 28 Jan 2022 12:48:04 +0100
Subject: [PATCH 3/4] Change borders to self._borders

---
 src/graphnet/data/i3extractor.py | 10 ++++++++--
 src/graphnet/data/utils.py       |  9 ++++-----
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/graphnet/data/i3extractor.py b/src/graphnet/data/i3extractor.py
index b06d7959d..b3275f813 100644
--- a/src/graphnet/data/i3extractor.py
+++ b/src/graphnet/data/i3extractor.py
@@ -197,8 +197,14 @@ class I3FeatureExtractorIceCubeUpgrade(I3FeatureExtractorIceCube86):
 
 
 class I3TruthExtractor(I3Extractor):
-    def __init__(self, name="truth"):
+    def __init__(self, name="truth", borders=None):
         super().__init__(name)
+        if borders == None:
+            border_xy = np.array([(-256.1400146484375, -521.0800170898438), (-132.8000030517578, -501.45001220703125), (-9.13000011444092, -481.739990234375), (114.38999938964844, -461.989990234375), (237.77999877929688, -442.4200134277344), (361.0, -422.8299865722656), (405.8299865722656, -306.3800048828125), (443.6000061035156, -194.16000366210938), (500.42999267578125, -58.45000076293945), (544.0700073242188, 55.88999938964844), (576.3699951171875, 170.9199981689453), (505.2699890136719, 257.8800048828125), (429.760009765625, 351.0199890136719), (338.44000244140625, 463.7200012207031), (224.5800018310547, 432.3500061035156), (101.04000091552734, 412.7900085449219), (22.11000061035156, 509.5), (-101.05999755859375, 490.2200012207031), (-224.08999633789062, 470.8599853515625), (-347.8800048828125, 451.5199890136719), (-392.3800048828125, 334.239990234375), (-437.0400085449219, 217.8000030517578), (-481.6000061035156, 101.38999938964844), (-526.6300048828125, -15.60000038146973), (-570.9000244140625, -125.13999938964844), (-492.42999267578125, -230.16000366210938), (-413.4599914550781, -327.2699890136719), (-334.79998779296875, -424.5)])
+            border_z = np.array([-512.82,524.56])
+            self._borders = [border_xy,border_z]
+        else:
+            self._borders = borders
 
     def __call__(self, frame, padding_value=-1) -> dict:
         """Extracts truth features."""
@@ -242,7 +248,7 @@ class I3TruthExtractor(I3Extractor):
                 output.update({
                     'track_length': MCInIcePrimary.length,
                 })
-                final_position, stopped = muon_stopped(output)
+                final_position, stopped = muon_stopped(output,self._borders)
                 output.update({
                     'final_position_x': final_position[0],
                     'final_position_y': final_position[1],
diff --git a/src/graphnet/data/utils.py b/src/graphnet/data/utils.py
index 05d3c3c9e..3dc3a7de7 100644
--- a/src/graphnet/data/utils.py
+++ b/src/graphnet/data/utils.py
@@ -251,17 +251,16 @@ def frame_has_key(frame, key: str):
     except:
         return False
 
-def muon_stopped(truth, horizontal_pad = 100, vertical_pad = 100):
+def muon_stopped(truth, borders, horizontal_pad = 100, vertical_pad = 100):
     '''
     Determine if a simulated muon stops inside the fiducial volume of the IceCube detector as defined in the RIDE study.
+    Borders should be a tuple containing two arrays, first entry is xy outlining points, second entry is z min and max depth
     Vertical and horizontal pad shrink fiducial volume further.
     Using track length, azimuth and zenith travel from the starting/generation point,
     also return x,y,z of muon end point (to be reconstructed)
     '''
     #to do:remove hard-coded border coords and replace with GCD file contents using string no's
-    border_coords = np.array([(-256.1400146484375, -521.0800170898438), (-132.8000030517578, -501.45001220703125), (-9.13000011444092, -481.739990234375), (114.38999938964844, -461.989990234375), (237.77999877929688, -442.4200134277344), (361.0, -422.8299865722656), (405.8299865722656, -306.3800048828125), (443.6000061035156, -194.16000366210938), (500.42999267578125, -58.45000076293945), (544.0700073242188, 55.88999938964844), (576.3699951171875, 170.9199981689453), (505.2699890136719, 257.8800048828125), (429.760009765625, 351.0199890136719), (338.44000244140625, 463.7200012207031), (224.5800018310547, 432.3500061035156), (101.04000091552734, 412.7900085449219), (22.11000061035156, 509.5), (-101.05999755859375, 490.2200012207031), (-224.08999633789062, 470.8599853515625), (-347.8800048828125, 451.5199890136719), (-392.3800048828125, 334.239990234375), (-437.0400085449219, 217.8000030517578), (-481.6000061035156, 101.38999938964844), (-526.6300048828125, -15.60000038146973), (-570.9000244140625, -125.13999938964844), (-492.42999267578125, -230.16000366210938), (-413.4599914550781, -327.2699890136719), (-334.79998779296875, -424.5)])
-    border_z = [-512.82,524.56]
-    border = mpath.Path(border_coords)
+    border = mpath.Path(borders[0])
 
     start_pos = np.array([truth['position_x'],
                           truth['position_y'],
@@ -274,7 +273,7 @@ def muon_stopped(truth, horizontal_pad = 100, vertical_pad = 100):
     end_pos = start_pos+travel_vec
 
     stopped_xy = border.contains_point((end_pos[0],end_pos[1]),radius=-horizontal_pad) 
-    stopped_z = (end_pos[2] > border_z[0] + vertical_pad) * (end_pos[2] < border_z[1] - vertical_pad) 
+    stopped_z = (end_pos[2] > borders[1][0] + vertical_pad) * (end_pos[2] < borders[1][1] - vertical_pad) 
     stopped_muon = stopped_xy * stopped_z 
 
     return end_pos,stopped_muon
\ No newline at end of file
-- 
GitLab


From 91f9375e8a47f3a29ba247583208f60714f8f9d3 Mon Sep 17 00:00:00 2001
From: bozianuleon <qzr746@alumni.ku.dk>
Date: Fri, 28 Jan 2022 16:30:04 +0100
Subject: [PATCH 4/4] Radius graph builder straight from torch_geometric

---
 src/graphnet/models/graph_builders.py | 33 ++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/src/graphnet/models/graph_builders.py b/src/graphnet/models/graph_builders.py
index 06a118a35..0306dc002 100644
--- a/src/graphnet/models/graph_builders.py
+++ b/src/graphnet/models/graph_builders.py
@@ -1,7 +1,7 @@
 from abc import ABC, abstractmethod
 from typing import List
 
-from torch_geometric.nn import knn_graph
+from torch_geometric.nn import knn_graph,radius_graph
 from torch_geometric.data import Data
 
 
@@ -42,6 +42,37 @@ class KNNGraphBuilder(GraphBuilder):  # pylint: disable=too-few-public-methods
 
         return data
 
+class RadialGraphBuilder(GraphBuilder):  
+    """Builds graph adjacency according to a sphere of chosen radius centred at each DOM hit"""
+    def __init__ (
+        self,
+        r: float,
+        columns: List[int] = None,
+        device: str = None,
+    ):
+        # Check(s)
+        if columns is None:
+            columns = [0,1,2]
+
+        # Member variable(s)
+        self._r = r
+        self._columns = columns
+        self._device = device
+
+    def __call__ (self, data: Data) -> Data:
+        # Constructs the adjacency matrix from the raw, DOM-level data and returns this matrix
+        if data.edge_index is not None:
+            print("WARNING: GraphBuilder received graph with pre-existing structure. ",
+                  "Will overwrite.")
+
+        data.edge_index = radius_graph(
+            data.x[:, self._columns],
+            self._r,
+            data.batch,
+        ).to(self._device)
+
+        return data
+
 
 #class EuclideanGraphBuilder(GraphBuilder):
 #    ...
-- 
GitLab