The ObjectScript edition now processes the 20 independent Gaia DR3 input files in parallel using IRIS %SYSTEM.WorkMgr.
Each input file is processed as an independent work unit. The parent routine merges worker results in deterministic file and row order, preserving byte-identical output with the previously verified serial implementation.
The updated edition continues to produce 57,099 qualifying sources, passes all 16 validation cases, and matches the independent Python reference oracle.
In local testing, the median internal processing time improved from approximately 101 seconds for the serial implementation to approximately 33.6 seconds for the parallel implementation. Official moderator results may differ.
A solution to InterSystems Employee Programming Challenge #1. It scans 20 gzipped
Gaia DR3 epoch-photometry files and reports every astronomical object whose BP or RP
flux varied by more than 100 % across the observation period.
Implementation language: InterSystems ObjectScript (pure — no Python on the
execution path). A companion Python Embedded Python Edition exists as a separate
variant; this repository is the ObjectScript variant and is fully self-contained.
The ObjectScript edition now processes the 20 independent Gaia input files in
parallel using IRIS %SYSTEM.WorkMgr. Each worker writes indexed intermediate
results, and the parent routine merges them in deterministic input order. The
result remains byte-identical to the previous verified serial implementation.
For each source_id, over the valid (finite, non-NaN) values of each band:
bp_percentage_change = ((bp_max - bp_min) / bp_min) * 100
rp_percentage_change = ((rp_max - rp_min) / rp_min) * 100
percentage_change = max(bp_percentage_change, rp_percentage_change)
A source is written only if percentage_change > 100 (strict; exactly 100 is
excluded). Output columns, in order:
source_id,bp_min_flux,bp_max_flux,rp_min_flux,rp_max_flux,percentage_change
git clone https://github.com/bostonbrad/gaia-dr3-flux-objectscript.git
cd gaia-dr3-flux-objectscript
docker compose up --build -d
docker compose exec iris iris session iris
Then in the IRIS terminal (namespace USER):
USER>do ^RunScript
This prints the qualifying row count and elapsed time, and writes the result to
data/out/result.csv.
The production pipeline is pure ObjectScript. It runs the 20 independent input
files in parallel using IRIS %SYSTEM.WorkMgr (a shipped IRIS feature — no
third-party dependency), then merges deterministically.
src/RunScript.mac — the benchmark entry point. Run() times the work with$ZHOROLOG and calls $$Process^GaiaChallenge.src/GaiaChallenge.mac — the solution:
Process assigns each data/in/*.csv.gz a stable index in sorted filename%SYSTEM.WorkMgr queue, and dispatches one independentWaitForComplete.Worker (runs in a worker process) parses its one file and writes that^GaiaWork(fileIdx, seq)seq = row order within the file).%Stream.FileCharacterGzip (no externalrp_flux column (17),$DOUBLE flux values per band are collected (ignoringNaN/null/±Inf/invalid), min/max and the per-band percentage are computed,WriteOutput merges ^GaiaWork to data/out/result.csv by iteratingfileIdx in sorted-filename order, then seq in within-file order — so theWaitForComplete surfaces it to the parent, whichCorrectness is defined by an independent Python reference oracle
(tools/reference_solution.py), kept structurally separate from the production code.
A tolerance comparator (tools/compare_results.py) checks equivalence by parsed value
(abs/rel 1e-9), not text.
tests/, run python tests/test_reference.py).source_id set and order, all fields within 1e-9.docker compose build --no-cache reproduces the output byte-identically776a0e3e…).Median ~33.6 s inside Run() on the development machine, processing the 20 files
in parallel via %SYSTEM.WorkMgr (one warm-up run, then three measured runs:
32.84 / 35.79 / 33.65 s → min 32.84 s, median 33.65 s, spread 2.95 s). Environment:
22 cores / 32 GB, worker pool sized to the 20 files. Every run produced 57,099 rows and
the identical output SHA-256. These are local measurements; runtime is
hardware-dependent and official moderator results may differ. Only the code inside
Run() is timed. (The previous serial implementation measured a ~101 s median on the
same machine; that figure is retained for comparison in docs/performance-report.md.)
data/out/result.csv776a0e3ea95c5befa6663cdf3cfe176608b5745e5bb701d8ab0ea794aff6ed7eDesign decisions, data profiling, and engineering reports are in docs/. The data/in/
inputs are the fixed challenge benchmark and are never modified.
See LICENSE.