-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmean_hyst.py
712 lines (647 loc) · 29.5 KB
/
mean_hyst.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
"""
--> Executable Script
Perform mean of hysteresis nanoloops (on / off / coupled) by reading a
certain set of txt file nanoloops defined by the user
The set of files can be chosen manually or with a mask application of a chosen
condition on a chosen reference property
Inspired by: Kelley et al. "Ferroelectricity in Hafnia Controlled via Surface
Electrochemical State". 10.48550/arXiv.2207.12525
"""
import os
import tkinter.filedialog as tkf
import numpy as np
from PySSPFM.settings import get_setting, get_config
from PySSPFM.utils.core.figure import print_plots
from PySSPFM.utils.nanoloop.file import extract_nanoloop_data
from PySSPFM.utils.nanoloop.analysis import nanoloop_treatment, AllMeanLoop
from PySSPFM.utils.nanoloop.phase import gen_dict_pha
from PySSPFM.utils.map.main import gen_mask_ref, plot_and_save_maps
from PySSPFM.utils.nanoloop_to_hyst.file import \
generate_file_nanoloop_paths, extract_properties
from PySSPFM.utils.nanoloop_to_hyst.plot import plot_differential_analysis
from PySSPFM.utils.nanoloop_to_hyst.analysis import gen_analysis_mode
from PySSPFM.utils.nanoloop_to_hyst.electrostatic import \
gen_differential_loop, linreg_differential
from PySSPFM.utils.nanoloop_to_hyst.analysis import \
find_best_nanoloop, hyst_analysis, electrostatic_analysis
from PySSPFM.utils.path_for_runable import \
save_path_management, copy_json_res, create_json_res
from PySSPFM.utils.raw_extraction import csv_meas_sheet_extract
def single_script(file, user_pars, meas_pars, sign_pars,
analysis_mode='mean_loop'):
"""
Find the best nanoloop for a single considered txt nanoloop file
Parameters
----------
file: str
Path of the single considered file (txt nanoloop save) (in)
user_pars: dict
All user parameters for the treatment
meas_pars: dict
Measurement parameters
sign_pars: dict
sspfm bias signal parameters
analysis_mode: str, optional
Operating mode for the reader: three possible modes:
- 'on_f_loop' for on-field measurement
- 'mean_loop' for off-field measurement with a constant value of
read voltage
- 'multi_loop' for off-field measurement with different values of
read voltage
Returns
-------
best_loop: loop (MultiLoop or MeanLoop) object
Best nanoloop depending on the analysis mode
dict_str: dict
Used for figure annotation
"""
assert analysis_mode in ['multi_loop', 'mean_loop', 'on_f_loop']
data_dict, dict_str, _ = extract_nanoloop_data(file)
dict_pha = gen_dict_pha(meas_pars, user_pars['pha corr'],
pha_fwd=user_pars['pha fwd'],
pha_rev=user_pars['pha rev'],
func=user_pars['pha func'],
main_elec=user_pars['main elec'],
locked_elec_slope=user_pars['locked elec slope'])
# Don't apply Q factor divisor
meas_pars['Q factor'] = 1
loop_tab, _, _ = nanoloop_treatment(
data_dict, sign_pars, dict_pha=dict_pha, dict_str=dict_str,
q_fact_scalar=meas_pars['Q factor'])
_, _, best_loop, _, _ = find_best_nanoloop(
loop_tab, dict_pha['counterclockwise'],
grounded_tip=dict_pha['grounded tip'], analysis_mode=analysis_mode,
del_1st_loop=user_pars['del 1st loop'], model=user_pars['func'],
asymmetric=user_pars['asymmetric'], method=user_pars['method'],
locked_elec_slope=user_pars['locked elec slope'])
return best_loop, dict_str
def find_best_nanoloops(user_pars, mask, mode='off', verbose=False):
"""
Find the best nanoloops for all considered txt loop files
Parameters
----------
user_pars: dict
Dict of all user parameters for the treatment
mask: list(n) of int
List of index for mask
mode: str, optional
Type of measurement mode: 'on', 'off', 'coupled'
verbose: bool, optional
Activation key for verbosity
Returns
-------
best_loops: list(m) of loop (MultiLoop or MeanLoop) object
List of best loops depending on the analysis mode
analysis_mode: str
Operating mode for the reader: three possible modes:
- 'on_f_loop' for on-field measurement
- 'mean_loop' for off-field measurement with a constant value of
read voltage
- 'multi_loop' for off-field measurement with different values of
read voltage
dict_str: dict
Used for figure annotation
"""
meas_pars, sign_pars = csv_meas_sheet_extract(user_pars['dir path in pars'])
file_paths_in = generate_file_nanoloop_paths(
user_pars['dir path in loop'], mode=f'{mode}_f')
file_paths_in_sel = [path[0] for cont, path in enumerate(file_paths_in)
if cont not in mask]
analysis_mode = gen_analysis_mode(mode=mode,
read_mode=sign_pars['Mode (R)'])
best_loops, dict_str = [], None
for cont, file_path_in in enumerate(file_paths_in_sel):
file_name_in = os.path.split(file_path_in)[1]
if verbose:
if cont == 0:
print(f'\tanalysis mode: {analysis_mode}')
print(f' - file n°{cont + 1}: {file_name_in}')
best_loop, dict_str = single_script(
file_path_in, user_pars, meas_pars, sign_pars,
analysis_mode=analysis_mode)
best_loops.append(best_loop)
return best_loops, analysis_mode, dict_str
def mean_analysis_on_off(user_pars, best_loops, analysis_mode='mean_loop',
dict_str=None, make_plots=False):
"""
Compute the mean of all loops (on or off field) and perform analysis (
fit...) on it
Parameters
----------
user_pars: dict
Dict of all user parameters for the treatment
best_loops: list(m) of loop (MultiLoop or MeanLoop) object
List of best loops depending on analysis mode
analysis_mode: str, optional
Operating mode for the reader: three possible modes:
- 'on_f_loop' for on-field measurement
- 'mean_loop' for off-field measurement with a constant value of read
voltage
- 'multi_loop' for off-field measurement with different values of
read voltage
dict_str: dict, optional
Dict used for figure annotation
make_plots: bool, optional
Activation key for figures generation
Returns
-------
mean_best_loop: MultiLoop or MeanLoop object
Mean best MultiLoop or MeanLoop object
mean_best_hyst: Hysteresis object
Mean best Hysteresis object
figures: list(p) of Matplotlib figures
"""
figures = []
# Compute the mean of all best_loops
mean_best_loop = AllMeanLoop(best_loops, del_1st_loop=False)
x_hyst = [np.array(mean_best_loop.piezorep.write_volt_right),
np.array(mean_best_loop.piezorep.write_volt_left)]
y_hyst = [np.array(mean_best_loop.piezorep.y_meas_right),
np.array(mean_best_loop.piezorep.y_meas_left)]
meas_pars, _ = csv_meas_sheet_extract(user_pars['dir path in pars'])
dict_pha = gen_dict_pha(meas_pars, user_pars['pha corr'],
pha_fwd=user_pars['pha fwd'],
pha_rev=user_pars['pha rev'],
func=user_pars['pha func'],
main_elec=user_pars['main elec'],
locked_elec_slope=user_pars['locked elec slope'])
res = hyst_analysis(x_hyst, y_hyst, mean_best_loop,
dict_pha['counterclockwise'], dict_pha['grounded tip'],
dict_str=dict_str,
infl_threshold=user_pars['inf thresh'],
sat_threshold=user_pars['sat thresh'],
model=user_pars['func'],
asymmetric=user_pars['asymmetric'],
method=user_pars['method'],
analysis_mode=analysis_mode,
locked_elec_slope=user_pars['locked elec slope'],
make_plots=make_plots)
(mean_best_hyst, props_tot, props_no_bckgnd, hyst_figs) = res
figures += hyst_figs
props = {}
for key, value in zip(
['offset', 'slope', 'ampli_0', 'ampli_1', 'coef_0', 'coef_1',
'x0_0', 'x0_1'], mean_best_hyst.params):
props[f'fit pars: {key}'] = mean_best_hyst.params[value].value
for key, value in props_tot.items():
props[f'charac tot fit: {key}'] = value
for key, value in props_no_bckgnd.items():
props[f'charac ferro fit: {key}'] = value
if user_pars['sat mode'] == 'auto':
sat_domain = [min([props_tot['x sat r'], props_tot['x sat l']]),
max([props_tot['x sat r'], props_tot['x sat l']])]
elif user_pars['sat mode'] == 'set':
sat_domain = [user_pars['sat domain']['min'],
user_pars['sat domain']['max']]
else:
raise NotImplementedError("sat domain must be 'auto' or 'set'")
res = electrostatic_analysis(mean_best_loop, analysis_mode=analysis_mode,
sat_domain=sat_domain,
make_plots=make_plots, dict_str=dict_str,
func=user_pars['pha func'])
(electrostatic_dict, figs_elec) = res
for key, value in electrostatic_dict.items():
props[key] = value
figures += figs_elec
return mean_best_loop, mean_best_hyst, figures
def mean_analysis_coupled(best_loops, bias_min=-5., bias_max=5.,
selected_offsets_off=None, make_plots=False):
"""
Compute the mean of all coupled loops and perform coupled analysis on it
Parameters
----------
best_loops: dict(2) (on and off field) of list(m) of (MultiLoop or MeanLoop)
Dict of on and off field best loops depending on analysis mode
bias_min: float, optional
Initial minimum value of write voltage axis range for the differential
analysis (in V)
bias_max: float, optional
Initial maximum value of write voltage axis range for the differential
analysis (in V)
selected_offsets_off: list, optional
List of off field hysteresis offset for selected best loops
make_plots: bool, optional
Activation key for figures generation
Returns
-------
mean_diff_piezorep: list(q) of float
List of mean differential piezoresponse
fit_res: tuple(5)
Result of linear regression of mean differential piezoresponse
figures: list(1) of Matplotlib figure
"""
figure, all_diff_piezorep_left, all_diff_piezorep_right = [], [], []
write_volt_left, write_volt_right = [], []
for cont, (best_loop_on, best_loop_off) in \
enumerate(zip(best_loops['on'], best_loops['off'])):
if selected_offsets_off is not None:
offset_off = selected_offsets_off[cont]
else:
offset_off = 0.0
res = gen_differential_loop(
best_loop_on, best_loop_off, offset_off=offset_off)
(write_volt_left, diff_piezorep_left, write_volt_right,
diff_piezorep_right, _) = res
all_diff_piezorep_left.append(diff_piezorep_left)
all_diff_piezorep_right.append(diff_piezorep_right)
mean_diff_piezorep_left = np.mean(np.array(all_diff_piezorep_left), axis=0)
mean_diff_piezorep_right = np.mean(np.array(all_diff_piezorep_right),
axis=0)
mean_diff_piezorep = []
for elem_left, elem_right in zip(np.flip(mean_diff_piezorep_left),
mean_diff_piezorep_right):
mean_diff_piezorep.append(np.mean([elem_left, elem_right]))
mean_piezorep_grad = np.gradient(mean_diff_piezorep, write_volt_right)
res = linreg_differential(
write_volt_right, mean_diff_piezorep, bias_min, bias_max)
(_, _, fit_res) = res
(a_diff, y_0_diff, _, r_square, diff_fit) = fit_res
figures = []
if make_plots:
figure = plot_differential_analysis(
write_volt_left, write_volt_right, diff_fit,
mean_diff_piezorep_left, mean_diff_piezorep_right,
mean_diff_piezorep, mean_piezorep_grad, a_diff, y_0_diff, r_square,
bias_min=bias_min, bias_max=bias_max)
figures += [figure]
return mean_diff_piezorep, fit_res, figures
def main_mean_hyst(user_pars, verbose=False, make_plots=False):
"""
Main function used for mean loop analysis
Parameters
----------
user_pars: dict
Dict of all user parameters for the treatment
verbose: bool, optional
Activation key for verbosity
make_plots: bool, optional
Activation key for figures generation
Returns
-------
Figures or data of analysis result
"""
assert os.path.exists(user_pars['dir path in prop']), \
f"{user_pars['dir path in prop']} doesn't exist"
assert os.path.exists(user_pars['dir path in loop']), \
f"{user_pars['dir path in loop']} doesn't exist"
assert os.path.exists(user_pars['dir path in pars']), \
f"{user_pars['dir path in pars']} doesn't exist"
figures = []
mode = user_pars['mode']
mask, mask_pars = user_pars['mask']['man mask'], user_pars['mask']
lab_dict = {'on': ['on_f', 'y', 'On Field'],
'off': ['off_f', 'w', 'Off Field'],
'coupled': ['coupled', 'r', 'Coupled']}
properties, dim_pix, dim_mic = extract_properties(
user_pars['dir path in prop'])
mean_best_loop, mean_best_hyst = None, None
mean_diff_piezorep = []
fit_res = ()
if mask is None:
dict_map = {'label': lab_dict[mode][2], 'col': lab_dict[mode][1]}
ref_mode = user_pars['mask']['ref']['mode']
ref = properties[ref_mode][mask_pars['ref']['prop']]
_, _, mask = gen_mask_ref(
ref, dim_pix, dim_mic=dim_mic, min_val=mask_pars['ref']['min val'],
max_val=mask_pars['ref']['max val'],
mode_man=mask_pars['ref']['interactive'],
ref_str=mask_pars['ref']["prop"], dict_map=dict_map)
applied_mask = [index for index in range(len(ref)) if
index not in mask] if mask_pars['revert mask'] else mask
if make_plots:
dict_interp = {'fact': user_pars['interp fact'],
'func': user_pars['interp func']}
prop_key = {'mode': ref_mode, 'prop': mask_pars['ref']['prop']}
full_mask = np.arange(len(ref))
highlight_pix = [indx for indx in full_mask
if indx not in applied_mask]
fig_map = plot_and_save_maps(
ref, dim_pix, dim_mic=dim_mic, dict_interp=dict_interp, mask=[],
prop_str=prop_key['prop'], highlight_pix=highlight_pix)
figures.append(fig_map)
else:
applied_mask = [index for index in range(int(dim_pix['x']*dim_pix['y']))
if index not in mask] \
if mask_pars['revert mask'] else mask
if verbose:
print(f'mask: {applied_mask}')
if mode in ['on', 'off']:
res = find_best_nanoloops(
user_pars, applied_mask, mode=mode, verbose=verbose)
best_loops, analysis_mode, dict_str = res
res = mean_analysis_on_off(user_pars, best_loops, analysis_mode,
dict_str, make_plots=make_plots)
mean_best_loop, mean_best_hyst, on_off_fig = res
figures.extend(on_off_fig)
elif mode == 'coupled':
best_loops = {}
for mode_lab in ['on', 'off']:
res = find_best_nanoloops(
user_pars, applied_mask, mode=mode_lab, verbose=verbose)
best_loops[mode_lab], analysis_mode, dict_str = res
offsets_off = properties['off']['charac tot fit: y shift']
selected_offsets_off = [val for cont, val in enumerate(offsets_off) if
cont not in applied_mask]
elec_offset = get_setting('electrostatic_offset')
selected_offsets_off = selected_offsets_off if elec_offset else None
res = mean_analysis_coupled(
best_loops,
bias_min=user_pars['diff domain']['min'],
bias_max=user_pars['diff domain']['max'],
selected_offsets_off=selected_offsets_off, make_plots=make_plots)
mean_diff_piezorep, fit_res, coupled_fig = res
figures.extend(coupled_fig)
else:
raise IOError("'mode' should be 'on' or 'off' or 'coupled'")
if make_plots:
return figures
elif mode in ['on', 'off']:
return mean_best_loop, mean_best_hyst
else:
return mean_diff_piezorep, fit_res
def parameters(fname_json=None):
"""
To complete by user of the script: return parameters for analysis
fname_json: str
Path to the JSON file containing user parameters. If None,
the file is created in a default path:
(your_user_disk_access/.pysspfm/script_name_params.json)
- mode: str
Measurement mode used for analysis.
This parameter specifies the mode used for analysis.
Three possible values: 'on,' 'off,' or 'coupled.'
- revert_mask: bool
Revert option of the mask for selecting specific files.
This parameter specifies if the mask should be reverted (True), or not
(False)
- man_mask: list
Manual mask for selecting specific files.
This parameter is a list of pixel indices.
- If the list of pixels is empty ( [] ), all files are selected.
- If the list of pixels is None, the criterion of selection is made
with the reference property.
- If the list of pixels is [a, b, c ...], files of index a, b, c [...]
are not selected.
- ref: dict
--> construct a mask with a criterion selection on ref values
(valid if man_mask is None)
- mode: str --> mode of reference property chosen
- prop: str --> reference property chosen
- min val: float --> minimum value of ref required (if None no minimum
value criterion) (valid if interactive is False)
- max val: float --> maximum value of ref required (if None no maximum
value criterion) (valid if interactive is False)
- fmt: str --> format of printed value in the map
- interactive: bool --> if True, user select interactively the criterion
selection
- func: algebraic func
Function used for hysteresis fit.
This parameter specifies the algebraic function used to fit
hysteresis branches.
sigmoid or arctan
- method: str
Method used for the fit.
This parameter specifies the fitting method used for the analysis.
'leastsq' or 'least_square' (faster but harder to converge) or
'nelder' (vice versa)
- asymmetric: bool
Asymmetric Hysteresis Fit
This parameter determines whether an asymmetric fit of hysteresis
should be performed. An asymmetric fit allows each branch of the
hysteresis curve to have a different slope coefficient.
- inf_thresh: float
Inflection Point Threshold
This parameter defines the threshold, expressed as a percentage of
the hysteresis amplitude, used to calculate the value of the
inflection point at the beginning of the hysteresis switch.
- sat_thresh: float
Saturation Point Threshold
This parameter defines the threshold, expressed as a percentage of
the hysteresis amplitude, used to calculate the value of the
saturation point at the end of the hysteresis switch.
- del_1st_loop: bool
Delete First Loop
If this parameter is set to True, it deletes the first loop of the
analysis, which is typically used for calculating the mean hysteresis.
This can be useful when the first write voltage values are equal to
zero, indicating that the material is in a pristine state, and the
loop shape would be different from the polarized state.
Deleting the first loop helps to avoid artifacts in the analysis.
- pha_corr: str
Phase Correction Mode
This parameter specifies the correction mode for the value of the
phase nanoloop. There are four possible correction modes:
- 'raw': No correction is applied.
- 'offset': Offset correction is applied.
- 'affine': Affine correction is applied.
- 'up_down': Phase is set to the up value or down value.
- pha_fwd: float
Phase Forward Target Value
This parameter represents the target value for the phase in the
forward direction. It is used to generate a multiplied coefficient
equal to 1 between amplitude and piezoresponse.
- pha_rev: float
Phase Reverse Target Value
This parameter represents the target value for the phase in the
reverse direction. It is used to generate a multiplied coefficient
equal to -1 between amplitude and piezoresponse.
- pha_func: algebraic func
Piezoresponse Function
This parameter represents the function used to determine the
piezoresponse from amplitude and phase.
The piezoresponse (PR) is calculated as PR = amp * func(pha),
where 'amp' is the amplitude and 'pha' is the phase.
Value: Algebraic function (np.cos or np.sin)
- main_elec: bool
Dominant Electrostatics in On Field Mode
It determines whether the electrostatics are higher than
ferroelectric effects. In other words, it indicates if the
electrostatics are responsible for the phase loop's sense of
rotation in the On Field mode.
Active if On Field mode is selected.
- locked_elec_slope: str
Locked Electrostatic Slope
It specifies and locks the sign of the electrostatic slope in
the loop whatever measurement parameters
(theory: grounded tip: negative, bottom: positive).
Value: 'negative', 'positive', or None
Active if: On Field mode is selected.
- diff_domain: dict
Voltage Range for Linear Differential Component
This parameter defines the voltage range considered for the linear part
of the differential component. It specifies the voltage range for
differential analysis.
If left empty or set to None, no limit is applied.
Active if: coupled mode is selected.
- sat_mode: str
Saturation Electrostatic Analysis Mode
This parameter determines the mode for analyzing the saturation
electrostatic component, which defines the saturation domain of the
loop.
Possible values:
- 'set': User-defined saturation domain in the sat_domain parameter.
- 'auto': Automatic calculation from hysteresis fit.
Active if: On Field mode is selected.
- sat_domain: dict
Voltage Range for Saturation Electrostatic Analysis
This parameter sets the voltage range for the saturation part of
hysteresis loop.
If left empty or set to None, the limit is not considered.
Active if: On Field mode is selected and saturation mode is set to
'set'.
- interp fact: int
Interpolation factor for sspfm maps interpolation.
This parameter determines the level of interpolation to be applied to
SSPFM maps.
Active if: Mask is built on ref property (i.e. list of pixels is
None)."
- interp_func: str
Interpolation function
This parameter specifies the interpolation function used for sspfm
maps interpolation. It can take one of the following values:
'linear', or 'cubic'.
Active if: Mask is built on ref property (i.e. list of pixels is
None)."
- dir_path_in: str
Results of analysis directory.
This parameter specifies the directory containing the results of
analysis generated after the 1st and 2nd step of the analysis.
Default: 'title_meas_out_mode'
- dir_path_out: str
Saving directory for analysis results figures
(optional, default: toolbox directory in the same root)
This parameter specifies the directory where the figures
generated as a result of the analysis will be saved.
- dir_path_in_prop: str
Properties files directory
This parameter specifies the directory containing the properties text
files generated after the 2nd step of the analysis.
Optional, Default: 'properties'
- dir_path_in_loop: str
Txt loop files directory.
This parameter specifies the directory containing the loop text files
generated after the 1st step of the analysis.
Optional, Default: 'nanoloops'
- dir_path_in_pars: str
Path of the CSV measurement sheet directory.
This parameter specifies the directory containing path of the CSV
measurement sheet.
Optional, Default: 'title_meas_out_mode'
- verbose: bool
Activation key for printing verbosity during analysis.
This parameter serves as an activation key for printing verbose
information during the analysis.
- show_plots: bool
Activation key for generating matplotlib figures during analysis.
This parameter serves as an activation key for generating
matplotlib figures during the analysis process.
- save: bool
Activation key for saving results of analysis.
This parameter serves as an activation key for saving results
generated during the analysis process.
"""
if get_setting("extract_parameters") in ['json', 'toml']:
config_params, fname_json = get_config(__file__, fname_json)
dir_path_in = config_params['dir_path_in']
elif get_setting("extract_parameters") == 'python':
print("user parameters from python file")
dir_path_in = tkf.askdirectory()
# dir_path_in = r'...\KNN500n_15h18m02-10-2023_out_dfrt
dir_path_out = None
# dir_path_out = r'...\KNN500n_15h18m02-10-2023_out_dfrt\toolbox\
# mean_loop_2023-10-02-16h38m
config_params = {
"dir_path_in": dir_path_in,
"dir_path_out": dir_path_out,
"verbose": True,
"show_plots": True,
"save": False,
"user_pars": {
"mode": "off",
"mask": {
"revert mask": False,
"man mask": None,
"ref": {
"prop": "charac tot fit: area",
"mode": "off",
"min val": 0.005,
"max val": None,
"fmt": ".2f",
"interactive": False
}
},
"func": "sigmoid",
"method": "least_square",
"asymmetric": False,
"inf thresh": 10,
"sat thresh": 90,
"del 1st loop": True,
"pha corr": "offset",
"pha fwd": 0,
"pha rev": 180,
"pha func": "np.cos",
"main elec": True,
"locked elec slope": None,
"diff domain": {
"min": -5.0,
"max": 5.0
},
"sat mode": "set",
"sat domain": {
"min": -9.0,
"max": 9.0
},
"interp fact": 4,
"interp func": "linear"
}
}
else:
raise NotImplementedError("setting 'extract_parameters' "
"should be in ['json', 'toml', 'python']")
properties_folder_name = get_setting('default_properties_folder_name')
dir_path_in_prop = os.path.join(dir_path_in, properties_folder_name)
# dir_path_in_prop = r'...\KNN500n_15h18m02-10-2023_out_dfrt\properties
nanoloops_folder_name = get_setting('default_nanoloops_folder_name')
dir_path_in_loop = os.path.join(dir_path_in, nanoloops_folder_name)
# dir_path_in_loop = r'...\KNN500n_15h18m02-10-2023_out_dfrt\nanoloops
user_pars = config_params['user_pars']
user_pars['dir path in prop'] = dir_path_in_prop
user_pars['dir path in loop'] = dir_path_in_loop
user_pars['dir path in pars'] = dir_path_in
return user_pars, config_params['dir_path_in'], \
config_params['dir_path_out'], config_params['verbose'], \
config_params['show_plots'], config_params['save'], fname_json, \
config_params
def main(fname_json=None):
"""
Main function for data analysis.
fname_json: str
Path to the JSON file containing user parameters. If None,
the file is created in a default path:
(your_user_disk_access/.pysspfm/script_name_params.json)
"""
figs = []
# Extract parameters
res = parameters(fname_json=fname_json)
(user_pars, dir_path_in, dir_path_out, verbose, show_plots, save,
fname_json, config_params) = res
# Generate default path out
dir_path_out = save_path_management(
dir_path_in, dir_path_out, save=save, dirname="mean_loop", lvl=0,
create_path=True, post_analysis=True)
# Main function
figs += main_mean_hyst(
user_pars, verbose=verbose, make_plots=bool(show_plots or save))
# Plot figures
print_plots(figs, show_plots=show_plots, save_plots=save,
dirname=dir_path_out, transparent=False)
# Save parameters
if save:
if get_setting("extract_parameters") in ['json', 'toml']:
copy_json_res(fname_json, dir_path_out, verbose=verbose)
else:
create_json_res(config_params, dir_path_out,
fname="mean_hyst_params.json",
verbose=verbose)
if __name__ == '__main__':
main()