Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
546 commits
Select commit Hold shift + click to select a range
f0b16db
added sftp loading
Jun 17, 2022
922e51b
Merge branch 'master' of https://git.scc.kit.edu/nanospin/semispin/qkit
Jun 17, 2022
204c201
Error handling for sftp load
Jun 17, 2022
1808fb5
Changed many files to better suit the script based workflow
Jun 29, 2022
db23c87
First usable version of the Peak_Tracking script. Test it, and hunt i…
Jun 29, 2022
66f2b7e
Timetrace jump analyzer is now able to fit, find big jumps, and tell …
Jun 29, 2022
56960b2
push from updates of Phi-ndus
Daniel-AG-WW Jul 1, 2022
06e24db
Peaktracker now supports looking to next to nearest peaks in case of …
Jul 1, 2022
b8893d0
AnalyzerSpectralNoiseDensity now supports multilinear fits.
Jul 1, 2022
ff983b8
PlotterSpectralNoiseDensity now supports bilinear fits
Jul 4, 2022
8b90d39
Saver_json now appends data to files if they already exist, instead o…
Jul 4, 2022
1098c37
Savepath creation
Jul 5, 2022
9acad8c
Merge branch 'script_based_analysis' of https://git.scc.kit.edu/nanos…
Jul 5, 2022
1c2d6f3
Saver_json now supports appending to files
Jul 5, 2022
7b3d6aa
Peak_tracking analysis script now does overview saving
Jul 5, 2022
67a6627
Loaderh5 can now handle filepaths as strings directly
Jul 5, 2022
8d3e8bd
Script now supports saving of multiple tg voltages in the overview.
Jul 5, 2022
3600ecd
Saver_json now updates the saved data correctly
Jul 6, 2022
72afbe8
Overview Plot added
Jul 12, 2022
67779eb
Fixed bug in spin excite where the measurement divider wouldn't reset…
Jul 12, 2022
cc7b4eb
B4 compatible
Jul 14, 2022
e1b1396
Delta V over int PSD
Jul 14, 2022
9c3e1ff
Changed UHFLI backend to use zero based indexing and qupulse decoder …
Daniel-AG-WW Jul 15, 2022
4ec65ca
Merge branch 'master' of https://git.scc.kit.edu/nanospin/semispin/qkit
Daniel-AG-WW Jul 15, 2022
d941a56
moved the position of the fit guess to the standard.
Jul 15, 2022
1d792a0
started rework
Jul 15, 2022
34f890f
Removed mapping. Moved Sample count calculation to decoder
Jul 19, 2022
d76a974
timetrace mode working, pp_vs_t not yet tho.
Jul 21, 2022
2799ced
Changes to the overall esthetics
Jul 21, 2022
e420f9f
spin_excite and backend bugfixes
Daniel-AG-WW Jul 22, 2022
f0e5134
changing the way the parameters are defined
Jul 25, 2022
fdb26a8
Fixed qviewkit bugs and qkit.start()
Jul 25, 2022
ac9c025
Revert "Fixed qviewkit bugs and qkit.start()"
Jul 26, 2022
d34f92a
Fixed qkit.start() for IPython
Jul 26, 2022
e64c4cc
fixed crash in _measure_pp_vs_t
Jul 28, 2022
b40b215
First version of the postanalysis script
Aug 3, 2022
9547505
no changes, just me being dumb
Aug 3, 2022
17be5ad
re-introduced channel and measurement mapping
Aug 3, 2022
463d7a9
Cosmetic changes
Aug 3, 2022
98eb07a
Changed output of analyzer back to log scale. Plotter no longer plots…
Aug 10, 2022
fde53cd
Fixed measure3D. The new data is now added to the correct location
Aug 10, 2022
fd0943f
shutdown hoock fixed
Daniel-AG-WW Aug 24, 2022
55bc322
beta Version 3 of ADwin
Daniel-AG-WW Aug 31, 2022
71dc1a3
Saver_json now updates sub-dictionaries as well
Sep 2, 2022
daa0ea6
_choose_measurement_function now supports pulse_parameter, timetrace …
Sep 2, 2022
17d13b3
fixed merge conflict
Sep 2, 2022
17f2fad
fixed another merge conflict
Sep 2, 2022
1043469
working version V3
Daniel-AG-WW Sep 7, 2022
d9805c0
\n added in sequencer
Daniel-AG-WW Sep 7, 2022
669f4d0
Saver_json creates folder if does not exist, postanalysis script update
Sep 15, 2022
48c0b8a
Appends to files per default now
Sep 15, 2022
b445e77
class tuneSET: finding the working point of a SET
phi-tis Sep 27, 2022
c875739
added user interaction in peakfinder and a test version of the find
phi-tis Oct 13, 2022
97eb818
added a safety feature in find_oscillation_window to avoid high demod
phi-tis Oct 17, 2022
0a642da
continuous readout working
Daniel-AG-WW Oct 18, 2022
2c12195
Merge branch 'master' of git.scc.kit.edu:nanospin/semispin/qkit
Daniel-AG-WW Oct 18, 2022
c670821
alpha
Daniel-AG-WW Oct 20, 2022
b1f83d9
More user-friendly plot of the good peaks. Below_cutoff criterium
phi-tis Oct 20, 2022
f994774
pulse readout working
Daniel-AG-WW Oct 20, 2022
49b9711
tuneSET of Thomas added in order to pull
Daniel-AG-WW Oct 20, 2022
7a8150e
loacal changes on phi-ndus commited in order to finally pull
Daniel-AG-WW Oct 20, 2022
94a506c
Merge branch 'master' of https://git.scc.kit.edu/nanospin/semispin/qkit
phi-tis Oct 27, 2022
cd11e59
deleted
phi-tis Oct 27, 2022
11b9634
Changed restore_accumulation method. Instead of first making the 2
phi-tis Oct 27, 2022
a3241ec
removed typo
phi-tis Oct 27, 2022
d3feb4e
new method set_barriers_to_peak_value, find_peaks_in_2D_sweep does no…
phi-tis Oct 27, 2022
9ebf1e1
find_oscillation_window: handling the first iteration differently: in…
phi-tis Oct 27, 2022
a074f84
visualization of the tuning process, any change of gate voltages
phi-tis Oct 27, 2022
0a8d916
updated visualization of tuning process
phi-tis Oct 28, 2022
cfd7baa
degugging with sample
Daniel-AG-WW Nov 3, 2022
914f0c4
Merge branch 'tuneSET' debugged tuneSET.py with sample
Daniel-AG-WW Nov 3, 2022
65aad48
removed some prints
Daniel-AG-WW Nov 3, 2022
297fa3b
set default value of accumulation_value and shutoff_value to none, to…
phi-tis Nov 4, 2022
97b4213
Additional arguments are now optionally passable to PlotterTimetraceS…
Nov 14, 2022
ca8327b
Fixed bug in analyzer
Dec 2, 2022
b3b9328
averaging in triggered readout implemented
Dec 2, 2022
e6ef0eb
lokal changes on Phi-ndus
Daniel-AG-WW Dec 8, 2022
71c1205
local changes on Phi-ndus
Daniel-AG-WW Dec 8, 2022
3b7329e
averaging debuged
Daniel-AG-WW Dec 8, 2022
9e9d89d
readout backend debuged
Daniel-AG-WW Dec 8, 2022
3a6fae0
Logging string for direct gate logging change to actual name. Should …
Dec 16, 2022
84c2798
Spin excite was updated to new gate_string
Dec 16, 2022
e7e592c
made the gate search strings accesible to the user. Will show additio…
Dec 16, 2022
e0fc044
Added the change_averages command to spin_excite, to change the avera…
Dec 16, 2022
221f738
fixes
Daniel-AG-WW Dec 19, 2022
a68e1c9
Merge branch 'master' of https://git.scc.kit.edu/nanospin/semispin/qkit
Daniel-AG-WW Dec 19, 2022
5e235ba
logging string ignore added
Daniel-AG-WW Dec 19, 2022
c6083af
Added change averages function
Dec 19, 2022
613ee55
Merge branch 'master' of git.scc.kit.edu:nanospin/semispin/qkit
Dec 19, 2022
17dd200
Changed parameter search. Type abc89814def for you parameter now. 898…
Dec 19, 2022
a02e242
Change averages now supports measurement mapping
Dec 20, 2022
73b1922
created frst draft for new _stream1D function without averaging
Dec 20, 2022
4cb3cb4
I dunno wut i just did. came back from holidays 2day, but file was ch…
Jan 9, 2023
cdf7caf
Unknown changes to loader
Jan 24, 2023
efd9404
Iterations parameter integrated into the spin excite architecture
Jan 24, 2023
9115b3f
Single timetrace streaming is now available. Use 'no_avg' mode.
Jan 27, 2023
a05b3fb
Fixed little mode bug
Feb 1, 2023
795895c
beta of MFLI drivers adapted from UHFLI drivers
Feb 2, 2023
548b27f
merge master, no changes
Feb 2, 2023
cc2ba1d
Merge branch 'master' of git.scc.kit.edu:nanospin/semispin/qkit
Feb 2, 2023
32e317d
beta of MFLI drivers of UHFLI clone added
Feb 2, 2023
fa20aae
git tackle nan - None problem
Daniel-AG-WW Feb 8, 2023
5c615ee
find peaks in 2D sweeps for specific file
Daniel-AG-WW Feb 8, 2023
28e514e
merge of github qkit and gitlab semicon_qkit
Feb 9, 2023
0f8d703
MFLI 1.0
Daniel-AG-WW Feb 10, 2023
86f42b8
Removed spyders .bak files from repo
Feb 13, 2023
0b8273b
Removed redundant loader in loaderh5
Feb 13, 2023
0ca53b6
Loaderh5 hotfixes
Feb 13, 2023
4c4319f
Merge branch 'master' of https://github.com/ThomasK-AGWW/Semicon_qkit
Feb 13, 2023
c3cab8a
temporary Hack funktion to HDAWG driver added
Daniel-AG-WW Feb 17, 2023
07d31ef
removed deprecated check_center criterium from findpeaks_in_2D_sweep …
Mar 1, 2023
f55c1ba
Moved new AWG function to branch AWG_tweaks where it can be developed…
Mar 1, 2023
41fd374
basic functions for SMW200A implemented
Daniel-AG-WW Mar 3, 2023
0848281
initialization Vs after ADwin crash added and working
Daniel-AG-WW Mar 7, 2023
d7ffe3e
ramping down of outputs after reboot taken out
Daniel-AG-WW Mar 20, 2023
eb872f0
spin_excite hotfix: All averages are now weighed equally
Mar 31, 2023
8893b69
excite first trigger bug and continuous crashing fixed
Daniel-AG-WW Apr 3, 2023
757006c
coil params ignored from now on
Daniel-AG-WW Apr 3, 2023
791ffe0
spin_excite hotfix, empty data is now handled correctly.
Daniel-AG-WW Apr 12, 2023
57e81e8
spin_excite hotfix, removed debug messages.
Daniel-AG-WW Apr 12, 2023
9183cbe
moku driver and backends added
Daniel-AG-WW Apr 15, 2023
2768bd9
removed coil_params version control
Daniel-AG-WW Apr 15, 2023
33e3e7f
removed coil_params from version control
Daniel-AG-WW Apr 15, 2023
96622d8
Rename ADwin_Pro2_coil_params.py to ADwin_Pro2_coil_params_template.py
ThomasK-AGWW Apr 15, 2023
a5fbf94
coil_params_template
Daniel-AG-WW Apr 15, 2023
da3d204
Different update rates added
Daniel-AG-WW Apr 15, 2023
8bf16c3
Documentation enriched
Daniel-AG-WW Apr 26, 2023
59b726a
WIP Modular modes
May 11, 2023
43d7cdc
10kHz averaging in spin-excite added
Daniel-AG-WW May 12, 2023
b0919a6
Started working on the ModeBase ModeChild structure
May 12, 2023
07755bf
WIP
May 16, 2023
29944cf
Averaging doubling bug fixed
Daniel-AG-WW May 23, 2023
1a08ff9
First working version of modular spin_excite
May 24, 2023
efb7bd0
measure2D working. Fixed bug in filehandler where datasets where not …
May 25, 2023
ca44393
Measure3D working, Mode multiplexing as well
May 26, 2023
e18af80
Modular modestructure fully implemented
Jun 2, 2023
006cd34
NoAvg WIP
Jun 7, 2023
1054499
Fixed idref count bug, implemented PulseParameter and NoAvg. Fixed Fi…
Jun 16, 2023
4460b4a
PpvsT added
Jun 16, 2023
197a7c5
TimeTrace mode added
Jun 16, 2023
1877cc1
simplified the coordinate and dataset creation process for the modes
Jun 23, 2023
2de3143
Removed the continue statement where non necessary.
Jun 26, 2023
5d91160
Fixed merge conflict
Jun 26, 2023
3396e5d
Added the ability to name measurements back into spin_excite
Jul 14, 2023
b153089
Hotfix active_modes
Jul 14, 2023
7e1d787
Settings now takes backend as contructor arguments, reducing code cou…
Jul 17, 2023
0af1e25
Fixed Naming for windows, won't use colons in filenames anymore, mino…
Jul 19, 2023
5e4dce9
Moku bug fixes by Thomas
Daniel-AG-WW Aug 8, 2023
82f4b4b
minor changes in ADwin excite
Daniel-AG-WW Aug 8, 2023
f7e3d44
hi removed - sorry Julian
Daniel-AG-WW Aug 8, 2023
0bfd658
Moku compile qupulse removed
Daniel-AG-WW Aug 8, 2023
25b04c6
Adwin minor trigger delay added
Daniel-AG-WW Aug 8, 2023
4bd0ee4
Updated error message for active_modes.setter
Aug 8, 2023
177f48d
Merge branch 'master' of https://github.com/ThomasK-AGWW/Semicon_qkit
Aug 8, 2023
ed89186
Modes are now reset upon measurement abort
Aug 29, 2023
7c069a6
Bugfix, added qviewkit optional, modes choosable
Aug 31, 2023
ec99318
get_Bfield added
Daniel-AG-WW Nov 8, 2023
93c56f1
Treiber für AnaPico
Daniel-AG-WW Nov 23, 2023
2a0ec94
Treiber für AnaPico mit on off
Daniel-AG-WW Nov 23, 2023
8978a7e
Merge branch 'master' of https://github.com/ThomasK-AGWW/Semicon_qkit
Daniel-AG-WW Nov 23, 2023
67e77e5
bugs fixed in: on() and off()
Daniel-AG-WW Nov 25, 2023
bae712c
Latest drivers of Idefix
Daniel-AG-WW Nov 27, 2023
aea2144
Important line missed in Adwin driver for triggered readout
Daniel-AG-WW Nov 27, 2023
4bfd479
Important was too much in Adwin driver for triggered readout
Daniel-AG-WW Nov 27, 2023
5466461
Fixed the plotting of triggers and -finally- renamed plot to plut.
Feb 1, 2024
7710031
... and updated the docstring :)
Feb 1, 2024
fd1935a
First driver, continuous working
Daniel-AG-WW Apr 4, 2024
f93bf39
Merge branch 'master' of https://github.com/ThomasK-AGWW/Semicon_qkit
Daniel-AG-WW Apr 4, 2024
5d911fd
Changed pulse modulation names and added additional info
Apr 4, 2024
b476dad
Adaptation of driver to only load waveforms up to wave2 in core 0 usi…
Daniel-AG-WW Apr 4, 2024
5b61845
Merge branch 'master' of https://github.com/ThomasK-AGWW/Semicon_qkit
Apr 5, 2024
6911b64
ADwin Pro2 basic files added. In seperate folder
Daniel-AG-WW Apr 8, 2024
7429f7c
Merge branch 'master' of https://github.com/ThomasK-AGWW/Semicon_qkit
Daniel-AG-WW Apr 8, 2024
1f920df
ignore coil params of ADwin_Pro
Daniel-AG-WW Apr 8, 2024
b36775d
set_field_2d_xy_compensated added
Daniel-AG-WW May 13, 2024
99ca020
add first version of adwin driver
kaptnkapton May 14, 2024
5adbb05
add working_point class for magnetoconductance measurements
kaptnkapton May 14, 2024
802d0e9
add raise error when nan adwin output
May 15, 2024
9158200
reformatting
May 15, 2024
07ccf3f
Merge branch 'master' of https://github.com/ThomasK-AGWW/Semicon_qkit
AngryRabbitChicken May 15, 2024
5002d6a
semiconductor.utils.qupulse_tools.plut now works as intended plotting…
AngryRabbitChicken May 15, 2024
8b2536d
added upload_waveform and updated according to new zhinst library
May 22, 2024
31ebecd
Merge branch 'master' of https://github.com/ThomasK-AGWW/Semicon_qkit
May 22, 2024
2b54003
Bugfix: hard_config dict gets overwritten by function
May 23, 2024
0e50d0a
updated module docstring
May 23, 2024
9f4a98d
prevent adding unconfigured channels
May 23, 2024
6aaf6c4
set_field_2d_xy_compensated added
Daniel-AG-WW Jun 3, 2024
8f341b6
Update io_handler.py
kaptnkapton Jun 3, 2024
7da9398
reduced jitter by adbasic optimization
kaptnkapton Jun 3, 2024
9962031
implemented lockin readout while not communicating with adwin
kaptnkapton Jun 3, 2024
074df92
remove debug print command
Jun 3, 2024
fb89119
unified 'lockin' and 'lockin dc' mode
kaptnkapton Jun 5, 2024
b408b55
Merge branch 'st_adwin_driver_implementation' of https://github.com/A…
kaptnkapton Jun 5, 2024
ff9d421
remove start_data and use Par1-Par8 instead
kaptnkapton Jun 5, 2024
a8e2760
bugfix: read_outputs
PeffeFejes Jun 5, 2024
525a45f
Merge branch 'st_adwin_driver_implementation' of github.com:AG-WoWe/q…
PeffeFejes Jun 5, 2024
ca4d569
implemented Par_1-Par_8 as output buffer instead of START_DATA
kaptnkapton Jun 5, 2024
0dd5cda
unified all adbasic files to sweep.TB2 and lockin.TB1
kaptnkapton Jun 10, 2024
8448c86
unified dc and lockin measurement mdes
kaptnkapton Jun 12, 2024
d151d3d
changed input to channel 8
kaptnkapton Jun 14, 2024
a05c90f
added sleep for correct sequencer upload and moved initialization
Jun 14, 2024
0ef0728
corrected sleep timing for waveform upload
Daniel-AG-WW Jun 18, 2024
b7a9aed
changed timings
Daniel-AG-WW Jun 18, 2024
f54ca07
first version of full measurement routine for ST
Jun 20, 2024
fdaabf3
changed duration input to rate for sweep
Jun 25, 2024
3e03e11
add view for trace and retrace in one plot
Jun 25, 2024
9e4bb02
allow only one instance of adwin
Jul 3, 2024
7264cf9
add default adwin config
Jul 3, 2024
56f82b9
add all functions for measurement, without external getter or setter …
Jul 3, 2024
d783657
delete view creation, now implemented in MeasurementScript
Jul 3, 2024
0331aaf
add constants for analysis
Jul 3, 2024
d9905fd
add class for analysis dataset similar to hdf_view
Jul 3, 2024
e242e84
add function for adding an analysis dataset with new class in hdf_ana…
Jul 3, 2024
55700f2
delete last changes, not nessesary
Jul 4, 2024
659e0c0
fixing errors and set adwin instrument as input
Jul 4, 2024
2d9edaa
delete dataset and datafile preparation, now in measurement_script
Jul 4, 2024
a372eb7
fix errror for adding analysis datasets
Jul 4, 2024
03f932e
add data folder to gitignore
Jul 4, 2024
9ff7717
gi
PeffeFejes Jul 9, 2024
0398cb3
add progressbar for single 2D measurement, add possibility for easy m…
Jul 9, 2024
5855c54
fix error, where sweep rate is not used correct
Jul 10, 2024
48a5ec6
add save/load config in/from .h/hdf5 file
Jul 11, 2024
67f23ef
add measurement config dataset and load config from .h/hdf5 file
Jul 11, 2024
c674211
reduce saved information in analysis dataset to needed minimum
Jul 11, 2024
5db1181
del unnecessary function for create analysis dataset, add new view ->…
Jul 13, 2024
0887e0c
del wrong import from deleted file
Jul 13, 2024
98b5053
fix errors in polarview and live polar plot
Jul 13, 2024
f3df981
correct maximal sweep rate of magnetic field
Jul 15, 2024
fdc91b2
add comments to measurement script class
Jul 15, 2024
72a7be4
correct error, where plot view on dataset could not be changed
Jul 15, 2024
87748c5
add polar colormap save plot, del grid and rticks from polarplot
Jul 17, 2024
0a25795
add missing sweep duration update if set duration is ot valid
Jul 17, 2024
e497d32
remove unnecessary changes on measurement base for easier merge witho…
Jul 26, 2024
675a4ce
Change in program structure for simpler explanation
Aug 10, 2024
b5689ec
correct errors from restructuring
Aug 12, 2024
2bf1460
Added waveform upload for 2x2 mode
Sep 11, 2024
273372b
Waveupload 2x2 over array
Sep 11, 2024
a390fa3
Updated Version for upload waveform
Sep 12, 2024
da967a2
New manipulation backend for upload waveform
Sep 12, 2024
d594590
Changed wave_data dictionary to match HDAWG driver. Added failsave fo…
Daniel-AG-WW Sep 19, 2024
3139d4b
v_range modified
Daniel-AG-WW Oct 24, 2024
acfe440
the console output can now be turned off
Daniel-AG-WW Oct 30, 2024
d54ddb5
added wait wave to sequencer code
Daniel-AG-WW Oct 30, 2024
eab9b2f
Trigger 2 inverted by Sitter
Daniel-AG-WW Dec 3, 2024
f60729a
changed marker encoding to bits (hotfix)
Daniel-AG-WW Dec 4, 2024
28369d7
added logging of voltage offset
Dec 16, 2024
ccf6ba7
removed #
Dec 16, 2024
473ef38
added ramping of voltage offset
Dec 17, 2024
d1bd38f
Merged changes from upstream master
Jan 14, 2025
4bda532
Merged changes from semicon_qkit fork
LucasBeyens Jan 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README_SEMISPIN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Added drivers by SemiSpin group:
* ADwin Pro II driver(s):
*
272 changes: 272 additions & 0 deletions qkit/analysis/semiconductor/analyzers/AnalyzerPeakTracker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
from typing import Any, Dict, List

import numpy as np
from qkit.analysis.semiconductor.main.fit_functions import sech
from scipy.signal import find_peaks, peak_widths
from scipy.optimize import curve_fit

class ItsAllDanielsFaultError(Exception):
pass

class Peak_fit:
"""Class for peak fits. Takes a callable argument f and assumes f(x, height, width, position) -> Peak.
width ist the full-width-half-maximum of Peak."""
def __init__(self, fit_func):
self.fit_func = fit_func
self.min_peak_height = 0.002
self.min_peak_width = 2
self.min_peak_distance = 30
self.fit_interval_peak_relheight = 0.5

@property
def fit_interval_peak_relheight(self):
return self._fit_interval_peak_relheight
@fit_interval_peak_relheight.setter
def fit_interval_peak_relheight(self, new_height):
self._fit_interval_peak_relheight = new_height
if new_height == 0.5: self.find_fit_interval = self._calc_fit_interval_peak_width
else: self.find_fit_interval = self._calc_fit_interval_rel_height

def construct_guess(self, single_trace):
self.peak_pos, params = find_peaks(single_trace, height = self.min_peak_height,\
width = self.min_peak_width,\
distance = self.min_peak_distance)
self.peak_heights = params["peak_heights"]
self.peak_fwhms = peak_widths(single_trace, self.peak_pos, rel_height = 0.5) [0]

def _calc_fit_interval_rel_height(self, single_trace):
self.fit_idxs_left, self.fit_idxs_right = np.rint(\
peak_widths(single_trace, self.peak_pos, \
rel_height = self.fit_interval_peak_relheight)\
[2:]).astype(np.int_)

def _calc_fit_interval_peak_width(self, single_trace):
self.fit_idxs_left = np.rint(self.peak_pos - self.peak_fwhms / 2).astype(np.int_)
self.fit_idxs_right = np.rint(self.peak_pos + self.peak_fwhms / 2).astype(np.int_)

def fit(self, single_trace):
self.construct_guess(single_trace)
self.find_fit_interval(single_trace)

x = range(len(single_trace))
popts, covs = [], []

for i in range(len(self.peak_pos)):
guess = (self.peak_heights[i], self.peak_fwhms[i], self.peak_pos[i])
try:
popt, cov = curve_fit(self.fit_func, x[self.fit_idxs_left[i] : self.fit_idxs_right[i]],
single_trace[self.fit_idxs_left[i] : self.fit_idxs_right[i]],
p0 = guess, maxfev = 10000)
except TypeError:
raise TypeError(f"{__name__}: Fit interval for peak {i} does not contain enough data points. Reconsider the min_peak_width.")
popts.append(popt)
covs.append(cov)

return popts, covs

def sech_fwhm(x, a, b, c):
return sech(x, a, b /2.634, c)

class Analyzer:
def __init__(self, matrix_to_analyze, timestamps, gate_axis, peak_function = sech_fwhm) -> None:
self.pf = Peak_fit(peak_function)

self.matrix_to_analyze = matrix_to_analyze
self.timestamps = timestamps
self.gate_axis = gate_axis

self.rel_jump_height = 0.2
self.f_clock = 1.8e9
self.LR_offset = 0

@property
def matrix_to_analyze(self):
return self._matrix_to_analyze
@matrix_to_analyze.setter
def matrix_to_analyze(self, new_matrix):
if not isinstance(new_matrix, np.ndarray):
raise TypeError(f"{__name__}: Invalid data matrix. Must be a 2D numpy array.")
if new_matrix.ndim != 2:
raise ValueError(f"{__name__}: Invalid data matrix. Must be a 2D numpy array.")
self._matrix_to_analyze = new_matrix

@property
def timestamps(self):
return self._timestamps
@timestamps.setter
def timestamps(self, new_stamps):
if not isinstance(new_stamps, np.ndarray):
raise TypeError(f"{__name__}: Invalid timestamps. Must be a 2D numpy array.")
if new_stamps.shape != self.matrix_to_analyze.shape:
raise ValueError(f"{__name__}: Invalid timestamps. Must have the same shape as matrix_to_analyze.")
self._timestamps = new_stamps

@property
def gate_axis(self):
return self._gate_axis

@gate_axis.setter
def gate_axis(self, new_axis):
if not isinstance(new_axis, np.ndarray):
raise TypeError(f"{__name__}: Invalid gate_axis. Must be a numpy array.")
if len(new_axis) != len(self.matrix_to_analyze[0]):
raise ValueError(f"{__name__}: Invalid gate_axis. Must have the same length as a trace from matrix_to_analyze.")
self._gate_axis = new_axis

def _append_to_nearest(self, tracked_positions, position):
distances = []
for last_positions in tracked_positions:
distances.append(abs(np.average(last_positions[-5:]) - position))

idx = distances.index(min(distances))
tracked_positions[idx].append(position)

def _append_to_nearest_2(self, tracked_positions, positions):
forbidden_tracks = []
for position in positions:
distances = []
for last_positions in tracked_positions:
distances.append(abs(np.average(last_positions[-5:]) - position))
idx = distances.index(min(distances))
if idx not in forbidden_tracks:
tracked_positions[idx].append(position)
forbidden_tracks.append(idx)

def _find_nth_smallest(self, array, n):
nth_smallest = np.partition(array, n)[n]
idx = np.where(array == nth_smallest)[0][0]
return idx

def _append_to_nearest_3(self, peak_tracks, positions):
forbidden_tracks = []
for peak_track in peak_tracks:
#Calculate the distance of each newly found peak to the average of the
#last five positions.
distances = []
peak_track_avg = np.average(peak_track[-5:])
for position in positions:
distances.append(peak_track_avg - position)

distances = np.array(distances)
abs_distances = abs(distances)

#Append the value to one of the peak_tracks based on conditions:

#Did the peak position change by more then self.rel_jump_height * 100 percent?
sub_cond11 = (abs_distances > (peak_track_avg * self.rel_jump_height)).all()
sub_cond12 = (distances < 0).any()
sub_cond13 = len(distances) >= 2
condition1 = sub_cond11 and sub_cond12 and sub_cond13
if condition1:
#If this is the case, the jump went up therefore append the closest position
#above the current one.
idx = self._find_nth_smallest(abs_distances, 1)
#elif condition2:
# ...
else:
idx = abs_distances.argmin()

if idx not in forbidden_tracks:
peak_track.append(positions[idx])
forbidden_tracks.append(idx)

def _translate_samples(self, tracked_positions : List[List[float]]) -> List[List[float]]:
v_offset = self.gate_axis[0]
v_step = self.gate_axis[1] - v_offset
translated_tracks = []
for track in tracked_positions:
trans_track = v_step * np.array(track) + v_offset
translated_tracks.append(trans_track)
return translated_tracks

def _create_time_axis_avg(self):
durations = []
for timestamps in self.timestamps:
duration_of_trace = timestamps[-1] - timestamps[0]
durations.append(duration_of_trace)
translated_durations = np.array(durations)/self.f_clock
avg_duration = np.average(translated_durations)
time_axis = np.arange(0, len(translated_durations)) * avg_duration
return time_axis

def analyze(self) -> Dict[str, Any]:
raw = self.matrix_to_analyze

tracked_positions = []
trace = self.matrix_to_analyze[0]
peak_pars, _ = self.pf.fit(trace)
for peak_par in peak_pars:
peak_pos = peak_par[2]
tracked_positions.append([peak_pos])

for trace in raw[1:]:
peak_pars, _ = self.pf.fit(trace)
peak_pos = [peak_par[2] for peak_par in peak_pars]
self._append_to_nearest_3(tracked_positions, peak_pos)

peak_pos = self._translate_samples(tracked_positions)
time_axis = self._create_time_axis_avg()
return {"tracked_peak_positions" : peak_pos, "time_axis" : time_axis}

def main():
pass
if __name__ == "__main__":
main()
# from scipy.signal import find_peaks, peak_widths
# from scipy.optimize import curve_fit
# from random import uniform

# def sech(x, a, b, c):
# return a / np.cosh((x - c) / b)

# def multi_sech(x, *params):
# y = np.zeros_like(x)
# for i in range(0, len(params), 3):
# a = params[i]
# b = params[i+1]
# c = params[i+2]
# y = y + sech(x, a, b, c)
# return y

# def create_jitter(amplitude):
# return uniform(-amplitude, amplitude)

# xdata = np.linspace(-40, 40, 1000) # create x_axis
# x_step = xdata[1] - xdata[0]
# rng = np.random.default_rng()
# y_noise = 0
# y_noise = 0.1 * rng.normal(size=xdata.size) # create some noise

# jitter_ampl = 0
# y = multi_sech(xdata, 1, 1, 30 + create_jitter(jitter_ampl),
# 1, 1, 15 + create_jitter(jitter_ampl),
# 1, 3, -30 + create_jitter(jitter_ampl),
# 1, 1, -15 + create_jitter(jitter_ampl))
# ydata = y + y_noise

# peak_pos, params = find_peaks(ydata, height = 0.5, width = 6)
# results = peak_widths(ydata, peak_pos, rel_height=0.5)
# peak_widths = results[0] * x_step / 2.634
# no_peaks = len(peak_pos)
# print(f"peak_widths: {peak_widths}")
# print(f"peak_pos: {xdata[peak_pos]}")
# lower_bounds = [0, 0, -np.inf] * no_peaks
# upper_bounds = [np.inf, np.inf, np.inf] * no_peaks
# bounds = (lower_bounds, upper_bounds)
# print(bounds)
# guess = []
# for peak, height, width in zip(xdata[peak_pos], params["peak_heights"], peak_widths):
# guess.extend([height, width, peak])
# print(guess)
# #guess = [1, 1, 0, 1, 1, 20, 1, 1, -8, 1, 1, -15]
# popt, pcov = curve_fit(multi_sech, xdata, ydata, p0 = guess, bounds = bounds, maxfev = 1000)

# plt.figure()
# plt.plot(np.arange(len(ydata)) * x_step - 40, ydata)
# plt.plot(xdata, multi_sech(xdata, *popt), 'r-')
# for i in range(len(results[1:][0])):
# y = results[1:][0][i]
# x_min = results[1:][1][i] * x_step + xdata[0]
# x_max = results[1:][2][i] * x_step + xdata[0]
# plt.hlines(y, x_min, x_max, color ="C2")
# print(popt)
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import numpy as np
from scipy.optimize import curve_fit

from qkit.analysis.semiconductor.main.find_index_of_value import map_array_to_index
from qkit.analysis.semiconductor.main.time_conversion import convert_secs_2D


class AnalyzerPeakTracker:
"""Fits a sechans function to a plunger gate sweep in two iterations.
"""
def __init__(self) -> None:
self.init_params = None
self.intervall1 = 0.01
self.intervall2 = 0.01
self.max_iter = 10000
self.peak_voltage = 0

def analyze(self, data:dict, nodes):
"""self.peak_voltage is the Voltage of the peak eyeballed.
width and width2 are the intervalls of idices used to fit the data to. Better in Volts in future?
The sechans fit is NOT using Volt values as x values but instead indices of the array.
init_params: first values [a, b, d] of f(x) = a * (1 / np.cosh(b * (x - c))) + d
self.peak_voltage: first value of c
"""
def sech(x, a, b, c, d):
'''hyperbolic secans function'''
return a * (1 / np.cosh(b * (x - c))) + d # return is scaled in Volts

if self.init_params is None:
# initial parameters for fit
a, b, d = 0.01, -0.1, 0.0
else:
a, b, d = self.init_params[0], self.init_params[1], self.init_params[2]

peak_index = map_array_to_index(data[nodes[1]], self.peak_voltage)
intervall1_half_index = map_array_to_index(data[nodes[1]], abs(self.intervall1 / 2) + data[nodes[1]][0])
intervall2_half_index= map_array_to_index(data[nodes[1]], abs(self.intervall2 / 2) + data[nodes[1]][0])

p0 = [a, b, peak_index, d] #initatal guess of a, b, c, d
timestamps = convert_secs_2D(data[nodes[0]])
length_sweep = len(timestamps)
data["timestamps_diff"] = np.diff(timestamps)
data["avg_sweep_time"] = np.average(np.diff(timestamps))
data["peaks_plunger_V"] = np.array([None] * length_sweep) # initialize None array for peaks
data["peaks_value"] = np.array([None] * length_sweep)
data["peaks_plunger_V_cov"] = np.array([None] * length_sweep)
data["peaks_fit_popts"] = np.array([None] * length_sweep)
data["peaks_fit_intervall_half"] = intervall2_half_index # saves the index size of the fit intervall/2

for trace_num in range(len(timestamps)):
try:
# bigger intervall, first fit
popt, pcov = curve_fit(sech, np.arange(peak_index-intervall1_half_index, peak_index+intervall1_half_index, 1),
data[nodes[2]][trace_num][peak_index-intervall1_half_index : peak_index+intervall1_half_index], p0, maxfev=self.max_iter)
peak_fitted_index = int(round(popt[2]))

try:
# smaller intervall, second fit around peak of first fit
if peak_fitted_index > intervall2_half_index and peak_fitted_index < (length_sweep-intervall2_half_index):
p1 = [a, b, peak_fitted_index, d]

popt1, pcov1 = curve_fit(sech, np.arange(peak_fitted_index-intervall2_half_index, peak_fitted_index+intervall2_half_index, 1),
data[nodes[2]][trace_num][peak_fitted_index-intervall2_half_index : peak_fitted_index+intervall2_half_index], p1, maxfev=self.max_iter)

data["peaks_plunger_V"][trace_num] = data[nodes[1]][int(round(popt1[2]))] # plunger gate voltage of peak
data["peaks_value"][trace_num] = sech(popt1[2], *popt1) # lock-in value of fitted peak
data["peaks_plunger_V_cov"][trace_num] = pcov1 # covariance on index of peak
data["peaks_fit_popts"][trace_num] = popt1 # values of [a, b, c, d]

if pcov1[2][2] > 1:
print("COV TOO BIG ", trace_num)
data["peaks_plunger_V"][trace_num] = None
data["peaks_value"][trace_num] = None
data["peaks_plunger_V_cov"][trace_num] = None
data["peaks_fit_popts"][trace_num] = None

else:
print("Peak not found in first fit")
data["peaks_plunger_V"][trace_num] = None
data["peaks_value"][trace_num] = None
data["peaks_plunger_V_cov"][trace_num] = None
data["peaks_fit_popts"][trace_num] = None


except RuntimeError:
print("RUNTIME ERROR second ", trace_num)
pass

except RuntimeError:
print("RUNTIME ERROR first ", trace_num)
pass

Loading