-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DM-39206 - Power on ATCalSys #116
Conversation
6f1c821
to
bb330bd
Compare
1e81124
to
56946d6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here some initial comments.
# self.log.info(f"Lamp didn't turn on after {self.lamp_warm_up_time} s") | ||
|
||
async def wait_for_lamp_to_warm_up(self): | ||
await self.white_light_source.evt_lampState.flush() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
flush
is a regular method not a coroutine. You should drop the await
.
python/lsst/ts/standardscripts/auxtel/calibrations/power_on_atcalsys.py
Outdated
Show resolved
Hide resolved
) | ||
if lamp_state.basicState == ATWhiteLight.LampBasicState.WARMUP: | ||
warmup_time_left = ( | ||
lamp_state.warmupEndTime - lamp_state.private_rcvStamp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you probably want to use private_sndStamp
instead of private_rcvStamp
. Difference should be small but still.
python/lsst/ts/standardscripts/auxtel/calibrations/power_on_atcalsys.py
Outdated
Show resolved
Hide resolved
self.log.info( | ||
f"White Light Lamp is on after a warm up of {warm_up_elapsed_time} s" | ||
) | ||
else: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this correct? if the status is not WARMUP
nor ON
it will fail?
Also, if it is a fail, shouldn't you raise an exception or something?
"Time Left for lamp warmup: {} min.".format(warmup_time_left / 60.0) | ||
) | ||
await asyncio.sleep(self.track_lamp_warmup) | ||
elif lamp_state.basicState == ATWhiteLight.LampBasicState.ON: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could drop this elif
and just do this after the while
loop has ended (it saves you from doing a comparison).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have changed the code a little more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, not sure I understand the logic here. Do you need to break in this condition? it seems like it is going to continue in the loop until is time out.
However, see my suggestion for simplifying this loop.
5575a22
to
6127f47
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here some comments for you to consider... I haven't been able to read through it all yet, sorry..
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing the final phrase:
# along with this program. If not, see <https://www.gnu.org/licenses/>.
python/lsst/ts/standardscripts/auxtel/calibrations/power_on_atcalsys.py
Outdated
Show resolved
Hide resolved
|
||
from lsst.ts import salobj | ||
|
||
track_lamp_warmup = 60 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is supposed to be a constant, please, make is all caps,
TRACK_LAMP_WARMUP = 60
But maybe best to have this as a class attribute instead, e.g.,. move it to the __init__
method and make it self.track_lamp_warmup
.
index : `int` | ||
Index of Script SAL component. | ||
|
||
Notes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you don't have any Notes, you can remove this session.
self.timeout_chiller_cool_down = 60 * 10 | ||
self.chiller_temp_tolerance_relative = 0.1 | ||
|
||
if self.white_light_source is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need to move all this code from here until line 86 to the configure
method. Or maybe make a setup_remotes
coroutine and await it in configure
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried moving it to __init__
because it didn't configure properly if it was in the configure
method, and all unittest were failing quickly.
log=self.log | ||
) | ||
|
||
asyncio.gather( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to await
this otherwise nothing happens.. Once you move this to the configure
method, you will be able to do:
await asyncio.gather(...)
# domain=self.domain, name="ATMonochromator" | ||
# ) | ||
|
||
self.config = config |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Above you are creating individual attributes to get the values from config
and then here you just store the entire thing. I think pick one method. Either set them up individually or get the full thing, but not both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!!
|
||
async def run(self): | ||
"""Run script.""" | ||
#await self.assert_components_enabled() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, remove commented code or uncomment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uncommented.
await self.white_light_source.cmd_startChiller.set(timeout=self.timeout_chiller_cool_down) | ||
|
||
async def wait_for_chiller_temp_within_tolerance(self): | ||
start_time_chill_time = time.time() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
time is repeated here.. maybe rename it start_chill_time
?
python/lsst/ts/standardscripts/auxtel/calibrations/power_on_atcalsys.py
Outdated
Show resolved
Hide resolved
c7cff59
to
e35a0d3
Compare
e35a0d3
to
6ee7a0c
Compare
|
||
Raises | ||
------ | ||
salobj.ExpectedError : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually we only document the exceptions that the method itself raises. This one in particular is raised by another method that does the configuration validation before calling configure
. You should probably remove this here.
d1feb7b
to
1930f20
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here another round of comments..
self.white_light_source = salobj.Remote( | ||
domain=self.domain, | ||
name="ATWhiteLight", | ||
log=self.log, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remote does not take log
as a parameter.
self.monochromator = salobj.Remote( | ||
domain=self.domain, | ||
name="ATMonochromator", | ||
log=self.log, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remote does not take log
as a parameter.
doc/version_history.rst
Outdated
@@ -32,6 +32,8 @@ v1.22.0 | |||
|
|||
* Add new ``MoveP2P`` maintel script. | |||
|
|||
* Add new ``auxtel/calibrations/power_on_atcalsys.py`` script, unit test and executable to set up and turn on the ATCalSys white light. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Version 1.22.0 was already released, please make this a new release 1.25.0
) | ||
|
||
async def open_white_light_shutter(self): | ||
await self.white_light_source.cmd_openShutter.set_start() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, add a timeout to the command, otherwise it can stop here forever. Also, since you are not passing in any parameter, use, start
instead, e.g,:
await self.white_light_source.cmd_openShutter.start(timeout=self.timeout_open_shutter)
and you need to define self.timeout_open_shutter
in the __init__
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have put 5 minutes timeout, does that sound right?
|
||
async def open_white_light_shutter(self): | ||
await self.white_light_source.cmd_openShutter.set_start() | ||
# Q? Should we include a check that the shutter is open? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this command only finishes when the shutter is open, and fails if the shutter doesn't open.. So think it is ok to leave it as is, e.g., no need to check.
"Time Left for lamp warmup: {} min.".format(warmup_time_left / 60.0) | ||
) | ||
await asyncio.sleep(self.track_lamp_warmup) | ||
elif lamp_state.basicState == ATWhiteLight.LampBasicState.ON: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, not sure I understand the logic here. Do you need to break in this condition? it seems like it is going to continue in the loop until is time out.
However, see my suggestion for simplifying this loop.
) | ||
|
||
async def wait_for_lamp_to_warm_up(self): | ||
self.white_light_source.evt_lampState.flush() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is best to flush
just before you send the command. Flushing here can create a race condition where the event is published between the time the command is sent and the time to get here, in which case you loose the event.
I would actually suggest changing the loop a little bit.
Consider something like this:
lamp_state = await self.white_light_source.evt_lampState.aget(
timeout=self.timeout_lamp_warm_up
) # gets the most recent data
# Now enters the loop with the stop condition being that the lamp is ON
while lamp_state.basicState != ATWhiteLight.LampBasicState.ON:
lamp_state = await self.white_light_source.evt_lampState.next(
flush=False, timeout=self.timeout_lamp_warm_up
)
self.log.info(f"Lamp state: {ATWhiteLight.LampBasicState(lamp_state.basicState)!r}.")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestion.
) | ||
|
||
async def get_monochromator_parameters(self): | ||
tmp1 = await self.monochromator.evt_selectedGrating.aget() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, add a timeout for all these aget
statements, otherwise it can block here for ever.
Also you can probably do this in "in parallel" using asyncio.gather
:
return await asyncio.gather(
self.monochromator.evt_selectedGrating.aget(timeout=self.std_timeout),
self.monochromator.evt_wavelength.aget(timeout=self.std_timeout),
self.monochromator.evt_entrySlitWidth.aget(timeout=self.std_timeout),
self.monochromator.evt_exitSlitWidth.aget(timeout=self.std_timeout),
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion with the asynctio.gather
if salobj.State(summary_state.summaryState) != salobj.State( | ||
salobj.State.ENABLED | ||
): | ||
raise Exception(f"{comp} is not ENABLED") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, raise RuntimeError
instead of a bare exception.
8fc0495
to
1053af4
Compare
a3e7e31
to
bc03365
Compare
bc03365
to
f005fd1
Compare
No description provided.