Commit 075dd062 authored by Philipp Oleynik's avatar Philipp Oleynik
Browse files

Some docstrings added. g4simutils.py added.

parent dc93532d
# Philipp packages
# Philipp's packages
Here are several python packages with functions that I prefer to pack away.
Here are several python packages with functions that I prefer to pack away.
# Plot utilities
plotutil.py provides axes setup functions that was copied over and over my scripts.
energygrid.py provides log-scaled grid, initially aimed to use as energy bins for simulations.
\ No newline at end of file
# SIXS utilities
sixsutils.py provides several common methods used in processing and analyzing of SIXS data.
# Geant4 simulation utilities
g4simutils.py provides log-scaled energy grid.
\ No newline at end of file
import numpy as np
def mk_energy_grid(*, channels_per_decade=256, min_energy=0.01, max_energy=1.0E5):
"""
Calculates a standard logarithmic energy grid. A method to be separated from SIXS utilities.
:param channels_per_decade: Number of channels between 1 and 10, excluding exact value of 10.
:param min_energy: Starting energy. Can be anything, not necessarily powers of 10
:param max_energy: Upper limit of energy. Can be anything, not necessarily powers of 10
:return: An integer and three float arrays: number_of_energy_steps, energy_midpoints, energy_upper_cuts, energy_bin_widths
The cuts are the upper limits.
"""
emin_start = (np.floor(np.log10(min_energy) * channels_per_decade) / channels_per_decade)
emax_stop = (np.floor(np.log10(max_energy) * channels_per_decade) / channels_per_decade)
number_of_energy_steps = int((emax_stop - emin_start) * channels_per_decade + 1)
log_step = 1.0 / channels_per_decade
energy_midpoints = np.zeros(shape=(number_of_energy_steps,), dtype=float)
energy_upper_cuts = np.zeros(shape=(number_of_energy_steps,), dtype=float)
energy_bin_widths = np.zeros(shape=(number_of_energy_steps,), dtype=float)
for i in range(0, number_of_energy_steps, 1):
midpoint = np.power(10, emin_start) * np.power(10, log_step * (i + 0.5))
energy_bin_low = np.power(10, emin_start) * np.power(10, log_step * i)
energy_bin_high = np.power(10, emin_start) * np.power(10, log_step * (i + 1))
energy_upper_cuts[i] = energy_bin_high
energy_midpoints[i] = midpoint
energy_bin_widths[i] = energy_bin_high - energy_bin_low
return number_of_energy_steps, energy_midpoints, energy_upper_cuts, energy_bin_widths
#!/usr/bin/python3
# import numpy as np
import matplotlib.patches as pt
import matplotlib.pyplot as plt
def setup_latex(rcParams, noFourier = False):
def setup_latex(rcParams, no_fourier=False):
"""
Sets LaTeX environment for better text formatting on plots.
:param rcParams: rcParams imported locally from matplotlib
:param noFourier: True if there is no fourier package in your LaTeX distribution and it is impossible to install it (e.g. on Dione)
:param no_fourier: True if there is no fourier package in your LaTeX distribution and it is impossible to install it (e.g. on Dione)
"""
rcParams['text.usetex'] = True
if noFourier:
if no_fourier:
rcParams['text.latex.preamble'] = [
r'\usepackage{amsmath}',
r'\usepackage{amssymb}',
......@@ -43,86 +44,126 @@ def setup_plotstyle(rcParams):
rcParams['figure.autolayout'] = False
def plotsave_transparent(rcParams, transparency = True):
def plotsave_transparent(rcParams, transparency=True):
"""
Sets transparent background for the plots.
:param rcParams: The global matplotlib rcParams.
:param transparency: boolean, if True, the plots are saved with transparent background.
"""
rcParams['savefig.transparent'] = transparency
def set_log_axes_noaspect(axes):
axes.tick_params(direction = 'in', which = 'both', zorder = 4)
axes.set_xscale("log", nonposx = 'clip', subsx = [2, 3, 4, 5, 6, 7, 8, 9])
axes.set_yscale("log", nonposy = 'clip')
def set_log_axes(axes: plt.Axes, aset=False, aspect=0.36):
"""
Sets log-log scale for an Axis object. Adds 1-3-10 major ticks for the X-axis. Enables grid with 30% alpha.
:param aset: True if aspect must be set.
:param aspect: aspect to set.
:param axes: an Axis object to operate on.
"""
axes.tick_params(direction='in', which='both', zorder=4)
axes.set_xscale("log", nonposx='clip', subsx=[2, 3, 4, 5, 6, 7, 8, 9])
axes.set_yscale("log", nonposy='clip')
axes.set_xticks([0.01, 0.03, 0.1, 0.3, 1, 3,
10, 30, 50, 100, 300, 1000, 3000,
10000, 30000, 100000, 300000, 1000000],
minor = False)
minor=False)
axes.set_xticklabels([r'0.01', r'0.03', r'0.1', r'0.3', r'1',
r'3', r'10', r'30', r'50', r'100', r'300', r'1000', r'3G',
r'10G', r'30G', r'100G', r'300G', r'1T'],
minor = False)
axes.grid(True, which = 'both', alpha = 0.3, zorder = 0)
minor=False)
axes.grid(True, which='both', alpha=0.3, zorder=0)
if aset:
plt.Axes.set_aspect(axes, aspect=aspect, adjustable='box')
def set_log_axes_simple(axes):
axes.tick_params(direction = 'in', which = 'both', zorder = 4)
axes.set_xscale("log", nonposx = 'clip', subsx = [2, 3, 4, 5, 6, 7, 8, 9])
axes.set_yscale("log", nonposy = 'clip')
axes.grid(True, which = 'both', alpha = 0.3, zorder = 0)
def set_log_axes_simple(axes: plt.Axes):
"""
The same as set_log_axes_noaspect, but without setting X-axis ticks.
:param axes: an Axis object to operate on.
"""
axes.tick_params(direction='in', which='both', zorder=4)
axes.set_xscale("log", nonposx='clip', subsx=[2, 3, 4, 5, 6, 7, 8, 9])
axes.set_yscale("log", nonposy='clip')
axes.grid(True, which='both', alpha=0.3, zorder=0)
def set_time_log_axes_simple(axes):
axes.tick_params(direction = 'in', which = 'both', zorder = 4)
axes.set_yscale("log", nonposy = 'clip')
axes.grid(True, which = 'both', alpha = 0.3, zorder = 0)
def set_time_log_axes_simple(axes: plt.Axes):
"""
Sets the Y-axis to log scale and enables grid.
:param axes: an Axis object to operate on.
"""
axes.tick_params(direction='in', which='both', zorder=4)
axes.set_yscale("log", nonposy='clip')
axes.grid(True, which='both', alpha=0.3, zorder=0)
def set_lin_axes_simple(axes):
axes.tick_params(direction = 'in', which = 'both', zorder = 4)
def set_lin_axes_simple(axes: plt.Axes):
"""
Sets linear scale for X and Y axes
:param axes: an Axis object to operate on.
"""
axes.tick_params(direction='in', which='both', zorder=4)
axes.set_yscale("linear")
axes.set_xscale("linear")
axes.grid(True, which = 'both', alpha = 0.3, zorder = 0)
def set_log_axes_2048(axes):
axes.tick_params(direction = 'in', which = 'both', zorder = 4)
axes.set_xscale("log", nonposx = 'clip', basex = 2.0)
axes.set_yscale("log", nonposy = 'clip', basey = 2.0)
axes.grid(True, which = 'both', alpha = 0.3, zorder = 0)
axes.set_xticks([1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048], minor = False)
axes.set_yticks([1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048], minor = False)
axes.set_xticklabels([r'1', r'2', r'4', r'8', r'16', r'32', r'64', r'128', r'256', r'512', r'1024', r'2048'], minor = False)
axes.set_yticklabels([r'1', r'2', r'4', r'8', r'16', r'32', r'64', r'128', r'256', r'512', r'1024', r'2048'], minor = False)
axes.grid(True, which='both', alpha=0.3, zorder=0)
def set_log_axes_2048(axes: plt.Axes):
"""
Sets log-log scale with the major ticks on the powers of two. The ticks span from 1 to 2048.
:param axes: an Axis object to operate on.
"""
axes.tick_params(direction='in', which='both', zorder=4)
axes.set_xscale("log", nonposx='clip', basex=2.0)
axes.set_yscale("log", nonposy='clip', basey=2.0)
axes.grid(True, which='both', alpha=0.3, zorder=0)
axes.set_xticks([1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048], minor=False)
axes.set_yticks([1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048], minor=False)
axes.set_xticklabels([r'1', r'2', r'4', r'8', r'16', r'32', r'64', r'128', r'256', r'512', r'1024', r'2048'], minor=False)
axes.set_yticklabels([r'1', r'2', r'4', r'8', r'16', r'32', r'64', r'128', r'256', r'512', r'1024', r'2048'], minor=False)
axes.set_ylim(1, 2048)
axes.set_xlim(1, 2048)
def set_log_axes_bin16(axes):
axes.tick_params(direction = 'in', which = 'both', zorder = 4)
axes.set_xscale("log", nonposx = 'clip', basex = 2.0)
axes.set_yscale("log", nonposy = 'clip', basey = 2.0)
axes.grid(True, which = 'both', alpha = 0.3, zorder = 0)
def set_log_axes_bin16(axes: plt.Axes):
"""
Sets log-log scale with the major ticks on the powers of two. The ticks span from 1 to 65536.
:param axes: an Axis object to operate on.
"""
axes.tick_params(direction='in', which='both', zorder=4)
axes.set_xscale("log", nonposx='clip', basex=2.0)
axes.set_yscale("log", nonposy='clip', basey=2.0)
axes.grid(True, which='both', alpha=0.3, zorder=0)
axes.set_xticks([1, 2, 4, 8, 16, 32, 64, 128, 256,
512, 1024, 2048, 4096, 8192, 16384, 32768, 65536], minor = False)
512, 1024, 2048, 4096, 8192, 16384, 32768, 65536], minor=False)
axes.set_yticks([1, 2, 4, 8, 16, 32, 64, 128, 256,
512, 1024, 2048, 4096, 8192, 16384, 32768, 65536], minor = False)
512, 1024, 2048, 4096, 8192, 16384, 32768, 65536], minor=False)
axes.set_xticklabels([r'1', r'2', r'4', r'8', r'16', r'32', r'64', r'128', r'256',
r'512', r'1024', r'2048', r'4096', r'8192', r'16384', r'32768', r'65536'],
minor = False)
minor=False)
axes.set_yticklabels([r'1', r'2', r'4', r'8', r'16', r'32', r'64', r'128', r'256',
r'512', r'1024', r'2048', r'4096', r'8192', r'16384', r'32768', r'65536'],
minor = False)
axes.set_ylim(1, 2048)
axes.set_xlim(1, 2048)
def set_log_axes(axes):
set_log_axes_noaspect(axes)
axes.set_aspect(0.56, adjustable = 'box')
minor=False)
axes.set_ylim(1, 65536)
axes.set_xlim(1, 65536)
def draw_bar_text(axis, begin, end, ypos, text = 'text', height = 10, color = 'bisque', xposcorr = 0.0):
def draw_bar_text(axis, begin, end, ypos, text='text', height=10, color='bisque', xposcorr=0.0):
"""
Draws a box with text, similar to Gant chart.
:param axis: an Axis object to operate on.
:param begin: The X-axis start position of a box
:param end: The X-axis end position of a box
:param ypos: The Y-axis position
:param text: Text to be printed inside the box
:param height: The height of the box
:param color: Fill color.
:param xposcorr: A correction for a misalignment caused by some fonts.
"""
rect = pt.Rectangle((begin, ypos), end - begin,
height, alpha = 1, ec = 'k', fc = color, zorder = 0)
height, alpha=1, ec='k', fc=color, zorder=0)
axis.add_artist(rect)
axis.text(begin + xposcorr + (end - begin) / 2.0, ypos + height / 2, text,
fontsize = 12, ha = 'center', va = 'center_baseline',
alpha = 1, zorder = 1)
fontsize=12, ha='center', va='center_baseline',
alpha=1, zorder=1)
......@@ -297,19 +297,12 @@ class Sixs:
adc_8 = self.logbit11to8(adc11=adc_11)
return adc_8 // 4
def classifier_64(self, side6bit, core6bit, sidenum=0, thlevel=1):
def classifier_64(self, side6bit, core6bit):
"""
:param side6bit:
:param core6bit:
:param sidenum:
:param thlevel:
:return:
"""
if thlevel == 1:
channel = self.lut[list(map(int, 63 - side6bit)), list(map(int, core6bit))]
elif thlevel == 2:
channel = self.lut[list(map(int, 63 - side6bit)), list(map(int, core6bit))]
else:
channel = self.lut[63 - side6bit, core6bit]
channel = self.lut[list(map(int, 63 - side6bit)), list(map(int, core6bit))]
return channel
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment