Research workflows

Reproduce a Python analysis in a fresh project

Run a complete example twice, compare input hashes and saved results, and record the research environment.

Reproduce a small Python analysis in a new project, starting from its saved inputs and code. You will check the input bytes and numeric result, and record the software used. Reopening a notebook's old output is not this check.

Before you start

Use two projects that you can edit, with Python 3 available. This example uses only the Python standard library. It does not require a GPU or installation of analysis packages. Use a new research-workflow folder so existing work is not overwritten. The commands below run in a CoCalc project terminal, not on your laptop. See Create a project and Use the terminal.

The complete example files are in the public source repository. Download measurements.csv and analyze.py using each file's Download raw file control, then upload them into the same project folder. For scripted transfer, use Run an analysis from your laptop.

Run the original analysis

In the project terminal, go to that folder. These examples assume the standard project home; use pwd and adjust the path if yours differs.

cd /home/user/research-workflow
python3 --version
python3 analyze.py measurements.csv result.json

Expected output:

count=4 mean=5.0

The CSV contains a value header followed by 2, 4, 6, and 8. The script writes result.json with count, mean, and input_sha256. Check the saved result, rather than treating an exit message as evidence that the right file was used:

python3 - <<'CHECK'
import hashlib
import json
from pathlib import Path
r = json.loads(Path("result.json").read_text())
assert r["count"] == 4
assert r["mean"] == 5.0
assert r["input_sha256"] == hashlib.sha256(Path("measurements.csv").read_bytes()).hexdigest()
print("PASS: saved result and input hash match")
CHECK

A hash checks identical input bytes; it does not establish whether research data are correct. A changed line ending also changes the hash.

Record the environment and evidence

Create a small manifest beside the result:

python3 - <<'MANIFEST'
import hashlib
import json
import platform
from pathlib import Path
manifest = {
    "python": platform.python_version(),
    "system": platform.system(),
    "machine": platform.machine(),
    "files": {
        name: hashlib.sha256(Path(name).read_bytes()).hexdigest()
        for name in ("analyze.py", "measurements.csv", "result.json")
    },
}
Path("manifest.json").write_text(json.dumps(manifest, indent=2) + "\n")
print("Saved manifest.json")
MANIFEST

Add a README.md with the question, the run command, expected output, Python version, selected runtime image or catalog identifier, and what you checked. For a real analysis, also record package versions or a lockfile, data provenance, seeds, and appropriate numerical tolerances. Do not copy credentials into the manifest or publish private data to make an example reproducible.

Rerun independently

  1. Create a new project and a new research-workflow folder.
  2. Transfer analyze.py, measurements.csv, manifest.json, and the README from the first project. Do not copy result.json yet; the second run must create it. You may use download/upload or the CLI transfer guide.
  3. In the second project's terminal, change to the new folder and verify the transferred inputs against the first run's manifest:
python3 - <<'CHECK'
import hashlib
import json
from pathlib import Path
m = json.loads(Path("manifest.json").read_text())
for name in ("analyze.py", "measurements.csv"):
    assert hashlib.sha256(Path(name).read_bytes()).hexdigest() == m["files"][name], name
print("PASS: input and code match the original")
CHECK
python3 analyze.py measurements.csv result.json
  1. Repeat the saved-result check above. For this deterministic example, compare the new artifact with the original manifest as well:
python3 - <<'CHECK'
import hashlib
import json
from pathlib import Path
m = json.loads(Path("manifest.json").read_text())
assert hashlib.sha256(Path("result.json").read_bytes()).hexdigest() == m["files"]["result.json"]
print("PASS: independent result matches the original")
CHECK
  1. Record the second project's Python version and image independently. Keep the original manifest; do not overwrite it with a new manifest before comparing. Matching this simple result does not prove all software environments are equivalent. For real floating-point or GPU workloads, compare the scientific acceptance criteria rather than assuming byte-for-byte output equality.

Reproduce software as well as files

A custom kernel can isolate notebook dependencies. Record its executable and recreate its packages in the new project. A published RootFS can share installed system software, but publishing excludes /home/user, /root, and /tmp. Research files and a virtual environment under HOME are not automatically included. Transfer the files and recreate HOME-based environments separately. Do not assume an image label alone captures a dataset or an external service.

For a notebook version of this analysis, follow Move a Jupyter or Colab notebook. Then use Research handoff to let a collaborator repeat the same checks, with the correct access to the files.

Diagnose a mismatch

After review, retain the source, manifest, and result together. Remove only the example folders or disposable projects you no longer need through the normal project controls.