qt3uw / qt3-utils Goto Github PK
View Code? Open in Web Editor NEWData Acquisition for Confocal Microscope and Spin Control Experiments
Home Page: https://sites.google.com/uw.edu/qt3-lab/projects
License: BSD 3-Clause "New" or "Revised" License
Data Acquisition for Confocal Microscope and Spin Control Experiments
Home Page: https://sites.google.com/uw.edu/qt3-lab/projects
License: BSD 3-Clause "New" or "Revised" License
Want to remove reset-daq calls at the beginning of scans.
A reset affects all channels, including analog output channels. This will have significant side-effects, like moving the piezo actuator stage.
tqdm?
After zooming with the magnifier, then selecting a position and clicking 'go to position'. when returning to full scan with the 'home' button, the full y range is no longer visible. not sure if the data is gone, or if the y scale is incorrect.
possibly related to the extent
option in the imshow call (?) the extent uses model.current_y.
might need to create a fixed size array and fixed scan parameters, then sequentially update the data. right now, at reset, the data array
is emptied and we append with each scan of x. possibly cleaner to create data array with full size at the beginnng on scan.
While still retaining the explicit start and stop functionality, creating context manager for the object will assist (ensure?) proper cleanup of nidaq tasks after exceptions.
The qt3scan application should have a button that allows the user to hold open the AOM with the PulseBlaster, rather than needing to do that manually.
Adds a button "Hold AOM with PB" and an entry for the pulse blaster channel number (default 0)
Or perhaps a label "Hold AOM with PB", followed by a checkbox, followed by the channel number.
Would like the ability to keep a scan's data on screen and run a new scan in order to compare scans.
One idea is to have a 'pop out' button, that builds a figure in a separate window.
Right now, the selected position in the qt3scan GUI are labels.
These should be 'entry' widgets so that one can directly enter the position to 'go to' if needed.
We should probably switch to continous data acquisition and add start/stop functionality to NI daq objects. This will likely speed up data acquistion considerably.
Then, in the qt3scan device, we should add DAQ start/stop buttons. This will block other applications, but as long as there's a stop button in order to disengage the DAQ (that is, close out DAQ related tasks), that should be sufficient
Confocal scans should be saved with more information than is currently saved.
Presently we only save the measured count rates in a simple 2D numpy array.
Ideally, we should save the following per stage position
into a 2D array.
Additionally, at a minimum we should save the scan range and resolution. And we could envision the usefulness of also saving other data acquisition parameters, such as clock sample rate, and number of clock samples per position.
There is also a push to save data in hdfs format - see issue #67 - which we could consider doing in this ticket.
To accomplish these goals we would need to
If we work on this issue, then Issue #67 and Issue #35 should be closed. Or Issue #67 can be re-written just to define the work to incorporate the qt3experimentmanager tool.
Build integration with the qt3experimentmanager repository to save data to hdfs, and add features to the GUI to specify sample name, scan name, etc.
the analysis functions for cwodmr, poems, rabi, etc, currently need to have some knowledge of the timing of signal and background parts of the recorded data.
a lock-in amplifier solution may be a robust way of analyzing the data with minimal number of parameters. Only one parameter would be needed -- a time value that bifurcates the signal and background portions of the recorded data. The lock-in amplifier technique is to convolve the first half of the signal with a +1 and the second half of the signal with a -1, then integrate the entire recorded trace.
use the side panel to display running average count rate (over some reasonable recent time range)
Previously we've changed the 'rf_width' variable name to 'rf_pulse_duration' as requested. However, the variables for other channels still use "width", such as "aom_width" and "trigger_width". We should change the names of these values to "X_pulse_duration" as well for consistency
should be a refresh z button so that the z entry widget value can be updated
automatically instead of needed to manually enter
noticed that the qt3scan crashed when setting the color
simple fix will be to grey out the set color and log options until scan is complete.
or perhaps try/catch will appropriately fix.
There are still many methods and functions that need docstrings
Instead of creating new windows for each optimize call, reuse the window.
we want to be able to refresh the go to position entry values with the current optimal position.
add button to left (or below) current 'go to position'
'refresh to current' ?
Currently there are no checks in the code to ensure the various pulses do not generate laser / rf signals that overlap in unexpected ways. That is, it's possible to provide settings where the rf signal width + aom width are greater than the total width of the full pulse cycle.
We should add checks to the code to ensure that pulses sequences are not generated that overlap.
When running an optimize scan about a position, if the range exceeds the limits (0, 80 microns), the application crashes without a response
'rf_width' is not descriptive enough for users to understand.
Need to change to something like 'rf_pulse_duration' or similar. Discuss with KMF to determine best name.
The qt3rfsynthcontrol package was built in order to encapsulate specific configurations of the windfreak synth hd pro device.
However, in the current implementation of qt3-utils experiments (CW- or p-ODMR), the frequency and power of the MW source is fixed while data are acquired, which only requires two simple commands to the synth hd pro. There already exists a python package called windfreak
, upon which qt3rfsynthcontrol
is built. It would be trivial to drop qt3rfsynthcontrol
and replace entirely with windfreak
. (Eliminating unnecessary code that would require maintenance is always a good thing.)
On the other hand, we may still want encapsulation of more advanced configurations. Initially, the sweep mode of the device was utilized in order to program the device to sweep through a range of frequencies over time. This was how the Qudi program used the device. One advantage of this mode is that it allows the experimenter to sweep through a range of MW frequencies quickly (via hardware loops rather than software loops), observe the data and continue to sweep until the desired signal to noise (contrast) is reached. In order to do this properly, it should be pointed out, we need to coordinate the frequency changes with the DAQ. This would be done by programming an appropriate trigger signal -- we would need the pulse blaster since the QC Sapphire has only 4 channels.
Having written all of that, however, without using the designated sweep mode, we can still achieve the same results and nearly the same functionality of data collection, observation, and continued sweeps until desired. One would use the CWODMR or PODMR experiment classes, instruct the system to acquire a modest amount of data for each frequency, perform the sweep, collect and append the data to an external data structure, observe the contrast and then re-run the sweep via software. This would certainly be slower, but unclear by how much slower. My intuition is that the time to obtain the desired statistical significance be dominated by the hardware configuration (laser power, collection efficiency) except for when using bright sources.
Finally, one solution would be to simply move the functions that encapsulate the code needed to program the sweep into a utility module within qt3-utils. This would reduce the code overhead / maintenance requirement of a separate package and still retain the potentially useful code in the future.
Notebooks should be re-worked after
Currently we just save the numpy array of the scan without the scan axis positions.
We could fix this through a few ways.
nidaqmx.task has a number of useful high level functions that we could utilize to simplify our code.
https://nidaqmx-python.readthedocs.io/en/latest/task.html
In particular
sometimes when the DAQ tasks are reserved, qt3scan fails to start scans, as expected. However, the only message is in the terminal and the scan buttons remain greyed out.
Ideally, a warning box would appear. At the very least, the scan buttons should return to enabled mode.
in the matlab gui there were separate optimization ranges for xy and for z. Would like to have separate range in qt3scan as well.
Upon review, there's no good reason for the sample_counts method in daqsamplers.RateBaseCounter and subclasses to have a "n_batches" option. Though unlikely, if the caller needs multiple sets of samples, they can call the function multiple times. Most (all?) of the time this function is called with n_batches = 1
We want to support both the Quantum Composer Sapphire and the Spin Core Pulse Blaster hardware in the experiment objects
To facilitate this, and other future uses, we need a more abstract layer
We should build a new submodule called pulsers
where abstract layers (interfaces) are defined and specific implementations for each hardware.
Some example interfaces and concrete classes
ODMRPulser
set_pulser_state(width)
start
stop
The ODMRPulser interface works with both CW and pulsed ODMR.
RabiPulser
set_pulser_state(freq)
start
stop
Note that one could image a more abstract interface
Pulser
set_pulser_state(*args, **kwargs)
start
stop
Concrete classes could be
QCSapphCWODMRPulser
QCSapphPODMRPulser
QCSapphRabiPulser
And similarly QCSapph --> PulseBlasterXPulser for X = CWODMR, PODMR, Rabi
The object should retain and have methods that return the actual counts per sample read.
It's critical that the sampler can return raw counts.
A method to return a rate can still exist, of course.
Could add functionality of piezo scanner to display either raw counts or count rate.
Setup auto documentation creation with sphinx: https://www.sphinx-doc.org/en/master/
sometimes the best-fit gaussian to the optimize scan results in a central location outside of the scanned range. Sometimes, very far outside of the scanned range. Add check to post-fit step to ensure central location is reasonable. ie within the scan range (~2 microns)
For the given rf amplifier in our setup, there is a recommended power regime. In particular, there is a maximum input power, beyond which device damage can occur.
This will be true for any experimental setup.
Need to add a check into code to prevent users from exceeding a particular power setting.
This could be added to experiment objects with a default value. But it could also be added to the QT3RFSynthControl object.... ? But that just controls the windfreak device, which doesn't itself have a limitation. Q - where to put this hardware check / restriction?
Add simple jupyter notebook to show how to load numpy 2d array and view with imshow.
It would be helpful to add a timestamp to the output optimization plots in the qt3scan application. This would help experimenters know which of the open windows was the most recent
Currently, show_optimization_plot
, is a method of the main application view. This function is called by the main_application app (the controller in the model-view-controller design paradigm) after running the optimization routine (which optimizes the position by searching for maximal count rate).
This function creates a new window to display the optimization. Should this function actually exist inside of the main_application controller?
All of the current experiments sweep through parameter space from low to high.
I believe that I've read that randomization of parameter values can improve contrast when randomly selecting different MW frequency values instead of sweeping contiguously through. I am pretty sure that qudi has this option in their odmr tools
Adding the option to randomly sweep through parameter space may be useful to verify/refute this claim.
The default N samples / step is 25. However, this is already a small amount of time = 250 microseconds. This is not a significant amount of time for the scan. Increasing the default data acquisition by a factor of 10 does not significantly contribute to the scan time and results in a much smoother scan.
We should increase the default value from 25 to 250
The qt3scope app hangs after pressing 'start'. An error is reported in the console, which is that the nidaq task is reserved. This can occur when using the cwodmr experiment class in an external notebook or script. However, in the current incident of this bug, the cwodmr code is supposed to close out the counter task upon completion of data acquisition.
Would be helpful to experimenter to know, with the given settings of range, N samples/step, step size, clock rate, etc. how long it will take to run a scan and how long to run optimization calls.
Display this on GUI
It would be nice to have a general pulse blaster class where a user can program an arbitrary sequence without much difficulty.
Current classes can be rewritten to use this base class.
This example notebook contains a few unnecessary and confusing parts. In particular, using the "Namespace" object was a hack that shouldn't have been there.
Remove that and type out all of the arguments explicitly because that is simpler to read.
Then review the notebook to make sure it's clear what is happening.
The object same should be more specific: NiDaqDigitalInputRateCounter
development of the oscilloscope and piezo scanner applications included new objects, based on nidaq submodule, to configure hardware and acquire data.
These new objects provide a higher-level interface and should be preferred over the more direct usage of the nidaq.config module.
Would be useful to have a run_scan function, especially for the Jupiter notebook usage.
run_scan():
start()
go_to_start_position()
while still_scanning():
scan_x
move_y
stop()
This would clean up the Jupyter notebook a tad and be useful for the user
remove aggregation.py module as this is just a simple wrapper around numpy functions, which we could move into the experiment classes.
Rename rabi.py to contrast.py and move some of the functions found in pulsed odmr example notebook to here.
Folks prefer 'gray' as default scan color - where white indicates high count rate and black indicates low count rate.
While there is a try/catch around the optimization function, it only catches nidaq errors. We should change this to handle all errors (since the piezo stage controller may also throw an error).
By adding 'classname': to the output of experimental conditions method, if that returned dictionary is used to save data in a pickle, the type of experiment will be recorded in the serialized data file.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.