OpenwaterHealth / OpenLIFU-python

focused ultrasound toolbox
GNU Affero General Public License v3.0
10 stars 2 forks source link

Define `Run`s #96

Open ebrahimebrahim opened 1 month ago

ebrahimebrahim commented 1 month ago

Add to openlifu the concept of a Run and the ability to serialize them to and from json. Runs should be things that are saved under a particular session, so also add a method to the Database class to save a run for a particular session, and update the Session definition. Like transducers (and protocols), sessions should save the ID referencing the run and not the run itself.

The Database should also be able to retrieve runs by ID.

See also SlicerOpenLIFURun for more context as to why the Run concept is desired.

Depends on #92

ebrahimebrahim commented 1 week ago

Just like how volumes live under a subject, and how solutions live under a session, runs should live under a session. There can be a runs.json that just lists run IDs (just like solutions.json and volumes.json do).

Define a Run class. In can live in the plan/ directory

Database class can have similar methods to write new runs, overwrite rights, etc. Each Run should have the same basic serialization functionality: to/from file and to/from json. See how Solution is written and do a similar thing to that.

The attributes of a run: id (str), success flag (bool), note (str, large text field), associated session ID (str), associated solution ID (str). (We can fill in more attributes as we find that we need them)

So: define Run class, include serialization capabilities, unit test it, add Database write functionality, add an example to the example db testing resource, unit test the Database functionality.


Here is something extra that we want: the ability to save a snapshot of a session's protocol, transducer transform, and target alongside a run. This can be achieved by saving a snapshot of the protocol and a snapshot of the session. (Perhaps we don't need to snapshot a Solution because solutions are most likely write-only at the application level?) A way to do this is to add optional arguments to the Database.write_run function (or whatever it's called): protocol_to_snapshot:Protocol, session_to_snapshot:Session. When provided, the Protocol and/or Session json are written to a file alongside the run (in the same directory, so for example inside db/subjects/example_subject/sessions/example_session/runs/example_run/ you would have example_run.json and example_run_session_snapshot.json and example_run_protocol_snapshot.json. Then we would have Database methods similar to load_session and load_protocol called load_session_snapshot and load_protocol_snapshot that can retrieve those snapshots.