Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion specs/001-pathway-pdfs/contracts/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ The single-event service (contracts/service.md).
| Flag | Environment | Meaning |
| ------------------------------ | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--port` | `PORT` | default 4370 |
| `--bind` | `BIND_ADDRESS` | default `127.0.0.1`; in its own container, an address the content service can reach |
| `--bind` | `BIND_ADDRESS` | default `127.0.0.1`; in its own container, an address only the content service and the analysis gateway (spec 002) can reach |
| `--graph`, `--files`, `--site` | | as for `book` |
| `--figures` | | as for `book`: the release's figures' folder, read for a PDF without an analysis while it passes `book`'s folder checks, ignored otherwise (contracts/service.md) |
| `--render` | `RENDER_SERVICE` | as for `figures`: draws the figures of a PDF with an analysis, and any the folder lacks |
Expand Down
5 changes: 3 additions & 2 deletions specs/001-pathway-pdfs/contracts/render.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ of WebsiteAngular (research R10).
- a single-event PDF goes on without it.
- **The text** is set in Roboto. pdf-export's page supplies the font, at weights 300 to
600 (research R5).
- **Node labels are 12 px** in the SVG (compartments' 80 px), and the smallest sets the figure's scale
against the legibility floor (research R4).
- **Node labels are 12 px** in the SVG (compartments' 80 px), and the smallest sets the size reported
against the run report's threshold (research R4). An illustration's lettering is outlines,
read from its `PATHWAY TEXT` paths and its viewport's scale (`src/layout/lettering.ts`).

## Settings for the figures' run (research R3, R7)

Expand Down
7 changes: 4 additions & 3 deletions specs/001-pathway-pdfs/data-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ the short entry alone, pointing at the full section, and not its subtree again.
after FR-017: the list substituted, and in a PDF made on request any other character
no font draws replaced by U+FFFD (in the book, such a character is a fault).
- `scale`: its size on the page, from which its labels' size follows (12 px for node labels in the SVG; the smallest sets it).
At least 5 pt, or a landscape page of its own; below that only for a diagram too large
for any page, listed in the run report (research R4).
As large as the page allows: the portrait text, or a landscape page of its own where that
prints it larger. Below 1 pt even so, it is listed in the run report (research R4).
- `link`: its interactive form on the website (FR-003).
- `overlay`: the analysis token, when there is one.

**Choosing a pathway's figure** (research R2, as graph-core does today):
Expand Down Expand Up @@ -154,7 +155,7 @@ cause (`unanswered`, `failed`, `refused`, `invalid` or `label`, contracts/figure

- `release`, the time taken, the page count and the size.
- Figures by kind, and those missing or stale in the figures' folder, by stable identifier.
- Figures below the legibility floor, by stable identifier.
- Figures whose labels print below 1 pt, by stable identifier (research R4).
- Release files missing, by name, from the preflight.
- Characters FR-017's list replaced, by code point and count; characters off the list, by
code point and stable identifier (a fault in the book, U+FFFD in a PDF made on request).
Expand Down
2 changes: 1 addition & 1 deletion specs/001-pathway-pdfs/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ Dockerfile
(R7), on the machine the release would use (if it is not this host, `event-pdf`'s
baseline is run again there);
- a single-event PDF's stages, with the render service's cache off (R7, SC-005);
- the diagrams' widths against FR-016's floor (R4);
- the diagrams' widths against FR-016's floor (R4; measured by T008, which replaced the floor);
- what the analysis service answers for an expired and a malformed token, and its
retention period, on a private instance (R6);
- the join's memory, and stamping page numbers after it (R4).
Expand Down
75 changes: 60 additions & 15 deletions specs/001-pathway-pdfs/research.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,19 +215,63 @@ synthetic documents, on this host under load.
are numbered as the book's are: a first print with placeholders, its anchors' pages
read back, and a second print. A reaction alone, or depth 0, has no contents list and
is printed once. The second print is in SC-005's budget (R7).
- **The legibility floor** (FR-016): a diagram's node labels, 12 px in the render
service's SVG (measured in its cache on 30 Oct 2026: 140–165 labels a diagram at 12 px,
compartments' at 80 px, a few at 16 px), never below 5 pt on the page. The smallest
label in the figure sets its scale, not the first. The figure's scale on the page gives its
labels' size. A figure that would fall below the floor at the text width gets a
landscape page of its own, at the largest size the page allows. A diagram so large
that even that is below the floor is accepted at that size (the PDF's vector drawing
can still be zoomed) and listed in the run report; FR-016 is amended to say so ("5 pt,
or the largest a landscape page allows"). A figure is never split across pages.
- At 12 px labels, 5 pt allows a figure about 1,155 of the SVG's pixels wide in
portrait and about 1,750 on an A4 landscape page with 20 mm margins (inference,
from the page sizes: 481.9 and 728.5 pt of text width, at 5/12 pt a pixel). Many diagrams are wider, so the exception may be common. The
first tasks count the release's diagram widths (R7, to measure).
- **Figure size** (FR-016, T008): a figure prints as large as the page allows, never
split: in the portrait text, or on a landscape page of its own where that prints it
larger. Its labels' size follows from its scale (the smallest label, not the first); one
whose labels print below 1 pt even so is listed in the run report.
- **Planned first:** a 5 pt floor, diagrams' node labels being 12 px in the render
service's SVG (measured in its cache on 30 Oct 2026: 140–165 labels a diagram at 12 px,
compartments' at 80 px, a few at 16 px). 5 pt allows about 1,155 of the SVG's pixels
in portrait and 1,750 on a landscape page (481.9 and 728.5 pt of text width).
- **Measured (T008):** release 98's 1,170 human diagrams, each drawn by the render
service from the release's files (its `RENDER_FILES`, WebsiteAngular #777–#779),
measured and placed by `measure()` and `place()`; none failed. Their sizes cannot be
read from the files: the render draws at twice the files' coordinates, with margins
of −10 to +478 px. 1,168 have 12 px labels, two 6 px. The median is 3,654 px wide,
the widest 19,652. Even on its best page, only 80 (7%) print labels at 5 pt, 311 at
3 pt, 652 at 2 pt and 1,070 at 1 pt; the median prints at 2.1 pt.
- **Today's book has no floor.** `event-pdf` (2c070d5) scales each diagram, a vector
drawing from the Java DiagramExporter, to the portrait text's width and at most half
the page's height (40% for a reaction), whatever its labels' size. The old exporter's
labels are 8 units of the diagram files' coordinates (Arial Bold, `FontProperties`,
shrunk further to fit a node); the render service's are 6 (12 px at twice the
coordinates), 25% smaller beside their diagram. From the files' sizes (inference, the
book's pages not measured; its margins taken as 20 mm), today's labels print at a
median of 1.85 pt (10% under 0.93, 10% over 3.8), and 51 diagrams reach 5 pt. The
rule above prints a median of 2.14 pt (1.08 and 4.36), at least today's size for
1,143 of the 1,170.
- **So 1,060 diagrams (91%) print on a landscape page**, being wider than tall, about
1.5 times as large as in the portrait text; 110 stay in portrait; 100 are
listed below 1 pt (the widest, at 0.44 pt).
- **Illustrations, measured from their outlines.** Their lettering is drawn as
outlines, so no font size can be read. Each pathway's label is one path
(`id="PATHWAY TEXT…"`), each letter a closed subpath of absolute commands. A label's
letters are measured as their cap height: from a line's baseline (the bottom most of its
letters share) to the top of the letters standing on it, the label taken at its tallest
line, since one label is one text layer at one size and a dash set apart on a line of
its own would otherwise pass for small letters (five illustrations have such lines).
The cap height is taken as a font's of the same cap height (0.71 of its size, Roboto's
0.711, Arial's 0.716). Release 98's 221 illustrations, every one with labels, none
transformed:
- every label's cap height is 8.49–8.94 of the file's units, a font of about 12 px,
as the diagrams' labels are;
- the render service fits each into its 1,600 × 1,000 frame (its viewport's
`matrix(a,0,0,a,e,f)`, 1.17 for the usual 1,366 × 768), so in the figure the
lettering is 13.9–14.8 px, except R-HSA-5619102 (2,664 × 1,230, fitted at 0.60), at
7.2 px. The reading from the render service's SVG and from the file agree, checked on
two (13.92 and 7.18 px);
- in the portrait text that prints at 4.2–4.5 pt; on a landscape page, larger, at
6.3–6.7 pt (R-HSA-5619102 at 3.3 pt), so every illustration prints landscape.
- **Decision** (user, 3 Nov 2026), for the reader, who reads the book on a screen: most
screens are wider than tall, so a wide figure on a landscape page fills more of one;
no page makes most diagrams' labels readable unzoomed, so every figure links to its
interactive form on the website (FR-003), where they are. The rule is two constants
in `src/layout/figure.ts`, `FLOOR_PT` (the report's threshold) and the comparison in
`place()`, so curators who prefer another, such as portrait unless the labels would
fall below a size, change it there. `measure()` reads an illustration's lettering
(`src/layout/lettering.ts`) as it reads text's sizes, the smaller of the two counting;
a label whose outlines are not read (a relative command, an arc, a viewport that is
not a plain scale) counts as unread, so the figure is reported as unmeasured.
- **pdf-lib:** the maintained MIT fork `@cantoo/pdf-lib`, if it passes the same tests;
otherwise pdf-lib 1.17.

Expand Down Expand Up @@ -646,8 +690,9 @@ dependencies, though a person may use them to look.
output path in, `TheReactomeBook.pdf` and a run report out;
- `pdf-export serve`, an HTTP service for the website: `GET /event/{stId}.pdf` with
depth and token, answering a PDF or the errors of Story 2's scenario 4. Its bind
address is a setting, loopback by default: in its own container it binds where the
content service can reach it.
address is a setting, loopback by default: in its own container it binds where its
two callers can reach it, the content service (these PDFs) and the analysis gateway
(spec 002's reports, served by the same process), and nothing else can.
- **The website's address** for FR-003's links to its pages is a setting (`--site`),
written into the links and never fetched.
- **WebsiteAngular's content service calls it** as it calls the Java library service
Expand Down
13 changes: 9 additions & 4 deletions specs/001-pathway-pdfs/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,10 @@ of pages with today's book.
to its page on the website;
- for a reaction, the events before and after it (only those the PDF holds) to their
sections;
- each event's name to its page on the website.
- each event's name to its page on the website;
- each figure to its interactive form on the website (user's decision, 3 Nov 2026): a
pathway's diagram or illustration in the Pathway Browser, the event selected where an
ancestor's diagram draws it, and a reaction's figure to its page, which opens it there.
- **FR-004**: An event held by more than one pathway MUST be written in full once in a
PDF, at its first place in document order. In the book, its later places MUST show a
short entry (name and stable identifier) linked to that section.
Expand Down Expand Up @@ -419,9 +422,11 @@ of pages with today's book.
- a running header naming the top-level pathway (in the book) or the event (in a
single-event PDF), or on front pages (introduction, analysis properties,
contents) that part's name, and a page number on every page but the cover;
- no figure split across pages, and none shrunk below the legibility size the plan
sets, unless it is already at the largest a landscape page of its own allows, in
which case it is listed in the run report;
- no figure split across pages, and each printed as large as the page allows: in the
portrait text, or on a landscape page of its own where that prints it larger (user's
decision, 3 Nov 2026: at release 98 most diagrams' labels print below 5 pt on any page,
as today's book's do, and are read by zooming or on the website); a figure whose labels
print below the size the plan sets for the run report is listed there;
- a cover in the website's style (User Story 6, scenario 3).
- **FR-017**: Characters no embedded typeface draws (user's decision, 30 Oct 2026), in
the text the layout writes and in the figures' labels alike:
Expand Down
7 changes: 5 additions & 2 deletions specs/001-pathway-pdfs/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@ for WebsiteAngular to ship it (T042).

**Done** (research R7): figures alone exceed `event-pdf`'s whole time for every reaction and every pathway in the sample but Signal Transduction; one figure with a token takes 4.6 s, and 18.7 s for the last of eight at once. SC-005 raised with the user, who left the choice to us: a PDF without an analysis, of an event the figures' folder holds, reads its figures from it and must keep `event-pdf`'s times (T023 measures it); one with an analysis, or of another species, draws them on request within 8 s plus 3 s per figure (spec SC-005; T022, T023). The script is `ci/measure/single.ts`.

- [ ] T008 [P] Measure the diagrams' widths (FR-016's floor, research R4). From the release's diagram files, take each diagram's width in SVG pixels at the website's 12 px node labels. Count how many fit at 5 pt in portrait (about 1,155 px), in landscape (about 1,750 px), and in neither. Record the counts in research R4. If more than 5% fit neither, raise FR-016's floor with the user. Measure the illustrations' lettering too (their text is outlines, so the layout cannot read it and reports them as unmeasured, T018): the smallest letter height in a sample of release 98's EHLDs, rasterised, and the scale that keeps it at 5 pt; then give `place()` a rule for them.
- [x] T008 [P] Measure the diagrams' widths (FR-016's floor, research R4). From the release's diagram files, take each diagram's width in SVG pixels at the website's 12 px node labels. Count how many fit at 5 pt in portrait (about 1,155 px), in landscape (about 1,750 px), and in neither. Record the counts in research R4. If more than 5% fit neither, raise FR-016's floor with the user. Measure the illustrations' lettering too (their text is outlines, so the layout cannot read it and reports them as unmeasured, T018): the smallest letter height in a sample of release 98's EHLDs, rasterised, and the scale that keeps it at 5 pt; then give `place()` a rule for them.

**Done** (research R4) — #106. Release 98's 1,170 human diagrams, drawn by the render service from the release's own files: only 80 (7%) can print their 12 px labels at 5 pt on any page, the median at 2.1 pt; today's book, which has no floor, prints a median of about 1.85 pt. Raised with the user, who chose, for the reader on a screen: each figure as large as the page allows, portrait or a landscape page of its own where that is larger (1,060 diagrams and all 221 illustrations landscape), never split, linked to its interactive form on the website (FR-003, amended), and listed in the run report below 1 pt (100 diagrams). FR-016 and the data model amended. The illustrations' lettering, outlines, is read from their `PATHWAY TEXT` paths at the render service's viewport scale (`src/layout/lettering.ts`): every label about a 12 px font, 13.9–14.8 px in the render's frame, one at 7.2 px; the render's SVG and the file agreed. Tests: 11 for the lettering, 6 for the figure's links, the placement tests rewritten for the rule. Each of these mutants made one fail: the tallest line not taken, glyphs off the baseline counted, the viewport ignored or any matrix taken, relative commands read as absolute, subpaths merged, no cap-height ratio, an unreadable label skipped or its count dropped, the lettering ignored or used only without text, never landscape, landscape on a tie, the threshold back at 5 pt, the report at the portrait size, no link, no selection, a reaction to the Browser, the section linking the event's page. The link was printed and read back: one annotation over the figure on its landscape page; without the link's `inline-block`, two. From #105's review: `serve`'s bind names its second caller, the analysis gateway (contracts/cli.md, research R9).

- [ ] T009 [P] Measure the analysis service's answers (research R6), on a private instance with a submitted analysis, never production. For each case, record the status and body in research R6:
- a good token;
- an unknown one;
Expand Down Expand Up @@ -383,7 +386,7 @@ passes.
- [ ] T029 [US1] `book` end to end, `src/cli.ts` (contracts/cli.md).
- **Flags and their environment variables** (contracts/cli.md): `--graph` (`NEO4J_URI`), `--database` (`NEO4J_DATABASE`), `--figures`, `--site` (`REACTOME_SITE`), `--files`, `--species`, `--out`, `--parallel` and `--report`. Credentials come from `NEO4J_USER` and `NEO4J_PASSWORD`, never the command line.
- **Writing:** the file is written beside its name and moved into place.
- **The run report:** the release; the characters FR-017's list replaced, by code point and count; each stage's time; pages and size; figures by kind; the figures below the legibility floor; missing figures and missing release files; and each FR-011 check's result. Everything is named by stable identifier, never a person.
- **The run report:** the release; the characters FR-017's list replaced, by code point and count; each stage's time; pages and size; figures by kind; the figures whose labels print below 1 pt (research R4); missing figures and missing release files; and each FR-011 check's result. Everything is named by stable identifier, never a person.

Tests:
- exit 0 on the fixture with one PDF (provisional until T030 adds the check);
Expand Down
Loading
Loading