integrate_module 0.99.5__tar.gz → 0.99.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {integrate_module-0.99.5/integrate_module.egg-info → integrate_module-0.99.6}/PKG-INFO +10 -1
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate/integrate_io.py +86 -5
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate/integrate_plot.py +137 -127
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate/integrate_rejection.py +131 -37
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate/integrate_rejection_jax.py +29 -6
- integrate_module-0.99.6/integrate/mlmapping.py +1110 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6/integrate_module.egg-info}/PKG-INFO +10 -1
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate_module.egg-info/SOURCES.txt +1 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate_module.egg-info/requires.txt +12 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/pyproject.toml +13 -1
- {integrate_module-0.99.5 → integrate_module-0.99.6}/LICENSE +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/README.md +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate/__init__.py +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate/gex.py +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate/integrate.py +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate/integrate_borehole.py +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate/integrate_hdf5_info_cli.py +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate/integrate_query.py +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate/integrate_rejection_cli.py +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate/integrate_timing_cli.py +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate/integrate_www_cli.py +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate_module.egg-info/dependency_links.txt +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate_module.egg-info/entry_points.txt +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/integrate_module.egg-info/top_level.txt +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/setup.cfg +0 -0
- {integrate_module-0.99.5 → integrate_module-0.99.6}/tests/test_likelihood_multinomial.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: integrate_module
|
|
3
|
-
Version: 0.99.
|
|
3
|
+
Version: 0.99.6
|
|
4
4
|
Summary: Localized probabilistic data integration
|
|
5
5
|
Author-email: Thomas Mejer Hansen <tmeha@geo.au.dk>
|
|
6
6
|
License: MIT
|
|
@@ -34,6 +34,13 @@ Requires-Dist: jax
|
|
|
34
34
|
Provides-Extra: dev
|
|
35
35
|
Requires-Dist: pytest; extra == "dev"
|
|
36
36
|
Requires-Dist: black; extra == "dev"
|
|
37
|
+
Provides-Extra: ml
|
|
38
|
+
Requires-Dist: tensorflow; extra == "ml"
|
|
39
|
+
Requires-Dist: scikit-learn; extra == "ml"
|
|
40
|
+
Requires-Dist: keras_tuner; extra == "ml"
|
|
41
|
+
Provides-Extra: examples
|
|
42
|
+
Requires-Dist: geopandas; extra == "examples"
|
|
43
|
+
Requires-Dist: shapely; extra == "examples"
|
|
37
44
|
Provides-Extra: docs
|
|
38
45
|
Requires-Dist: sphinx; extra == "docs"
|
|
39
46
|
Requires-Dist: nbsphinx; extra == "docs"
|
|
@@ -43,6 +50,8 @@ Requires-Dist: myst-parser; extra == "docs"
|
|
|
43
50
|
Requires-Dist: sphinx-rtd-theme; extra == "docs"
|
|
44
51
|
Requires-Dist: furo; extra == "docs"
|
|
45
52
|
Requires-Dist: tomli; python_version < "3.11" and extra == "docs"
|
|
53
|
+
Provides-Extra: jax-cuda
|
|
54
|
+
Requires-Dist: jax[cuda12]; extra == "jax-cuda"
|
|
46
55
|
Dynamic: license-file
|
|
47
56
|
|
|
48
57
|
# INTEGRATE Python Module
|
|
@@ -3240,7 +3240,7 @@ def save_data_gaussian(D_obs, D_std = [], d_std=[], Cd=[], id=1, id_prior=None,
|
|
|
3240
3240
|
return f_data_h5
|
|
3241
3241
|
|
|
3242
3242
|
|
|
3243
|
-
def xyz_to_h5(file_xyz, file_gex, f_data_h5=None, i_lm_skip=None, i_hm_skip=None, nan_value=None, showInfo=0, disregardFullNan=True, data_obs=None, data_std=None):
|
|
3243
|
+
def xyz_to_h5(file_xyz, file_gex, f_data_h5=None, i_lm_skip=None, i_hm_skip=None, nan_value=None, showInfo=0, disregardFullNan=True, data_obs=None, data_std=None, altitude=None, altitude_std=None, tx_altitude=None, tx_altitude_std=None, rx_altitude=None, rx_altitude_std=None):
|
|
3244
3244
|
"""
|
|
3245
3245
|
Convert Aarhus Workbench XYZ export file(s) to an INTEGRATE HDF5 data file.
|
|
3246
3246
|
|
|
@@ -3292,6 +3292,38 @@ def xyz_to_h5(file_xyz, file_gex, f_data_h5=None, i_lm_skip=None, i_hm_skip=None
|
|
|
3292
3292
|
same length as ``data_obs``. Use ``None`` for an individual entry to
|
|
3293
3293
|
fall back to ``0.05 * |d_obs|`` for that column. If the whole
|
|
3294
3294
|
parameter is omitted, all columns default to ``0.05 * |d_obs|``.
|
|
3295
|
+
altitude : str, optional
|
|
3296
|
+
Flightlines column name (case-insensitive) holding the platform's
|
|
3297
|
+
flight altitude/height, e.g. ``'Alt'``. When given, written as its
|
|
3298
|
+
own Gaussian data block with ``id=2`` (the second dataset, after the
|
|
3299
|
+
``/D1`` dbdt data). Any ``data_obs`` columns are then written
|
|
3300
|
+
starting at ``id=3`` instead of ``id=2``.
|
|
3301
|
+
altitude_std : str, float, or None, optional
|
|
3302
|
+
Uncertainty for ``altitude``.
|
|
3303
|
+
- A **string** is treated as another flightlines column name
|
|
3304
|
+
(case-insensitive) holding the absolute std directly.
|
|
3305
|
+
- A **number** with ``abs(altitude_std) < 1`` is treated as a
|
|
3306
|
+
*relative* std: ``std = altitude_std * altitude``.
|
|
3307
|
+
- A **number** with ``abs(altitude_std) >= 1`` is treated as an
|
|
3308
|
+
*absolute* std in meters, constant for all soundings.
|
|
3309
|
+
- If ``None`` (default), falls back to ``0.05 * |altitude|``.
|
|
3310
|
+
tx_altitude : str, optional
|
|
3311
|
+
Flightlines column name (case-insensitive) holding the transmitter
|
|
3312
|
+
altitude/height. When given, written as its own Gaussian data block,
|
|
3313
|
+
immediately after ``altitude`` (if also given). Optional — omitted
|
|
3314
|
+
entirely if not given.
|
|
3315
|
+
tx_altitude_std : str, float, or None, optional
|
|
3316
|
+
Uncertainty for ``tx_altitude``. Same rules as ``altitude_std``
|
|
3317
|
+
(string column name / relative number / absolute number / default
|
|
3318
|
+
5% relative if ``None``). Only used if ``tx_altitude`` is given.
|
|
3319
|
+
rx_altitude : str, optional
|
|
3320
|
+
Flightlines column name (case-insensitive) holding the receiver
|
|
3321
|
+
altitude/height. When given, written as its own Gaussian data block,
|
|
3322
|
+
after ``altitude`` and ``tx_altitude`` (if also given). Optional —
|
|
3323
|
+
omitted entirely if not given.
|
|
3324
|
+
rx_altitude_std : str, float, or None, optional
|
|
3325
|
+
Uncertainty for ``rx_altitude``. Same rules as ``altitude_std``.
|
|
3326
|
+
Only used if ``rx_altitude`` is given.
|
|
3295
3327
|
|
|
3296
3328
|
Returns
|
|
3297
3329
|
-------
|
|
@@ -3380,9 +3412,22 @@ def xyz_to_h5(file_xyz, file_gex, f_data_h5=None, i_lm_skip=None, i_hm_skip=None
|
|
|
3380
3412
|
ld = {k: pd.concat([xyz.layer_data[k] for xyz in xyz_list], ignore_index=True)
|
|
3381
3413
|
for k in xyz_list[0].layer_data}
|
|
3382
3414
|
|
|
3383
|
-
# Handle XYZ files that use
|
|
3415
|
+
# Handle XYZ files that use alternate column names for geometry
|
|
3416
|
+
# (e.g. tTEM: utmx/utmy/line_no/elevation, SkyTEM: e/n/line/dem)
|
|
3384
3417
|
if 'utmx' not in fl.columns and 'x' in fl.columns:
|
|
3385
3418
|
fl = fl.rename(columns={'x': 'utmx', 'y': 'utmy'})
|
|
3419
|
+
if 'utmx' not in fl.columns and 'e' in fl.columns:
|
|
3420
|
+
fl = fl.rename(columns={'e': 'utmx', 'n': 'utmy'})
|
|
3421
|
+
if 'line_no' not in fl.columns and 'line' in fl.columns:
|
|
3422
|
+
fl = fl.rename(columns={'line': 'line_no'})
|
|
3423
|
+
if 'elevation' not in fl.columns and 'dem' in fl.columns:
|
|
3424
|
+
fl = fl.rename(columns={'dem': 'elevation'})
|
|
3425
|
+
|
|
3426
|
+
# Handle single-channel XYZ files (e.g. SkyTEM) that store the sounding
|
|
3427
|
+
# data under a plain component name instead of the tTEM 'ch1gt' naming
|
|
3428
|
+
if 'dbdt_ch1gt' not in ld and 'z_dbdt' in ld:
|
|
3429
|
+
ld['dbdt_ch1gt'] = ld['z_dbdt']
|
|
3430
|
+
ld['dbdt_std_ch1gt'] = ld['relunc_z_dbdt']
|
|
3386
3431
|
|
|
3387
3432
|
# Determine dummy/missing value: explicit arg > XYZ header > fallback 9999
|
|
3388
3433
|
if nan_value is None:
|
|
@@ -3393,7 +3438,12 @@ def xyz_to_h5(file_xyz, file_gex, f_data_h5=None, i_lm_skip=None, i_hm_skip=None
|
|
|
3393
3438
|
# --- pair ch1 / ch2 rows (mirrors MATLAB logic) ---
|
|
3394
3439
|
# Every ch1 row becomes a sounding. HM data is filled where the
|
|
3395
3440
|
# immediately following row is ch2; otherwise those columns stay NaN.
|
|
3396
|
-
|
|
3441
|
+
# Single-channel systems (e.g. SkyTEM) have no 'channel_no' column at
|
|
3442
|
+
# all: every row is its own (channel-1) sounding.
|
|
3443
|
+
if 'channel_no' in fl.columns:
|
|
3444
|
+
channel_arr = fl['channel_no'].values
|
|
3445
|
+
else:
|
|
3446
|
+
channel_arr = np.ones(len(fl))
|
|
3397
3447
|
ch1_pos = np.where(channel_arr == 1)[0]
|
|
3398
3448
|
|
|
3399
3449
|
# geometry from channel-1 rows (all of them)
|
|
@@ -3475,7 +3525,38 @@ def xyz_to_h5(file_xyz, file_gex, f_data_h5=None, i_lm_skip=None, i_hm_skip=None
|
|
|
3475
3525
|
if n_channels >= 2:
|
|
3476
3526
|
hf.create_dataset('/D1/i_hm', data=np.arange(i_hm_start, i_hm_end))
|
|
3477
3527
|
|
|
3478
|
-
# --- write
|
|
3528
|
+
# --- write altitude / rx_altitude / tx_altitude (if given) as their own Gaussian data blocks ---
|
|
3529
|
+
def _resolve_std(obs, std_arg):
|
|
3530
|
+
if isinstance(std_arg, str):
|
|
3531
|
+
return fl[std_arg.lower()].values[ch1_pos][keep].reshape(-1, 1).astype(float)
|
|
3532
|
+
elif isinstance(std_arg, (int, float)):
|
|
3533
|
+
if abs(std_arg) < 1:
|
|
3534
|
+
return std_arg * np.abs(obs) # relative
|
|
3535
|
+
else:
|
|
3536
|
+
return np.full_like(obs, float(std_arg)) # absolute, meters
|
|
3537
|
+
else:
|
|
3538
|
+
return 0.05 * np.abs(obs) # default: 5% relative
|
|
3539
|
+
|
|
3540
|
+
next_id = 2
|
|
3541
|
+
for col, col_std, name in (
|
|
3542
|
+
(altitude, altitude_std, 'Altitude'),
|
|
3543
|
+
(tx_altitude, tx_altitude_std, 'Tx_altitude'),
|
|
3544
|
+
(rx_altitude, rx_altitude_std, 'Rx_altitude'),
|
|
3545
|
+
):
|
|
3546
|
+
if col is not None:
|
|
3547
|
+
obs = fl[col.lower()].values[ch1_pos][keep].reshape(-1, 1).astype(float)
|
|
3548
|
+
std = _resolve_std(obs, col_std)
|
|
3549
|
+
save_data_gaussian(
|
|
3550
|
+
obs, D_std=std,
|
|
3551
|
+
f_data_h5=f_data_h5,
|
|
3552
|
+
id=next_id,
|
|
3553
|
+
name=name,
|
|
3554
|
+
delete_if_exist=False,
|
|
3555
|
+
showInfo=showInfo,
|
|
3556
|
+
)
|
|
3557
|
+
next_id += 1
|
|
3558
|
+
|
|
3559
|
+
# --- write additional data columns as D2, D3, ... (or shifted if altitude present) ---
|
|
3479
3560
|
if data_obs is not None:
|
|
3480
3561
|
_data_std = data_std if data_std is not None else [None] * len(data_obs)
|
|
3481
3562
|
for i, col_obs in enumerate(data_obs):
|
|
@@ -3488,7 +3569,7 @@ def xyz_to_h5(file_xyz, file_gex, f_data_h5=None, i_lm_skip=None, i_hm_skip=None
|
|
|
3488
3569
|
save_data_gaussian(
|
|
3489
3570
|
obs, D_std=std,
|
|
3490
3571
|
f_data_h5=f_data_h5,
|
|
3491
|
-
id=
|
|
3572
|
+
id=next_id + i,
|
|
3492
3573
|
name=col_obs,
|
|
3493
3574
|
delete_if_exist=False,
|
|
3494
3575
|
showInfo=showInfo,
|
|
@@ -2902,20 +2902,23 @@ def plot_discrete_data_entropy(f_data_h5, id_list, depth_reduce='min', **kwargs)
|
|
|
2902
2902
|
return plot_xy(H, f_data_h5=f_data_h5, **kwargs)
|
|
2903
2903
|
|
|
2904
2904
|
|
|
2905
|
-
def plot_data(f_data_h5, i_plot=[], Dkey=[], plType='imshow', uselog=True, **kwargs):
|
|
2905
|
+
def plot_data(f_data_h5, i_plot=[], Dkey=[], id=None, plType='imshow', uselog=True, **kwargs):
|
|
2906
2906
|
"""
|
|
2907
2907
|
Plot observational data from an HDF5 file.
|
|
2908
|
-
|
|
2908
|
+
|
|
2909
2909
|
This function creates visualizations of electromagnetic data including time-series plots,
|
|
2910
2910
|
2D image displays, and other data representations. Supports multiple data types and
|
|
2911
2911
|
plotting styles for comprehensive data analysis.
|
|
2912
|
-
|
|
2912
|
+
|
|
2913
2913
|
:param f_data_h5: Path to the HDF5 file containing observational data
|
|
2914
2914
|
:type f_data_h5: str
|
|
2915
2915
|
:param i_plot: Indices of data points to plot. If empty, plots all available data
|
|
2916
2916
|
:type i_plot: list or array-like, optional
|
|
2917
2917
|
:param Dkey: Data keys/identifiers to plot. If empty, uses all available datasets
|
|
2918
2918
|
:type Dkey: str or list, optional
|
|
2919
|
+
:param id: Dataset id to plot (e.g. id=1 plots only 'D1'). If None (default) and
|
|
2920
|
+
Dkey is also unset, every dataset found in the file (D1, D2, ...) is plotted.
|
|
2921
|
+
:type id: int, optional
|
|
2919
2922
|
:param plType: Plotting method - 'imshow' for 2D image display, 'plot' for line plots
|
|
2920
2923
|
:type plType: str, optional
|
|
2921
2924
|
:param uselog: Apply logarithmic scaling to data visualization (default is True)
|
|
@@ -2947,155 +2950,162 @@ def plot_data(f_data_h5, i_plot=[], Dkey=[], plType='imshow', uselog=True, **kwa
|
|
|
2947
2950
|
return
|
|
2948
2951
|
|
|
2949
2952
|
|
|
2953
|
+
# set plot in kwarg to True if not already set
|
|
2954
|
+
if 'hardcopy' not in kwargs:
|
|
2955
|
+
kwargs['hardcopy'] = True
|
|
2956
|
+
|
|
2950
2957
|
with h5py.File(f_data_h5,'r') as f_data:
|
|
2951
2958
|
|
|
2952
|
-
if
|
|
2953
|
-
|
|
2959
|
+
if id is not None:
|
|
2960
|
+
Dkeys = ['D%d' % id]
|
|
2961
|
+
elif len(Dkey)==0:
|
|
2954
2962
|
Dkeys = []
|
|
2955
2963
|
for key in f_data.keys():
|
|
2956
2964
|
if key[0]=='D':
|
|
2957
2965
|
if showInfo>0:
|
|
2958
2966
|
print("plot_data: Found data set %s" % key)
|
|
2959
2967
|
Dkeys.append(key)
|
|
2960
|
-
nd += 1
|
|
2961
|
-
Dkey=Dkeys[0]
|
|
2962
2968
|
if showInfo>0:
|
|
2963
|
-
print("plot_data: Using data set %s" %
|
|
2969
|
+
print("plot_data: Using data set(s) %s" % Dkeys)
|
|
2970
|
+
elif isinstance(Dkey, str):
|
|
2971
|
+
Dkeys = [Dkey]
|
|
2972
|
+
else:
|
|
2973
|
+
Dkeys = list(Dkey)
|
|
2964
2974
|
|
|
2965
|
-
|
|
2975
|
+
for Dkey in Dkeys:
|
|
2976
|
+
noise_model = f_data['/%s' % Dkey].attrs['noise_model']
|
|
2966
2977
|
|
|
2967
|
-
|
|
2968
|
-
|
|
2978
|
+
# Get name attribute if it exists
|
|
2979
|
+
name_attr = f_data['/%s' % Dkey].attrs.get('name', None)
|
|
2969
2980
|
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2981
|
+
# Force plot type for discrete/multinomial data
|
|
2982
|
+
cur_plType = plType
|
|
2983
|
+
if noise_model == 'multinomial' or Dkey.upper() in ['D2', 'D3', 'D4', 'D5']:
|
|
2984
|
+
cur_plType = 'plot'
|
|
2973
2985
|
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2986
|
+
if noise_model == 'gaussian':
|
|
2987
|
+
noise_model = 'Gaussian'
|
|
2988
|
+
d_obs = f_data['/%s' % Dkey]['d_obs'][:]
|
|
2989
|
+
d_std = f_data['/%s' % Dkey]['d_std'][:]
|
|
2978
2990
|
|
|
2979
2991
|
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2992
|
+
ndata,ns = f_data['/%s' % Dkey]['d_obs'].shape
|
|
2993
|
+
# set i_plot_cur as an array from 0 to ndata
|
|
2994
|
+
if len(i_plot)==0:
|
|
2995
|
+
i_plot_cur = np.arange(ndata)
|
|
2996
|
+
else:
|
|
2997
|
+
i_plot_cur = np.asarray(i_plot)
|
|
2985
2998
|
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2999
|
+
# remove all values in i_plot_cur that are larger than the number of data
|
|
3000
|
+
i_plot_cur = i_plot_cur[i_plot_cur<ndata]
|
|
3001
|
+
# remove all values in i_plot_cur that are smaller than 0
|
|
3002
|
+
i_plot_cur = i_plot_cur[i_plot_cur>=0]
|
|
2990
3003
|
|
|
2991
|
-
|
|
2992
|
-
|
|
3004
|
+
# find number of nan values on d_obs
|
|
3005
|
+
non_nan = np.sum(~np.isnan(d_obs), axis=1)
|
|
2993
3006
|
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3007
|
+
# Calculate the extent
|
|
3008
|
+
# extent = [left, right, bottom, top]; imshow row 0 maps to top,
|
|
3009
|
+
# so bottom=N_gates and top=0 gives gate 0 at the top of the plot
|
|
3010
|
+
# with the y-axis label reading 0→N_gates from top to bottom.
|
|
3011
|
+
xlim = [i_plot_cur.min(), i_plot_cur.max()]
|
|
3012
|
+
extent = [xlim[0], xlim[1], d_obs.shape[1], 1]
|
|
3000
3013
|
|
|
3001
|
-
|
|
3014
|
+
# plot figure with data
|
|
3002
3015
|
|
|
3003
|
-
|
|
3016
|
+
fig, ax = plt.subplots(4,1,figsize=(10,12), gridspec_kw={'height_ratios': [3, 3, 3, 1]})
|
|
3004
3017
|
|
|
3005
|
-
|
|
3018
|
+
# Set suptitle with optional name attribute
|
|
3006
3019
|
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3020
|
+
if cur_plType=='plot':
|
|
3021
|
+
if uselog:
|
|
3022
|
+
im1 = ax[0].semilogy(d_obs[i_plot_cur,:], linewidth=.5)
|
|
3023
|
+
im2 = ax[1].semilogy(d_std[i_plot_cur,:], linewidth=.5)
|
|
3024
|
+
im3 = ax[2].semilogy((d_obs[i_plot_cur,:]/d_std[i_plot_cur,:]), linewidth=.5)
|
|
3025
|
+
else:
|
|
3026
|
+
im1 = ax[0].plot(d_obs[i_plot_cur,:], linewidth=.5)
|
|
3027
|
+
im2 = ax[1].plot(d_std[i_plot_cur,:], linewidth=.5)
|
|
3028
|
+
im3 = ax[2].plot(100.0 * d_std[i_plot_cur,:]/d_obs[i_plot_cur,:], linewidth=.5)
|
|
3029
|
+
ax[0].set_xlim(xlim)
|
|
3030
|
+
ax[1].set_xlim(xlim)
|
|
3031
|
+
ax[2].set_xlim(xlim)
|
|
3032
|
+
ax[2].set_ylim([0, 20])
|
|
3033
|
+
ax[0].set_ylabel('d_obs')
|
|
3034
|
+
ax[1].set_ylabel('d_std')
|
|
3035
|
+
ax[2].set_ylabel('Relative noise [%] (d_std/d_obs × 100)')
|
|
3036
|
+
|
|
3037
|
+
elif cur_plType=='imshow':
|
|
3038
|
+
def _masked(arr):
|
|
3039
|
+
"""Mask NaN, inf, and non-positive values; leave positives intact."""
|
|
3040
|
+
return np.ma.masked_where(~np.isfinite(arr) | (arr <= 0), arr)
|
|
3041
|
+
|
|
3042
|
+
def _cmap_white_bad(name):
|
|
3043
|
+
cmap = matplotlib.colormaps[name].copy()
|
|
3044
|
+
cmap.set_bad('white')
|
|
3045
|
+
return cmap
|
|
3046
|
+
|
|
3047
|
+
if uselog:
|
|
3048
|
+
im1 = ax[0].imshow(_masked(d_obs[i_plot_cur,:]).T, aspect='auto',
|
|
3049
|
+
cmap=_cmap_white_bad('jet_r'),
|
|
3050
|
+
norm=matplotlib.colors.LogNorm(), extent=extent)
|
|
3051
|
+
im2 = ax[1].imshow(_masked(d_std[i_plot_cur,:]).T, aspect='auto',
|
|
3052
|
+
cmap=_cmap_white_bad('hot_r'),
|
|
3053
|
+
norm=matplotlib.colors.LogNorm(), extent=extent)
|
|
3054
|
+
else:
|
|
3055
|
+
im1 = ax[0].imshow(np.ma.masked_invalid(d_obs[i_plot_cur,:]).T,
|
|
3056
|
+
aspect='auto', cmap=_cmap_white_bad('jet_r'), extent=extent)
|
|
3057
|
+
im2 = ax[1].imshow(np.ma.masked_invalid(d_std[i_plot_cur,:]).T,
|
|
3058
|
+
aspect='auto', cmap=_cmap_white_bad('hot_r'), extent=extent)
|
|
3059
|
+
|
|
3060
|
+
# Relative noise in % — mask invalid entries
|
|
3061
|
+
rel_noise = np.ma.masked_invalid(100.0 * d_std[i_plot_cur,:] / d_obs[i_plot_cur,:])
|
|
3062
|
+
im3 = ax[2].imshow(rel_noise.T, aspect='auto', vmin=0, vmax=20,
|
|
3063
|
+
cmap=_cmap_white_bad('turbo'), extent=extent)
|
|
3064
|
+
|
|
3065
|
+
fig.colorbar(im1, ax=ax[0])
|
|
3066
|
+
fig.colorbar(im2, ax=ax[1])
|
|
3067
|
+
fig.colorbar(im3, ax=ax[2])
|
|
3068
|
+
|
|
3069
|
+
ax[0].set_ylabel('gate number')
|
|
3070
|
+
ax[1].set_ylabel('gate number')
|
|
3071
|
+
ax[2].set_ylabel('gate number')
|
|
3072
|
+
|
|
3073
|
+
ax[0].set_title('d_obs: observed data')
|
|
3074
|
+
ax[1].set_title('d_std: standard deviation')
|
|
3075
|
+
ax[2].set_title('Relative noise, % (d_std / d_obs × 100)')
|
|
3076
|
+
|
|
3077
|
+
|
|
3078
|
+
im4 = ax[3].plot(i_plot_cur,non_nan[i_plot_cur], 'k.', markersize=.5)
|
|
3079
|
+
ax[3].set_ylabel('Number of data')
|
|
3080
|
+
ax[3].set_xlim(xlim)
|
|
3081
|
+
|
|
3082
|
+
if cur_plType=='imshow':
|
|
3083
|
+
# Create an invisible colorbar for the last subplot
|
|
3084
|
+
cbar4 = fig.colorbar(im3, ax=ax[3])
|
|
3085
|
+
cbar4.solids.set(alpha=0)
|
|
3086
|
+
cbar4.outline.set_visible(False)
|
|
3087
|
+
cbar4.ax.set_yticks([]) # Hide the colorbar ticks
|
|
3088
|
+
cbar4.ax.set_yticklabels([]) # Hide the colorbar ticks labels
|
|
3089
|
+
|
|
3090
|
+
ax[-1].set_xlabel('Index')
|
|
3091
|
+
|
|
3092
|
+
ax[0].grid()
|
|
3093
|
+
ax[1].grid()
|
|
3094
|
+
ax[2].grid()
|
|
3095
|
+
ax[3].grid()
|
|
3096
|
+
|
|
3097
|
+
if name_attr is not None:
|
|
3098
|
+
fig.suptitle("Dataset %s: %s" % (Dkey, name_attr))
|
|
3041
3099
|
else:
|
|
3042
|
-
|
|
3043
|
-
aspect='auto', cmap=_cmap_white_bad('jet_r'), extent=extent)
|
|
3044
|
-
im2 = ax[1].imshow(np.ma.masked_invalid(d_std[i_plot,:]).T,
|
|
3045
|
-
aspect='auto', cmap=_cmap_white_bad('hot_r'), extent=extent)
|
|
3046
|
-
|
|
3047
|
-
# Relative noise in % — mask invalid entries
|
|
3048
|
-
rel_noise = np.ma.masked_invalid(100.0 * d_std[i_plot,:] / d_obs[i_plot,:])
|
|
3049
|
-
im3 = ax[2].imshow(rel_noise.T, aspect='auto', vmin=0, vmax=20,
|
|
3050
|
-
cmap=_cmap_white_bad('turbo'), extent=extent)
|
|
3051
|
-
|
|
3052
|
-
fig.colorbar(im1, ax=ax[0])
|
|
3053
|
-
fig.colorbar(im2, ax=ax[1])
|
|
3054
|
-
fig.colorbar(im3, ax=ax[2])
|
|
3055
|
-
|
|
3056
|
-
ax[0].set_ylabel('gate number')
|
|
3057
|
-
ax[1].set_ylabel('gate number')
|
|
3058
|
-
ax[2].set_ylabel('gate number')
|
|
3059
|
-
|
|
3060
|
-
ax[0].set_title('d_obs: observed data')
|
|
3061
|
-
ax[1].set_title('d_std: standard deviation')
|
|
3062
|
-
ax[2].set_title('Relative noise, % (d_std / d_obs × 100)')
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
im4 = ax[3].plot(i_plot,non_nan[i_plot], 'k.', markersize=.5)
|
|
3066
|
-
ax[3].set_ylabel('Number of data')
|
|
3067
|
-
ax[3].set_xlim(xlim)
|
|
3068
|
-
|
|
3069
|
-
if plType=='imshow':
|
|
3070
|
-
# Create an invisible colorbar for the last subplot
|
|
3071
|
-
cbar4 = fig.colorbar(im3, ax=ax[3])
|
|
3072
|
-
cbar4.solids.set(alpha=0)
|
|
3073
|
-
cbar4.outline.set_visible(False)
|
|
3074
|
-
cbar4.ax.set_yticks([]) # Hide the colorbar ticks
|
|
3075
|
-
cbar4.ax.set_yticklabels([]) # Hide the colorbar ticks labels
|
|
3076
|
-
|
|
3077
|
-
ax[-1].set_xlabel('Index')
|
|
3078
|
-
|
|
3079
|
-
ax[0].grid()
|
|
3080
|
-
ax[1].grid()
|
|
3081
|
-
ax[2].grid()
|
|
3082
|
-
ax[3].grid()
|
|
3083
|
-
|
|
3084
|
-
if name_attr is not None:
|
|
3085
|
-
fig.suptitle("Dataset %s: %s" % (Dkey, name_attr))
|
|
3086
|
-
else:
|
|
3087
|
-
fig.suptitle("Dataset %s" % Dkey)
|
|
3100
|
+
fig.suptitle("Dataset %s" % Dkey)
|
|
3088
3101
|
|
|
3089
|
-
|
|
3090
|
-
else:
|
|
3091
|
-
print("plot_data: Unknown noise model: %s" % noise_model)
|
|
3102
|
+
plt.tight_layout()
|
|
3092
3103
|
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
plt.savefig('%s_%s_%s.png' % (os.path.splitext(f_data_h5)[0],Dkey,plType), bbox_inches='tight')
|
|
3104
|
+
if kwargs['hardcopy']:
|
|
3105
|
+
# strip the filename from f_data_h5
|
|
3106
|
+
plt.savefig('%s_%s_%s.png' % (os.path.splitext(f_data_h5)[0],Dkey,cur_plType), bbox_inches='tight')
|
|
3107
|
+
else:
|
|
3108
|
+
print("plot_data: Unknown noise model: %s" % noise_model)
|
|
3099
3109
|
|
|
3100
3110
|
|
|
3101
3111
|
|