Visualization API#
This notebook provides a Visualization and debugging tools of SysVar. This follows the previous example in Sysvar 101 example.#
We will now try to save the same figure that we had in the previous example. This will fail, but have a look at the end of the error message
[9]:
from sysvar import plot_cov_diff
fig, ax= plot_cov_diff(egd, save=True, filename = "test_figure")
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
File ~/Documents/PhD/frameworks/sysvar/src/sysvar/saver.py:102, in Saver.populate_mandatory_fields(self, saving_info)
101 try:
--> 102 self.saving_info[mk] = saving_info[mk]
103 except KeyError:
KeyError: 'top_dir'
During handling of the above exception, another exception occurred:
MissingMandatorySavingInfo Traceback (most recent call last)
Cell In[9], line 2
1 from sysvar import plot_cov_diff
----> 2 fig, ax= plot_cov_diff(egd, save=True, filename = "test_figure")
File ~/Documents/PhD/frameworks/sysvar/src/sysvar/api.py:304, in plot_cov_diff(eigendecomposer_obj, save, filename)
287 def plot_cov_diff(
288 eigendecomposer_obj: EigenDecomposer,
289 save: bool = False,
290 filename: Union[None, str] = None,
291 ) -> tuple[plt.Figure, plt.Axes]:
292 """
293 Plot the normalized covariance difference between original and eigendecomposed covariance matrix for an initial truncation guess.
294
(...)
301 None
302 """
--> 304 fig, ax = eigendecomposer_obj.plot_cov_diff(save=save, filename=filename)
305 return fig, ax
File ~/Documents/PhD/frameworks/sysvar/src/sysvar/eigendecomposer.py:464, in EigenDecomposer.plot_cov_diff(self, save, filename)
461 def plot_cov_diff(self, save: bool = False, filename: str = ""):
463 self.visualizer = EigenDecomposerVisualizer(self)
--> 464 fig, ax = self.visualizer.plot_cov_diff(save=save, filename=filename)
465 return fig, ax
File ~/Documents/PhD/frameworks/sysvar/src/sysvar/visualize.py:1020, in EigenDecomposerVisualizer.plot_cov_diff(self, fig, ax, save, filename)
1018 if save:
1019 self.instance.saving_info["namespace"] = ["egd", "cov", "diff"]
-> 1020 self.save_figure(fig, filename)
1021 return fig, ax
File ~/Documents/PhD/frameworks/sysvar/src/sysvar/visualize.py:50, in Visualizer.save_figure(self, figure, filename)
49 def save_figure(self, figure, filename: str):
---> 50 plot_saver = PlotSaver(figure, filename, self.instance.saving_info)()
File ~/Documents/PhD/frameworks/sysvar/src/sysvar/saver.py:163, in PlotSaver.__init__(self, object_to_save, filename, saving_info)
161 def __init__(self, object_to_save, filename, saving_info):
162 """Initializes the PlotSaver with the object, filename, and saving information."""
--> 163 super().__init__(object_to_save, filename, saving_info)
File ~/Documents/PhD/frameworks/sysvar/src/sysvar/saver.py:54, in Saver.__init__(self, object_to_save, filename, saving_info)
51 self.saving_info = {}
52 self.object_to_save = object_to_save
---> 54 self.populate_mandatory_fields(saving_info)
55 self.populate_optional_fields(saving_info)
56 self.save_dir = self._get_save_dir(
57 self.saving_info["top_dir"], self.saving_info.get("deep_dir")
58 )
File ~/Documents/PhD/frameworks/sysvar/src/sysvar/saver.py:104, in Saver.populate_mandatory_fields(self, saving_info)
102 self.saving_info[mk] = saving_info[mk]
103 except KeyError:
--> 104 self.raise_missing_mandatory_field(mk)
File ~/Documents/PhD/frameworks/sysvar/src/sysvar/saver.py:196, in PlotSaver.raise_missing_mandatory_field(self, key)
187 def raise_missing_mandatory_field(self, key: str):
188 """Raises an error if a mandatory field is missing.
189
190 Args:
(...)
194 MissingMandatorySavingInfo: If the mandatory field is not found in `saving_info`.
195 """
--> 196 raise MissingMandatorySavingInfo(
197 f"\n You are attempting to save a Figure but you're missing the mandatory field {key}. \n"
198 f"SysVar will not save objects in default locations, or with default names. \n"
199 f"Please call the register_figure_saving_info method in order to specify the necessary information. \n"
200 f"A description of {key} follows in the next line: \n {self.get_key_description(key)}"
201 )
MissingMandatorySavingInfo:
You are attempting to save a Figure but you're missing the mandatory field top_dir.
SysVar will not save objects in default locations, or with default names.
Please call the register_figure_saving_info method in order to specify the necessary information.
A description of top_dir follows in the next line:
The top directory that your objects should be saved in
[10]:
from sysvar import register_saving_info
saving_info = {
"top_dir": "./"
}
register_saving_info(egd, saving_info)
Now let’s try again#
Notice that the saving is not failing now, but we are informed that we can more control over the way that the figure are being saved
[11]:
fig, ax= plot_cov_diff(egd, save=True, filename = "test_figure")
WARNING : log_missing_optional_field: 209 :
You are attempting to save a Figure but you're missing the optional field deep_dir.
This will not prevent SysVar from saving the Figure, but be aware that you could have more control over your saved object.
A description of deep_dir follows in the next line:
A deeper directory inside the top_dir that specifies the final location of the saved file
WARNING : log_missing_optional_field: 209 :
You are attempting to save a Figure but you're missing the optional field extensions.
This will not prevent SysVar from saving the Figure, but be aware that you could have more control over your saved object.
A description of extensions follows in the next line:
Extra extensions for the file to be saved. For figures this defaults to pdf and png
INFO : save: 247 : Saved figures in ./
Save the templates in the format cabinetry expects#
If you did not enable save_variations = True because you were not sure that you want to save the variation you can still do this since you have access to the eigenvariation object.
[12]:
# Now save the templates variations throught the EigenDecomposer object
egd.save_template_variations()
INFO : save_template_variations: 294 : Updating file with uproot: ./test_output.root
INFO : save_template_variations: 306 : ##################################################
INFO : save_template_variations: 307 : ########## Reco channel: channel1 ##########
INFO : save_template_variations: 308 : ##################################################
/Users/agrimaggarwal/Documents/PhD/frameworks/sysvar/src/sysvar/eigendecomposer.py:115: RuntimeWarning: invalid value encountered in sqrt
return np.real(self.eigen_vectors * np.sqrt(self.eigen_values))
INFO : save_template_variations: 319 : Saving Up variation of MC template signal in TBranch: channel1/signal/charged_slow_pi_var1_up
INFO : save_template_variations: 330 : Saving Down variation of signal in TBranch: channel1/signal/charged_slow_pi_var1_down
INFO : save_template_variations: 319 : Saving Up variation of MC template signal in TBranch: channel1/signal/charged_slow_pi_var2_up
INFO : save_template_variations: 330 : Saving Down variation of signal in TBranch: channel1/signal/charged_slow_pi_var2_down
INFO : save_template_variations: 319 : Saving Up variation of MC template signal in TBranch: channel1/signal/charged_slow_pi_var3_up
INFO : save_template_variations: 330 : Saving Down variation of signal in TBranch: channel1/signal/charged_slow_pi_var3_down
/Users/agrimaggarwal/Documents/PhD/frameworks/sysvar/src/sysvar/eigendecomposer.py:115: RuntimeWarning: invalid value encountered in sqrt
return np.real(self.eigen_vectors * np.sqrt(self.eigen_values))
INFO : save_template_variations: 319 : Saving Up variation of MC template bkg in TBranch: channel1/bkg/charged_slow_pi_var1_up
INFO : save_template_variations: 330 : Saving Down variation of bkg in TBranch: channel1/bkg/charged_slow_pi_var1_down
INFO : save_template_variations: 319 : Saving Up variation of MC template bkg in TBranch: channel1/bkg/charged_slow_pi_var2_up
INFO : save_template_variations: 330 : Saving Down variation of bkg in TBranch: channel1/bkg/charged_slow_pi_var2_down
INFO : save_template_variations: 319 : Saving Up variation of MC template bkg in TBranch: channel1/bkg/charged_slow_pi_var3_up
INFO : save_template_variations: 330 : Saving Down variation of bkg in TBranch: channel1/bkg/charged_slow_pi_var3_down
INFO : save_template_variations: 306 : ##################################################
INFO : save_template_variations: 307 : ########## Reco channel: channel2 ##########
INFO : save_template_variations: 308 : ##################################################
/Users/agrimaggarwal/Documents/PhD/frameworks/sysvar/src/sysvar/eigendecomposer.py:115: RuntimeWarning: invalid value encountered in sqrt
return np.real(self.eigen_vectors * np.sqrt(self.eigen_values))
INFO : save_template_variations: 319 : Saving Up variation of MC template signal in TBranch: channel2/signal/charged_slow_pi_var1_up
INFO : save_template_variations: 330 : Saving Down variation of signal in TBranch: channel2/signal/charged_slow_pi_var1_down
INFO : save_template_variations: 319 : Saving Up variation of MC template signal in TBranch: channel2/signal/charged_slow_pi_var2_up
INFO : save_template_variations: 330 : Saving Down variation of signal in TBranch: channel2/signal/charged_slow_pi_var2_down
INFO : save_template_variations: 319 : Saving Up variation of MC template signal in TBranch: channel2/signal/charged_slow_pi_var3_up
INFO : save_template_variations: 330 : Saving Down variation of signal in TBranch: channel2/signal/charged_slow_pi_var3_down
/Users/agrimaggarwal/Documents/PhD/frameworks/sysvar/src/sysvar/eigendecomposer.py:115: RuntimeWarning: invalid value encountered in sqrt
return np.real(self.eigen_vectors * np.sqrt(self.eigen_values))
INFO : save_template_variations: 319 : Saving Up variation of MC template bkg in TBranch: channel2/bkg/charged_slow_pi_var1_up
INFO : save_template_variations: 330 : Saving Down variation of bkg in TBranch: channel2/bkg/charged_slow_pi_var1_down
INFO : save_template_variations: 319 : Saving Up variation of MC template bkg in TBranch: channel2/bkg/charged_slow_pi_var2_up
INFO : save_template_variations: 330 : Saving Down variation of bkg in TBranch: channel2/bkg/charged_slow_pi_var2_down
INFO : save_template_variations: 319 : Saving Up variation of MC template bkg in TBranch: channel2/bkg/charged_slow_pi_var3_up
INFO : save_template_variations: 330 : Saving Down variation of bkg in TBranch: channel2/bkg/charged_slow_pi_var3_down
This will save the template variations in the same root file that you saved the nominal templates earlier.
Let’s examine a bit more closely the templates that we have created
[13]:
from sysvar import plot_templates_relative_variations_in_grid, plot_up_and_down_variations
figures1= plot_up_and_down_variations(egd)
figures2= plot_templates_relative_variations_in_grid(egd)
/Users/agrimaggarwal/Documents/PhD/frameworks/sysvar/src/sysvar/visualize.py:725: RuntimeWarning: invalid value encountered in divide
h_up[0].flatten() / self.instance.nom_hist[0].flatten(),
/Users/agrimaggarwal/Documents/PhD/frameworks/sysvar/src/sysvar/visualize.py:733: RuntimeWarning: invalid value encountered in divide
h_down[0].flatten() / self.instance.nom_hist[0].flatten(),
/Users/agrimaggarwal/Documents/PhD/frameworks/sysvar/src/sysvar/visualize.py:757: RuntimeWarning: invalid value encountered in divide
(h_up[0].flatten() - self.instance.nom_hist[0].flatten())
/Users/agrimaggarwal/Documents/PhD/frameworks/sysvar/src/sysvar/visualize.py:725: RuntimeWarning: invalid value encountered in divide
h_up[0].flatten() / self.instance.nom_hist[0].flatten(),
/Users/agrimaggarwal/Documents/PhD/frameworks/sysvar/src/sysvar/visualize.py:733: RuntimeWarning: invalid value encountered in divide
h_down[0].flatten() / self.instance.nom_hist[0].flatten(),
/Users/agrimaggarwal/Documents/PhD/frameworks/sysvar/src/sysvar/visualize.py:757: RuntimeWarning: invalid value encountered in divide
(h_up[0].flatten() - self.instance.nom_hist[0].flatten())
/Users/agrimaggarwal/Documents/PhD/frameworks/sysvar/src/sysvar/visualize.py:545: RuntimeWarning: invalid value encountered in divide
relative_variations = np.nan_to_num(variations.T / nominals[0], nan=1)
/Users/agrimaggarwal/Documents/PhD/frameworks/sysvar/src/sysvar/visualize.py:545: RuntimeWarning: invalid value encountered in divide
relative_variations = np.nan_to_num(variations.T / nominals[0], nan=1)
Now how did we get those variations ?#
Every EigenDecomposer object creates a Variator object which implements a covariance matrix between the different correction bins#
This ensures that the variations that we sample from are common for every template
[14]:
from sysvar import plot_correction_variations_in_grid, plot_correction_cov_and_corr
fig1, ax1= plot_correction_variations_in_grid(egd)
fig2, ax2= plot_correction_cov_and_corr(egd)
What about the corrections itself ?#
SysVar provides a visualisation method to inspect the central correction values together with their uncertainties.
All visualisation methods return the Matplotlib figure and axes objects, so you have full freedom to modify the plots after SysVar has created them.
[15]:
from sysvar import plot_correction_errors
fig, ax= plot_correction_errors(egd)