ModulePlottingUtilities
Module containing some useful functions for generating various plots. It exists mostly to avoid cluttering the main plotting module.
Created in November 2024
@author: André Kalouguine + Stefan Haessler + Anthony Guillaume
1""" 2Module containing some useful functions for generating various plots. 3It exists mostly to avoid cluttering the main plotting module. 4 5Created in November 2024 6 7@author: André Kalouguine + Stefan Haessler + Anthony Guillaume 8""" 9# %% Module imports 10import weakref 11import numpy as np 12import colorcet as cc 13import matplotlib.pyplot as plt 14 15import ARTcore.ModuleProcessing as mp 16import ARTcore.ModuleGeometry as mgeo 17import ARTcore.ModuleProcessing as mp 18 19 20# %% Definition of observer class to make plots interactive 21class Observable(): 22 """ 23 Observer class to make several plots interactive simultaneously. 24 It encapsulates a single value. 25 When it's modified, it notifies all registered observers. 26 """ 27 def __init__(self, value): 28 self._value = value 29 self._observers = set() 30 self._calculation = set() 31 32 def register_calculation(self, callback): 33 """ 34 Register a calculation to be performed when the value is modified before notifying the observers. 35 For instance, this can be used to perform the ray tracing calculation when the value is modified. 36 The other callbacks will be notified after the calculation is performed and will update the plots. 37 """ 38 self._calculation.add(callback) 39 40 def unregister_calculation(self, callback): 41 self._calculation.discard(callback) 42 43 @property 44 def value(self): 45 return self._value 46 47 @value.setter 48 def value(self, new_value): 49 self._value = new_value 50 for callback in self._calculation: 51 callback(new_value) 52 self.notify(new_value) 53 54 def register(self, callback): 55 self._observers.add(callback) 56 57 def unregister(self, callback): 58 self._observers.discard(callback) 59 60 def notify(self, event): 61 for callback in self._observers: 62 callback(event) 63 64 65# %% Utility functions 66def generate_distinct_colors(num_colors): 67 """ 68 Utility function to generate a list of distinct colors for plotting. 69 70 Parameters 71 ---------- 72 num_colors : int 73 The number of colors to generate. 74 75 Returns 76 ------- 77 distinct_colors : list 78 List of distinct colors. 79 """ 80 # Get a color palette from colorcet 81 palette = cc.glasbey 82 83 # Make sure the number of colors does not exceed the palette length 84 num_colors = min(num_colors, len(palette)) 85 86 # Slice the palette to get the desired number of colors 87 distinct_colors = palette[:num_colors] 88 89 return distinct_colors 90 91 92def _getDetectorPoints(RayListAnalysed, Detector) -> tuple[np.ndarray, np.ndarray, float, float]: 93 """ 94 Prepare the ray impact points on the detector in a format used for the plotting, 95 and along the way also calculate the "spotsize" of this point-cloud on the detector. 96 97 Parameters 98 ---------- 99 RayListAnalysed : list(Ray) 100 A list of objects of the ModuleOpticalRay.Ray-class. 101 102 Detector : Detector 103 An object of the ModuleDetector.Detector-class. 104 105 Returns 106 ------- 107 DectectorPoint2D_Xcoord : np.ndarray with x-coordinates 108 109 DectectorPoint2D_Ycoord : np.ndarray with y-coordinates 110 111 FocalSpotSize : float 112 113 SpotSizeSD : float 114 """ 115 116 Points2D = Detector.get_2D_points(RayListAnalysed) 117 Points2D -= np.mean(Points2D, axis=1) # Centering the points 118 X = Points2D[0][:,0] * 1e3 # To convert to µm 119 Y = Points2D[0][:,1] * 1e3 # To convert to µm 120 121 FocalSpotSize = float(mgeo.DiameterPointArray(Points2D[0])) 122 SpotSizeSD = mp.StandardDeviation(Points2D[0]) 123 return X, Y, FocalSpotSize, SpotSizeSD 124 125def show(): 126 plt.show(block=False)
class
Observable:
22class Observable(): 23 """ 24 Observer class to make several plots interactive simultaneously. 25 It encapsulates a single value. 26 When it's modified, it notifies all registered observers. 27 """ 28 def __init__(self, value): 29 self._value = value 30 self._observers = set() 31 self._calculation = set() 32 33 def register_calculation(self, callback): 34 """ 35 Register a calculation to be performed when the value is modified before notifying the observers. 36 For instance, this can be used to perform the ray tracing calculation when the value is modified. 37 The other callbacks will be notified after the calculation is performed and will update the plots. 38 """ 39 self._calculation.add(callback) 40 41 def unregister_calculation(self, callback): 42 self._calculation.discard(callback) 43 44 @property 45 def value(self): 46 return self._value 47 48 @value.setter 49 def value(self, new_value): 50 self._value = new_value 51 for callback in self._calculation: 52 callback(new_value) 53 self.notify(new_value) 54 55 def register(self, callback): 56 self._observers.add(callback) 57 58 def unregister(self, callback): 59 self._observers.discard(callback) 60 61 def notify(self, event): 62 for callback in self._observers: 63 callback(event)
Observer class to make several plots interactive simultaneously. It encapsulates a single value. When it's modified, it notifies all registered observers.
def
register_calculation(self, callback):
33 def register_calculation(self, callback): 34 """ 35 Register a calculation to be performed when the value is modified before notifying the observers. 36 For instance, this can be used to perform the ray tracing calculation when the value is modified. 37 The other callbacks will be notified after the calculation is performed and will update the plots. 38 """ 39 self._calculation.add(callback)
Register a calculation to be performed when the value is modified before notifying the observers. For instance, this can be used to perform the ray tracing calculation when the value is modified. The other callbacks will be notified after the calculation is performed and will update the plots.
def
generate_distinct_colors(num_colors):
67def generate_distinct_colors(num_colors): 68 """ 69 Utility function to generate a list of distinct colors for plotting. 70 71 Parameters 72 ---------- 73 num_colors : int 74 The number of colors to generate. 75 76 Returns 77 ------- 78 distinct_colors : list 79 List of distinct colors. 80 """ 81 # Get a color palette from colorcet 82 palette = cc.glasbey 83 84 # Make sure the number of colors does not exceed the palette length 85 num_colors = min(num_colors, len(palette)) 86 87 # Slice the palette to get the desired number of colors 88 distinct_colors = palette[:num_colors] 89 90 return distinct_colors
Utility function to generate a list of distinct colors for plotting.
Parameters
num_colors : int
The number of colors to generate.
Returns
distinct_colors : list
List of distinct colors.
def
show():