diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bee8a64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/code-reference.pdf b/code-reference.pdf new file mode 100644 index 0000000..525ba19 Binary files /dev/null and b/code-reference.pdf differ diff --git a/commands/__init__.py b/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/commands/__pycache__/__init__.cpython-312.pyc b/commands/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index 19201de..0000000 Binary files a/commands/__pycache__/__init__.cpython-312.pyc and /dev/null differ diff --git a/commands/__pycache__/tnmr_commands.cpython-312.pyc b/commands/__pycache__/tnmr_commands.cpython-312.pyc deleted file mode 100644 index 24bf7a2..0000000 Binary files a/commands/__pycache__/tnmr_commands.cpython-312.pyc and /dev/null differ diff --git a/example_scripts/old_scripts/dvg_T1_scan.py b/example_scripts/old_scripts/dvg_T1_scan.py new file mode 100644 index 0000000..d9c241d --- /dev/null +++ b/example_scripts/old_scripts/dvg_T1_scan.py @@ -0,0 +1,59 @@ +# ***************************************************************************** +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Module authors: +# Davis V. Garrad +# +# ***************************************************************************** + +# do "accessory" stuff. Set field, temperature, etc. +SetEnvironment(tt, mf) # Add the PPMS temperature and field to the file at every write. +#maw(tt, 3) # set PPMS temperature +#maw(mf, 3) # set PPMS field +#nicossleep(20*60) # 20 minutes +# ... + +# Create the pulse sequence +# generate_pulse(pulse_width, amplitude, delay_time, pulse_cycle) +pw90 = 2.3 # us +amp = 40 # percent +tau = 50 # us + +p180 = generate_pulse(2*pw90, amp, 1, '1 3 3 1 2 0 0 2 0 2 2 0 3 1 1 3') # 180deg +p90 = generate_pulse(pw90, amp, tau, '0 2 0 2 1 3 1 3 0 2 0 2 1 3 1 3') # 90deg +p180_2 = generate_pulse(2*pw90, amp, 0, '1 3 3 1 2 0 0 2 0 2 2 0 3 1 1 3') # 180deg +seq = [ p180, p90, p180_2 ] + +# Create the list of sequences to scan (specifically, for a T1 scan) +delay_times = log_durations(10, 1_000_000, 20) +# generates a list of sequences; copies of seq are made, only the zeroth pulse is modified. Each copy is given a 'delay_time' value from delay_times +seq_list = generate_sequences(seq, [0], 'delay_time', delay_times) + +# Set some parameters independent of pulse sequence +globalparams = { + 'acq_phase_cycle': '0 2 0 2 1 3 1 3 2 0 2 0 3 1 3 1', + 'acquisition_time': 204.8, # us + 'num_acqs': 100, # "1D scans" in TNMR. Our 16-fold phase cycling means this should be a multiple of 16 for proper averaging + 'ringdown_time': 15, # us + 'post_acquisition_time': 250, # ms + 'obs_freq': 45.5, # MHz. Receiver frequency + 'nucleus': 'NUCMgReS', + 'comments': 'An example of a T1 scan', +} +update_device_parameters(nmr_daq_scout, globalparams) + +# Acquire data +scan_sequences(nmr_daq_scout, seq_list) # gather the data diff --git a/example_scripts/old_scripts/dvg_T2_scan.py b/example_scripts/old_scripts/dvg_T2_scan.py new file mode 100644 index 0000000..0d7a8ea --- /dev/null +++ b/example_scripts/old_scripts/dvg_T2_scan.py @@ -0,0 +1,62 @@ +# ***************************************************************************** +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Module authors: +# Davis V. Garrad +# +# ***************************************************************************** + +# do "accessory" stuff. Set field, temperature, etc. +SetEnvironment(tt, mf) # Add the PPMS temperature and field to the file at every write. +#maw(se_tt, 3) # set PPMS temperature +#nicossleep(20*60) # 20 minutes +# ... + +# Create the pulse sequence +# generate_pulse(pulse_width, amplitude, delay_time, pulse_cycle) +pw90 = 2.5 # us +amp = 40 # percent +tau = 50 # us + +p180 = generate_pulse(2*pw90, amp, 1, '1 3 3 1 2 0 0 2 0 2 2 0 3 1 1 3') # 180deg +p90 = generate_pulse(pw90, amp, tau, '0 2 0 2 1 3 1 3 0 2 0 2 1 3 1 3') # 90deg +p180_2 = generate_pulse(2*pw90, amp, 0, '1 3 3 1 2 0 0 2 0 2 2 0 3 1 1 3') # 180deg +seq = [ p180, p90, p180_2 ] + +# Create the list of sequences to scan (specifically, for a T1 scan) +delay_times = log_durations(10, 1_000_000, 20) +# generates a list of sequences; copies of seq are made, only the zeroth pulse is modified. Each copy is given a 'delay_time' value from delay_times +seq_list = generate_sequences(seq, [0], 'delay_time', delay_times) + +# Now, the reader should note how easy manipulating pulse sequences really is +for i in range(len(seq_list)): + seq_list[i][1]['delay_time'] = max(seq_list[i][0]['delay_time'] - 10.0, 0.1) + +# Set some parameters independent of pulse sequence +globalparams = { + 'acq_phase_cycle': '0 2 0 2 1 3 1 3 2 0 2 0 3 1 3 1', + 'acquisition_time': 204.8, # us + 'num_scans': 1024, # "1D scans" in TNMR. Our 16-fold phase cycling means this should be a multiple of 16 for proper averaging + 'ringdown_time': 1, # us + 'post_acquisition_time': 250, # ms + 'obs_freq': 45.5, # MHz. Receiver frequency + 'nucleus': 'NUCMgReS', + 'comments': 'An example of a T2 scan', +} +update_device_parameters(nmr_daq_scout, globalparams) + +# Acquire data +scan_sequences(nmr_daq_scout, seq_list) # gather the data diff --git a/example_scripts/old_scripts/dvg_magsweep.py b/example_scripts/old_scripts/dvg_magsweep.py new file mode 100644 index 0000000..87809c0 --- /dev/null +++ b/example_scripts/old_scripts/dvg_magsweep.py @@ -0,0 +1,50 @@ +# ***************************************************************************** +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Module authors: +# Davis V. Garrad +# +# ***************************************************************************** + +p90 = generate_pulse(2.5, 40, 50, '0 2 0 2 1 3 1 3 0 2 0 2 1 3 1 3') +p180_2 = generate_pulse(5, 40, 0.1, '1 3 3 1 2 0 0 2 0 2 2 0 3 1 1 3') + +seq = [ p90, p180_2 ] + +# Set some parameters independent of pulse sequence +globalparams = { + 'acq_phase_cycle': '0 2 0 2 1 3 1 3 2 0 2 0 3 1 3 1', + 'acquisition_time': 204.8, # us + 'num_scans': 1024, # "1D scans" in TNMR. Our 16-fold phase cycling means this should be a multiple of 16 for proper averaging + 'ringdown_time': 15, # us + 'post_acquisition_time': 250, # ms + 'obs_freq': 41.59, # MHz. Receiver frequency + 'nucleus': 'NUCMgReS', + 'comments': 'An example of a field sweep', +} +update_device_parameters(nmr_daq_scout, globalparams) + +fields = [ 6.8 + i*1e-3 for i in range(2000) ] + +print(timestring(estimate_scan_length(globalparams, seq)*len(fields))) + +with tnmr_scan(): # Enters a mode of manual file control. Values will now be written into a single file until the context is lost + for field in fields: + maw(se_mf, field) # assuming se_mf controls the reader's external field strength (PPMS, etc.) + print_sequence(seq) + + # Acquire data + scan_sequence(nmr_daq_scout, seq) # gather the data diff --git a/example_scripts/ta_T1_scan.py b/example_scripts/ta_T1_scan.py new file mode 100644 index 0000000..6107fa8 --- /dev/null +++ b/example_scripts/ta_T1_scan.py @@ -0,0 +1,65 @@ +# ***************************************************************************** +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Module authors: +# Davis V. Garrad +# Tina Arh +# +# ***************************************************************************** + +# Select the parameters that are written under environment in HDF file at every write +SetEnvironment(tt, mf, nmr_TSSOP16, nmr_RP100Node_CH1, nmr_RP100Node_CH2, r1, tps)#, ZVLNode) + +# PPMS: Set field & temperature + +#maw(tt, 3) # set PPMS temperature (in Kelvin) +#maw(mf, 3) # set the starting PPMS field (in Tesla) +#nicossleep(20*60) # 20 minutes +# ... + +# Create the pulse sequence + +pw90 = 2.5 # us +amp = 25 # percent +tau = 20 # us + +# generate_pulse(pulse_width, amplitude, delay_time, pulse_cycle) +p180 = generate_pulse(2*pw90, amp, 1, '0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0') # 180deg +p90 = generate_pulse(pw90, amp, tau, '0 2 0 2 1 3 1 3 0 2 0 2 1 3 1 3') # 90deg +p180_2 = generate_pulse(2*pw90, amp, 0, '1 3 3 1 2 0 0 2 0 2 2 0 3 1 1 3') # 180deg +seq = [ p180, p90, p180_2 ] + +# Create the list of sequences to scan (specifically, for a T1 scan) +delay_times = log_durations(1, 600000, 20) +# generates a list of sequences; copies of seq are made, only the zeroth pulse is modified. Each copy is given a 'delay_time' value from delay_times +seq_list = generate_sequences(seq, [0], 'delay_time', delay_times) + +# Set some parameters independent of pulse sequence +globalparams = { + 'acq_phase_cycle': '0 2 0 2 1 3 1 3 2 0 2 0 3 1 3 1', + 'acquisition_time': 204.8, # us + 'num_acqs': 16000, # "1D scans" in TNMR. Our 16-fold phase cycling means this should be a multiple of 16 for proper averaging + 'ringdown_time': 11, # us + 'post_acquisition_time': 200, # ms + 'obs_freq': 42.09, # MHz. Receiver frequency + 'nucleus': 'NUCMgReS', # For example, 139La. Will be used in a filename! + 'comments': 'An example of a T1 scan', + 'title': 'T1', # Goes at the beginning of a filename! +} +update_device_parameters(nmr_daq_scout, globalparams) + +# Acquire data +scan_sequences(nmr_daq_scout, seq_list) # gather the data diff --git a/example_scripts/ta_T2_scan.py b/example_scripts/ta_T2_scan.py new file mode 100644 index 0000000..a9c6a33 --- /dev/null +++ b/example_scripts/ta_T2_scan.py @@ -0,0 +1,75 @@ +# ***************************************************************************** +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Module authors: +# Davis V. Garrad +# Tina Arh +# +# ***************************************************************************** + +# Select the parameters that are written under environment in HDF file at every write +SetEnvironment(tt, mf, nmr_TSSOP16, nmr_RP100Node_CH1, nmr_RP100Node_CH2, r1, tps)#, ZVLNode) + +# PPMS: Set field & temperature + +#maw(tt, 3) # set PPMS temperature (in Kelvin) +#maw(mf, 3) # set the starting PPMS field (in Tesla) +#nicossleep(20*60) # 20 minutes +# ... + +# Create the pulse sequence + +pw90 = 2.5 # us +amp = 40 # percent +tau = 50 # us + +# generate_pulse(pulse_width, amplitude, delay_time, pulse_cycle) +p90 = generate_pulse(pw90, amp, tau, '0 0 2 2 1 1 3 3 0 0 2 2 1 1 3 3') +p180_2 = generate_pulse(2*pw90, amp, 0, '1 3 3 1 2 0 0 2 0 2 2 0 3 1 1 3') + +seq = [ p90, p180_2 ] + +# Create the list of sequences to scan (for a T2 scan, the delay after the first pulse - tau - increases linearly from tau_min to tau_max) +tau_min = 50 # us +tau_max = 20000 # us +n_points = 20 + +delay_times = [tau_min + i * (tau_max - tau_min) / (n_points - 1) for i in range(n_points)] + +# Generates a list of sequences; copies of seq are made, only the zeroth pulse is modified. Each copy is given a 'delay_time' value from delay_times +seq_list = generate_sequences(seq, [0], 'delay_time', delay_times) + +# We now modify the delay after the second pulse to be a fixed time shorter than tau, this means the spin echo will always appear at the same time after the start of acquisition + +for i in range(len(seq_list)): + seq_list[i][1]['delay_time'] = max(seq_list[i][0]['delay_time'] - 20.0, 0.1) + +# Set some parameters independent of pulse sequence +globalparams = { + 'acq_phase_cycle': '0 0 2 2 1 1 3 3 2 2 0 0 3 3 1 1', + 'acquisition_time': 204.8, # us + 'num_acqs': 4096, # "1D scans" in TNMR. Our 16-fold phase cycling means this should be a multiple of 16 for proper averaging + 'ringdown_time': 5, # us + 'post_acquisition_time': 100, # ms + 'obs_freq': 42.09, # MHz + 'nucleus': '139La', # For example, 139La. Will be used in a filename! + 'comments': 'An example of a T2 scan', + 'title': 'T2', # Goes at the beginning of a filename! +} +update_device_parameters(nmr_daq_scout, globalparams) + +# Acquire data +scan_sequences(nmr_daq_scout, seq_list) # gather the data diff --git a/example_scripts/ta_cooldown.py b/example_scripts/ta_cooldown.py new file mode 100644 index 0000000..c3799c2 --- /dev/null +++ b/example_scripts/ta_cooldown.py @@ -0,0 +1,59 @@ +# ***************************************************************************** +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Module authors: +# Tina Arh +# +# ***************************************************************************** + +# Select the parameters that are written under environment in HDF file at every write +SetEnvironment(tt, mf, nmr_TSSOP16, nmr_RP100Node_CH1, nmr_RP100Node_CH2, r1, tps)#, ZVLNode) + +# PPMS: Set field & temperature +#maw(mf, 7.05) # set PPMS field (in Tesla) + +#maw(tt, 60) # set PPMS temperature (in Kelvin) +#nicossleep(5*60) # 5 minutes + +# Create the pulse sequence + +pw90 = 1 # us +amp = 40 # percent +tau = 25 # us + +# generate_pulse(pulse_width, amplitude, delay_time, pulse_cycle) +p90 = generate_pulse(pw90, amp, tau, '0 0 2 2 1 1 3 3 0 0 2 2 1 1 3 3') +p180_2 = generate_pulse(2*pw90, amp, 0, '1 3 3 1 2 0 0 2 0 2 2 0 3 1 1 3') + +seq = [ p90, p180_2 ] + +# Set some parameters independent of pulse sequence +globalparams = { + 'acq_phase_cycle': '0 0 2 2 1 1 3 3 2 2 0 0 3 3 1 1', + 'acquisition_time': 204.8, # us + 'num_acqs': 128, # "1D scans" in TNMR. Our 16-fold phase cycling means this should be a multiple of 16 for proper averaging + 'ringdown_time': 15, # us + 'post_acquisition_time': 100, # ms + 'obs_freq': 42.09, # MHz + 'nucleus': '139La', # For example, 139La. Will be used in a filename! + 'comments': 'Cooling from 50 K to 25 K', + 'title': 'cooldown', # Goes at the beginning of a filename! +} +update_device_parameters(nmr_daq_scout, globalparams) + +with tnmr_scan(): # Enters a mode of manual file control. Values will now be written into a single file until the context is lost + for i in range(10000): + scan_sequence(nmr_daq_scout, seq) # Acquire data diff --git a/example_scripts/ta_field_scan.py b/example_scripts/ta_field_scan.py new file mode 100644 index 0000000..9613dc6 --- /dev/null +++ b/example_scripts/ta_field_scan.py @@ -0,0 +1,66 @@ +# ***************************************************************************** +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Module authors: +# Davis V. Garrad +# Tina Arh +# +# ***************************************************************************** + +# Select the parameters that are written under environment in HDF file at every write +SetEnvironment(tt, mf, nmr_TSSOP16, nmr_RP100Node_CH1, nmr_RP100Node_CH2, r1, tps)#, ZVLNode) + +# PPMS: Set field & temperature + +#maw(tt, 3) # set PPMS temperature (in Kelvin) +#maw(mf, 3) # set the starting PPMS field (in Tesla) +#nicossleep(20*60) # 20 minutes +# ... + +pw90 = 1 # us +amp = 40 # percent +tau = 20 # us + +# generate_pulse(pulse_width, amplitude, delay_time, pulse_cycle) +p90 = generate_pulse(pw90, amp, tau, '0 0 2 2 1 1 3 3 0 0 2 2 1 1 3 3') +p180_2 = generate_pulse(2*pw90, amp, 0, '1 3 3 1 2 0 0 2 0 2 2 0 3 1 1 3') + +seq = [ p90, p180_2 ] + +# Set some parameters independent of pulse sequence +globalparams = { + 'acq_phase_cycle': '0 0 2 2 1 1 3 3 2 2 0 0 3 3 1 1', + 'acquisition_time': 204.8, # us + 'num_acqs': 2048, # "1D scans" in TNMR. Our 16-fold phase cycling means this should be a multiple of 16 for proper averaging + 'ringdown_time': 5, # us + 'post_acquisition_time': 100, # ms + 'obs_freq': 42.09, # MHz. Receiver frequency + 'nucleus': 'NUCMgReS', # For example, 139La. Will be used in a filename! + 'comments': 'An example of a field scan', + 'title': 'Bscan', # Goes at the beginning of a filename! +} +update_device_parameters(nmr_daq_scout, globalparams) + +fields = [ 6.95 + i*5e-2 for i in range(6) ] + +# Estimate the length of scan and multiply by number of fields +print(f'Beginning scan. ETA: {timestring(estimate_sequence_length_from_device(nmr_daq_scout, seq)*len(fields))}') + +with tnmr_scan(): # Enters a mode of manual file control. Values will now be written into a single file until the context is lost + for field in fields: + maw(mf, field) # assuming mf controls the reader's external field strength (PPMS, etc.) + + scan_sequence(nmr_daq_scout, seq) # Acquire data diff --git a/example_scripts/ta_freq_scan.py b/example_scripts/ta_freq_scan.py new file mode 100644 index 0000000..a7cb290 --- /dev/null +++ b/example_scripts/ta_freq_scan.py @@ -0,0 +1,76 @@ +# ***************************************************************************** +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Module authors: +# Tina Arh +# +# ***************************************************************************** + +# Select the parameters that are written under environment in HDF file at every write +SetEnvironment(tt, mf, nmr_TSSOP16, nmr_RP100Node_CH1, nmr_RP100Node_CH2, r1, tps)#, ZVLNode) + +# PPMS: Set field & temperature + +#maw(tt, 3) # set PPMS temperature (in Kelvin) +#maw(mf, 3) # set the starting PPMS field (in Tesla) +#nicossleep(20*60) # 20 minutes +# ... + +# Create the pulse sequence + +pw90 = 2.5 # us +amp = 40 # percent +tau = 50 # us + +# generate_pulse(pulse_width, amplitude, delay_time, pulse_cycle) +p90 = generate_pulse(pw90, amp, tau, '0 0 2 2 1 1 3 3 0 0 2 2 1 1 3 3') +p180_2 = generate_pulse(2*pw90, amp, 0, '1 3 3 1 2 0 0 2 0 2 2 0 3 1 1 3') + +seq = [ p90, p180_2 ] + +# Set some parameters independent of pulse sequence +globalparams = { + 'acq_phase_cycle': '0 0 2 2 1 1 3 3 2 2 0 0 3 3 1 1', + 'acquisition_time': 204.8, # us + 'num_acqs': 16, # "1D scans" in TNMR. Our 16-fold phase cycling means this should be a multiple of 16 for proper averaging + 'ringdown_time': 15, # us + 'post_acquisition_time': 100, # ms +# 'obs_freq': 45.5, # MHz + 'nucleus': 'NUCMgReS', # For example, 139La. Will be used in a filename! + 'comments': 'An example of a frequency scan with manual tuning', + 'title': 'FRscan', # Goes at the beginning of a filename! +} +update_device_parameters(nmr_daq_scout, globalparams) + +# Choose the frequencies (in MHz) +central_frequency = 45.50 # MHz +frequency_range = 0.6 # MHz +half_N = 3 +frequencies = [ central_frequency - frequency_range/2 + frequency_range * (i/(2*half_N)) for i in range(0, 2*half_N+1) ] + +# Estimate the length of scan and multiply by number of frequencies +print(f'Beginning scan. ETA: {timestring(estimate_sequence_length_from_device(nmr_daq_scout, seq)*len(frequencies))}') + +with tnmr_scan(): # Enters a mode of manual file control. Values will now be written into a single file until the context is lost + for fr in frequencies: + globalparams['obs_freq']=fr + update_device_parameters(nmr_daq_scout, globalparams) + + # Pause to manually tune the frequency + print(f'New frequency: {fr:.2f} MHz') + pause(f'Tune the resonance circuit to {fr:.2f} MHz and click \'Continue script\' when you are done!') + + scan_sequence(nmr_daq_scout, seq) # Acquire data diff --git a/nicos.conf b/nicos.conf new file mode 100644 index 0000000..2f70015 --- /dev/null +++ b/nicos.conf @@ -0,0 +1,26 @@ +# ***************************************************************************** +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Module authors: +# Davis V. Garrad +# +# ***************************************************************************** + +[nicos] + +logging_path = "/home/l_samenv/nicoslog/tnmr" +pid_path = "/home/l_samenv/nicoslog/tnmr" +setup_subdirs = [ "tnmr", "frappy_sinq"] diff --git a/setups/ppms.py b/setups/ppms.py new file mode 100644 index 0000000..2a9bb8e --- /dev/null +++ b/setups/ppms.py @@ -0,0 +1,26 @@ +from os import environ +description = 'frappy main setup' +group = 'optional' + +devices = { + 'se_ppms': + device('nicos_sinq.frappy_sinq.devices.FrappyNode', + uri='pc12694:5000', + description='main SEC node', unit='', + prefix=environ.get('SE_PREFIX', ''), auto_create=True, service='main', + ), + 'timestamp': device('nicos_sinq.linse_nicos.timestamp.Timestamp', description='time, a dummy detector'), +} + +startupcode = ''' +printinfo("=======================================================================================") +printinfo("Welcome to the NICOS frappy secnode setup for PPMS!") +printinfo(" ") +printinfo("Usage:") +printinfo(" frappy(stick='') # change sample-stick configuration") +printinfo(" frappy(addons=', ...') # change SE addons") +printinfo(" frappy(stick=None) # remove stick") +printinfo(" frappy(addons=None) # remove addons") +printinfo("=======================================================================================") +SetDetectors(timestamp) +''' diff --git a/setups/special/cache.py b/setups/special/cache.py new file mode 100644 index 0000000..c6df5b7 --- /dev/null +++ b/setups/special/cache.py @@ -0,0 +1,18 @@ +description = 'setup for the cache server' +group = 'special' +import os +insname = os.environ['INSTRUMENT'].rsplit('.')[-1] + +devices = dict( + DB = device('nicos.services.cache.database.FlatfileCacheDatabase', + description = 'On disk storage for Cache Server', + storepath = os.path.join(os.environ.get('NICOS_CACHE', 'data'), insname, 'cache'), + loglevel = 'info', + makelinks = 'soft', + ), + Server=device('nicos.services.cache.server.CacheServer', + db='DB', + server='localhost:%s' % os.environ['NICOS_CACHE_PORT'], + loglevel='info', + ), +) diff --git a/setups/special/config.py b/setups/special/config.py new file mode 100644 index 0000000..817c54a --- /dev/null +++ b/setups/special/config.py @@ -0,0 +1,3 @@ +description = 'Generic configuration settings' + +group = 'configdata' diff --git a/setups/special/daemon.py b/setups/special/daemon.py new file mode 100644 index 0000000..18ab252 --- /dev/null +++ b/setups/special/daemon.py @@ -0,0 +1,37 @@ +description = 'setup for the execution daemon' +group = 'special' +import os + +devices = dict( + # fixed list of users: + # first entry is the user name, second the hashed password, third the user + # level + # The user level are 'guest, 'user', and 'admin', ascending ordered in + # respect to the rights + # The entries for the password hashes are generated from randomized + # passwords and not reproduceable, please don't forget to create new ones: + # start python + # >>> import hashlib + # >>> hashlib.md5('password').hexdigest() + # or + # >>> hashlib.sha1('password').hexdigest() + Auth=device('nicos.services.daemon.auth.list.Authenticator', + # the hashing maybe 'md5' or 'sha1' + hashing='sha1', + passwd=[('guest', '', + 'guest'), + ('user', '21fb8406e5f81c24d4a5f5c7dd356e70a7288dc9', + 'user'), + ('admin', '76702e9ada292df094a875e5f72e9f778099d477', + 'admin'), + ], + ), + Daemon=device('nicos.services.daemon.NicosDaemon', + server='0.0.0.0:%s' % os.environ['NICOS_DAEMON_PORT'], + authenticators=['Auth', ], # and/or 'UserDB' + loglevel='info', + ), +) + +startupcode = ''' +''' diff --git a/setups/special/poller.py b/setups/special/poller.py new file mode 100644 index 0000000..fdca8ff --- /dev/null +++ b/setups/special/poller.py @@ -0,0 +1,24 @@ +description = 'setup for the poller' +group = 'special' +import os + +sysconfig = dict( + # use only 'localhost' if the cache is really running on the same machine, + # otherwise use the official computer name + cache='localhost:%s' % os.environ['NICOS_CACHE_PORT'] +) + +devices = dict( + Poller=device('nicos.services.poller.Poller', + autosetup=True, + poll=['system', 'setup'], + alwayspoll=[], + # setups that should be polled regardless if loaded + neverpoll=['frappy_main', 'frappy_stick', 'frappy_addons'], + # setups that should not be polled even if loaded + blacklist=[], # DEVICES that should never be polled + # (usually detectors or devices that have problems + # with concurrent access from processes) + loglevel='info' + ), +) diff --git a/setups/startup.py b/setups/startup.py new file mode 100644 index 0000000..18e2717 --- /dev/null +++ b/setups/startup.py @@ -0,0 +1,7 @@ +description = 'NICOS LIN SE startup setup' +group = 'lowlevel' + +startupcode = ''' +print("============================================================") +print("Welcome to LIN SE tests and lab experiments") +''' diff --git a/setups/system.py b/setups/system.py new file mode 100644 index 0000000..ac19350 --- /dev/null +++ b/setups/system.py @@ -0,0 +1,68 @@ +# basic frappy setup + +description = 'system setup' +group = 'lowlevel' +import os +insname = os.environ['INSTRUMENT'].split('.')[-1] + +sysconfig = dict( + cache = 'localhost:%s' % os.environ['NICOS_CACHE_PORT'], + instrument = 'instrument', + experiment = 'Exp', + datasinks = ['conssink', 'dmnsink' ], + notifiers = [], +) + +modules = ['nicos.commands.standard', 'nicos_sinq.frappy_sinq.commands' ] + +devices = dict( + instrument = device('nicos.devices.instrument.Instrument', + description = 'lab instrument %s' % insname, + instrument = insname, + responsible = 'whoever@wherever.ch', + website = '', + operators = ['whoever'], + facility = 'wherever', + ), + Sample = device('nicos.devices.sample.Sample', + description = 'sample object', + ), + Exp = device('nicos.devices.experiment.Experiment', + description = 'experiment object', + dataroot = os.path.join(os.environ['NICOS_DATA'], insname), + # proposalpath = 'data/%s' % insname, + sendmail = True, + serviceexp = 'service', + sample = 'Sample', + reporttemplate = '', + ), + conssink = device('nicos.devices.datasinks.ConsoleScanSink'), + dmnsink = device('nicos.devices.datasinks.DaemonSink'), + Space = device('nicos.devices.generic.FreeSpace', + description = 'The amount of free space for storing data', + warnlimits = (5., None), + path = None, + minfree = 5, + ), + LogSpace = device('nicos.devices.generic.FreeSpace', + description = 'Space on log drive', + path = os.path.join(os.environ['NICOS_LOG'], insname), + warnlimits = (.5, None), + minfree = 0.5, + lowlevel = True, + ), +) + +startupcode = ''' +from nicos.core import SIMULATION +if not Exp.proposal and Exp._mode != SIMULATION: + try: + SetMode('master') + except Exception: + pass + else: + NewExperiment(0, 'demo experiment', + localcontact='Nico Suser ') + AddUser('Paul Scherrer max_len): + max_len = len(i) + print(max_len, val_list) + if(len(k) > max_len): + max_len = len(k) + new_arr = np.ndarray((len(group.attrs[name])+1,), dtype=f' 10): + session.log.info(f'Failed to read {key}. Setting zero.') + v = 0 + break + session.log.info(f'Trying to read {key} again') + pass + if(dummytime == 0): + dummytime = time.time() + val = (dummytime, v) + write_time_val_pair(file, key, val) + + + def putResults(self, quality, results): + pass + #session.log.info('HDF_NeXus putResults is not implemented! Use putValues.') + + def addSubset(self, subset): + pass + #session.log.info('HDF_NeXus addSubset is not implemented! Use putValues.') + + #def end(self): + # pass # nothing afaik needs to be done here. + + +class HDF5ScanfileSink(FileSink): + + handlerclass = HDF5ScanfileSinkHandler + parameter_overrides = { + 'settypes': Override(default=[SCAN, SUBSCAN]), + 'filenametemplate': Override(default=['%(proposal)s_%(year)04d-%(month)02d-%(day)02d_%(hour)02d-%(minute)02d-%(second)02d.hdf']) + }