Targets and Sessions#
CaptureGraph organizes data hierarchically: Targets contain Sessions, and sessions contain your captured files.
Targets#
A target is the subject of your capture—a building, patient, specimen, or project. It corresponds to the root directory:
See GetRootDirectory in the API reference.
Users name their targets when creating them in the app (e.g., "Daily Plant Growth", "Patient #42").
Target-Level Data#
Files and directories at the target level persist across all sessions:
# Configuration that applies to every session
settings = target.new_file(".settings").cache(
cgp.UserInputBool(label="Use RAW format?"),
skip_if_exists=True
)
# Reference data for comparison
reference = target.new_file("baseline").cache(
cgp.CaptureImage(label="Baseline photo"),
skip_if_exists=True
)
Use target-level storage for:
- User preferences and configuration
- Reference images or baseline data
- Participant/subject information
- Calibration data
Sessions#
A session is a timestamped subfolder for a single execution of your procedure:
See new_session() for the full signature.
Session folder names include:
- Your chosen prefix (e.g.,
daily_capture) - A hex-encoded microsecond timestamp
This ensures:
- Chronological sorting — Sessions sort by date automatically
- Mergeability — Data from multiple devices won't conflict
- No overwrites — Each run creates a new folder
Session-Level Data#
Files at the session level are specific to one execution:
# Data from this run only
session.new_file("photo").save(cgp.CaptureImage(label="Today's photo"))
session.new_file("measurement").save(cgp.UserInputNumber(label="Reading"))
Subdirectories#
Create subdirectories to organize related files:
# Session subdirectories
photos = session.new_directory("photos")
measurements = session.new_directory("measurements")
photos.new_file("front").save(cgp.CaptureImage(label="Front view"))
photos.new_file("side").save(cgp.CaptureImage(label="Side view"))
# Target subdirectories (persist across sessions)
config = target.new_directory(".config")
Naming conventions:
- Use dot-prefix (
.config,.settings) for hidden/system directories - Use descriptive names (
photos,measurements) for user-visible data
Accessing Sessions#
Retrieve existing sessions for comparison or validation:
# Get the first/last session with this prefix
first_session = target.get_first_session("daily_capture")
last_session = target.get_last_session("daily_capture")
# Check if this is the first execution
is_first_run = ~cgp.ProcedureCompleted(procedure=first_session)
Complete Example#
import capturegraph.procedures as cgp
def patient_visit_procedure():
target = cgp.GetRootDirectory()
session = target.new_session("visit")
# Target-level: Patient info (persists across visits)
patient_info = target.new_directory("patient")
demographics = patient_info.new_file("demographics").cache(
cgp.UserInputString(label="Patient ID"),
skip_if_exists=True
)
# Session-level: This visit's data
vitals = session.new_directory("vitals")
photos = session.new_directory("documentation")
return cgp.ProcedureSequence(
label="Patient Visit",
procedures=[
vitals.new_file("bp").save(
cgp.UserInputNumber(label="Blood Pressure (systolic)")
),
vitals.new_file("temp").save(
cgp.UserInputNumber(label="Temperature (°F)")
),
photos.new_file("wound").save(
cgp.CaptureImage(label="Wound Documentation")
),
session.new_file("notes").save(
cgp.UserInputString(label="Clinical Notes")
),
]
)
This creates a structure like:
My Patient/
├── patient/
│ └── demographics.json
└── sessions/
└── visit/
├── 00063B40E29D696A/
│ ├── vitals/
│ │ ├── bp.json
│ │ └── temp.json
│ ├── documentation/
│ │ └── wound.heic
│ └── notes.json
└── 00063B41A2C8F1B0/
└── ...
See Also#
- Fluent API —
.save(),.cache(),.load()patterns - Types and Nodes — Understanding PTypes and node categories
- Data Framework — Loading and analyzing captured data
- Filesystem Nodes API — All directory and file operations