# Workflows A workflow is what you do by hand in the viewer, written down once as a graph of steps and run again on other data. *Open this folder, find the CT and the target in it, segment the heart and file it as `heart total`, open the 4DCT, do the same on every phase, carry the target across anchored on the heart, measure the motion, build the ITV, write everything out* is one workflow of twelve steps. Saved, it is a small file; run, it reads the folders it names (or the ones the run dialog points it at), does every step with the program's own code - the same engines, pipelines and landing rules the modules use - and writes its results into a folder of its own. A run either works **in the background**, leaving the workspaces alone, or **shows every step in the viewer**: each study is put in a workspace and, after each step, the viewer shows what the step did before the next one starts, the way a person working through it would see it. A workflow that starts from *DICOM folders* is a **batch**: it runs once per patient folder and puts the tables of every case together. The MCP server runs saved workflows too (`list_workflows`, `run_workflow`; see [mcp.md](mcp.md)). ## The Workflows menu | Entry | What it does | |---|---| | 🔀 New | Opens the workflow editor on an empty canvas. | | 📂 Load | Opens a workflow file (`.rdsflow`) in the editor. The dialog starts in your workflow folder. | | 🕐 Last saved | The five workflow files saved last, newest first. | | Examples | Workflows that ship with the program, opened as unsaved copies to adapt. | | Show the editor / Show the run | Brings back a closed editor or run window; the workflow and the run stay in memory while their windows are closed. | Your workflows are kept in `/user_data/workflows` (`%LOCALAPPDATA%\RustDICOMStation\user_data\workflows` on Windows, `~/.local/share/RustDICOMStation/user_data/workflows` on Linux, `~/Library/Application Support/RustDICOMStation/user_data/workflows` on macOS); the menu shows the path. Any other folder works as well - the file dialogs only start there. The *Last saved* list lives in `viewer_settings.txt` as `recent_workflows`. Replacing a workflow that has unsaved changes (New, Load, an example, a recent file) asks first, in the editor window. ## The editor A window of its own with four parts: * **The canvas**, in the middle. Every step is a node: its header, then what it gives (output pins on the right edge), a few lines saying what it is set to do, then what it takes (input pins on the left edge). A wire runs from an output pin to an input pin. Drag a node by its header, pan by dragging empty space, zoom with the wheel; **⛶ Fit** (or a double click on empty space) brings every step into view. A right click on empty space offers every kind of step; a wire dropped on empty space offers the steps that can take it and connects the new one. A right click on a node offers *Duplicate* and *Remove*; a right click on a pin drops its wires; the ▼ in a header folds the node. **Delete** removes the step shown in the inspector, or the steps selected with Shift-click or a Shift-drag. * **The palette**, on the left: the steps by group, one click adds one. Under it, *Frames* (below) and *Workflow*: a description, and where runs write (below). * **The inspector**, on the right: the selected step's title, what it does, its parameters, and what its pins take and give. * **The status line**, at the bottom: whether the workflow can run, and if not, why - a required input left free, a folder not given, an organ name TotalSegmentator does not know, a circle of wires. **Wires are typed.** A pin's colour says what it carries, and a wire goes only where its type is accepted; a refused wire says why in the status line. An input that takes one wire (a round pin) gives up the old one for a new one; an input that takes several (a square pin) collects them. | Colour | Carries | |---|---| | grey | a **study**: everything read from one folder | | violet | an **image series** of a study | | orange | a **4D group**: its phases, in order | | green | **structures** by name, on one image series or on every phase of a group | | blue | a **registration** (or one per phase) | | red | a **report**: what a step measured | Structures carry where they are. Structures made on every phase of a 4D group name that group, so a step that wants a group (*Propagate to 4D group*'s *Onto*, *Motion and ITV*'s *Group*) also takes the structures - which makes it wait for the step that made them. Node headers are coloured by group (input, finding, segmenting, registering, 4D, output). While a run is going each header carries the step's state: ⏳ running (outlined), ✔ done with its time, ✖ failed with the reason. **Editing** with the pointer over the canvas and no text field active: | Keys | What they do | |---|---| | Ctrl+Z, Ctrl+Shift+Z or Ctrl+Y | Undo, redo (also **⟲ Undo** / **⟳ Redo**). A drag or a typed title is one step of the history; the last 100 are kept. | | Ctrl+C, Ctrl+X | Copy or cut the selected steps (else the one in the inspector) with the wires between them. The clipboard holds them as workflow JSON, so they paste into another workflow, or another copy of the program. | | Ctrl+V | Paste under the pointer, with ids of their own. | | Ctrl+D | Duplicate the selected steps. | | Arrow keys | Move the selected steps by 10 units; with Shift, by a grid square. | | Delete | Remove the selected steps. | **Frames.** **⬚ Frame** draws a titled box around the selected steps, behind them: a row of the example, the phase work, a note for whoever opens the file next. The box follows its steps; dragging its title moves every step inside. Title and colour are set under *Frames* in the palette (🗑 removes a frame, not its steps). Frames are saved in the file and mean nothing to a run. **The map.** With *Map* ticked, the canvas's corner shows every step and frame in small, with the part in view outlined; a click or a drag on it moves the view there. **Save** writes to the file the workflow came from, or asks for a name (in your workflow folder) the first time; **Save as** always asks. The title bar carries a `*` while there are unsaved changes. ## The steps | Step | Takes | Gives | What it does | |---|---|---|---| | 📂 DICOM folder | - | study | Reads every DICOM file in the folder and its subfolders: patients, studies, series, RT objects, and the 4D groups among the series. *Workspace* is where a run that shows its steps puts the study. | | 📁 DICOM folders | - | study | A batch: the folder's subfolders that match the pattern (`*`, `P*`, `case ??`) are the cases, one patient each, and the whole workflow runs once per case (see *Batches*). One per workflow. | | 🏥 From the archive | - | study | A study of the station's local archive (*Tools ▸ PACS*): the patient by ID or name, the study by date, words of its description or its Study Instance UID, or the newest. Run as a task of a PACS server ([pacs-server.md](pacs-server.md#tasks-letting-the-server-do-the-work)), it reads the server's archive, bound to the study the station chose. | | 🔏 Anonymize | study | study | Writes an anonymized copy of the study's folder into the run folder (identifiers replaced by an alias, dates fixed, private tags removed, UIDs remapped) and goes on with the copy. | | 🔍 Image series | study | image | One image series by modality, words in the description, *the largest* (most slices), *the first* or *the last*; optionally not a phase of a 4D group. | | 🎞 4D group | study | group | The 4D group whose name contains the words given (empty: the first). When the loader recognised none, the series of one modality can be grouped instead (by phase percent, temporal position, series number). | | 🎯 Find structures | study, image or group | structures | Names or patterns with `*` and `?`, separated by commas (`target*, GTV*`), case-insensitive; *only the first match* takes one. On an image it looks at the structure sets and segmentations drawn on that image; on a group, a name counts when every phase has it. | | 🔬 Auto-segmentation | image or group | structures, report | Any automatic model of [auto-segmentation.md](auto-segmentation.md) on the image or on every phase: TotalSegmentator CT (3 mm, 1.5 mm or 6 mm, v2 or v3), its MR and task models, MRSegmentator, lungmask, MONAI whole body, CT-FM, VISTA-3D; the file stores the model's key (`"model": "lungmask_lobes"`; a workflow saved before the registry has none and keeps its TotalSegmentator variant). *Organs to keep* lists the classes kept and the name each is filed under (`heart` as `heart total`); none listed keeps everything found; *TG-263 names* names the structures by AAPM TG-263. With a model of sub-models, only the sub-models holding the listed organs run. Filed as RT structures (type ORGAN), segments, or both - in the image's own structure set (each phase's own on a group; a new one when it has none) or always a new set. A listed organ not found on an image stops the run. | | 👤 Body contour | image or group | structures, report | The body outline (type EXTERNAL), classical or model-assisted, filed like the organs. | | 💬 Prompt by name | image or group | structures, report | SegVol with text prompts (`liver`, `pancreas`, `aorta`): one line per structure, the prompt and the name it is filed under (empty keeps the prompt). For what TotalSegmentator's classes do not name. | | ⊕ Combine structures | A, B (optional, several) | structures, report | A alone with a margin (a PTV from an ITV), A ∪ B, A ∩ B or A − B, each side grown or shrunk first (uniform or per direction), the result cleaned (fill holes, close, keep the largest piece, drop small ones). On an image, or on every phase of a group. | | ✏ Rename or delete | structures | structures | Renames the structures that arrived by rules (`GTV*` to `GTV`), or deletes them, where they are: on an image, on every phase, or in the whole study. When no rule matches anything, the run stops. | | 📌 Transfer by relationship | target, reference, onto | structures, report | Places the target onto another image (or every phase) at the offset it has from a reference structure both images carry: the target placed by the heart when the images share no registration. | | 🔁 Copy to each phase | structures, group | structures | Copies structures onto every phase as they are, in patient coordinates, no registration: a fixed margin, a couch, an ITV. | | ⇄ Register | image, image | registration, report | Rigid or rigid + B-spline (elastix) or B-spline (plastimatch) of the moving image onto the fixed one, with the start (automatic, identity, centres of gravity) and the effort. | | ◎ Register by structures | structures, structures | registration, report | The image the *Fixed* structures were found on and the one the *Moving* structures were found on, aligned on those structures alone (paired by name; *Pairs* adds the ones named differently, `Heart = heart_total`): rigid or translation only, then optionally a local B-spline per structure, the start as for *Register*. The report has the registration's numbers and, per structure, the mean surface distance and Dice before and after. See [registration.md](registration.md#registration-by-structures). | | ➕ Propagate | registration, structures | structures, report | Carries the structures across the registration onto the other image, into its structure set or a segmentation series, with an optional name suffix, closing, filling and *keep the shape*. | | ⏩ Propagate to 4D group | structures, anchor (optional), group | structures, registrations, report | One image onto every phase, one registration per phase. With an anchor - a structure on the source image that every phase also has, the heart - the run is anchored: centroids matched, a rigid fit on the anchor plus a margin (by contours or by intensity), then a local deformable refinement, and the anchor's own landed copy (`_prop`) is compared with each phase's contour (Dice, HD95, centroid distance, a verdict). Without one, a plain deformable run. Filed in each phase's own structure set (or a segmentation series). See [star-target-propagation.md](star-target-propagation.md). | | 📈 Motion and ITV | targets, reference (optional), group (optional) | structures (the ITVs), report | The 4D motion pipeline of [motion-4d.md](motion-4d.md): each target (and the reference structure) as contoured on every phase when every phase has it, rigidly (around each structure, or one global body) and deformably; centroid tracks, peak-to-peak, correlation with the reference, registration QA; the ITV per target and model with an optional margin, filed on the reference phase. | | 📊 DVH | structures (several) | report | Dose-volume histograms against a dose of the study (by words of its label, else the first): the metrics listed (`D95%, D2cc, V20Gy, Dmean`), and with a protocol (`Heart Dmean < 5`, one per line, or a protocol file) which constraints hold. Optionally the cumulative curves. | | 📐 Dose estimation | structures (several) | report | One row of dose metrics per structure against the physical or the RBE-weighted dose, as the *Dose estimation* module shows it. | | ☢ DRR | image | report | Radiographs of the image at the gantry angles listed, or at the plan's beams: PNG files in the run folder, and optionally planar images of the study. | | 💾 Export DICOM | studies (several) | - | Writes each study it is given: its structures as RTSTRUCT or SEG - only the sets the run made or added to, or all - and optionally its images, doses and plans, keeping the UIDs or minting new ones. | | 📋 Save report | reports (several) | - | One CSV per table of every report (the motion report also as its full CSV) and one Markdown summary. | | 📥 File in the archive | studies (several) | - | Files the studies into the station's local archive: what an *Export DICOM* step of the run wrote of them, or the folders they were read from. | Folder parameters (*Export DICOM*, *Save report*) are inside the run's folder unless absolute; `{input}` is the title of the folder node the study came from, `{workflow}`, `{date}` and `{time}` are the run's. **Names already taken.** Every step that files structures says what happens when a set already holds the name (*Name taken*): *add a counter* (`heart total (2)`, the default, as the modules do), *file it as name_prop* (`heart total_prop`), or *replace the one there*. On a 4D group the choice is made once for every phase, so the target lands under one name on all of them even when only one phase had a structure of that name; the steps downstream are handed the names as landed. ## Running **▶ Run** in the editor opens the run window on the workflow as it is on the canvas. **Inputs.** One line per folder node, filled with the folder the node names. Change it here to run the same workflow on other data: the file is not changed. A relative folder is looked for beside the workflow file, then in the current folder, then beside the program. **Results go to.** The run makes a folder of its own there, ` -