Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
11 changes: 9 additions & 2 deletions exopy_hqc_legacy/instruments/drivers/visa/cryomagnetics_cs4.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class CS4(VisaInstrument):
#: Typical fluctuations at the output of the instrument.
#: We use a class variable since we expect this to be identical for all
#: instruments.
OUTPUT_FLUCTUATIONS = 2e-4
OUTPUT_FLUCTUATIONS = 5e-4

caching_permissions = {'heater_state': True,
'target_field': True,
Expand Down Expand Up @@ -116,6 +116,10 @@ def sweep_to_field(self, value, rate=None):

# Start ramping.
self.target_field = value
# Added a pause and then sweep up due to a buggy behavior of the source
sleep(1)
self.activity = 'Hold'
sleep(1)
self.activity = 'To set point'

# Create job.
Expand All @@ -124,11 +128,14 @@ def sweep_to_field(self, value, rate=None):
job = InstrJob(self.is_target_reached, wait, cancel=self.stop_sweep)
return job

@secure_communication()
def stop_sweep(self):
"""Stop the field sweep at the current value.
"""Stop the field sweep at the current value, and turn of the switch heater.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change in behavior ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was specified in the job after job.cancel() was called (which in turn calls this method), it is more logical to integrate it directly to the method called as cancel()

Copy link
Member

@MatthieuDartiailh MatthieuDartiailh Dec 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree, you may stop a sweep but need to run a new one right after in which case automatically closing the switch heater would be a bad idea (this is hypothetical). Also if you wanted to go that way you need to be sure all driver are consistent.


"""
self.activity = 'Hold'
driver.heater_state = 'Off'
sleep(self.post_switch_wait)

def check_connection(self):
pass
Expand Down
10 changes: 10 additions & 0 deletions exopy_hqc_legacy/instruments/drivers/visa/cryomagnetics_g4.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ def target_field(self, target):
# can't reuse CS4 class because a semi-colon is needed
self.write('ULIM {};'.format(target * 10))

@instrument_property
@secure_communication()
def field_sweep_rate(self):
"""Rate at which to ramp the field (T/min).

"""
# converted from A/s to T/min
rate = float(self.ask('RATE? 0'))
return rate * (60 * self.field_current_ratio)

@field_sweep_rate.setter
@secure_communication()
def field_sweep_rate(self, rate):
Expand Down
28 changes: 17 additions & 11 deletions exopy_hqc_legacy/tasks/tasks/instr/apply_mag_field_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,41 +59,47 @@ def perform(self, target_value=None):

driver = self.driver
normal_end = True
if (abs(driver.read_persistent_field() - target_value) >
driver.output_fluctuations):
# Only if driver.heater_state == 'Off' otherwise we wait for
# post_switch_wait no matter what
if driver.heater_state == 'Off':
job = driver.sweep_to_persistent_field()
if job.wait_for_completion(self.check_for_interruption,
timeout=60, refresh_time=1):
timeout=60, refresh_time=3):
driver.heater_state = 'On'
sleep(self.post_switch_wait)
else:
return False

if (abs(driver.read_persistent_field() - target_value) >
driver.output_fluctuations):
# set the magnetic field
job = driver.sweep_to_field(target_value, self.rate)
normal_end = job.wait_for_completion(self.check_for_interruption,
timeout=60,
refresh_time=10)
print('field:', driver.read_persistent_field())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to keep this it should be a logger call.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No this was for debugging purpose I'll remove it


# Always close the switch heater when the ramp was interrupted.
if not normal_end:
job.cancel()
driver.heater_state = 'Off'
sleep(self.post_switch_wait)
job.cancel() # stops the sweep and turn off the switch heater
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why cancelling the job should always close the switch heater. Also you only modified the cg4 and cs4 but I believe the Oxford source behaves differently.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't add this but it seems rather reasonable to me since the switch heater increases the He consumption

The oxford source is broken so I have not updated the driver (since I am not able to test it and I didn't want to leave something buggy behind)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am fine with closing the heater my concern is the same above regarding the location of that code inside cancel.

self.write_in_database('field', driver.read_persistent_field())
return False
# if not normal_end, fail the measurement
self.root.should_stop.set()
raise ValueError(cleandoc('''Field source did not set the field to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is debatable since it will appear as a hard failure even if the measurement was properly interrupted. This point to the need of differentiating between stop and timeout as I was suggesting in #61 .

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm I was under the impression that when the measurement was manually stopped, the program stopped before going there but it is not clear to me how the stop signal is dealt with.
I am fine with #61 !

{}'''.format(target_value)))

# turn off heater
# turn off heater if required
if self.auto_stop_heater:
driver.heater_state = 'Off'
sleep(self.post_switch_wait)
job = driver.sweep_to_field(0)
# sweep down to zero at the fast sweep rate
job = driver.sweep_to_field(0, driver.fast_sweep_rate)
job.wait_for_completion(self.check_for_interruption,
timeout=60, refresh_time=1)
timeout=60, refresh_time=3)

self.write_in_database('field', target_value)


class ApplyMagFieldAndDropTask(InstrumentTask):
"""Use a supraconducting magnet to apply a magnetic field. Parallel task.

Expand Down