From 2094390b79a84ad367c60f6a06ac159537a23245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20S=C3=B8gaard?= Date: Thu, 30 Nov 2023 14:38:20 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20graphnet?= =?UTF-8?q?-team/graphnet@1b8809671ba696371a03963047fb77bd3badda4b=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _modules/graphnet/data/constants.html | 1 + .../data/extractors/i3truthextractor.html | 14 ++- .../graphnet/models/task/reconstruction.html | 23 ++++ api/graphnet.data.constants.html | 6 +- api/graphnet.models.task.html | 1 + api/graphnet.models.task.reconstruction.html | 111 ++++++++++++++++++ genindex.html | 8 ++ objects.inv | Bin 6459 -> 6483 bytes searchindex.js | 2 +- 9 files changed, 159 insertions(+), 7 deletions(-) diff --git a/_modules/graphnet/data/constants.html b/_modules/graphnet/data/constants.html index b6526af39..d89457cb9 100644 --- a/_modules/graphnet/data/constants.html +++ b/_modules/graphnet/data/constants.html @@ -367,6 +367,7 @@

Source code for graphnet.dat ICECUBE86 = [ "energy", "energy_track", + "energy_cascade", "position_x", "position_y", "position_z", diff --git a/_modules/graphnet/data/extractors/i3truthextractor.html b/_modules/graphnet/data/extractors/i3truthextractor.html index 19d005d0d..58d7323e6 100644 --- a/_modules/graphnet/data/extractors/i3truthextractor.html +++ b/_modules/graphnet/data/extractors/i3truthextractor.html @@ -434,6 +434,7 @@

Source cod "track_length": padding_value, "stopped_muon": padding_value, "energy_track": padding_value, + "energy_cascade": padding_value, "inelasticity": padding_value, "DeepCoreFilter_13": padding_value, "CascadeFilter_13": padding_value, @@ -503,10 +504,15 @@

Source cod try: ( energy_track, + energy_cascade, inelasticity, ) = self._get_primary_track_energy_and_inelasticity(frame) except RuntimeError: # track energy fails on northeren tracks with ""Hadrons" has no mass implemented. Cannot get total energy." - energy_track, inelasticity = (padding_value, padding_value) + energy_track, energy_cascade, inelasticity = ( + padding_value, + padding_value, + padding_value, + ) output.update( { @@ -523,6 +529,7 @@

Source cod frame, padding_value ), "energy_track": energy_track, + "energy_cascade": energy_cascade, "inelasticity": inelasticity, } ) @@ -702,7 +709,7 @@

Source cod def _get_primary_track_energy_and_inelasticity( self, frame: "icetray.I3Frame", - ) -> Tuple[float, float]: + ) -> Tuple[float, float, float]: """Get the total energy of tracks from primary, and inelasticity. Args: @@ -725,9 +732,10 @@

Source cod energy_total = primary.total_energy energy_track = sum(track.total_energy for track in tracks) + energy_cascade = energy_total - energy_track inelasticity = 1.0 - energy_track / energy_total - return energy_track, inelasticity + return energy_track, energy_cascade, inelasticity # Utility methods def _find_data_type(self, mc: bool, input_file: str) -> str: diff --git a/_modules/graphnet/models/task/reconstruction.html b/_modules/graphnet/models/task/reconstruction.html index ccb644a97..feda16781 100644 --- a/_modules/graphnet/models/task/reconstruction.html +++ b/_modules/graphnet/models/task/reconstruction.html @@ -470,6 +470,29 @@

Source code for +
+[docs] +class EnergyTCReconstruction(Task): + """Reconstructs track and cascade energies using stable method.""" + + # Requires two features: untransformed energy for track and cascade + default_target_labels = ["energy_track", "energy_cascade"] + default_prediction_labels = ["energy_track_pred", "energy_cascade_pred"] + nb_inputs = 2 + + def _forward(self, x: Tensor) -> Tensor: + # Transform to positive energy domain avoiding `-inf` in `log10` + # Transform, thereby preventing overflow and underflow error. + x[:, 0] = torch.nn.functional.softplus( + x[:, 0].clone(), beta=0.05 + ) + eps_like(x[:, 0].clone()) + x[:, 1] = torch.nn.functional.softplus( + x[:, 1].clone(), beta=0.05 + ) + eps_like(x[:, 1].clone()) + return x
+ + +
[docs] class EnergyReconstructionWithUncertainty(EnergyReconstruction): diff --git a/api/graphnet.data.constants.html b/api/graphnet.data.constants.html index 98b2c312c..dbbe41f3e 100644 --- a/api/graphnet.data.constants.html +++ b/api/graphnet.data.constants.html @@ -639,15 +639,15 @@

Namespace for standard names working with I3TruthExtractor.

-ICECUBE86 = ['energy', 'energy_track', 'position_x', 'position_y', 'position_z', 'azimuth', 'zenith', 'pid', 'elasticity', 'sim_type', 'interaction_type', 'interaction_time', 'inelasticity', 'stopped_muon']
+ICECUBE86 = ['energy', 'energy_track', 'energy_cascade', 'position_x', 'position_y', 'position_z', 'azimuth', 'zenith', 'pid', 'elasticity', 'sim_type', 'interaction_type', 'interaction_time', 'inelasticity', 'stopped_muon']
-DEEPCORE = ['energy', 'energy_track', 'position_x', 'position_y', 'position_z', 'azimuth', 'zenith', 'pid', 'elasticity', 'sim_type', 'interaction_type', 'interaction_time', 'inelasticity', 'stopped_muon']
+DEEPCORE = ['energy', 'energy_track', 'energy_cascade', 'position_x', 'position_y', 'position_z', 'azimuth', 'zenith', 'pid', 'elasticity', 'sim_type', 'interaction_type', 'interaction_time', 'inelasticity', 'stopped_muon']
-UPGRADE = ['energy', 'energy_track', 'position_x', 'position_y', 'position_z', 'azimuth', 'zenith', 'pid', 'elasticity', 'sim_type', 'interaction_type', 'interaction_time', 'inelasticity', 'stopped_muon']
+UPGRADE = ['energy', 'energy_track', 'energy_cascade', 'position_x', 'position_y', 'position_z', 'azimuth', 'zenith', 'pid', 'elasticity', 'sim_type', 'interaction_type', 'interaction_time', 'inelasticity', 'stopped_muon']
diff --git a/api/graphnet.models.task.html b/api/graphnet.models.task.html index bff35ba4e..1ed6eb8be 100644 --- a/api/graphnet.models.task.html +++ b/api/graphnet.models.task.html @@ -487,6 +487,7 @@
  • ZenithReconstructionWithKappa
  • EnergyReconstruction
  • EnergyReconstructionWithPower
  • +
  • EnergyTCReconstruction
  • EnergyReconstructionWithUncertainty
  • VertexReconstruction
  • PositionReconstruction
  • diff --git a/api/graphnet.models.task.reconstruction.html b/api/graphnet.models.task.reconstruction.html index c1d6963b9..e5141fd93 100644 --- a/api/graphnet.models.task.reconstruction.html +++ b/api/graphnet.models.task.reconstruction.html @@ -445,6 +445,16 @@ +
  • EnergyTCReconstruction +
  • EnergyReconstructionWithUncertainty
  • +
  • + + + EnergyTCReconstruction +
  • @@ -993,6 +1031,16 @@ +
  • EnergyTCReconstruction +
  • EnergyReconstructionWithUncertainty
  • +
    +class graphnet.models.task.reconstruction.EnergyTCReconstruction(*args, **kwargs)[source]
    +

    Bases: Task

    +

    Reconstructs track and cascade energies using stable method.

    +

    Construct Task.

    +
    +
    Parameters:
    +
      +
    • hidden_size (int) – The number of nodes in the layer feeding into this +tasks, used to construct the affine transformation to the +predicted quantity.

    • +
    • loss_function (LossFunction) – Loss function appropriate to the task.

    • +
    • target_labels (Union[str, List[str], None], default: None) – Name(s) of the quantity/-ies being predicted, used +to extract the target tensor(s) from the Data object in +.compute_loss(…).

    • +
    • prediction_labels (Union[str, List[str], None], default: None) – The name(s) of each column that is predicted by +the model during inference. If not given, the name will auto +matically be set to target_label + _pred.

    • +
    • transform_prediction_and_target (Optional[Callable], default: None) – Optional function to transform +both the predicted and target tensor before passing them to the +loss function. Useful e.g. for having the model predict +quantities on a physical scale, but transforming this scale to +O(1) for a numerically stable loss computation.

    • +
    • transform_target (Optional[Callable], default: None) – Optional function to transform only the target +tensor before passing it, and the predicted tensor, to the loss +function. Useful e.g. for having the model predict a +transformed version of the target quantity, e.g. the log10- +scaled energy, rather than the physical quantity itself. Used +in conjunction with transform_inference to perform the +inverse transform on the predicted quantity to recover the +physical scale.

    • +
    • transform_inference (Optional[Callable], default: None) – Optional function to inverse-transform the +model prediction to recover a physical scale. Used in +conjunction with transform_target.

    • +
    • transform_support (Optional[Tuple], default: None) – Optional tuple to specify minimum and maximum +of the range of validity for the inverse transforms +transform_target and transform_inference in case this is +restricted. By default the invertibility of transform_target +is tested on the range [-1e6, 1e6].

    • +
    • loss_weight (Optional[str], default: None) – Name of the attribute in data containing per-event +loss weights.

    • +
    • args (Any) –

    • +
    • kwargs (Any) –

    • +
    +
    +
    Return type:
    +

    object

    +
    +
    +
    +
    +default_target_labels = ['energy_track', 'energy_cascade']
    +
    +
    +
    +default_prediction_labels = ['energy_track_pred', 'energy_cascade_pred']
    +
    +
    +
    +nb_inputs = 2
    +
    +
    +
    class graphnet.models.task.reconstruction.EnergyReconstructionWithUncertainty(*args, **kwargs)[source]

    Bases: EnergyReconstruction

    diff --git a/genindex.html b/genindex.html index b69caa13e..3d2278c55 100644 --- a/genindex.html +++ b/genindex.html @@ -517,6 +517,8 @@

    D

  • (graphnet.models.task.reconstruction.EnergyReconstructionWithPower attribute)
  • (graphnet.models.task.reconstruction.EnergyReconstructionWithUncertainty attribute) +
  • +
  • (graphnet.models.task.reconstruction.EnergyTCReconstruction attribute)
  • (graphnet.models.task.reconstruction.InelasticityReconstruction attribute)
  • @@ -553,6 +555,8 @@

    D

  • (graphnet.models.task.reconstruction.EnergyReconstructionWithPower attribute)
  • (graphnet.models.task.reconstruction.EnergyReconstructionWithUncertainty attribute) +
  • +
  • (graphnet.models.task.reconstruction.EnergyTCReconstruction attribute)
  • (graphnet.models.task.reconstruction.InelasticityReconstruction attribute)
  • @@ -615,6 +619,8 @@

    E

      +
    • EnergyTCReconstruction (class in graphnet.models.task.reconstruction) +
    • EnsembleDataset (class in graphnet.data.dataset.dataset)
    • eps_like() (in module graphnet.utilities.maths) @@ -1933,6 +1939,8 @@

      N

    • (graphnet.models.task.reconstruction.EnergyReconstructionWithPower attribute)
    • (graphnet.models.task.reconstruction.EnergyReconstructionWithUncertainty attribute) +
    • +
    • (graphnet.models.task.reconstruction.EnergyTCReconstruction attribute)
    • (graphnet.models.task.reconstruction.InelasticityReconstruction attribute)
    • diff --git a/objects.inv b/objects.inv index 76b43570247a798f04487ab865d1ff4334fa66e7..53193911c6103715ac0b70f24e2ca9d2d250ff07 100644 GIT binary patch delta 6380 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