Bipixel rotation method: An algorithm for chirality analysis of biological mesh network.
The 4 matches
- [1] § Materials and methods › Bipixel method ↔ scripts/Step4_GUI_CA_DRbias.py, lines 1–48 · score 0.94 · Step4_GUI_CA_DRbias.py, fitted spline, global maximum, spline curve, gui bipixel, asymmetry score
- [2] § Results › The bipixel method and rotation algorithm ↔ scripts/Step4_GUI_CA_DRbias.py, lines 109–182 · score 0.56 · log ratio, spline interpolation, Asymmetry score, peak, smoothed, CA
- [3] § CRediT authorship contribution statement ↔ scripts/Step4_GUI_CA_DRbias.py, lines 1–48 · score 0.56 · Kanta Kumaki, Koichi Matsuo
- [4] § CRediT authorship contribution statement ↔ scripts/Step3_GUI_Bipixel_Counts.py, lines 1–43 · score 0.55 · Kanta Kumaki, Koichi Matsuo
Paper
Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
Python · 348 lines · 13 KB · MIT · 3 matches
- # Step4_GUI_CA_DRbias.py
- # Dated: 2026-05-8 (Updated)
- # Author: Kanta Kumaki & Koichi Matsuo [Keio University School of Medicine & CIEM]
- """
- Chirality Analysis and Asymmetry Scoring Tool
- Usage:
- 1. CLI Mode:
- python Step4_GUI_CA_DRbias.py <excel_file1> [<excel_file2> ...]
- 2. GUI Mode:
- python GUI_CA_DRbias.py
- (Then select Excel files and plot options via dialogs)
- Description:
- This script performs automated chirality analysis on bipixel count data.
- Workflow:
- - Reads Excel files (compatible with GUI_Bipixel_Counts.py output).
- - For each sheet, fits a robust periodic spline to the 'angle' vs. 'count' data.
- - Handles circular periodicity (180-degree wrapping) for seamless boundary analysis.
- - Identifies the 'Center Angle' based on the global maximum of the fitted curve.
- - Calculates key metrics:
- 1. Center Angle (deg)
- 2. Log10(S1/S2) Ratio
- 3. Asymmetry Score (Mean absolute difference normalized by amplitude)
- - Generates publication-quality plots containing:
- - Raw samples and fitted spline curve.
- - Center angle (dashed vertical line).
- - S1 (Left) and S2 (Right) integrated areas filled from y=0.
- - Outputs a "Summary_Analysis" sheet as the first sheet in the original Excel file.
- Requirements:
- - numpy (2.0+ compatible), pandas, matplotlib, scipy, openpyxl
- """
- import os
- import sys
- import argparse
- import numpy as np
- import pandas as pd
- import matplotlib.pyplot as plt
- import tkinter as tk
- from tkinter import filedialog, messagebox
- from pathlib import Path
- from dataclasses import dataclass
- from typing import Dict, List, Optional
- from scipy.interpolate import UnivariateSpline
- from scipy.integrate import trapezoid # Required for NumPy 2.0+ compatibility
- # --- 1. Physics & Mathematical Helpers ---
- def wrap180(a: np.ndarray | float) -> np.ndarray:
- """Wrap angle(s) to [-90, +90) on a 180° circle."""
- return ((np.asarray(a) + 90.0) % 180.0) - 90.0
- def build_interpolant_tiled(x_deg: np.ndarray, y: np.ndarray, smoothing: float = None):
- """
- Fits a UnivariateSpline with ±180° tiling for periodic boundary stability.
- Strictly uses s=0 (interpolating through all points) by default to maintain
- biological fidelity. If the fit fails or results in non-finite values,
- it returns None to indicate the data quality is insufficient for analysis.
- """
- x = np.asarray(x_deg, float)
- y = np.asarray(y, float)
- # Pre-process: Remove NaN values
- mask = ~np.isnan(y)
- x, y = x[mask], y[mask]
- # Ensure at least enough points exist for a cubic spline (k=3)
- if len(x) < 4:
- return None
- # Pre-process: Ensure circular periodicity by ±180° tiling
- x_ext = np.concatenate([x - 180.0, x, x + 180.0])
- y_ext = np.concatenate([y, y, y])
- try:
- # Use user-defined smoothing if provided; otherwise, force s=0
- s_val = smoothing if smoothing is not None else 0
- # Fit the spline (Cubic, k=3)
- spl = UnivariateSpline(x_ext, y_ext, s=s_val, k=3)
- # Validate that the resulting spline is numerically stable at original points
- if not np.all(np.isfinite(spl(x))):
- return None # Return None if fit is unstable
- except Exception:
- # Return None for any convergence or mathematical errors
- return None
- # Return a functional wrapper for the spline interpolant
- return lambda ang: spl(np.asarray(ang, float))
- @dataclass
- class AnalysisResult:
- """Container for chirality metrics and visualization data."""
- status: str
- center_angle: Optional[float] # 失敗時は None
- asymmetry_score: Optional[float]
- S1: Optional[float]
- S2: Optional[float]
- log_S1_over_S2: Optional[float]
- details: Dict
- # --- 2. Core Analysis Engine ---
- def run_analysis(x_deg: np.ndarray, y: np.ndarray, smoothing: float = None) -> AnalysisResult:
- """
- Core Analysis Engine: Computes the center angle and integrates S1/S2 areas.
- This function reconciles the experimental data with a spline interpolant.
- If the interpolation fails due to poor data quality (returning None),
- the function returns a 'Failed' AnalysisResult with null (None) metrics.
- """
- f = build_interpolant_tiled(x_deg, y, smoothing=smoothing)
- # Handle cases where spline fitting is impossible (e.g., s=0 convergence failure)
- if f is None:
- return AnalysisResult(
- status="Failed",
- center_angle=None,
- asymmetry_score=None,
- S1=None, S2=None,
- log_S1_over_S2=None,
- details={}
- )
- # Generate a dense grid for numerical integration and peak detection
- xd = np.linspace(-90.0, 90.0, 3600)
- yd = f(xd)
- if np.all(np.isnan(yd)):
- raise ValueError("Interpolation resulted in All-NaN slice.")
- amp = np.nanmax(yd) or 1.0
- # Locate peak-based center (Global Maximum) as the primary Center Angle candidate
- gmax_idx = np.nanargmax(yd)
- max_ang = float(xd[gmax_idx])
- # Internal helper to calculate Asymmetry Score based on a given center angle
- def calc_asymmetry(ca: float) -> float:
- offs = np.linspace(0.0, 90.0, 900)
- y_plus = f(wrap180(ca + offs))
- y_minus = f(wrap180(ca - offs))
- return float(np.mean(np.abs(y_plus - y_minus)) / amp)
- best_ca = max_ang
- best_score = calc_asymmetry(best_ca)
- # Calculate S1 (Left) and S2 (Right) integrals split by the identified center angle
- t_span = np.linspace(-90.0, 90.0, 3600)
- y_centered = f(wrap180(best_ca + t_span))
- left_mask = t_span <= 0
- right_mask = t_span >= 0
- # Perform numerical integration using the trapezoidal rule
- S1 = float(trapezoid(y_centered[left_mask], t_span[left_mask]))
- S2 = float(trapezoid(y_centered[right_mask], t_span[right_mask]))
- log_ratio = np.log10(S1 / S2) if S1 > 0 and S2 > 0 else None
- # Helper function to extract periodic visualization segments
- def get_fill_data(t_start, t_end):
- ts = np.linspace(t_start, t_end, 1800)
- return wrap180(best_ca + ts), f(wrap180(best_ca + ts))
- return AnalysisResult(
- status="Success",
- center_angle=best_ca,
- asymmetry_score=best_score,
- S1=S1, S2=S2,
- log_S1_over_S2=log_ratio,
- details={
- "xd": xd, "yd": yd,
- "S1_fill": get_fill_data(-90, 0),
- "S2_fill": get_fill_data(0, 90)
- }
- )
- # --- 3. Visualization ---
- def save_plot(res: AnalysisResult, x_raw, y_raw, sheet_name, out_path, show_legend):
- """Generates area plots with specific legend order and periodic fill handling."""
- plt.figure(figsize=(8, 5))
- # 1. Samples
- plt.plot(x_raw, y_raw, 'o', label='Samples', color='black', markersize=5, alpha=0.6, zorder=3)
- # 2. Spline curve
- plt.plot(res.details["xd"], res.details["yd"], '-', label='Spline curve', color='black', linewidth=1.5, zorder=4)
- # 3. Center angle (Dashed line)
- plt.axvline(res.center_angle, color='black', linestyle='--', linewidth=1.2,
- label='Center angle' if show_legend else "", zorder=5)
- # Internal helper to handle plotting wrapped fill areas without horizontal artifacts
- def draw_periodic_fill(x, y, color, label_prefix, alpha=0.4):
- jumps = np.where(np.abs(np.diff(x)) > 90)[0]
- if len(jumps) == 0:
- s_idx = np.argsort(x)
- plt.fill_between(x[s_idx], y[s_idx], 0, color=color, alpha=alpha,
- label=label_prefix if show_legend else "", zorder=2)
- else:
- idx_splits = jumps + 1
- x_segments = np.split(x, idx_splits)
- y_segments = np.split(y, idx_splits)
- for i, (xs, ys) in enumerate(zip(x_segments, y_segments)):
- s_idx = np.argsort(xs)
- lbl = label_prefix if (show_legend and i == 0) else ""
- plt.fill_between(xs[s_idx], ys[s_idx], 0, color=color, alpha=alpha, label=lbl, zorder=2)
- # 4. S1 (Left) and S2 (Right) areas
- x_s1, y_s1 = res.details["S1_fill"]
- x_s2, y_s2 = res.details["S2_fill"]
- draw_periodic_fill(x_s1, y_s1, color='#4C86C6', label_prefix='S1 (Left)')
- draw_periodic_fill(x_s2, y_s2, color='#E15759', label_prefix='S2 (Right)')
- # Labels and Formatting
- plt.title(f"Sheet: {sheet_name}")
- plt.xlabel("Rotation angle")
- plt.ylabel("Bipixel count")
- tick_pos = [-90, -60, -30, 0, 30, 60, 90]
- plt.xticks(tick_pos, [f"{v}°" for v in tick_pos])
- plt.xlim(-90, 90)
- plt.ylim(0, None)
- plt.grid(True, linestyle=':', alpha=0.4, zorder=1)
- if show_legend:
- plt.legend(loc='upper right', frameon=True)
- plt.tight_layout()
- plt.savefig(out_path, dpi=300)
- plt.close()
- # --- 4. Main Controller ---
- def process_file(file_path: Path, show_legend: bool):
- """
- Main Controller: Iterates through worksheets and aggregates results into a summary Excel.
- Failed analyses are recorded as null entries in the summary table,
- effectively excluding 'bad data' while maintaining a record of the attempt.
- """
- xl = pd.ExcelFile(file_path)
- out_dir = file_path.parent / "plots"
- out_dir.mkdir(exist_ok=True)
- final_summary = []
- for sheet in xl.sheet_names:
- if "Summary" in sheet: continue # Skip existing summary sheets
- try:
- df = pd.read_excel(xl, sheet_name=sheet)
- df.columns = [str(c).strip() for c in df.columns]
- # Identify required columns using flexible keyword matching
- a_col = next((c for c in df.columns if 'angle' in c.lower()), None)
- v_col = next((c for c in df.columns if any(k in c.lower() for k in ['vertical', 'count', sheet.lower()])), None)
- if a_col is None or v_col is None:
- print(f"[WARN] Skipping {sheet}: Missing required columns.")
- continue
- # Extract target columns and remove rows with missing values
- df[a_col] = pd.to_numeric(df[a_col], errors='coerce').astype(float)
- df[v_col] = pd.to_numeric(df[v_col], errors='coerce').astype(float)
- valid_df = df[[a_col, v_col]].dropna().copy()
- if valid_df.empty:
- continue
- # Endpoint Harmonization:
- # If both -90° and +90° exist, average their values into -90°
- # and drop +90° to ensure seamless circular periodicity.
- idx_neg = valid_df[valid_df[a_col] == -90.0].index
- idx_pos = valid_df[valid_df[a_col] == 90.0].index
- if not idx_neg.empty and not idx_pos.empty:
- v_mean = (valid_df.at[idx_neg[0], v_col] + valid_df.at[idx_pos[0], v_col]) / 2.0
- valid_df.at[idx_neg[0], v_col] = v_mean
- valid_df = valid_df.drop(idx_pos)
- # Sort by angle and extract as numpy arrays for analysis
- valid_df = valid_df.sort_values(by=a_col)
- x, y = valid_df[a_col].values, valid_df[v_col].values
- # Execute analysis pipeline
- res = run_analysis(x, y)
- # Only generate visualization if the analysis was successful
- if res.status == "Success":
- save_plot(res, x, y, sheet, out_dir / f"{sheet}_plot.png", show_legend)
- print(f"[Done] {sheet}: Analysis successful.")
- else:
- print(f"[Skip] {sheet}: Spline fit failed (insufficient data quality).")
- # Append results to summary list (Metrics will be None/null if status is 'Failed')
- final_summary.append({
- "Sheet": sheet,
- "Status": res.status,
- "CenterAngle_deg": res.center_angle,
- "Log_S1_over_S2": res.log_S1_over_S2,
- "AsymmetryScore": res.asymmetry_score,
- "S1": res.S1,
- "S2": res.S2
- })
- except Exception as e:
- print(f"[ERROR] In sheet '{sheet}': {str(e)}")
- # Export aggregated summary to the original Excel file
- if final_summary:
- summary_df = pd.DataFrame(final_summary)
- with pd.ExcelWriter(file_path, engine='openpyxl', mode='a', if_sheet_exists='replace') as writer:
- # None values are automatically converted to empty cells in Excel
- summary_df.to_excel(writer, sheet_name="Summary_Analysis", index=False)
- # Reorder worksheets to place the Summary at the first position
- wb = writer.book
- wb._sheets.insert(0, wb._sheets.pop(-1))
- def main():
- """Application entry point handling arguments or GUI interaction."""
- parser = argparse.ArgumentParser(description="Chirality Analysis Pipeline with Hybrid GUI/CLI")
- parser.add_argument("--excel", nargs="*", help="List of Excel files to process")
- args = parser.parse_args()
- files = args.excel
- if not files:
- root = tk.Tk(); root.withdraw(); root.attributes('-topmost', True)
- files = filedialog.askopenfilenames(title="Select Excel Files", filetypes=[("Excel", "*.xlsx")])
- if not files: return
- show_legend = messagebox.askyesno("Plot Setting", "Show Legend in Plots?")
- else:
- show_legend = True
- for f in files:
- print(f"[INFO] Processing: {Path(f).name}")
- process_file(Path(f), show_legend)
- print("[DONE] Analysis completed.")
- if __name__ == "__main__":
- main()
Step4_GUI_CA_DRbias.py at commit faa0af4, under MIT · at the source
Overview
- Laboratory of Cell and Tissue Biology, Keio University School of Medicine, 35 Shinanomachi, Shinjuku-ku, Tokyo 160-8582, Japan
- Central Institute for Experimental Medicine and Life Science (CIEM), 3-25-22 Tonomachi, Kawasaki 210-0821, Japan
Abstract
Vertebrates are bilateral organisms characterized by both symmetrical and asymmetrical structures. While skeletons are grossly symmetrical, microscopic biological networks within the bone—such as cortical canals containing vascular networks—often exhibit deviations from precise mirror-image symmetry. These deviations make it challenging to detect subtle chiral biases amidst random structural variations. We developed the “bipixel rotation method” to quantify the extent of these biases, thereby enabling the characterization of porcine femoral cortical canals. In this approach, binarized 2D images are rotated stepwise and skeletonized, followed by the quantification of vertically adjacent pixel pairs. We defined “center angle” as the rotation angle that yields the peak vertical bipixel count, and calculated “down-right bias” based on the asymmetry of the distribution of vertical bipixels around this center angle. After validating the method using alphabetical fonts and geometric wallpaper patterns, we applied the method to the cortical canal layers in porcine fibrolamellar bone visualized via nano-computed tomography (nano-CT). The method successfully detected potential chirality in the cortical canals, identifying up-right versus down-right biases, demonstrating its capability to capture even subtle structural chirality. These results suggest that the bipixel method is a versatile tool for chirality analysis of diverse biological mesh structures in the body.
Reproduced under the paper's license (CC BY), from the paper cited above.
Repositories
Its files are read in the Code ↔ Paper reader above, with 4 matches between paragraphs and lines of code.
Koichimts/Bipixel_Method
faa0af4ccfd90e694470fe3404c43705b78339dc, 29 July 2026Availability: 1 check, the latest on 27 September 2026: the link answers
- 27 September 2026: the link answers
4 files
- scripts/
Step3_GUI_Bipixel_Counts , Python, 200 lines, 1 match.py - scripts/
Step4_GUI_CA_DRbias.py , Python, 348 lines, 3 matches - LICENSE, License, 21 lines
- README.md, Text, 153 lines
Zenodo 21439490
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
- 27 September 2026: the link answers (HTTP 200)
4 files
- scripts/
Step3_GUI_Bipixel_Counts , Python, 200 lines.py - scripts/
Step4_GUI_CA_DRbias.py , Python, 348 lines - LICENSE, License, 21 lines
- README.md, Text, 153 lines
The paper's code and data availability statement is in the Data section.
Tracing map
Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.
What the map holds:
- 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 4 scripts, each with its path and the digest of its content;
- 4 matches between paragraphs of the paper and lines of the code (method lexical-v1);
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
No dataset and no data link were found in the paper.
Data availability
Codes for performing the bipixel method are available at https://
Reproduced under the paper's license (CC BY), from the paper cited above.
Versions
The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.
Version 1, 27 September 2026: the first record
Recorded: type, language, journal, volume, pages, dates, 5 authors, 6 keywords, 1 funder, 26 references.
Cite
This paper
Kumaki, K., Kawaai, K., Noji, S., Kuroda, Y., & Matsuo, K. (2026). Bipixel rotation method: An algorithm for chirality analysis of biological mesh network. Journal of structural biology: X, 14, 100154. https://
BibTeX
@article{kumaki2026bipix
author = {Kumaki, Kanta and Kawaai, Katsuhiro and Noji, Shinobu and Kuroda, Yukiko and Matsuo, Koichi},
title = {{Bipixel rotation method: An algorithm for chirality analysis of biological mesh network}},
journal = {Journal of structural biology: X},
year = {2026},
month = jul,
volume = {14},
pages = {100154},
publisher = {Elsevier},
issn = {2590-1524},
doi = {10.1016/
url = {https://
pmid = {42564810},
pmcid = {PMC13446290}
}
RIS
TY - JOUR
AU - Kumaki, Kanta
AU - Kawaai, Katsuhiro
AU - Noji, Shinobu
AU - Kuroda, Yukiko
AU - Matsuo, Koichi
TI - Bipixel rotation method: An algorithm for chirality analysis of biological mesh network
T2 - Journal of structural biology: X
J2 - J Struct Biol X
PY - 2026
DA - 2026/
VL - 14
SP - 100154
SN - 2590-1524
PB - Elsevier
DO - 10.1016/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1016/
"type": "article-journal",
"title": "Bipixel rotation method: An algorithm for chirality analysis of biological mesh network",
"container-title": "Journal of structural biology: X",
"author": [
{
"family": "Kumaki",
"given": "Kanta"
},
{
"family": "Kawaai",
"given": "Katsuhiro"
},
{
"family": "Noji",
"given": "Shinobu"
},
{
"family": "Kuroda",
"given": "Yukiko"
},
{
"family": "Matsuo",
"given": "Koichi"
}
],
"container-title-short":
"volume": "14",
"page": "100154",
"DOI": "10.1016/
"PMID": "42564810",
"PMCID": "PMC13446290",
"ISSN": "2590-1524",
"publisher": "Elsevier",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
23
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.1364/boe.605322 [code]
- Generalized plaque digitization framework for multi-dimensional mesoscopic images.Journal: Biomedical optics expressIn common: Pillow, pandas, SciPy, 2 other tools, 1 reference
- [2] doi:10.1038/s41467-026-75662-w [code]
- Distinct Roles of Deep and Superficial Cortical Layers in Tone Prediction, Comparison, and Adaptation in Human Auditory Cortices.Journal: Nature communicationsIn common: Pillow, pandas, SciPy, 2 other tools, 1 reference
- [3] doi:10.1007/s00234-026-04103-8 [code]
- Enhanced detection of subtle cortical abnormalities in focal epilepsy using 7 T MRI surface-based models and graph neural networks.Journal: NeuroradiologyIn common: Pillow, pandas, SciPy, 2 other tools, 1 reference
- [4] doi:10.1038/s41598-026-51531-w [code]
- Multimodal age-dependent diffusion-MRI analysis of the neocortex in a rat model of cortical dysplasia.Journal: Scientific reportsIn common: pandas, SciPy, Matplotlib, 1 other tool, 1 reference
- [5] doi:10.1126/sciadv.aec4911 [code]
- Dendritic shaft constrictions shape synaptic integration in neurons.Journal: Science advancesIn common: pandas, SciPy, Matplotlib, 1 other tool, 1 reference
- [6] doi:10.7554/elife.110588 [code]
- Opening the black box toward a modular approach to spike sorting.Journal: eLifeIn common: Pillow, pandas, SciPy, 2 other tools
- [7] doi: [code]
- Real-time closed-loop feedback system for mouse mesoscale cortical signal and movement controlJournal: eLifeIn common: Pillow, pandas, SciPy, 2 other tools
- [8] doi:10.1371/journal.pone.0356243 [code]
- Functional organization and natural scene responses across mouse visual cortical areas revealed with encoding manifolds.Journal: PloS oneIn common: Pillow, pandas, SciPy, 2 other tools
- [9] doi:10.1038/s42003-026-10957-8 [code]
- Brain defence by the extracellular matrix protein Cochlin.Journal: Communications biologyIn common: Pillow, pandas, SciPy, 2 other tools
- [10] doi:10.1038/s41592-026-03211-w [code]
- Spatial isoform sequencing at single-cell resolution reveals cell-type-specific spatial isoform variability in multiple brain cell types.Journal: Nature methodsIn common: Pillow, pandas, SciPy, 2 other tools
Contribute
The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.
Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 2 repositories of the authors' code, each at its verified commit and with its license, 4 scripts, and 4 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:c1bb4848eee08f92…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
Request its removal
To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).
Discussion, reproductions, activity
Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.
Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
