Compare commits
8 Commits
f3bb6f870f
...
main
Author | SHA1 | Date | |
---|---|---|---|
aeef8f9253 | |||
247c503885 | |||
c4b0dd1fef | |||
3398414b55 | |||
1b66ac1f24 | |||
7d6b3403f5 | |||
313ef7d1de | |||
9570111f61 |
39
README.md
Normal file
39
README.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Ionization Probe Analysis Code
|
||||||
|
|
||||||
|
> Written by Cal Wing (<c.wing@uq.net.au> - 45811953) in 2024 for his Thesis
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Run `pip install -r requirements.txt` or equivilient for your envoroment.
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
Run `main.py` it will then generate all the output graphs and put them in (a git untracked) folder called `./images`.
|
||||||
|
|
||||||
|
By default all data graphs will be generated - you need to change the functions called at the end in the `if '__name__ == '__main__':` section.
|
||||||
|
|
||||||
|
## `./data` Explanation
|
||||||
|
|
||||||
|
I like YAML files to store information. All the data shot folders have a file call `_info.yaml` this file contained all the info about the shot so that when it would load & be graphed it would be correct.
|
||||||
|
|
||||||
|
I hope the values are self explanatory but they may not - sorry
|
||||||
|
|
||||||
|
## Changes to [canny_shock_finder.py](./canny_shock_finder.py)
|
||||||
|
|
||||||
|
Basically I hacked in an extra argument `print_func`, that is used to override the `print` function in the file. It assumes its either a callable reference (like print, the default) or None (it then uses a no-operation function to silence all output)
|
||||||
|
|
||||||
|
I also removed the error catching around lines ~497 so the function blindly continues if it can't graph.
|
||||||
|
|
||||||
|
I also enabled grid lines on the graphs.
|
||||||
|
|
||||||
|
The UQ colours being used on the graphs is due to some funky ~~abuse~~ *utlitly* I built into my [`makeGraph`](#makegraph) library.
|
||||||
|
|
||||||
|
## MakeGraph
|
||||||
|
|
||||||
|
> This refers to the [makeGraph.py](./makeGraph.py) file/version *in this code base*, I would not trust the exact specifics for versions found elsewhere, but the general gist is the same.
|
||||||
|
|
||||||
|
A *long* time ago I wrote a wrapper for matplotlib that has expanded into a formatting tool. The crux of it is that I can throw a dictionary at the `makeGraph` function and it will do all the hard work for me.
|
||||||
|
|
||||||
|
There are a few fun things that loading the lib will do - like overriding the default colour cyclers to use only the UQ colours - so if your going to liberate / adapt it be wary.
|
||||||
|
|
||||||
|
All the graphing done in the [`main.py`](./main.py) uses makeGraph, its not the most scary thing in the world as its basically ~~AI~~ *a big if conditional*.
|
@ -15,7 +15,7 @@ Chris James (c.james4@uq.edu.au) - 04/07/17
|
|||||||
|
|
||||||
# Amened by Cal Wing to make the function not print
|
# Amened by Cal Wing to make the function not print
|
||||||
|
|
||||||
VERSION_STRING = "17-Oct-2024"
|
VERSION_STRING = "20-Oct-2024"
|
||||||
|
|
||||||
def canny_shock_finder(time_list, pressure_list, sigma = 4, derivative_threshold = 0.001, auto_derivative = False, post_suppression_threshold = 0.05,
|
def canny_shock_finder(time_list, pressure_list, sigma = 4, derivative_threshold = 0.001, auto_derivative = False, post_suppression_threshold = 0.05,
|
||||||
post_shock_pressure = None, start_time = None, find_second_peak = None, plot = True, plot_scale_factor = None,
|
post_shock_pressure = None, start_time = None, find_second_peak = None, plot = True, plot_scale_factor = None,
|
||||||
@ -116,6 +116,8 @@ def canny_shock_finder(time_list, pressure_list, sigma = 4, derivative_threshold
|
|||||||
:param plot_time_scale: See plot_time_unit above. These two inputs allow the results plot to be in a different
|
:param plot_time_scale: See plot_time_unit above. These two inputs allow the results plot to be in a different
|
||||||
time unit to the original data. The user must specify this scale to connect the original and plotted
|
time unit to the original data. The user must specify this scale to connect the original and plotted
|
||||||
time units. Defaults to 1.0 (so no change if time units are seconds).
|
time units. Defaults to 1.0 (so no change if time units are seconds).
|
||||||
|
:param print_func: Callable Reference to call when print is called in this function. Defaults to 'print' but if 'None'
|
||||||
|
is passed it uses a no-operation function to silence all output.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Make the function silent / have print overridable
|
# Make the function silent / have print overridable
|
||||||
@ -360,6 +362,9 @@ def canny_shock_finder(time_list, pressure_list, sigma = 4, derivative_threshold
|
|||||||
|
|
||||||
data_ax.plot(time_list*plot_time_scale, pressure_list, '-o', label = 'original data')
|
data_ax.plot(time_list*plot_time_scale, pressure_list, '-o', label = 'original data')
|
||||||
|
|
||||||
|
data_ax.grid(True)
|
||||||
|
convolution_ax.grid(True)
|
||||||
|
|
||||||
convolution_ax.plot(time_list*plot_time_scale, first_order_data, '-o', label='first order gaussian (sigma = {0})'.format(sigma))
|
convolution_ax.plot(time_list*plot_time_scale, first_order_data, '-o', label='first order gaussian (sigma = {0})'.format(sigma))
|
||||||
convolution_ax.plot(time_list*plot_time_scale, second_order_data, '-o', label='second order gaussian (sigma = {0})'.format(sigma))
|
convolution_ax.plot(time_list*plot_time_scale, second_order_data, '-o', label='second order gaussian (sigma = {0})'.format(sigma))
|
||||||
convolution_ax.plot(time_list*plot_time_scale, suppressed_data, '-o', label='first order with non-max suppression')
|
convolution_ax.plot(time_list*plot_time_scale, suppressed_data, '-o', label='first order with non-max suppression')
|
||||||
|
@ -56,7 +56,7 @@ probe-info:
|
|||||||
- 2
|
- 2
|
||||||
locations: # In order of pulse
|
locations: # In order of pulse
|
||||||
- "st2"
|
- "st2"
|
||||||
- "st3"
|
# - "st3"
|
||||||
|
|
||||||
data-records:
|
data-records:
|
||||||
- type: "scope"
|
- type: "scope"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Data Info File
|
# Data Info File
|
||||||
# Cal Wing - Oct 24
|
# Cal Wing - Oct 24
|
||||||
|
|
||||||
long_name: "Shot 5 (x2s5829) - Thin Probe Pair (ST2 & ST3) - 2024-10-17\nProtruding ST2 & ST3 - Mars Entry Conditions"
|
long_name: "Shot 5 (x2s5830) - Thin Probe Pair (ST2 & ST3) - 2024-10-17\nProtruding ST2 & ST3 - Mars Entry Conditions"
|
||||||
name: "Shot 5"
|
name: "Shot 5"
|
||||||
date: "2024-10-18"
|
date: "2024-10-18"
|
||||||
time: "08:51"
|
time: "08:51"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Data Info File
|
# Data Info File
|
||||||
# Cal Wing - Oct 24
|
# Cal Wing - Oct 24
|
||||||
|
|
||||||
long_name: "Shot 6 (x2s5829) - Thin Probe Set (ST1, ST2 & ST3) - 2024-10-18\nProtruding ST1 & ST3, Flush ST2 (Only Gauge 1) - Mars Entry Conditions"
|
long_name: "Shot 6 (x2s5831) - Thin Probe Set (ST1, ST2 & ST3) - 2024-10-18\nProtruding ST1 & ST3, Flush ST2 (Only Gauge 1) - Mars Entry Conditions"
|
||||||
comments: "G2 Pointless, Wasn't attached"
|
comments: "G2 Pointless, Wasn't attached"
|
||||||
name: "Shot 6"
|
name: "Shot 6"
|
||||||
date: "2024-10-18"
|
date: "2024-10-18"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Data Info File
|
# Data Info File
|
||||||
# Cal Wing - Oct 24
|
# Cal Wing - Oct 24
|
||||||
|
|
||||||
long_name: "Shot 7 (x2s5829) - Thin Probe Set (ST1, ST2 & ST3) - 2024-10-18\nProtruding ST1 & ST1, Flush ST3 (Only Gauge 1) - Low Pressure, 'Pure' Air Conditions"
|
long_name: "Shot 7 (x2s5832) - Thin Probe Set (ST1, ST2 & ST3) - 2024-10-18\nProtruding ST1 & ST1, Flush ST3 (Only Gauge 1) - Low Pressure, 'Pure' Air Conditions"
|
||||||
name: "Shot 7"
|
name: "Shot 7"
|
||||||
date: "2024-10-18"
|
date: "2024-10-18"
|
||||||
time: "15:58"
|
time: "15:58"
|
||||||
|
104
main.py
104
main.py
@ -29,22 +29,6 @@ CANNY_TIME_OFFSET = 50 #us
|
|||||||
with open(TUNNEL_INFO_FILE, 'r') as file:
|
with open(TUNNEL_INFO_FILE, 'r') as file:
|
||||||
TUNNEL_INFO = yaml.safe_load(file)
|
TUNNEL_INFO = yaml.safe_load(file)
|
||||||
|
|
||||||
data_to_load = [
|
|
||||||
"x2s5823",
|
|
||||||
"x2s5824",
|
|
||||||
"x2s5827",
|
|
||||||
"x2s5829",
|
|
||||||
"x2s5830",
|
|
||||||
"x2s5831",
|
|
||||||
"x2s5832"
|
|
||||||
]
|
|
||||||
|
|
||||||
ref_data_to_load = [
|
|
||||||
"x2s5820",
|
|
||||||
"x2s5821",
|
|
||||||
"x2s5822"
|
|
||||||
]
|
|
||||||
|
|
||||||
# ==== Uncerts ====
|
# ==== Uncerts ====
|
||||||
# Taken from DOI: 10.1007/s00193-017-0763-3 (Implementation of a state-to-state analytical framework for the calculation of expansion tube flow properties)
|
# Taken from DOI: 10.1007/s00193-017-0763-3 (Implementation of a state-to-state analytical framework for the calculation of expansion tube flow properties)
|
||||||
|
|
||||||
@ -319,7 +303,12 @@ def load_data(data_path: str, data={}) -> dict:
|
|||||||
for i, probe in enumerate(dataInfo["probe-info"]["locations"]):
|
for i, probe in enumerate(dataInfo["probe-info"]["locations"]):
|
||||||
# Get the canny-args
|
# Get the canny-args
|
||||||
cArgs = dataInfo["canny-args"]
|
cArgs = dataInfo["canny-args"]
|
||||||
doCannyPlot = False
|
doCannyPlot = False # x2_shot == "x2s5829" and probe == "st2" # This condition was used to generate some graphs
|
||||||
|
plotValues = {
|
||||||
|
"plot_title": f"Canny Shock Finding Result for {x2_shot} - ST2 Gauge 1",
|
||||||
|
"plot_time_unit": "$\\mu$s",
|
||||||
|
"y_label": "Voltage Reading (V)",
|
||||||
|
}
|
||||||
if i in range(len(cArgs)):
|
if i in range(len(cArgs)):
|
||||||
sigma = cArgs[i]["sigma"]
|
sigma = cArgs[i]["sigma"]
|
||||||
post_sup_thresh = cArgs[i]["post_pres"]
|
post_sup_thresh = cArgs[i]["post_pres"]
|
||||||
@ -336,7 +325,7 @@ def load_data(data_path: str, data={}) -> dict:
|
|||||||
|
|
||||||
# Find G1 Shock Time
|
# Find G1 Shock Time
|
||||||
if 1 in dataInfo["probe-info"]["gauges"]:
|
if 1 in dataInfo["probe-info"]["gauges"]:
|
||||||
first_value, first_value_uncertainty, _, _ = canny_shock_finder(scope_time, probeCh1, sigma=sigma, post_suppression_threshold=post_sup_thresh, plot=doCannyPlot, start_time=time_offset, print_func=None)
|
first_value, first_value_uncertainty, _, _ = canny_shock_finder(scope_time, probeCh1, sigma=sigma, post_suppression_threshold=post_sup_thresh, plot=doCannyPlot, start_time=time_offset, print_func=None, **plotValues)
|
||||||
if first_value is None:
|
if first_value is None:
|
||||||
print(f"[ERROR] {x2_shot} - {probe}-g1 could not be detected using: Sigma = {sigma}, post_suppression_threshold = {post_sup_thresh}")
|
print(f"[ERROR] {x2_shot} - {probe}-g1 could not be detected using: Sigma = {sigma}, post_suppression_threshold = {post_sup_thresh}")
|
||||||
raise ValueError(f"{probe}-g1 not detected")
|
raise ValueError(f"{probe}-g1 not detected")
|
||||||
@ -664,7 +653,7 @@ def genGraph(gData: dict, showPlot: bool = True, doLimits: bool = True, forcePlo
|
|||||||
if not flag and not gData["shock-speed"][shock_speed_loc][2]:
|
if not flag and not gData["shock-speed"][shock_speed_loc][2]:
|
||||||
flag = True
|
flag = True
|
||||||
avg_speed = np.array(avg_speed_lst).mean()
|
avg_speed = np.array(avg_speed_lst).mean()
|
||||||
avg_uncert = np.sqrt(np.sum(np.pow(np.array(avg_uncert_lst), 2)))
|
avg_uncert = np.array(avg_uncert_lst).mean() # np.sqrt(np.sum(np.pow(np.array(avg_uncert_lst), 2)))
|
||||||
probeText += f"\nAverage Speed - {avg_speed/1000:.2f} $\\pm${avg_uncert/1000:.2f} [{avg_uncert/avg_speed * 100:.2f}%] km/s"
|
probeText += f"\nAverage Speed - {avg_speed/1000:.2f} $\\pm${avg_uncert/1000:.2f} [{avg_uncert/avg_speed * 100:.2f}%] km/s"
|
||||||
probeText += "\n" + "-"*50
|
probeText += "\n" + "-"*50
|
||||||
|
|
||||||
@ -732,7 +721,7 @@ def genRefGraph(gData: dict, showPlot: bool = True, addShockInfo: bool = True, f
|
|||||||
if not flag and not gData["shock-speed"][shock_speed_loc][2]:
|
if not flag and not gData["shock-speed"][shock_speed_loc][2]:
|
||||||
flag = True
|
flag = True
|
||||||
avg_speed = np.array(avg_speed_lst).mean()
|
avg_speed = np.array(avg_speed_lst).mean()
|
||||||
avg_uncert = np.sqrt(np.sum(np.pow(np.array(avg_uncert_lst), 2)))
|
avg_uncert = np.array(avg_uncert_lst).mean() # np.sqrt(np.sum(np.pow(np.array(avg_uncert_lst), 2)))
|
||||||
probeText += f"\nAverage Speed - {avg_speed/1000:.2f} $\\pm${avg_uncert/1000:.2f} [{avg_uncert/avg_speed * 100:.2f}%] km/s"
|
probeText += f"\nAverage Speed - {avg_speed/1000:.2f} $\\pm${avg_uncert/1000:.2f} [{avg_uncert/avg_speed * 100:.2f}%] km/s"
|
||||||
probeText += "\n" + "-"*50
|
probeText += "\n" + "-"*50
|
||||||
|
|
||||||
@ -855,7 +844,7 @@ def genComboRefGraph(data: dict, plotCh: list[str] = ["st1", "st2", "st3"], show
|
|||||||
probeText += f"\n{shock_speed_loc} - {speed/1000:.2f} $\\pm${uncert/1000:.2f} [{uncert/speed*100:.2f}%] km/s"
|
probeText += f"\n{shock_speed_loc} - {speed/1000:.2f} $\\pm${uncert/1000:.2f} [{uncert/speed*100:.2f}%] km/s"
|
||||||
|
|
||||||
avg_sp = np.array(avg_speeds).mean()
|
avg_sp = np.array(avg_speeds).mean()
|
||||||
avg_unc = np.sqrt(np.pow(np.array(avg_uncerts), 2).sum())
|
avg_unc = np.array(avg_uncerts).mean() #np.sqrt(np.pow(np.array(avg_uncerts), 2).sum())
|
||||||
probeText += f"\nAverage Speed - {avg_sp/1000:.2f} $\\pm${avg_unc/1000:.2f} [{avg_unc/avg_sp * 100:.2f}%] km/s"
|
probeText += f"\nAverage Speed - {avg_sp/1000:.2f} $\\pm${avg_unc/1000:.2f} [{avg_unc/avg_sp * 100:.2f}%] km/s"
|
||||||
|
|
||||||
graphData["plots"].append({
|
graphData["plots"].append({
|
||||||
@ -1077,7 +1066,7 @@ def genX2CompGraphs(gData: dict, showPlot: bool = True):
|
|||||||
graphData["plots"].append({
|
graphData["plots"].append({
|
||||||
"type": "axvLine",
|
"type": "axvLine",
|
||||||
"x": gData["shock-point"]["x2"][f"{probe}-g1"][1],#[i],
|
"x": gData["shock-point"]["x2"][f"{probe}-g1"][1],#[i],
|
||||||
"label": f"{probe}-Gauge 1 - X2 DAQ - Shock Point {gData['shock-point'][f'{probe}-g1'][1]:.2f}$\\mu$s",
|
"label": f"{probe}-Gauge 1 - X2 DAQ - Shock Point {gData['shock-point']["x2"][f'{probe}-g1'][1]:.2f}$\\mu$s",
|
||||||
"colour": UQC["dark_grey"],
|
"colour": UQC["dark_grey"],
|
||||||
"args":{"zorder":2, "linestyle":"--", "alpha":0.5}
|
"args":{"zorder":2, "linestyle":"--", "alpha":0.5}
|
||||||
})
|
})
|
||||||
@ -1087,7 +1076,7 @@ def genX2CompGraphs(gData: dict, showPlot: bool = True):
|
|||||||
graphData["plots"].append({
|
graphData["plots"].append({
|
||||||
"type": "axvLine",
|
"type": "axvLine",
|
||||||
"x": gData["shock-point"]["x2"][f"{probe}-g2"][1],#[i],
|
"x": gData["shock-point"]["x2"][f"{probe}-g2"][1],#[i],
|
||||||
"label": f"{probe}-Gauge 2 - X2 DAQ - Shock Point {gData['shock-point'][f'{probe}-g2'][1]:.2f}$\\mu$s",
|
"label": f"{probe}-Gauge 2 - X2 DAQ - Shock Point {gData['shock-point']["x2"][f'{probe}-g2'][1]:.2f}$\\mu$s",
|
||||||
"colour": UQC["dark_grey"],
|
"colour": UQC["dark_grey"],
|
||||||
"args":{"zorder":2, "linestyle":":", "alpha":0.5}
|
"args":{"zorder":2, "linestyle":":", "alpha":0.5}
|
||||||
})
|
})
|
||||||
@ -1111,52 +1100,67 @@ def genX2CompGraphs(gData: dict, showPlot: bool = True):
|
|||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
print("Loading Data")
|
if __name__ == "__main__":
|
||||||
|
data_to_load = [
|
||||||
|
"x2s5823",
|
||||||
|
"x2s5824",
|
||||||
|
"x2s5827",
|
||||||
|
"x2s5829",
|
||||||
|
"x2s5830",
|
||||||
|
"x2s5831",
|
||||||
|
"x2s5832"
|
||||||
|
]
|
||||||
|
|
||||||
# My Shot Data
|
ref_data_to_load = [
|
||||||
data = {}
|
"x2s5820",
|
||||||
for dp in data_to_load:
|
"x2s5821",
|
||||||
|
"x2s5822"
|
||||||
|
]
|
||||||
|
|
||||||
|
print("Loading Data")
|
||||||
|
|
||||||
|
# My Shot Data
|
||||||
|
data = {}
|
||||||
|
for dp in data_to_load:
|
||||||
pdp = f"{DATA_PATH}/{dp}/"
|
pdp = f"{DATA_PATH}/{dp}/"
|
||||||
load_data(pdp, data)
|
load_data(pdp, data)
|
||||||
|
|
||||||
loaded_data = tuple(data.keys())
|
loaded_data = tuple(data.keys())
|
||||||
|
|
||||||
# Reference Data from Mragank
|
# Reference Data from Mragank
|
||||||
ref_data = {}
|
ref_data = {}
|
||||||
for refShot in ref_data_to_load:
|
for refShot in ref_data_to_load:
|
||||||
load_ref_data(refShot, f"./data/referance/{refShot}/{refShot}.tdms", ref_data)
|
load_ref_data(refShot, f"./data/referance/{refShot}/{refShot}.tdms", ref_data)
|
||||||
|
|
||||||
print("Loaded Data")
|
print("Loaded Data")
|
||||||
|
|
||||||
|
print("Graphing Data")
|
||||||
|
|
||||||
|
# General Shot Graphing
|
||||||
print("Graphing Data")
|
for shot in loaded_data:
|
||||||
|
|
||||||
# General Shot Graphing
|
|
||||||
for shot in loaded_data:
|
|
||||||
#print(data[shot]['info']['long_name'].rsplit("\n", 1)[-1])
|
#print(data[shot]['info']['long_name'].rsplit("\n", 1)[-1])
|
||||||
genGraph(data[shot], showPlot=False, addShockInfo=False)
|
genGraph(data[shot], showPlot=False, addShockInfo=False)
|
||||||
genGraph(data[shot], showPlot=False, forcePlots=True)
|
genGraph(data[shot], showPlot=False, forcePlots=True)
|
||||||
|
|
||||||
combo_data = data.copy()
|
combo_data = data.copy()
|
||||||
combo_data.pop(loaded_data[-2])
|
combo_data.pop(loaded_data[-2])
|
||||||
combo_data.pop(loaded_data[-1])
|
combo_data.pop(loaded_data[-1])
|
||||||
|
|
||||||
genComboDataGraph(combo_data, doShockLabels=True)
|
genComboDataGraph(combo_data, doShockLabels=True)
|
||||||
|
|
||||||
|
|
||||||
genX2CompGraphs(data["x2s5831"], showPlot=False)
|
genX2CompGraphs(data["x2s5831"], showPlot=False)
|
||||||
genX2CompGraphs(data["x2s5832"], showPlot=False)
|
genX2CompGraphs(data["x2s5832"], showPlot=False)
|
||||||
|
|
||||||
# Reference Data
|
# Reference Data
|
||||||
for shot in ref_data:
|
for shot in ref_data:
|
||||||
genRefGraph(ref_data[shot], showPlot=False, addShockInfo=False)
|
genRefGraph(ref_data[shot], showPlot=False, addShockInfo=False)
|
||||||
genRefGraph(ref_data[shot], showPlot=False, forcePlots=True)
|
genRefGraph(ref_data[shot], showPlot=False, forcePlots=True)
|
||||||
|
|
||||||
genComboRefGraph(ref_data, doShockLabels=True)
|
genComboRefGraph(ref_data, doShockLabels=True)
|
||||||
genComboRefGraph(ref_data, ref_data[ref_data_to_load[0]]["info"]["pcb-refs"], addShockInfo=True)
|
genComboRefGraph(ref_data, ref_data[ref_data_to_load[0]]["info"]["pcb-refs"], addShockInfo=True)
|
||||||
|
|
||||||
|
|
||||||
# This forces matplotlib to hang until I tell it to close all windows
|
# This forces matplotlib to hang until I tell it to close all windows
|
||||||
pltKeyClose()
|
pltKeyClose()
|
||||||
print("Done")
|
print("Done")
|
Reference in New Issue
Block a user