OxfordIonTrapGroup / ndscan

N-dimensional scans for ARTIQ
GNU Lesser General Public License v3.0
19 stars 16 forks source link

Documentation: using fragments in vanilla artiq #250

Open hartytp opened 3 years ago

hartytp commented 3 years ago

A not uncommon use case is to want to use one or more Fragments in an ARTIQ EnvExperiment. This is easy to do, but is not documented / particularly obvious AFAICT.

To some degree, the real underlying issue here is that I haven't found / there doesn't exist good documentation describing the lifecycle of an ndscan experiment. Armed with that, I think it would be easy to figure out what needs doing. By way of example, I've had to read the source / hack in some debug prints a few times to remind myself when host_setup / device_setup actually run (AFAICT answer is that, for a coredevice scan, host_setup runs once each time the kernel is entered, so once at the start of the scan and one additional time every time the scan resumes after a scheduler pause).

For the basic case of using fragments with their default parameters inside an EnvExperiment, from looking over https://github.com/OxfordIonTrapGroup/ndscan/blob/master/ndscan/experiment/scan_runner.py my understanding is that for each Fragment we need to run

I think that's it unless the Fragments use a custom cleanup etc

hartytp commented 3 years ago

There are a few other things like when recompute_param_defaults needs to be called, which it would be good to have in a FAQ

hartytp commented 3 years ago

oh, and Fragments need to be added as class attributes in build to make sure their build attributes get called by ARTIQ.

So, something like

import artiq.language as aq
from artiq.language import kernel
import ndscan.experiment as nd
import my_fragments

class MyExp(aq.EnvExperiment):
    def build(self):
        self.setattr_device("core")
        self.fragment = my_fragments.MyFragment(self, [])

     def run(self):
        fragment.host_setup()
        self.krun()

     @kernel
     def krun(self):
        self.fragment.device_setup()
        self.fragment.foo()
dnadlinger commented 3 years ago

oh, and Fragments need to be added as class attributes in build to make sure their build attributes get called by ARTIQ.

Shouldn't build() be called immediately from the HasEnvironment constructor?

The setup/cleanup function order is documented in the respective Fragment doc comments, but I agree that a separate piece of documentation might be useful.