Merge pull request #4 from rasmusthog/rasmus_small_improvements
Rasmus small improvements
This commit is contained in:
commit
9490c338c1
4 changed files with 140 additions and 51 deletions
|
|
@ -178,19 +178,17 @@ def process_batsmall_data(df, options=None):
|
|||
def splice_cycles(df, options: dict) -> pd.DataFrame:
|
||||
''' Splices two cycles together - if e.g. one charge cycle are split into several cycles due to change in parameters.
|
||||
|
||||
Incomplete, only accomodates BatSmall so far.'''
|
||||
Incomplete, only accomodates BatSmall so far, and only for charge.'''
|
||||
|
||||
if options['kind'] == 'batsmall':
|
||||
|
||||
# Creates masks for charge and discharge curves
|
||||
chg_mask = df['current'] >= 0
|
||||
dchg_mask = df['current'] < 0
|
||||
|
||||
# Loop through all the cycling steps, change the current and capacities in the
|
||||
for i in range(df["count"].max()):
|
||||
sub_df = df.loc[df['count'] == i+1]
|
||||
sub_df_chg = sub_df.loc[chg_mask]
|
||||
#sub_df_dchg = sub_df.loc[dchg_mask]
|
||||
|
||||
# get indices where the program changed
|
||||
chg_indices = sub_df_chg[sub_df_chg["comment"].str.contains("program")==True].index.to_list()
|
||||
|
|
@ -203,33 +201,16 @@ def splice_cycles(df, options: dict) -> pd.DataFrame:
|
|||
if chg_indices:
|
||||
last_chg = chg_indices.pop()
|
||||
|
||||
|
||||
#dchg_indices = sub_df_dchg[sub_df_dchg["comment"].str.contains("program")==True].index.to_list()
|
||||
#if dchg_indices:
|
||||
# del dchg_indices[0]
|
||||
|
||||
|
||||
|
||||
if chg_indices:
|
||||
for i in chg_indices:
|
||||
add = df['specific_capacity'].iloc[i-1]
|
||||
df['specific_capacity'].iloc[i:last_chg] = df['specific_capacity'].iloc[i:last_chg] + add
|
||||
|
||||
#if dchg_indices:
|
||||
# for i in dchg_indices:
|
||||
# add = df['specific_capacity'].iloc[i-1]
|
||||
# df['specific_capacity'].iloc[i:last_dchg] = df['specific_capacity'].iloc[i:last_dchg] + add
|
||||
|
||||
|
||||
|
||||
|
||||
return df
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def process_neware_data(df, options={}):
|
||||
|
||||
""" Takes data from NEWARE in a DataFrame as read by read_neware() and converts units, adds columns and splits into cycles.
|
||||
|
|
|
|||
|
|
@ -5,17 +5,21 @@ import pandas as pd
|
|||
import numpy as np
|
||||
import math
|
||||
|
||||
import ipywidgets as widgets
|
||||
from IPython.display import display
|
||||
|
||||
import nafuma.electrochemistry as ec
|
||||
import nafuma.plotting as btp
|
||||
import nafuma.auxillary as aux
|
||||
|
||||
|
||||
|
||||
|
||||
def plot_gc(data, options=None):
|
||||
|
||||
|
||||
# Update options
|
||||
required_options = ['x_vals', 'y_vals', 'which_cycles', 'charge', 'discharge', 'colours', 'differentiate_charge_discharge', 'gradient', 'rc_params', 'format_params']
|
||||
|
||||
required_options = ['x_vals', 'y_vals', 'which_cycles', 'charge', 'discharge', 'colours', 'differentiate_charge_discharge', 'gradient', 'interactive', 'interactive_session_active', 'rc_params', 'format_params']
|
||||
default_options = {
|
||||
'x_vals': 'capacity', 'y_vals': 'voltage',
|
||||
'which_cycles': 'all',
|
||||
|
|
@ -23,15 +27,17 @@ def plot_gc(data, options=None):
|
|||
'colours': None,
|
||||
'differentiate_charge_discharge': True,
|
||||
'gradient': False,
|
||||
'interactive': False,
|
||||
'interactive_session_active': False,
|
||||
'rc_params': {},
|
||||
'format_params': {}}
|
||||
|
||||
options = aux.update_options(options=options, required_options=required_options, default_options=default_options)
|
||||
|
||||
|
||||
# Prepare plot, and read and process data
|
||||
|
||||
fig, ax = btp.prepare_plot(options=options)
|
||||
|
||||
if not 'cycles' in data.keys():
|
||||
data['cycles'] = ec.io.read_data(data=data, options=options)
|
||||
|
||||
# Update list of cycles to correct indices
|
||||
|
|
@ -39,6 +45,15 @@ def plot_gc(data, options=None):
|
|||
|
||||
colours = generate_colours(cycles=data['cycles'], options=options)
|
||||
|
||||
if options['interactive']:
|
||||
options['interactive'], options['interactive_session_active'] = False, True
|
||||
plot_gc_interactive(data=data, options=options)
|
||||
return
|
||||
|
||||
|
||||
# Prepare plot, and read and process data
|
||||
|
||||
fig, ax = btp.prepare_plot(options=options)
|
||||
|
||||
for i, cycle in enumerate(data['cycles']):
|
||||
if i in options['which_cycles']:
|
||||
|
|
@ -49,25 +64,42 @@ def plot_gc(data, options=None):
|
|||
cycle[1].plot(x=options['x_vals'], y=options['y_vals'], ax=ax, c=colours[i][1])
|
||||
|
||||
|
||||
if options['interactive_session_active']:
|
||||
update_labels(options, force=True)
|
||||
else:
|
||||
update_labels(options)
|
||||
print(options['xunit'])
|
||||
|
||||
fig, ax = btp.adjust_plot(fig=fig, ax=ax, options=options)
|
||||
|
||||
#if options['interactive_session_active']:
|
||||
|
||||
|
||||
return data['cycles'], fig, ax
|
||||
|
||||
|
||||
def plot_gc_interactive(data, options):
|
||||
|
||||
def update_labels(options):
|
||||
w = widgets.interactive(btp.ipywidgets_update, func=widgets.fixed(plot_gc), data=widgets.fixed(data), options=widgets.fixed(options),
|
||||
charge=widgets.ToggleButton(value=True),
|
||||
discharge=widgets.ToggleButton(value=True),
|
||||
x_vals=widgets.Dropdown(options=['specific_capacity', 'capacity', 'ions', 'voltage', 'time', 'energy'], value='specific_capacity', description='X-values')
|
||||
)
|
||||
|
||||
if 'xlabel' not in options.keys():
|
||||
options['widget'] = w
|
||||
|
||||
display(w)
|
||||
|
||||
|
||||
def update_labels(options, force=False):
|
||||
|
||||
if 'xlabel' not in options.keys() or force:
|
||||
options['xlabel'] = options['x_vals'].capitalize().replace('_', ' ')
|
||||
|
||||
if 'ylabel' not in options.keys():
|
||||
if 'ylabel' not in options.keys() or force:
|
||||
options['ylabel'] = options['y_vals'].capitalize().replace('_', ' ')
|
||||
|
||||
|
||||
if 'xunit' not in options.keys():
|
||||
if 'xunit' not in options.keys() or force:
|
||||
if options['x_vals'] == 'capacity':
|
||||
options['xunit'] = options['units']['capacity']
|
||||
elif options['x_vals'] == 'specific_capacity':
|
||||
|
|
@ -78,7 +110,7 @@ def update_labels(options):
|
|||
options['xunit'] = None
|
||||
|
||||
|
||||
if 'yunit' not in options.keys():
|
||||
if 'yunit' not in options.keys() or force:
|
||||
if options['y_vals'] == 'voltage':
|
||||
options['yunit'] = options['units']['voltage']
|
||||
|
||||
|
|
|
|||
|
|
@ -59,9 +59,10 @@ def integrate_1d(data, options={}, index=0):
|
|||
|
||||
|
||||
# Get image array from filename if not passed
|
||||
if 'image' not in data.keys():
|
||||
if 'image' not in data.keys() or not data['image']:
|
||||
data['image'] = get_image_array(data['path'][index])
|
||||
|
||||
|
||||
# Instanciate the azimuthal integrator from pyFAI from the calibrant (.poni-file)
|
||||
ai = pyFAI.load(data['calibrant'])
|
||||
|
||||
|
|
@ -72,11 +73,15 @@ def integrate_1d(data, options={}, index=0):
|
|||
if not os.path.isdir(options['extract_folder']):
|
||||
os.makedirs(options['extract_folder'])
|
||||
|
||||
if not os.path.isdir(options['save_folder']):
|
||||
os.makedirs(options['save_folder'])
|
||||
|
||||
|
||||
res = ai.integrate1d(data['image'], options['nbins'], unit=options['unit'], filename=filename)
|
||||
|
||||
data['path'][index] = filename
|
||||
diffractogram, wavelength = read_xy(data=data, options=options, index=index)
|
||||
diffractogram, _ = read_xy(data=data, options=options, index=index)
|
||||
wavelength = find_wavelength_from_poni(path=data['calibrant'])
|
||||
|
||||
if not options['save']:
|
||||
os.remove(filename)
|
||||
|
|
@ -278,8 +283,12 @@ def read_brml(data, options={}, index=0):
|
|||
|
||||
#if 'wavelength' not in data.keys():
|
||||
# Find wavelength
|
||||
|
||||
if not data['wavelength'][index]:
|
||||
for chain in root.findall('./FixedInformation/Instrument/PrimaryTracks/TrackInfoData/MountedOptics/InfoData/Tube/WaveLengthAlpha1'):
|
||||
wavelength = float(chain.attrib['Value'])
|
||||
else:
|
||||
wavelength = data['wavelength'][index]
|
||||
|
||||
|
||||
diffractogram = pd.DataFrame(diffractogram)
|
||||
|
|
@ -302,7 +311,11 @@ def read_xy(data, options={}, index=0):
|
|||
|
||||
#if 'wavelength' not in data.keys():
|
||||
# Get wavelength from scan
|
||||
|
||||
if not data['wavelength'][index]:
|
||||
wavelength = find_wavelength_from_xy(path=data['path'][index])
|
||||
else:
|
||||
wavelength = data['wavelength'][index]
|
||||
|
||||
with open(data['path'][index], 'r') as f:
|
||||
position = 0
|
||||
|
|
@ -326,6 +339,38 @@ def read_xy(data, options={}, index=0):
|
|||
return diffractogram, wavelength
|
||||
|
||||
|
||||
|
||||
|
||||
def strip_headers_from_xy(path: str, filename=None) -> None:
|
||||
''' Strips headers from a .xy-file'''
|
||||
|
||||
|
||||
xy = []
|
||||
with open(path, 'r') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
headerlines = 0
|
||||
for line in lines:
|
||||
if line[0] == '#':
|
||||
headerlines += 1
|
||||
else:
|
||||
xy.append(line)
|
||||
|
||||
|
||||
if not filename:
|
||||
ext = path.split('.')[-1]
|
||||
filename = path.split(f'.{ext}')[0] + f'_noheaders.{ext}'
|
||||
|
||||
|
||||
with open(filename, 'w') as f:
|
||||
for line in xy:
|
||||
f.write(line)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def read_data(data, options={}, index=0):
|
||||
|
||||
beamline_extensions = ['mar3450', 'edf', 'cbf']
|
||||
|
|
@ -351,6 +396,7 @@ def read_data(data, options={}, index=0):
|
|||
diffractogram = apply_offset(diffractogram, wavelength, index, options)
|
||||
|
||||
|
||||
|
||||
diffractogram = translate_wavelengths(data=diffractogram, wavelength=wavelength)
|
||||
|
||||
return diffractogram, wavelength
|
||||
|
|
@ -470,7 +516,7 @@ def translate_wavelengths(data: pd.DataFrame, wavelength: float, to_wavelength=N
|
|||
|
||||
data['2th_cuka'] = np.NAN
|
||||
|
||||
data['2th_cuka'].loc[data['2th'] <= max_2th_cuka] = 2*np.arcsin(cuka/wavelength * np.sin((data['2th']/2) * np.pi/180)) * 180/np.pi
|
||||
data['2th_cuka'].loc[data['2th'] <= max_2th_cuka] = 2*np.arcsin(cuka/wavelength * np.sin((data['2th'].loc[data['2th'] <= max_2th_cuka]/2) * np.pi/180)) * 180/np.pi
|
||||
|
||||
# Translate to MoKalpha
|
||||
moka = 0.71073 # Å
|
||||
|
|
@ -482,7 +528,7 @@ def translate_wavelengths(data: pd.DataFrame, wavelength: float, to_wavelength=N
|
|||
|
||||
data['2th_moka'] = np.NAN
|
||||
|
||||
data['2th_moka'].loc[data['2th'] <= max_2th_moka] = 2*np.arcsin(moka/wavelength * np.sin((data['2th']/2) * np.pi/180)) * 180/np.pi
|
||||
data['2th_moka'].loc[data['2th'] <= max_2th_moka] = 2*np.arcsin(moka/wavelength * np.sin((data['2th'].loc[data['2th'] <= max_2th_moka]/2) * np.pi/180)) * 180/np.pi
|
||||
|
||||
|
||||
# Convert to other parameters
|
||||
|
|
@ -501,7 +547,7 @@ def translate_wavelengths(data: pd.DataFrame, wavelength: float, to_wavelength=N
|
|||
|
||||
|
||||
data['2th'] = np.NAN
|
||||
data['2th'].loc[data['2th_cuka'] <= max_2th] = 2*np.arcsin(to_wavelength/cuka * np.sin((data['2th_cuka']/2) * np.pi/180)) * 180/np.pi
|
||||
data['2th'].loc[data['2th_cuka'] <= max_2th] = 2*np.arcsin(to_wavelength/cuka * np.sin((data['2th_cuka'].loc[data['2th_cuka'] <= max_2th]/2) * np.pi/180)) * 180/np.pi
|
||||
|
||||
|
||||
|
||||
|
|
@ -528,6 +574,22 @@ def find_wavelength_from_xy(path):
|
|||
elif 'Wavelength' in line:
|
||||
wavelength = float(line.split()[2])*10**10
|
||||
|
||||
else:
|
||||
wavelength = None
|
||||
|
||||
|
||||
|
||||
return wavelength
|
||||
|
||||
|
||||
def find_wavelength_from_poni(path):
|
||||
|
||||
with open(path, 'r') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
for line in lines:
|
||||
if 'Wavelength' in line:
|
||||
wavelength = float(line.split()[-1])*10**10
|
||||
|
||||
|
||||
return wavelength
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import nafuma.xrd as xrd
|
|||
import nafuma.auxillary as aux
|
||||
import nafuma.plotting as btp
|
||||
|
||||
|
||||
def plot_diffractogram(data, options={}):
|
||||
''' Plots a diffractogram.
|
||||
|
||||
|
|
@ -67,7 +66,14 @@ def plot_diffractogram(data, options={}):
|
|||
if not 'diffractogram' in data.keys():
|
||||
# Initialise empty list for diffractograms and wavelengths
|
||||
data['diffractogram'] = [None for _ in range(len(data['path']))]
|
||||
|
||||
# If wavelength is not manually passed it should be automatically gathered from the .xy-file
|
||||
if 'wavelength' not in data.keys():
|
||||
data['wavelength'] = [None for _ in range(len(data['path']))]
|
||||
else:
|
||||
# If only a single value is passed it should be set to be the same for all diffractograms passed
|
||||
if not isinstance(data['wavelength'], list):
|
||||
data['wavelength'] = [data['wavelength'] for _ in range(len(data['path']))]
|
||||
|
||||
for index in range(len(data['path'])):
|
||||
diffractogram, wavelength = xrd.io.read_data(data=data, options=options, index=index)
|
||||
|
|
@ -75,6 +81,9 @@ def plot_diffractogram(data, options={}):
|
|||
data['diffractogram'][index] = diffractogram
|
||||
data['wavelength'][index] = wavelength
|
||||
|
||||
# FIXME This is a quick fix as the image is not reloaded when passing multiple beamline datasets
|
||||
data['image'] = None
|
||||
|
||||
# Sets the xlim if this has not bee specified
|
||||
if not options['xlim']:
|
||||
options['xlim'] = [data['diffractogram'][0][options['x_vals']].min(), data['diffractogram'][0][options['x_vals']].max()]
|
||||
|
|
@ -114,7 +123,7 @@ def plot_diffractogram(data, options={}):
|
|||
options['reflections_data'] = [options['reflections_data']]
|
||||
|
||||
# Determine number of subplots and height ratios between them
|
||||
if len(options['reflections_data']) >= 1:
|
||||
if options['reflections_data'] and len(options['reflections_data']) >= 1:
|
||||
options = determine_grid_layout(options=options)
|
||||
|
||||
|
||||
|
|
@ -331,10 +340,10 @@ def plot_diffractogram_interactive(data, options):
|
|||
'heatmap_default': {'min': xminmax['heatmap'][0], 'max': xminmax['heatmap'][1], 'value': [xminmax['heatmap'][0], xminmax['heatmap'][1]], 'step': 10}
|
||||
},
|
||||
'ylim': {
|
||||
'w': widgets.FloatRangeSlider(value=[yminmax['start'][2], yminmax['start'][3]], min=yminmax['start'][0], max=yminmax['start'][1], step=0.5, layout=widgets.Layout(width='95%')),
|
||||
'w': widgets.FloatRangeSlider(value=[yminmax['start'][2], yminmax['start'][3]], min=yminmax['start'][0], max=yminmax['start'][1], step=0.01, layout=widgets.Layout(width='95%')),
|
||||
'state': 'heatmap' if options['heatmap'] else 'diff',
|
||||
'diff_default': {'min': yminmax['diff'][0], 'max': yminmax['diff'][1], 'value': [yminmax['diff'][2], yminmax['diff'][3]], 'step': 0.1},
|
||||
'heatmap_default': {'min': yminmax['heatmap'][0], 'max': yminmax['heatmap'][1], 'value': [yminmax['heatmap'][0], yminmax['heatmap'][1]], 'step': 0.1}
|
||||
'diff_default': {'min': yminmax['diff'][0], 'max': yminmax['diff'][1], 'value': [yminmax['diff'][2], yminmax['diff'][3]], 'step': 0.01},
|
||||
'heatmap_default': {'min': yminmax['heatmap'][0], 'max': yminmax['heatmap'][1], 'value': [yminmax['heatmap'][0], yminmax['heatmap'][1]], 'step': 0.01}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -356,7 +365,12 @@ def plot_diffractogram_interactive(data, options):
|
|||
w = widgets.interactive(btp.ipywidgets_update, func=widgets.fixed(plot_diffractogram), data=widgets.fixed(data), options=widgets.fixed(options),
|
||||
scatter=widgets.ToggleButton(value=False),
|
||||
line=widgets.ToggleButton(value=True),
|
||||
xlim=options['widgets']['xlim']['w'])
|
||||
heatmap=widgets.ToggleButton(value=options['heatmap']),
|
||||
x_vals=widgets.Dropdown(options=['2th', 'd', '1/d', 'q', 'q2', 'q4', '2th_cuka', '2th_moka'], value='2th', description='X-values'),
|
||||
xlim=options['widgets']['xlim']['w'],
|
||||
ylim=options['widgets']['ylim']['w'],
|
||||
offset_y=widgets.BoundedFloatText(value=options['offset_y'], min=-5, max=5, step=0.01, description='offset_y'),
|
||||
offset_x=widgets.BoundedFloatText(value=options['offset_x'], min=-1, max=1, step=0.01, description='offset_x'))
|
||||
|
||||
|
||||
options['widget'] = w
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue