APS-USAXS / usaxs-bluesky-ended-2023

Bluesky instrument for USAXS
0 stars 0 forks source link

rebuild linkam support using best practices #494

Closed prjemian closed 2 years ago

prjemian commented 3 years ago

Related problems appeared in these issues, (#484, #485, #487, #490). Time to rebuild this support and make it rely on common tools that any APS beam line can use.

Make sure that the same support can be used at other beam lines.

Look at PTC10, Linkam, Lakeshore, and others. (4ID-Polar and 8IDI)

repository files affected

jilavsky commented 3 years ago

I have been looking at linkam.py and various user plans we have and I am more and more confused. My recollection is, that we had two support versions. I cannot figure this all out as I think I see only one support version, linkam.py. Does this one needs to be modified still? I need to make sure only one version is available (new one) and user plans are all converted or deleted.

jilavsky commented 2 years ago

This will happen with installation of new release (1.6.0rc5+) of apstools.

prjemian commented 2 years ago

New support in apstools 1.6.0 (https://github.com/BCDA-APS/apstools/pull/560 and https://github.com/BCDA-APS/apstools/pull/625)

prjemian commented 2 years ago

Note, to make linkam.ramp.get() consistent for the two different devices, make a common alias in each:

# make a common term for the ramp rate (devices use different names)
linkam_ci94.ramp = linkam_ci94.rate
linkam_tc1.ramp = linkam_tc1.ramprate
prjemian commented 2 years ago

Note

change temperature and wait to reach inposition, use linkam.temperature

change temperature and do not wait to reach inposition, use linkam.temperature.setpoint

prjemian commented 2 years ago

I hope this plan will be much easier to edit: https://github.com/APS-USAXS/ipython-usaxs/blob/87ec787bb2cad97eb2a00ebb7abf99e7f7f5ba18/user/heater_profile.py#L202-L218

prjemian commented 2 years ago

See also #482

prjemian commented 2 years ago

Instances of "linkam" (case-independent) in the repo now:

```bash examples/README.md:* [Use a supported Linkam heater](use_linkam.md) examples/custom_loop.md: yield from bps.mv(linkam.rate, 100) # degrees C/minute examples/custom_loop.md: yield from linkam.set_target(temperature, wait=True) # degrees C examples/use_linkam.md:# Use a supported Linkam heater examples/use_linkam.md:There are two Linkam sample heaters already configured for use examples/use_linkam.md:`linkam_ci94` | Linkam_CI94 (the old one) | `9idcLAX:ci94:` examples/use_linkam.md:`linkam_tc1` | Linkam_T96 | `9idcLINKAM:tc1:` examples/use_linkam.md:In the examples below, replace `linkam_tc1` with the name of your temperature controller if it is different. examples/use_linkam.md:### `.target.value` : What temperature is `linkam_tc1` set to? examples/use_linkam.md: linkam_tc1.target.value examples/use_linkam.md:### `.set_target()` : Set `linkam_tc1` to a specific temperature examples/use_linkam.md: linkam_tc1.set_target(new_temperature) examples/use_linkam.md:By default, this will wait until `linkam_tc1` is *settled* before it returns. examples/use_linkam.md:### `.value` : What is the `linkam_tc1` actual temperature now? examples/use_linkam.md: print(linkam_tc1.value) examples/use_linkam.md: print(linkam_tc1.signal.value) examples/use_linkam.md:### `.settled` : Has `linkam_tc1` reached the desired temperature? examples/use_linkam.md: print(linkam_tc1.settled) examples/use_linkam.md:How close must the actual temperature (signal) be to the target temperature for `linkam_tc1` to indicate it is *settled*? examples/use_linkam.md: print(linkam_tc1.settled) examples/use_linkam.md:From the command line: `linkam_tc1.tolerance.put(2)` (sets it to 2 degrees) examples/use_linkam.md:From a plan: `yield from bps.mv(linkam_tc1.tolerance, 2)` examples/use_linkam.md: yield from bps.mv(linkam_tc1.rate, 100) # degrees C/minute examples/use_linkam.md: yield from linkam_tc1.set_target(temperature, wait=True) # degrees C examples/use_linkam.md: md["temperature_actual"] = linkam_tc1.value examples/use_linkam.md: md["temperature_actual"] = linkam_tc1.value examples/use_linkam.md: md["temperature_actual"] = linkam_tc1.value profile_bluesky/startup/instrument/devices/__init__.py:from .linkam import * profile_bluesky/startup/instrument/devices/general_terms.py: linkam_exit = Component(EpicsSignal, "9idcLAX:bit14") profile_bluesky/startup/instrument/devices/general_terms.py: linkam_pulse = Component(EpicsSignal, "9idcLAX:long16") profile_bluesky/startup/instrument/devices/general_terms.py: linkam_ready = Component(EpicsSignal, "9idcLAX:bit15") profile_bluesky/startup/instrument/devices/general_terms.py: linkam_trigger = Component(EpicsSignal, "9idcLAX:bit16") profile_bluesky/startup/instrument/devices/linkam.py:Linkam temperature controllers profile_bluesky/startup/instrument/devices/linkam.py: 'linkam_ci94', profile_bluesky/startup/instrument/devices/linkam.py: 'linkam_tc1', profile_bluesky/startup/instrument/devices/linkam.py:class Linkam_CI94(UsaxsProcessController): profile_bluesky/startup/instrument/devices/linkam.py: Linkam model CI94 temperature controller profile_bluesky/startup/instrument/devices/linkam.py: In [1]: linkam_ci94 = Linkam_CI94("9idcLAX:ci94:", name="ci94") profile_bluesky/startup/instrument/devices/linkam.py: In [2]: linkam_ci94.settled profile_bluesky/startup/instrument/devices/linkam.py: In [3]: linkam_ci94.settled profile_bluesky/startup/instrument/devices/linkam.py: linkam_ci94.record_signal() profile_bluesky/startup/instrument/devices/linkam.py: yield from (linkam_ci94.set_target(50)) profile_bluesky/startup/instrument/devices/linkam.py: controller_name = "Linkam CI94" profile_bluesky/startup/instrument/devices/linkam.py:class Linkam_T96(UsaxsProcessController): profile_bluesky/startup/instrument/devices/linkam.py: Linkam model T96 temperature controller profile_bluesky/startup/instrument/devices/linkam.py: linkam_tc1 = Linkam_T96("9idcLINKAM:tc1:", name="linkam_tc1") profile_bluesky/startup/instrument/devices/linkam.py: controller_name = "Linkam T96" profile_bluesky/startup/instrument/devices/linkam.py:linkam_ci94 = Linkam_CI94("9idcLAX:ci94:", name="ci94") profile_bluesky/startup/instrument/devices/linkam.py:linkam_tc1 = Linkam_T96("9idcLINKAM:tc1:", name="linkam_tc1") profile_bluesky/startup/usaxs_support/heater_profile_manager.sh:# a Linkam heater sequence: ./heater_profile_manager.py. profile_bluesky/startup/usaxs_support/heater_profile_process.py: linkam_exit = Component(EpicsSignal, "9idcLAX:bit14") profile_bluesky/startup/usaxs_support/heater_profile_process.py: linkam_pulse = Component(EpicsSignal, "9idcLAX:long16") profile_bluesky/startup/usaxs_support/heater_profile_process.py: linkam_ready = Component(EpicsSignal, "9idcLAX:bit15") profile_bluesky/startup/usaxs_support/heater_profile_process.py: linkam_trigger = Component(EpicsSignal, "9idcLAX:bit16") profile_bluesky/startup/usaxs_support/heater_profile_process.py: pulse0 = process_control.linkam_pulse.get() profile_bluesky/startup/usaxs_support/heater_profile_process.py: pulses = (process_control.linkam_pulse.get() - pulse0) % PULSE_MAX profile_bluesky/startup/usaxs_support/heater_profile_process.py: process_control.linkam_pulse.put( profile_bluesky/startup/usaxs_support/heater_profile_process.py: (process_control.linkam_pulse.get() +1) % PULSE_MAX profile_bluesky/startup/usaxs_support/heater_profile_process.py: process_control.linkam_exit.put(False) profile_bluesky/startup/usaxs_support/heater_profile_process.py: process_control.linkam_ready.put(False) profile_bluesky/startup/usaxs_support/heater_profile_process.py: process_control.linkam_ready.put(True) profile_bluesky/startup/usaxs_support/heater_profile_process.py: if process_control.linkam_exit.get(): profile_bluesky/startup/usaxs_support/heater_profile_process.py: process_control.linkam_exit.put(False) profile_bluesky/startup/usaxs_support/heater_profile_process.py: process_control.linkam_ready.put(False) profile_bluesky/startup/usaxs_support/heater_profile_process.py: elif process_control.linkam_trigger.get(): profile_bluesky/startup/usaxs_support/heater_profile_process.py: process_control.linkam_ready.put(False) profile_bluesky/startup/usaxs_support/heater_profile_process.py: process_control.linkam_trigger.put(False) profile_bluesky/startup/usaxs_support/heater_profile_process.py: process_control.linkam_ready.put(True) profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/saveFlyData.xml: profile_bluesky/startup/usaxs_support/surveillance.py: yield from linkam.set_temperature(t) user/README.md: %run -i -m user.linkam user/README.md: If you add or modify symbols in the user's command shell (IPython namespace) and those symbols are used in your file (`user/linkam.py` as the example shows), you must repeat the `%run` command (above) to load those changes. user/heater_profile.py:linkam_exit = EpicsSignal("9idcLAX:bit14", name="exit_request_signal") user/heater_profile.py:linkam_ci94 = devices.Linkam_CI94_Device("9idcLAX:ci94:", name="linkam_ci94") user/heater_profile.py:linkam_tc1 = devices.Linkam_T96_Device("9idcLINKAM:tc1:", name="linkam_tc1") user/heater_profile.py:for o in (linkam_exit, linkam_ci94, linkam_tc1, user_dir): user/heater_profile.py:linkam_ci94.ramp = linkam_ci94.rate user/heater_profile.py:linkam_tc1.ramp = linkam_tc1.ramprate user/heater_profile.py:linkam = linkam_tc1 # choose which one user/heater_profile.py:# linkam = linkam_ci94 # choose which one user/heater_profile.py:linkam.temperature.tolerance.put(1.0) user/heater_profile.py:linkam.temperature.cb_readback() user/heater_profile.py:def linkam_report(): user/heater_profile.py: units = linkam.units.get() user/heater_profile.py: f"{linkam.name}" user/heater_profile.py: f" T={linkam.temperature.position:.1f}{units}" user/heater_profile.py: f" setpoint={linkam.temperature.setpoint.get():.1f}{units}" user/heater_profile.py: f" ramp:{linkam.ramp.get()}" user/heater_profile.py: f" settled: {linkam.temperature.inposition}" user/heater_profile.py: f" done: {linkam.temperature.done.get()}" user/heater_profile.py: yield from bps.mv(linkam.ramp, value) user/heater_profile.py: f"Change {linkam.name} rate to {linkam.ramp.get():.0f} C/min" user/heater_profile.py: BS plan: Tell linkam controller to stop (a temperature change in progress). user/heater_profile.py: Can't call linkam.temperature.stop() since that has blocking code. user/heater_profile.py: if linkam_exit.get() in (0, linkam_exit.enum_strs[0]): user/heater_profile.py: yield from bps.mv(linkam.temperature, linkam.position) user/heater_profile.py: linkam_report() user/heater_profile.py:def linkam_change_setpoint_and_wait(value): user/heater_profile.py: bps.mv(linkam.temperature, value) user/heater_profile.py: bps.mv(linkam.temperature.setpoint, value) user/heater_profile.py: linkam.temperature.setpoint, value, user/heater_profile.py: log_it(f"Change {linkam.name} setpoint to {linkam.setpoint.get():.2f} C") user/heater_profile.py: while not linkam.temperature.inposition: user/heater_profile.py: linkam_report() user/heater_profile.py:def linkam_hold(duration): user/heater_profile.py: log_it("{linkam.name} holding for {readable_time(duration)}") user/heater_profile.py: log_it(f"{linkam.name} holding period ended") user/heater_profile.py: linkam_report() user/heater_profile.py: log_it(f"Starting planHeaterProcess() for {linkam.name}") user/heater_profile.py: linkam_report() user/heater_profile.py: yield from linkam_change_setpoint_and_wait(1083) user/heater_profile.py: yield from linkam_hold(3 * HOUR) user/heater_profile.py: yield from linkam_change_setpoint_and_wait(40) user/heater_profile.py: yield from bps.mv(linkam_exit, True) user/linkam.py:# this is a Linkam plan using BS to control Linkam temeprature in sync with data collection user/linkam.py:from instrument.devices import linkam_ci94, linkam_tc1 user/linkam.py:linkam_debug = Signal(name="linkam_debug",value=False) user/linkam.py:# In order to run as debug (without collecting data, only control Linkam) in command line run: user/linkam.py:#linkam_debug.put(True) user/linkam.py:def myLinkamPlan(pos_X, pos_Y, thickness, scan_title, temp1, rate1, delay1min, temp2, rate2, md={}): user/linkam.py: # %run -m linkam user/linkam.py: return f"{scan_title}_{linkam.value:.0f}C_{(time.time()-t0)/60:.0f}min" user/linkam.py: linkam = linkam_tc1 #New Linkam from windows ioc (all except NIST 1500). user/linkam.py: #linkam = linkam_ci94 #this is old TS1500 NIST from LAX user/linkam.py: logger.info(f"Linkam controller PV prefix={linkam.prefix}") user/linkam.py: isDebugMode = linkam_debug.get() user/linkam.py: yield from bps.mv(linkam.rate, 200) #sets the rate of next ramp user/linkam.py: yield from linkam.set_target(40, wait=True) #sets the temp of to 40C, waits until we get there (no data collection) user/linkam.py: yield from bps.mv(linkam.rate, rate1) #sets the rate of next ramp to rate1 (deg C/min) user/linkam.py: yield from linkam.set_target(temp1, wait=False) #sets the temp target of this ramp, temp1 is in C user/linkam.py: while not linkam.settled: #runs data collection until we reach the temperature temp1. user/linkam.py: yield from bps.mv(linkam.rate, rate2) #sets the rate of next ramp user/linkam.py: yield from linkam.set_target(temp2, wait=False) #sets the temp target of next ramp, temp2 is in C. Typically cooling period user/linkam.py: while not linkam.settled: #runs data collection until we reach temp2 user/localfile.py:# this is a Linkam plan user/old/fz_linkam.py:Linkam plan for Fan Zhang experiments 2020-12. user/old/fz_linkam.py: %run -m fz_linkam user/old/fz_linkam.py:from instrument.devices import linkam_ci94 user/old/fz_linkam.py:from instrument.devices import linkam_tc1 user/old/fz_linkam.py:def fzLinkamPlan( user/old/fz_linkam.py: # %run -m linkam user/old/fz_linkam.py: f"_{linkam.value+0.5:.0f}C" user/old/fz_linkam.py: "Linkam USAXS/SAXS/WAXS heating sequence\n" user/old/fz_linkam.py: f"fzLinkamPlan(pos_X={pos_X}, pos_Y={pos_Y},thickness={thickness}," user/old/fz_linkam.py: # Linkam device choice user/old/fz_linkam.py: linkam = linkam_tc1 # Linkam T96, 600, 1500V, 350V user/old/fz_linkam.py: #linkam = linkam_ci94 # Linkam 1500 using old controller. user/old/fz_linkam.py: logger.info(f"Linkam controller PV prefix={linkam.prefix}") user/old/fz_linkam.py: yield from bps.mv(linkam.rate, 50) #sets the rate of next ramp user/old/fz_linkam.py: yield from linkam.set_target(40, wait=True) #sets the temp of next ramp user/old/fz_linkam.py: yield from bps.mv(linkam.rate, rate1) #sets the rate of next ramp user/old/fz_linkam.py: yield from linkam.set_target(temp1, wait=True) #sets the temp of next ramp user/old/fz_linkam.py: #while not linkam.settled: #runs data collection until next temp user/old/fz_linkam.py: yield from bps.mv(linkam.rate, rate2) #sets the rate of next ramp user/old/fz_linkam.py: yield from linkam.set_target(temp2, wait=False) #sets the temp of next ramp user/old/fz_linkam.py: while not linkam.settled: #runs data collection until next temp user/old/james_linkam.py:Linkam plan for James Coakley experiments 2021-01. user/old/james_linkam.py: %run -i -m james_linkam user/old/james_linkam.py:from instrument.devices import linkam_ci94 user/old/james_linkam.py:from instrument.devices import linkam_tc1 user/old/james_linkam.py:def jamesLinkamPlan( user/old/james_linkam.py: # %run -i -m linkam user/old/james_linkam.py: return f"{title}_{linkam.value:.0f}C_{(time.time()-t1)/60:.0f}min" user/old/james_linkam.py: "Linkam USAXS/SAXS/WAXS heating sequence\n" user/old/james_linkam.py: f"james_LinkamPlan(pos_X={pos_X}, pos_Y={pos_Y},thickness={thickness}," user/old/james_linkam.py: # Linkam device choice user/old/james_linkam.py: #linkam = linkam_tc1 # Linkam T96, 600, 1500V, 350V user/old/james_linkam.py: linkam = linkam_ci94 # Linkam 1500 using old controller. user/old/james_linkam.py: logger.info(f"Linkam controller PV prefix={linkam.prefix}") user/old/james_linkam.py: yield from bps.mv(linkam.rate, 150) #sets the rate of next ramp user/old/james_linkam.py: yield from linkam.set_target(30, wait=False) #sets the temp of next ramp user/old/james_linkam.py: #TODO here: start Linkam somehow, if it is off, it stays off... user/old/james_linkam.py: yield from bps.mv(linkam.rate, 150) #sets the rate of next ramp user/old/james_linkam.py: yield from linkam.set_target(566, wait=False) #sets the temp of next ramp user/old/james_linkam.py: while not linkam.settled: #runs data collection until next temp user/old/james_linkam.py: yield from bps.mv(linkam.rate, 150) #sets the rate of next ramp user/old/james_linkam.py: yield from linkam.set_target(1170, wait=False) # temp measuremnt user/old/james_linkam.py: while not linkam.settled: #runs data collection until next temp user/old/james_linkam.py: yield from bps.mv(linkam.rate, 20) # sets the rate of next ramp user/old/james_linkam.py: yield from linkam.set_target(566, wait=False) # temp measuremnt user/old/james_linkam.py: while not linkam.settled: #runs data collection until next temp user/old/james_linkam.py: yield from bps.mv(linkam.rate, 150) # sets the rate of next ramp user/old/james_linkam.py: yield from linkam.set_target(1170, wait=False) # set temperature user/old/james_linkam.py: while not linkam.settled: # runs data collection until next temp user/old/james_linkam.py: yield from bps.mv(linkam.rate, rate) # sets the rate of next ramp user/old/james_linkam.py: yield from linkam.set_target(566, wait=False) # temp measuremnt user/old/james_linkam.py: while not linkam.settled: # runs data collection until next temp user/old/james_linkam.py: yield from bps.mv(linkam.rate, 150) # sets the rate of next ramp user/old/james_linkam.py: yield from linkam.set_target(1170, wait=False) # set temperature user/old/james_linkam.py: while not linkam.settled: # runs data collection until next temp user/old/james_linkam.py: yield from bps.mv(linkam.rate, 20) # sets the rate of next ramp user/old/james_linkam.py: yield from linkam.set_target(566, wait=False) # temp measuremnt user/old/james_linkam.py: while not linkam.settled: # runs data collection until next temp user/old/james_linkam.py: yield from bps.mv(linkam.rate, 150) #sets the rate of next ramp user/old/james_linkam.py: yield from linkam.set_target(temp, wait=False) # temp measuremnt user/old/james_linkam.py: while not linkam.settled: #runs data collection until next temp user/old/james_linkam.py: yield from linkam.set_target(50, wait=False) #sets the temp of next ramp user/old/james_linkam.py: while not linkam.settled: #runs data collection until next temp user/old/james_linkam2.py:Linkam plan for James Coakley experiments 2021-01. user/old/james_linkam2.py: %run -i -m james_linkam user/old/james_linkam2.py:from instrument.devices import linkam_ci94 user/old/james_linkam2.py:from instrument.devices import linkam_tc1 user/old/james_linkam2.py:def jamesLinkamPlan( user/old/james_linkam2.py: # %run -i -m linkam user/old/james_linkam2.py: return f"{title}_{linkam.value:.0f}C_{(time.time()-t1)/60:.0f}min" user/old/james_linkam2.py: "Linkam USAXS/SAXS/WAXS heating sequence\n" user/old/james_linkam2.py: f"james_LinkamPlan(pos_X={pos_X}, pos_Y={pos_Y},thickness={thickness}," user/old/james_linkam2.py: # Linkam device choice user/old/james_linkam2.py: #linkam = linkam_tc1 # Linkam T96, 600, 1500V, 350V user/old/james_linkam2.py: linkam = linkam_ci94 # Linkam 1500 using old controller. user/old/james_linkam2.py: logger.info(f"Linkam controller PV prefix={linkam.prefix}") user/old/james_linkam2.py: yield from bps.mv(linkam.rate, 150) #sets the rate of next ramp user/old/james_linkam2.py: yield from linkam.set_target(30, wait=False) #sets the temp of next ramp user/old/james_linkam2.py: #TODO here: start Linkam somehow, if it is off, it stays off... user/old/james_linkam2.py: yield from bps.mv(linkam.rate, 150) # sets the rate of next ramp user/old/james_linkam2.py: yield from linkam.set_target(400, wait=False) # sets the temp of next ramp user/old/james_linkam2.py: while not linkam.settled: # runs data collection until next temp user/old/james_linkam2.py: yield from bps.mv(linkam.rate, 10) # sets the rate of next ramp user/old/james_linkam2.py: yield from linkam.set_target(1170, wait=False) # temp measuremnt user/old/james_linkam2.py: while not linkam.settled: #runs data collection until next temp user/old/james_linkam2.py: yield from bps.mv(linkam.rate, 20) # sets the rate of next ramp user/old/james_linkam2.py: yield from linkam.set_target(400, wait=False) # temp measuremnt user/old/james_linkam2.py: while not linkam.settled: #runs data collection until next temp user/old/james_linkam2.py: yield from bps.mv(linkam.rate, 10) # sets the rate of next ramp user/old/james_linkam2.py: yield from linkam.set_target(772, wait=False) # temp measuremnt user/old/james_linkam2.py: while not linkam.settled: #runs data collection until next temp user/old/james_linkam2.py: yield from bps.mv(linkam.rate, 10) # sets the rate of next ramp user/old/james_linkam2.py: yield from linkam.set_target(1170, wait=False) # temp measuremnt user/old/james_linkam2.py: while not linkam.settled: #runs data collection until next temp user/old/james_linkam2.py: yield from bps.mv(linkam.rate, 20) # sets the rate of next ramp user/old/james_linkam2.py: yield from linkam.set_target(400, wait=False) # temp measuremnt user/old/james_linkam2.py: while not linkam.settled: #runs data collection until next temp user/old/james_linkam2.py: yield from bps.mv(linkam.rate, 10) # sets the rate of next ramp user/old/james_linkam2.py: yield from linkam.set_target(889, wait=False) # temp measuremnt user/old/james_linkam2.py: while not linkam.settled: #runs data collection until next temp user/old/james_linkam2.py: yield from bps.mv(linkam.rate, 20) # sets the rate of next ramp user/old/james_linkam2.py: yield from linkam.set_target(400, wait=False) # temp measuremnt user/old/james_linkam2.py: while not linkam.settled: #runs data collection until next temp user/old/james_linkam2.py: yield from bps.mv(linkam.rate, 150) # sets the rate of next ramp user/old/james_linkam2.py: yield from linkam.set_target(40, wait=False) # temp measuremnt user/old/james_linkam2.py: while not linkam.settled: #runs data collection until next temp user/old/linkam.py:# this is a Linkam plan user/old/linkam.py:from instrument.devices import linkam_ci94, linkam_tc1 user/old/linkam.py:def myLinkamPlan(pos_X, pos_Y, thickness, scan_title, temp1, rate1, delay1, temp2, rate2, md={}): user/old/linkam.py: # %run -m linkam user/old/linkam.py: return f"{scan_title}_{linkam.value:.0f}C_{(time.time()-t0)/60:.0f}min" user/old/linkam.py: #linkam = linkam_tc1 user/old/linkam.py: linkam = linkam_ci94 user/old/linkam.py: logger.info(f"Linkam controller PV prefix={linkam.prefix}") user/old/linkam.py: yield from bps.mv(linkam.rate, rate1) #sets the rate of next ramp user/old/linkam.py: yield from linkam.set_target(temp1, wait=False) #sets the temp of next ramp user/old/linkam.py: while not linkam.settled: #runs data collection until next temp user/old/linkam.py: yield from bps.mv(linkam.rate, rate2) #sets the rate of next ramp user/old/linkam.py: yield from linkam.set_target(temp2, wait=False) #sets the temp of next ramp user/old/linkam.py: while not linkam.settled: #runs data collection until next temp user/old/linkam_new.py:# this is a Linkam plan user/old/linkam_new.py:from instrument.devices import linkam_ci94, linkam_tc1, terms user/old/linkam_new.py:def myLinkamPlan(pos_X, pos_Y, thickness, scan_title, delayhours, md={}): user/old/linkam_new.py: collect USAXS/SAXS/WAXS while Linkam is runinng on its own user/old/linkam_new.py: # %run -m linkam_new user/old/linkam_new.py: return f"{title}_{linkam.value:.0f}C_{(time.time()-t1)/60:.0f}min" user/old/linkam_new.py: #linkam = linkam_tc1 user/old/linkam_new.py: linkam = linkam_ci94 user/old/linkam_new.py: logger.info(f"Linkam controller PV prefix={linkam.prefix}") user/old/linkam_new.py: # signal the (external) Linkam control python program to start user/old/linkam_new.py: logger.info("Starting external Linkam controller process ...") user/old/linkam_new.py: while terms.HeaterProcess.linkam_ready.get() != 1: user/old/linkam_new.py: logger.info("External Linkam is ready ...") user/old/linkam_new.py: # here we need to trigger the Linkam control python program... user/old/linkam_new.py: logger.info("Triggering (starting) the External Linkam heating plan ...") user/old/linkam_new.py: yield from bps.mv(terms.HeaterProcess.linkam_trigger, 1) user/old/linkam_new.py: # tell the Linkam control python program to exit... user/old/linkam_new.py: logger.info("Stopping the External Linkam heating plan ...") user/old/linkam_new.py: yield from bps.mv(terms.HeaterProcess.linkam_exit, 1) # orderly ```

Updating the issue description above with the list of files.