move to a more standard python packaging structure
This commit is contained in:
+1
-28
@@ -13,36 +13,9 @@ DAMARIS documentation
|
|||||||
:maxdepth: 3
|
:maxdepth: 3
|
||||||
:caption: Contents:
|
:caption: Contents:
|
||||||
|
|
||||||
|
api_reference
|
||||||
manual
|
manual
|
||||||
devel
|
devel
|
||||||
|
|
||||||
#############
|
|
||||||
API Reference
|
|
||||||
#############
|
|
||||||
|
|
||||||
This API reference is generated from the source code.
|
|
||||||
|
|
||||||
***********
|
|
||||||
Experiments
|
|
||||||
***********
|
|
||||||
|
|
||||||
.. automodule:: damaris.experiments.Experiment
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
|
|
||||||
************
|
|
||||||
Data Objects
|
|
||||||
************
|
|
||||||
|
|
||||||
.. automodule:: damaris.data.Accumulation
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
|
|
||||||
.. automodule:: damaris.data.ADC_Result
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
|
|
||||||
.. automodule:: damaris.data.DamarisFFT
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
|
|
||||||
|
|||||||
+3
-16
@@ -35,27 +35,14 @@ maintainers = [
|
|||||||
[project.scripts]
|
[project.scripts]
|
||||||
DAMARIS3 = "damaris.__main__:main"
|
DAMARIS3 = "damaris.__main__:main"
|
||||||
|
|
||||||
[tool.setuptools]
|
[tool.setuptools.packages.find]
|
||||||
packages = [
|
where = ["src"]
|
||||||
"damaris",
|
|
||||||
"damaris.data",
|
|
||||||
"damaris.experiments",
|
|
||||||
"damaris.gui",
|
|
||||||
"damaris.tools"
|
|
||||||
]
|
|
||||||
|
|
||||||
[tool.setuptools.package-dir]
|
|
||||||
"damaris" = "src"
|
|
||||||
"damaris.data" = "src/data"
|
|
||||||
"damaris.experiments" = "src/experiments"
|
|
||||||
"damaris.gui" = "src/gui"
|
|
||||||
"damaris.tools" = "src/tools"
|
|
||||||
|
|
||||||
[tool.setuptools.package-data]
|
[tool.setuptools.package-data]
|
||||||
"damaris.gui" = ["DAMARIS3.png", "DAMARIS3.ico", "damaris.xml", "python.xml"]
|
"damaris.gui" = ["DAMARIS3.png", "DAMARIS3.ico", "damaris.xml", "python.xml"]
|
||||||
|
|
||||||
[tool.setuptools.data-files]
|
[tool.setuptools.data-files]
|
||||||
"share/python3-damaris/images" = ["src/gui/DAMARIS3.png", "src/gui/DAMARIS3.ico"]
|
"share/python3-damaris/images" = ["src/damaris/gui/DAMARIS3.png", "src/damaris/gui/DAMARIS3.ico"]
|
||||||
#"share/python3-damaris/doc" = ["doc/index.html"]
|
#"share/python3-damaris/doc" = ["doc/index.html"]
|
||||||
#"share/python3-damaris/doc/reference-html" = ["doc/reference-html/*"]
|
#"share/python3-damaris/doc/reference-html" = ["doc/reference-html/*"]
|
||||||
#"share/python3-damaris/doc/tutorial-html" = ["doc/tutorial-html/*"]
|
#"share/python3-damaris/doc/tutorial-html" = ["doc/tutorial-html/*"]
|
||||||
|
|||||||
@@ -107,12 +107,40 @@ class Experiment:
|
|||||||
|
|
||||||
def ttl_pulse(self, length, channel = None, value = None):
|
def ttl_pulse(self, length, channel = None, value = None):
|
||||||
"""
|
"""
|
||||||
Creates a state with length **length** and switches
|
Creates a state with length **length** and switches requested bits of the pulse programmer to HIGH.
|
||||||
requested bits of the pulse programmer to HIGH:
|
|
||||||
|
|
||||||
:param float length: pulse length in seconds
|
This command generates a TTL pulse with the specified duration on a specific channel or multiple channels.
|
||||||
:param int channel: selects a single channel (No. 1 - 24)
|
|
||||||
:param int value: lines to set (integer) for example value=3 selects channels 0 and 1 (2**0 + 2**1)
|
Parameters:
|
||||||
|
-----------
|
||||||
|
length : float
|
||||||
|
Pulse length in seconds.
|
||||||
|
channel : int, optional
|
||||||
|
Selects a single channel (No. 1 - 24). If provided, the value is calculated as 2^channel.
|
||||||
|
value : int, optional
|
||||||
|
Lines to set (integer). For example, value=3 selects channels 0 and 1 (2**0 + 2**1).
|
||||||
|
If both channel and value are None, the pulse is set to 0.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
---------
|
||||||
|
>>> e.ttl_pulse(length=5e-6, channel=1)
|
||||||
|
Creates a 5 microsecond pulse on channel 1.
|
||||||
|
|
||||||
|
>>> e.ttl_pulse(length=3e-6, value=3)
|
||||||
|
Creates a 3 microsecond pulse on channels 0 and 1.
|
||||||
|
|
||||||
|
>>> e.ttl_pulse(length=1e-6, value=0xffffff)
|
||||||
|
Creates a 1 microsecond pulse on all channels.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
------
|
||||||
|
Hexadecimal representation (number starts with *0x*) is convenient as the numbers are shorter.
|
||||||
|
To set all channels, value would be in decimal 16777215 and in hexadecimal 0xffffff.
|
||||||
|
One letter in hexadecimal represents four bits.
|
||||||
|
|
||||||
|
See Also:
|
||||||
|
---------
|
||||||
|
ttls : Same as ttl_pulse, but no channel keyword.
|
||||||
"""
|
"""
|
||||||
the_value=0
|
the_value=0
|
||||||
if value is not None:
|
if value is not None:
|
||||||
@@ -176,12 +204,43 @@ class Experiment:
|
|||||||
|
|
||||||
def wait(self, time, ttls=None, gating=False):
|
def wait(self, time, ttls=None, gating=False):
|
||||||
"""
|
"""
|
||||||
Wait specified **time** doing nothing.
|
Waits for a specified amount of time without performing any actions.
|
||||||
|
|
||||||
|
This command inserts a delay in the pulse sequence, allowing time for relaxation,
|
||||||
|
or synchronization with other events.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
time : float
|
||||||
|
Time to wait in seconds.
|
||||||
|
The minimum time is 90 ns, and the maximum is essentially unlimited (years).
|
||||||
|
The backend driver circumvents the limit imposed by the pulse programmer by adding loops.
|
||||||
|
|
||||||
|
ttls : int, optional
|
||||||
|
Additional TTL lines to set (integer) during the wait period.
|
||||||
|
Allows simultaneous control of TTL lines while waiting.
|
||||||
|
For example, ttls=3 activates channels 0 and 1 (2^0 + 2^1).
|
||||||
|
|
||||||
|
gating : bool, optional
|
||||||
|
If True, reduces the wait time by the gating time (typically 2 µs).
|
||||||
|
This is useful for waiting in front of an rf_pulse to account for gating delays.
|
||||||
|
Default is False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
--------
|
||||||
|
None
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
---------
|
||||||
|
>>> e.wait(time=2e-3)
|
||||||
|
Waits for 2 milliseconds.
|
||||||
|
|
||||||
|
>>> e.wait(time=1e-6, ttls=3)
|
||||||
|
Waits for 1 microsecond while activating TTL channels 0 and 1.
|
||||||
|
|
||||||
|
>>> e.wait(time=5e-6, gating=True)
|
||||||
|
Waits for 5 microseconds, reduced by the gating time for rf_pulse synchronization.
|
||||||
|
|
||||||
:param float time: seconds to wait
|
|
||||||
:param int ttls: lines to set (integer)
|
|
||||||
:param bool gating: reduce time by gating, i.e. wait in front of rf_pulse
|
|
||||||
:return:
|
|
||||||
"""
|
"""
|
||||||
if gating:
|
if gating:
|
||||||
time -= self.gating
|
time -= self.gating
|
||||||
@@ -196,16 +255,70 @@ class Experiment:
|
|||||||
|
|
||||||
def record(self, samples, frequency, timelength=None, sensitivity = None, ttls=None, channels = 3, offset = None, impedance = None):
|
def record(self, samples, frequency, timelength=None, sensitivity = None, ttls=None, channels = 3, offset = None, impedance = None):
|
||||||
"""
|
"""
|
||||||
Records data with a given number of samples, sampling frequency and sensitivity.
|
Records data with a given number of samples, sampling frequency, and sensitivity.
|
||||||
Optionally, the time length of this state can be specified. If not specified, **timelength** is
|
This command starts data acquisition from the ADC (Analog-to-Digital Converter).
|
||||||
deduced from **samples**/**frequency**:
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
samples : int
|
||||||
|
Number of samples to record. This determines the number of data points in the resulting signal.
|
||||||
|
|
||||||
|
frequency : float
|
||||||
|
Sampling frequency in Hz. This determines how often samples are taken from the analog signal.
|
||||||
|
The maximum sampling frequency is 20 MHz.
|
||||||
|
|
||||||
|
timelength : float, optional
|
||||||
|
Length of this state in seconds. If not specified (None), it is calculated automatically as samples/frequency.
|
||||||
|
This parameter allows overriding the automatic calculation for special timing requirements.
|
||||||
|
|
||||||
|
sensitivity : float or list, optional
|
||||||
|
Sensitivity in U_MAX/V. Specifies the input voltage range for the ADC.
|
||||||
|
Accepted values are 0.2, 0.5, 1, 2, 5, and 10 V.
|
||||||
|
Can be a single value (applied to all channels) or a list of values (one per channel).
|
||||||
|
|
||||||
|
ttls : int, optional
|
||||||
|
Additional TTL lines to set (integer) during recording. Allows simultaneous control of TTL lines.
|
||||||
|
For example, ttls=3 activates channels 0 and 1 (2^0 + 2^1).
|
||||||
|
|
||||||
|
channels : int, optional
|
||||||
|
Channels to activate. Default is 3 (channels 0 and 1).
|
||||||
|
Accepted values are 1 (channel 0), 3 (channels 0 and 1), 5 (channels 0, 1, and 2), and 15 (all 4 channels).
|
||||||
|
|
||||||
|
offset : int or list, optional
|
||||||
|
Voltage offset for the ADC input. Can be a single integer value (applied to all channels)
|
||||||
|
or a list of values (one per channel).
|
||||||
|
Normally not used.
|
||||||
|
|
||||||
|
impedance : float or list, optional
|
||||||
|
Input impedance for the ADC. Can be a single number (applied to all channels)
|
||||||
|
or a list of values (one per channel).
|
||||||
|
Normally set in the backend config and not changeable.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
--------
|
||||||
|
None
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
---------
|
||||||
|
>>> e.record(samples=1024, frequency=2e6, sensitivity=2)
|
||||||
|
Records a signal with 1024 data points and 2 MHz sampling frequency.
|
||||||
|
The sensitivity will be ±2 V, providing a resolution of 0.2 mV with a 14-bit ADC card.
|
||||||
|
|
||||||
|
>>> e.record(samples=4096, frequency=10e6, sensitivity=[1, 2], channels=3)
|
||||||
|
Records a signal with 4096 data points and 10 MHz sampling frequency.
|
||||||
|
Channel 0 uses 1 V sensitivity, and channel 1 uses 2 V sensitivity.
|
||||||
|
|
||||||
|
>>> e.record(samples=2048, frequency=5e6, ttls=3)
|
||||||
|
Records a signal with 2048 data points and 5 MHz sampling frequency.
|
||||||
|
Simultaneously activates TTL channels 0 and 1.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
------
|
||||||
|
- Multiple record statements can be in a single scan (gated sampling) or in a loop.
|
||||||
|
- The onboard memory can hold 8M samples shared by all channels (depends on the board).
|
||||||
|
- The sensitivity setting affects the resolution of the ADC.
|
||||||
|
- The actual timing may vary slightly due to hardware limitationslike pre- and post-trigger delays.
|
||||||
|
|
||||||
:param int samples: Number of samples to record
|
|
||||||
:param float frequency: Sampling frequency / Hz
|
|
||||||
:param float timelength: Length of this state, per default calculated automatically
|
|
||||||
:param float sensitivity: Sensitivity in U_MAX/V
|
|
||||||
:param int ttls: additional ttl lines to set (integer)
|
|
||||||
:param int channels: channels to activate, default=3 (0+1)
|
|
||||||
"""
|
"""
|
||||||
attributes='s="%d" f="%d"'%(samples,frequency)#%g
|
attributes='s="%d" f="%d"'%(samples,frequency)#%g
|
||||||
if channels != 1 and channels != 3 and channels != 5 and channels != 15:
|
if channels != 1 and channels != 3 and channels != 5 and channels != 15:
|
||||||
@@ -371,17 +484,51 @@ class Experiment:
|
|||||||
|
|
||||||
def set_dac(self, dac_value, dac_id=1, length=None, is_seq=False, ttls=0):
|
def set_dac(self, dac_value, dac_id=1, length=None, is_seq=False, ttls=0):
|
||||||
"""
|
"""
|
||||||
This sets the value for the DAC and if given additional ttl lines.
|
Sets the value for the DAC (Digital-to-Analog Converter) and optionally additional TTL lines.
|
||||||
It also sets it back to zero automatically when is_seq=False.
|
This command is used to control analog output signals, such as pulsed field gradients.
|
||||||
If you don't wish to set the value back to zero (i.e. line shapes) set is_seq=True
|
|
||||||
|
|
||||||
The state length is at least 3.78 µs (is_seq=1) or 7.28µs (is_seq=0).
|
Parameters:
|
||||||
|
-----------
|
||||||
|
dac_value : int
|
||||||
|
DAC value, between -2**19-1 (-524287) and +2**19 (524288).
|
||||||
|
This value determines the analog output voltage.
|
||||||
|
|
||||||
:param int dac_value: DAC value, between -2**19-1 and +2**19
|
dac_id : int, optional
|
||||||
:param int dac_id: default=1, which DAC to control
|
Specifies which DAC to control. Default is 1.
|
||||||
:param float length: default=None, length of this state in seconds. If *None* length=42*90ns=3.78µs
|
This allows control of multiple DAC channels if available.
|
||||||
:param bool is_seq: default=False, do not reset DAC to 0 (zero) if True
|
|
||||||
:param int ttls: default=0, lines to set (integer)
|
length : float, optional
|
||||||
|
Length of this state in seconds. Default is None, which sets the length to 42*90ns=3.78µs.
|
||||||
|
If is_seq is False, the total length is doubled due to the automatic reset to zero.
|
||||||
|
|
||||||
|
is_seq : bool, optional
|
||||||
|
If True, the DAC value is not reset to zero after the pulse. Default is False.
|
||||||
|
Use is_seq=True for creating line shapes or sequential pulses.
|
||||||
|
|
||||||
|
ttls : int, optional
|
||||||
|
Lines to set (integer) for TTL output. Default is 0.
|
||||||
|
Allows simultaneous control of TTL lines along with the DAC.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
--------
|
||||||
|
None
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
---------
|
||||||
|
>>> e.set_dac(dac_value=15040, dac_id=1, length=1e-3)
|
||||||
|
Sets DAC channel 1 to value 15040 for 1 millisecond and then resets to zero.
|
||||||
|
|
||||||
|
>>> e.set_dac(dac_value=10000, is_seq=True)
|
||||||
|
Sets DAC to value 10000 for 3.78µs without resetting to zero.
|
||||||
|
|
||||||
|
>>> e.set_dac(dac_value=20000, ttls=3)
|
||||||
|
Sets DAC to value 20000 and activates TTL channel 1 (2^1 + 2^0 = 3).
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
------
|
||||||
|
- The minimum state length is 3.78 µs when is_seq=True.
|
||||||
|
- When is_seq=False, the DAC is automatically reset to zero, adding another 3.78 µs to the total length.
|
||||||
|
- The actual length may be longer than specified if additional time is required for DAC settling.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if length==None:
|
if length==None:
|
||||||
@@ -401,13 +548,40 @@ class Experiment:
|
|||||||
|
|
||||||
def set_phase(self, phase, ttls=0):
|
def set_phase(self, phase, ttls=0):
|
||||||
"""
|
"""
|
||||||
Sets the phase of the RF source to this value.
|
Sets the phase of the RF source to the specified value.
|
||||||
Note: This is relative to the phase at the beginnig of the experiment.
|
|
||||||
The state length is 0.5 µs, but the stabilisation time is RF source dependent. Typical
|
|
||||||
values for PTS310 is 2 µs.
|
|
||||||
|
|
||||||
:param float phase: phase to set
|
This command changes the phase of the frequency source. The phase is given in degrees and is
|
||||||
:param int ttls: default=0, lines to set (integer)
|
relative to the phase at the beginning of the experiment.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
phase : float
|
||||||
|
Phase to set in degrees. This value determines the phase of the RF signal.
|
||||||
|
|
||||||
|
ttls : int, optional
|
||||||
|
Lines to set (integer) for TTL output. Default is 0.
|
||||||
|
Allows simultaneous control of TTL lines along with setting the phase.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
--------
|
||||||
|
None
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
---------
|
||||||
|
>>> e.set_phase(phase=90)
|
||||||
|
Sets the receiver phase to 90 degrees.
|
||||||
|
|
||||||
|
>>> e.set_phase(phase=180, ttls=3)
|
||||||
|
Sets the phase to 180 degrees and activates TTL channels 0 and 1.
|
||||||
|
|
||||||
|
>>> e.set_phase(phase=45)
|
||||||
|
Sets the phase to 45 degrees.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
------
|
||||||
|
- The state length for this command is 0.5 µs.
|
||||||
|
- The stabilization time for the phase change is RF source dependent. A typical value for PTS310 is 2 µs.
|
||||||
|
- The phase is relative to the initial phase set at start of the experiment.
|
||||||
"""
|
"""
|
||||||
s_content = '<analogout phase="%f" />' % (phase)
|
s_content = '<analogout phase="%f" />' % (phase)
|
||||||
if ttls!=0:
|
if ttls!=0:
|
||||||
@@ -418,12 +592,40 @@ class Experiment:
|
|||||||
|
|
||||||
|
|
||||||
def set_description(self, key, value):
|
def set_description(self, key, value):
|
||||||
"""Sets a description which is carried via the back end result
|
"""
|
||||||
file to the result script in the front end. In the result script
|
Sets a description key-value pair in the experiment description dictionary.
|
||||||
you can extract the description with get_description
|
|
||||||
|
|
||||||
:param str key: the key
|
This command creates an entry with the specified key and value in the description dictionary.
|
||||||
:param value: the value, its type is saved.
|
In case of data being stored in a HDF5 file, this dictionary is stored as well, allowing
|
||||||
|
parameter passing between the experiment script and the result script.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
key : str
|
||||||
|
The key identifier for the description entry. This will be used to retrieve the value later.
|
||||||
|
|
||||||
|
value : any
|
||||||
|
The value to be associated with the key. Can be of any type (string, number, list, etc.).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
--------
|
||||||
|
None
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
---------
|
||||||
|
>>> e.set_description(key="tau", value=2e-3)
|
||||||
|
Sets the description entry with key "tau" to the value 0.002 seconds.
|
||||||
|
|
||||||
|
>>> e.set_description(key="temperature", value=298.15)
|
||||||
|
Sets the description entry with key "temperature" to the value 298.15 Kelvin.
|
||||||
|
|
||||||
|
>>> e.set_description(key="pulse_sequence", value="CPMG")
|
||||||
|
Sets the description entry with key "pulse_sequence" to the string "CPMG".
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
------
|
||||||
|
If the key already exists in the description dictionary, a warning message will be printed
|
||||||
|
indicating that the existing value will be overwritten.
|
||||||
"""
|
"""
|
||||||
if key in list(self.description.keys()):
|
if key in list(self.description.keys()):
|
||||||
print('Warning: Overwriting existing description "%s" = "%s" with "%s"' % (key, self.description[key], value))
|
print('Warning: Overwriting existing description "%s" = "%s" with "%s"' % (key, self.description[key], value))
|
||||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 664 B After Width: | Height: | Size: 664 B |
Reference in New Issue
Block a user