# Samlede uttrekksnotater


---
# alrajabi2021
# NOTES – alrajabi2021 (Alberta's Tomorrow Project)

Extractor: opus-H · 2026-10-30 · Source: `post2015/alrajabi2021.txt` (Br J Nutr accepted manuscript, 38 pages). Table 5 rows were parsed by script from text lines 1306–1355 and checked against the printed values.

## New vocabulary
- `cohort_id = alberta` (as assigned in the brief; not yet in cohorts.csv).
- `source_page = ms p. 37 / ms p. 38`: manuscript page numbers, because journal pagination is not in the file.

## Contents
- **estimates.csv: 64 rows.** Table 5 (colorectal) only.
  - 4 exposures: processed meat from red meat; processed meat from non-red meat; processed meat combined; red meat.
  - × 2 models (Model 1, Model 2) × 2 sexes × 4 quartiles, with Q1 coded as the reference row.
  - Tables 2–4 (all cancers, 15 cancers, GI cancers) are not colorectal, so they were not coded.
- **adjustments.csv: 2 rows** (m1, m2).
- **dose_conversions.csv: 16 rows**, one per category set.

## Missing (not available or not printed)
- **No per-unit (continuous) estimates exist in the paper.** The brief asked for "per-unit and categorical", but only quartile analyses are reported.
- **Supplementary B, Tables SB1–SB4.** Binary WCRF/AICR cut-offs (red meat < / ≥ 500 g/wk, processed < / ≥ 50 g/wk). The text says only that nothing was significant after adjustment.
- **Supplementary A, Table SA1** (meat definitions) and **Supplementary C** (competing risk, "data not shown").
- **No colon/rectum split.** No cases or person-years per category.

## Judgment calls
1. **Red meat = `red_unprocessed`, includes_processed = `no`.**
   - The paper defines red and processed meat by WCRF/AICR criteria. The Introduction defines red meat as "all types of unprocessed mammalian muscle meat", and processed meat is analysed separately.
   - SA1 (the actual food list) is not available.
2. **All three processed-meat variables are coded `exposure = processed`**, distinguished by `exposure_text` and the category-set suffix (`processed_red`, `processed_nonred`, `processed_all`).
   - "Processed meat from non-red meat" (largely processed poultry) has no vocabulary value of its own. It should be kept out of any `processed` pooling unless chosen deliberately.
   - **Which row is "the" processed meat** for pooling is an analysis decision. `processed_all` is closest to the conventional definition.
3. **is_main_model = yes on Model 2** for every exposure × sex. The paper calls it the covariate-adjusted model and uses it in the abstract (1.90 for women, Q4 processed-from-red). Model 1 (energy-only) = `no`.
4. **is_mutually_adjusted_processed.**
   - Model 2 adjusts every row for "red meat, and all processed meat" (footnote c).
     - Red-meat rows: `yes`.
     - Processed rows: `unclear`. As printed, each processed-meat variable is adjusted for "all processed meat", which would make the combined variable adjusted for itself. The footnote is almost certainly generic, and what was actually entered alongside each processed variable is not stated.
   - Model 1: `no` for all rows.
5. **Age.** For CRC (and GI cancers) the models were **not** age-stratified and include no age covariate. The age stratification described in the Table 2/3 footnotes applies only to all-cancer and 15-cancer outcomes. So `adj_age = no` in both models.
   - The time scale is follow-up time from enrolment.
   - This is unusual and worth flagging for any adjustment-gradient analysis.
6. **Firth penalized Cox estimation** for CRC (because of small numbers). This is noted in the row notes.
7. **adj_diabetes = unclear (m2).** "Personal history of at least one health condition" is a composite covering diabetes, colorectal polyps, IBD, heart disease and others. `adj_family_history = yes`, but it refers to family history of all cancer types, not CRC.
8. **Dose bounds** are in g/week, sex-specific quartile cut-points as printed.
   - Q1 has only `dose_high`; Q4 only `dose_low`.
   - Q2 and Q3 printed ">46-≤89" give `dose_low` 46, `dose_high` 89.
9. **dose_conversions.**
   - No medians are printed.
   - `g_day_assigned` = closed-category midpoint (Q1 from 0), with the open top quartile at cut-point + ½ × the Q3 width (CUP-rule style), divided by 7. This is a unit conversion only; no portion assumption.
   - **These are my computed values, not the paper's.** `midpoint_rule = cup_rule`. The g/week midpoints are listed in the notes.

## Inconsistencies (recorded as printed)
- **CRC case totals.**
  - Table 1 prints 119 men, 147 women, total 265. 119 + 147 = 266.
  - Table 5 prints 118 / 147 (Model 1) and 116 / 141 (Model 2).
  - study.csv `cases_colorectal = 265` (Table 1 total).
- **Ascertainment date.** The methods say ACR linkage was in June 2018. The Table 1 footnote m says November 2017.
- **Section headings.** The Results headings speak of "High red and processed meat intakes". The text says the women's Q1 effect for processed-from-red was elevated for all cancers. For CRC, though, Q1 is the reference: the "mild intake" wording applies to Tables 2–3, not Table 5.
- No CI or symmetry problems in Table 5. checks.py found no flags apart from the expected `9_uverifisert`.


---
# bernstein2015
# NOTES – bernstein2015 (NHS + HPFS)

Extractor: opus-F · 2026-10-30 · Source: `post2015/bernstein2015.txt` (PLoS ONE 10(8):e0135959, pages x/16). The 144 Table 2/3 values were checked by position against the txt with a script, and all match. The S1–S5 Files (DOCX) are not on disk.

## New vocabulary
- `cohort_id`: `nhs`, `hpfs` and `nhs_hpfs` (as instructed). The pooled rows are a random-effects meta-analysis of the two cohort-specific models, not a pooled-data model.
- `subgroup` values for exposure timing: `timing_baseline`, `timing_simple_update`, `timing_lag_4_8y`, `timing_lag_8_12y`, `timing_lag_12_16y`. The primary cumulative-average rows have an empty subgroup.
- Other `subgroup` values: `followup_from_1986`, `physical_activity_low`/`_high`, `family_history_crc_yes`/`_no`.

## Contents (163 rows, all continuous per 1 serving/day)
- **Tables 2–3: 144 rows.** 4 outcomes (colorectal, proximal, distal, rectum) × 3 exposures (total red, unprocessed red, processed red) × 2 models (age-adjusted, multivariable) × 6 timing models (baseline, simple update, 4–8, 8–12 and 12–16-y lag, cumulative average).
- **Results text: 19 rows.**
  - Sex-specific processed meat, distal colon: NHS 1.37, HPFS 1.35.
  - Sensitivity models: + fruit/veg; + animal, vegetable or total protein; mutual adjustment with fish and poultry.
  - NHS follow-up starting 1986.
  - Effect modification by physical activity and family history.
- **No category estimates are printed.** The paper reports only per-serving trends, so there are no category sets and dose_conversions has a single explanatory row.

## Judgment calls
1. **Unprocessed red meat includes hamburger.** The FFQ items are "beef or lamb as main dish", "pork as main dish", "hamburger" and "beef, pork, or lamb as a sandwich or mixed dish" (p. 3). Under R6, `exposure_includes_processed = partial`, while `exposure = red_unprocessed` is kept because the paper defines it as unprocessed. study.csv `includes_processed = partial`. Total red meat = `red_total` (yes). Processed red meat = bacon, beef/pork hot dogs, salami/bologna/other processed sandwiches, sausage/kielbasa.
2. **is_main_model = yes** goes to the multivariable cumulative-average rows, because the paper calls cumulative average "the primary model" (p. 4). That gives 12 pooled rows: 3 exposures × 4 outcomes, sex = all. The two sex-specific rows (NHS women, HPFS men; processed meat, distal colon) are also `yes`, since they are the only sex-specific estimates printed (one per exposure × outcome × sex). All age-adjusted, other-timing, sensitivity and subgroup rows are `no`.
3. **adj_sex = yes** for the pooled models, because they combine sex-specific cohorts. Endoscopy history → `adj_screening = yes`. Vitamin D and multivitamin use have no flag.
4. **Denominators.** `person_years` = the Table 2 cohort total for each timing model (e.g. 3,452,754 for cumulative average). It is not subsite-specific. `n_cases` = the outcome-specific cases from Tables 2/3 for each timing model. Text-only rows have `denominator_type = none`.
5. **Mutual-adjustment rows (p. 9).** The text says "With adjustment for processed red meat, fish, and poultry" for unprocessed meat. For the processed-meat HRs in the same sentence, I assumed adjustment for unprocessed red meat, fish and poultry (m8). The text does not state this explicitly.
6. **Timing for text-only stratified rows** is not restated. I assumed cumulative average (the paper's convention: "From here on … cumulative average unless otherwise noted").
7. **Not coded (not available):**
   - The S5 File gram-increment estimates (per 100/120 g unprocessed, 30/50 g processed). This matters for CUP-type use.
   - The S1–S4 sex-specific tables.
   - The poultry hot-dog and never-smoker sensitivity analyses (no numbers given).

## Discrepancies and typos in the paper
- **Distal colon cases:** Table 3 = 817 (= 514 + 303 from Results p. 4); Abstract = 816.
- **Rectal cancer, unprocessed red meat, multivariable cumulative average:** the Results text gives P trend 0.09, but Table 3 prints 0.37. The age-adjusted P in Table 3 is 0.09. The Table 3 value is recorded, and the row is flagged in notes.
- **Row 001** (total red meat, baseline, age-adjusted) prints 1.10 (1.04–1.15). checks.py flags its log asymmetry at 0.21; most likely rounding. Recorded as printed.
- **Colon total** is not reported. Proximal + distal + unspecified colon is not given as one number, so `cases_colon` is empty.

## Supplement rows (30.10)

Extractor: opus-S1 · 2026-10-30 · Sources: `/home/claude/drive/supplements/bernstein2015_S1.txt` … `_S5.txt` (text versions of S1–S5 Files). Rows bernstein2015_164–515 (352 rows), source_page = `suppl`.

### New vocabulary
- `dose_unit = per_120g` (S5, 120 g/day of red meat). `per_100g`, `per_30g`, `per_50g` and `servings_week` are already in the codebook.
- `subgroup`: reuses the timing values from the main text (`timing_baseline` … `timing_lag_12_16y`; empty = cumulative average).
- `category_set_id`: `bernstein2015_mv<timing>_colorectal_<sex>_<exposure>`, with timing ∈ baseline, simpleupd, lag4_8, lag8_12, lag12_16, cumavg. Continuous rows keep an empty category_set_id, as the main-text rows do.

### What was added
| Table | Rows | Content |
|---|---|---|
| S1 (NHS, women, `nhs`) | 108 | colorectal × 3 exposures × 6 timing models × (5 categories + per serving/day) |
| S2 (HPFS, men, `hpfs`) | 108 | same as S1 |
| S3 (NHS, women) | 53 | proximal / distal / rectum × 3 exposures × 6 timings, per serving/day. 54 printed; 1 duplicate skipped |
| S4 (HPFS, men) | 53 | same as S3 |
| S5 (pooled, `nhs_hpfs`) | 30 | colorectal / colon / proximal / distal / rectum × (total red 100/120 g, unprocessed red 100/120 g, processed 30/50 g) |

dose_conversions: 36 rows (bernstein2015_c2–c37), one per S1/S2 category set. g_day_assigned is empty because no gram weight per serving is given.

### Judgment calls
1. **is_main_model.**
   - S1/S2: cumulative-average rows (categories + per serving) = `yes` for exposure × colorectal × women/men. The other timings = `no`.
   - S3/S4: cumulative-average rows = `yes` per exposure × subsite × sex.
   - S5: per the supplement brief, unprocessed red meat per 100 g/d = `yes` for all five outcomes (_488, _494, _500, _506, _512). **Conflict:** the existing main-text per-serving rows _024, _060, _096 and _132 (same exposure × outcome × sex = all) stay `yes`, because existing rows may not be edited. A note has been appended to each. The controller must pick one per combination.
   - Colon (total) appears only in S5. For colon, total red per 100 g (_492) and processed per 50 g (_498) are also `yes` (CUP increments). Their 120 g / 30 g siblings are `no`. For the other outcomes, the S5 total-red and processed rows are `no`, since the per-serving main-text rows remain main.
2. **Duplicates skipped.** S3 and S4 processed red meat, distal colon, cumulative average (1.37 [1.02–1.85] P 0.04; 1.35 [0.98–1.85] P 0.07) are the existing rows _145 and _146. Their values match exactly. Notes were appended, adding n_cases 514/303.
3. **Category bounds.**
   - Recorded in servings/week.
   - Bounds printed per day were converted ×7: ">5 svg/wk to ≤1 svg/d" → 5–7; ">1 to ≤2 svg/d" → 7–14; ">2 svg/d" → 14+.
   - Processed "0 svg/wk" → 0–0.
   - Per-category cases and person-years are not printed (`denominator_type = none`). Continuous rows carry the timing-specific cohort totals from the S1/S2 header (cases / PY), following the main-text convention. Subsite rows use subsite cases with the cohort PY.
4. **P for trend (S1/S2)** is printed between the category rows and the per-serving row. Its values match the per-serving estimate (e.g. NHS processed, cumulative average: 1.17 [0.97–1.42], P 0.10), so it is placed on the continuous row as `p_trend`.
5. **Adjustment set.** All S1–S5 footnotes match m2 (S2/S4 without HRT, since the cohort is men), so m2 is reused. No new adjustment sets.
6. **S5.**
   - The table does not say how the cohorts were combined. `nhs_hpfs` is assumed, as for the pooled main-text rows (random effects).
   - One P value is printed per exposure and outcome. It is put in `p_trend` on both increment rows of the same linear term.
   - The S5 header says "processed meats". The paper's variable is processed red meat; the row is coded `processed` and noted.
   - Colon total cases are not printed anywhere, so n_cases is empty.
7. **Unprocessed red meat** keeps `exposure_includes_processed = partial` (hamburger), as in the main text.

### Discrepancies and contradictions
- **Main text vs supplement: distal colon, unprocessed red meat, pooled (row _096).** The main text prints 0.75 (0.68–0.82) in the Abstract, Results and Table 3. The cohort-specific values in the supplement are NHS 0.73 (0.53–1.01) and HPFS 0.75 (0.51–1.09). Inverse-variance pooling of these gives about 0.74 (0.58–0.94). The printed pooled CI is therefore implausibly narrow, probably a printing error. The S5 per 100 g value, 0.79 (0.65–0.97), is consistent with the wider interval. Flagged in _096 notes.
- **Methods text vs S5.** The Methods text says "per 50 g/day for processed red meat and 100 g and 120 g/day for unprocessed". S5 also gives 30 g/day for processed meat and 100/120 g for total red meat. All are coded.
- **Formatting only.** S4 prints "1.15(0.87-1.52)" without a space. S5 mixes "-" and "," as CI separators. Values are unaffected.
- **checks.py** (scratch copy) flags 1 new row: _194, NHS total red meat, baseline, per serving, 1.02 (0.95–1.11), asym 0.16. This is two-decimal rounding.
- **study.csv** is not changed. `cases_colon` is still empty because no colon total is printed.


---
# bostick1994
# Bostick 1994 (Iowa Women's Health Study): extraction notes (opus-C, 2026-10-30)

Source: Cancer Causes Control 5:38–52, full text `Understudier WCRF/bostick1994.txt` (OCR). All numbers come from the full text: Table 1 p. 41, Table 3 p. 42–44 (meat block p. 43, "Total eggs and meat" p. 44, footnotes f–g p. 44–45), Methods p. 39–41. The study card was opened only to locate tables. No supplement exists.

## New vocabulary
- `category_set_id` exposure tokens: `redmaindish`, `poultryskin`, `poultrynoskin`, `seafoods`, `processed`, `red`, `white`, `totaleggsmeat`. Model tokens: `age` (age-adjusted) and `mv` (multivariate).
- No new controlled-vocabulary values were needed.

## Scope coded (74 rows)
- **Table 3 "Meat (servings/wk)" block**: 8 variables × 2 models (age-adjusted, multivariate), reference rows included:
  - beef, lamb, or pork as main dish (4 categories)
  - poultry with skin (4)
  - poultry without skin (4)
  - seafoods (5)
  - processed meats (5)
  - red meat (5)
  - white meat (5)
  - total eggs and meat (5)
- Outcome is **colon only**. The 78 rectal cancers were not counted as cases (p. 40). Women only.
- **Not coded:** energy, sucrose-containing foods, sucrose, fructose, carbohydrates, fat, cholesterol and protein rows in Table 3. They are not meat, per the brief: "sugar-related rows … only if they are meat". Tables 4–5 (non-dietary factors) were also not coded. "Liver", eggs and individual seafoods are discussed in the text (p. 49: "no relationship … suggested" for liver, eggs) but no numbers are printed. Sensitivity statements about early-diagnosed cases cover energy only. No continuous estimates are printed.

## Judgment calls
1. **Main-dish item (as requested).** Table 3 fn g prints the FFQ item as **"beef, pork, or lamb as a main dish (e.g., steak, roast, ham, etc.)"**. Ham is included. Hamburger and "beef, pork, or lamb as a sandwich or mixed dish (e.g., stew, casserole, lasagna, etc.)" are separate FFQ items and not part of this variable. Bacon, hot dogs and other processed meats are also separate. Coded as `red_main_dish`, `exposure_includes_processed = partial` (ham in; bacon, sausage and luncheon meats out). The study-level `red_meat_definition` and `includes_processed = partial` refer to this variable, which is the one CUP used.
2. **"Red meat" (separate variable) = `red_undefined`, includes_processed `unclear`.** The paper gives no definition or footnote for "Red meat". Its baseline mean is 7.9 servings/week, against 2.4 for the main dish and 0.8 for processed meats (Table 1). It must therefore combine several FFQ items, probably hamburger, sandwich/mixed dishes, processed meats and liver, but this is not stated.
3. **"Processed meats" = `processed`, includes_processed `yes`.** Not defined. It is unclear whether the variable is the sum of bacon, hot dogs and "other processed meats (sausage, salami, bologna, etc.)" or just the last of these.
4. **Poultry with skin / without skin = `poultry`**, coded as two separate category sets. Table 1 calls them "Chicken with/without skin". **Seafoods = `fish`**. It includes shellfish; the variable is not defined, and the FFQ items are listed only in fn g. **White meat = `white_meat`**: fn f says chicken or turkey with or without skin, fish, shellfish.
5. **"Total eggs and meat" = `total_meat`, includes_processed `yes`, but it INCLUDES EGGS.** Fn g lists eggs, poultry, bacon, hot dogs, other processed meats, liver, hamburger, beef/pork/lamb sandwich or mixed dish, main dish, and fish/shellfish items. No vocabulary value fits, so the eggs are flagged on every row. Do not pool it as total meat without a decision.
6. **is_main_model.** `yes` for the multivariate RR (Table 3 fn a model) for every exposure, `no` for the age-adjusted RR. The paper reports only these two models.
7. **Age-adjusted rows have no CI.** The paper prints CIs only for the multivariate RRs. The age-adjusted points are coded with empty CI (R1: all models). checks.py flags them as `1_mangler_ci` (29 rows, all age-adjusted non-reference rows). This is expected and not an error.
8. **Trend statistics.** Table 3 prints "χ² for trend (P-value)", for example "0.16 (0.69)". `p_trend` holds the P-value on the top-category row, and the χ² is quoted in `notes`.
9. **Doses.** `dose_unit = servings_week` (table header "Meat (servings/wk)"). Bounds as printed: "< 1" → high 1; "1" → 1/1; "2-3" → 2/3; "> 3" → low 3, open. Single-value categories (0.5, 1, 1.5, 2.0) are coded low = high = value. No per-category medians or means are printed. Categories are "based on distribution of the data" (fn b).
10. **checks.py `4_dose_ikke_stigende` for both poultry variables** (`[0, 0.5, 1, 1]`). The categories are "1" and "> 1". The open top category's printed lower bound (1, exclusive) equals the previous single value. This is recorded as printed, not as an error.
11. **Denominators.** No person-years or participants per category are printed, so `denominator_type = none`. The total is 167,447 PY.
12. **Adjustment (m2).** Age, total energy (as a covariate), height, parity, total vitamin E, vitamin E × age, and vitamin A supplements. **Not adjusted:** BMI, smoking, alcohol, physical activity, fibre, calcium, other meats, NSAID, screening, family history. The last three were not measured (p. 48). The others were "considered" but did not enter the final model. `is_mutually_adjusted_processed = no` on all rows.
13. **Study-level.** `n_participants = 35,216` (p. 40; matches 212 + 35,004 in Tables 1–2). The abstract says 35,215. `followup_years` is empty and `followup_type = unclear`: the text says a "five-year period" from 1986 to 31 Dec 1990, with 167,447 PY, and gives no mean or median. `outcome_ascertainment = registry` (SEER Iowa). `cases_colon = 212`.

## Printed anomalies and OCR notes (recorded as printed)
- **White meat categories "< 1.0, 2.0, 2.5-3.5, 4.0-5.0, > 5.0"**: intake between 1.0 and 2.0 servings/week has no category. This may be a printing or OCR loss (e.g., "1.0-2.0"). Recorded as printed: category 2 has bounds 2.0/2.0.
- **OCR artefacts, corrected:** "(0.81-1,68)" for poultry with skin, category 2 (comma read as a decimal point) → coded 1.68. Reference "1,00" for poultry without skin → 1.00. "(0.71-1.61 )" → 1.61. No numeric ambiguity.
- **Covariate-adjustment jumps** (not typos, but notable): the main dish top category goes from 1.07 (age-adjusted) to 1.21 (multivariate); poultry without skin category 2 goes from 0.84 to 1.26. The paper does not explain either.
- **Text vs table:** the Discussion (p. 49) says increased risk was "suggested with higher intakes of poultry with skin and with processed meats, and to a lesser extent with beef, lamb, or pork as a main dish". This is consistent with Table 3 (1.52, 1.51, 1.21). No disagreement found.
- **Table 2 vs Table 4 never-smokers** (141 vs 142) is not a meat row and was not coded.
- No CI-asymmetry flags were raised for any multivariate row.

## Portion size / grams
- **No grams per serving** are printed. The FFQ is a 127-item semiquantitative Willett-type questionnaire, "virtually identical" to the NHS 1984 FFQ, with standard portions that are not given in this paper. No per-category medians are printed either. `g_day_assigned` is left empty in all 16 dose_conversions rows.
- Table 1 age-adjusted mean servings/week for cases vs noncases: main dish 2.4/2.4; chicken with skin 0.8/0.8; chicken without skin 0.9/1.1; seafoods 1.4/1.7; processed 0.9/0.8; red meat 7.7/7.9; white meat 3.2/3.5; total eggs and meat 13.1/13.6.
- `weight_basis = unclear`.


---
# bradbury2020
# NOTES – bradbury2020 (UK Biobank)

Extractor: opus-F · 2026-10-30 · Sources: `post2015/bradbury2020.txt` (IJE 49:246–258) and the rendered `pdf_in/dyz064.pdf` for Figure 1. The Figure 1 forest-plot numbers (mean intake, participants, cases, HR (95% CI), P trend) are printed in the figure image but missing from the txt. They are coded with `source_table = Fig 1` (tillegg rule 6: printed numbers only). `bradbury2019.txt` is the same paper (advance access) and is not coded separately.

## New vocabulary
- `subgroup`: `fish_type_oily_fish`, `fish_type_non_oily_fish`.
- `subgroup`: `excl_diet_change_illness` (opus-S3, supplement S3 sensitivity analysis).

## Contents (50 rows)
- **Figure 1 (p. 249): 5 exposures × 4 categories = 20 category rows + 5 per-increment rows.** Exposures: red and processed meat, red meat, processed meat, poultry, total fish. Multivariable model, colorectal, sexes combined.
- **Table 3 (p. 255):** 15 per-50 g rows for red and processed meat with cumulative sequential adjustment. The first row is the minimally adjusted model; the last equals the fully adjusted model.
- **Results text (pp. 252, 255): 10 rows.**
  - + milk/cheese/cereal fibre for red+processed, red and processed meat.
  - Red meat + processed meat (1.12) and processed meat + red meat (1.33), with the processed-meat per-50 g base (1.40).
  - Sex-specific men 1.39 / women 0.99.
  - Oily and non-oily fish.

## Judgment calls
1. **Measurement-error corrected rows.** As the brief instructs, every per-increment (trend) row is `is_calibrated = yes`. The trend uses the re-measured 24-h means assigned to the baseline categories ("reduces the impact of regression dilution bias", p. 251). That is 30 rows. `is_main_model = yes` goes to the Figure 1 category rows (5 sets, colorectal, all).
2. **dose_point = mean intake g/day per category (Figure 1)**, `paper_mean`, `dose_unit = g_day`. The frequency bounds are in `category_label`.
3. **Red meat definition (`includes_processed = no`) is inferred, not quoted.** The paper lists the touchscreen questions "processed meat, poultry, beef, lamb, pork" (p. 248) and treats red meat and processed meat as separate variables that sum to "red and processed meat". It never spells out that red meat = beef + lamb + pork. Knuppel 2020 (same questions) does.
4. **Sex-specific text rows (p. 255).** The sentence reports heterogeneity "for the associations between colorectal cancer and red and processed meat (Pheterogeneity = 0.008)", then gives "HR for each 50-g/day increment in red-meat intake = 1.39 (1.17–1.64)" in men and 0.99 (0.83–1.19) in women. The label conflicts with the sentence subject. I coded these as `red_total` (red and processed), with exposure_text noting the 'red-meat' label.
   - Supplementary Table 4 (sex-specific), Table 8 (colon/rectum) and Table 9 (proximal/distal) are **not on disk**. No colon, rectum or subsite rows could be coded, and `cases_colon`/`cases_rectum` are empty.
5. **Table 3 sequential models** each get their own adjustment set (`bradbury2020_s01`–`s13`), with cumulative flags. Waist circumference is not flagged as BMI. Steps with no matching flag (height, vitamin D, parity, menopause, OCA) leave the flags unchanged.
6. **The processed meat per 50 g row (1.40, 1.04–1.88)** is the paper's base for the mutual-adjustment analysis, not a separate model. It is coded with m2. It is consistent with 1.19 per 25 g (1.19² ≈ 1.42).
7. **adj_folate = yes** means folate *supplement* use only. Energy is not adjusted (not available). Screening is not adjusted.

## Discrepancies and typos in the paper
- **The poultry per-25 g row in Figure 1 prints no case count**, so `n_cases` is empty. The category cases sum to 2595.
- **Case totals differ by exposure:** red+processed 2575, red 2576, processed 2597, fish 2576 (vs 2609 overall).
- **Table 3 shows identical HRs** (1.17, 1.04–1.32) for the last ten steps. Recorded as printed.
- **The cereal fibre covariate:** the Methods mention a fibre score, but the main model does not include fibre. It enters only in the sensitivity model m3.

## Supplement rows (30.10)

Extractor: opus-S3 · 2026-10-30 · Source: `supplements/bradbury2020_File006.txt` (Supplementary Tables). Scope as assigned: S3, S4, S8, S9; meat, poultry and fish rows only. Rows `bradbury2020_051`–`_248` (198 new rows; file now 248 rows). This section supersedes the statement in judgment call 4 above that S4, S8 and S9 are not on disk.

### Rows added per table
| Table | Rows | Content |
|---|---|---|
| Suppl Table S3 | 50 | Minimally adjusted model (m1): 5 exposures × 4 categories + 5 per-increment trends. Sensitivity analysis excluding participants who changed diet due to illness (n = 425,112; m2; `subgroup = excl_diet_change_illness`): 5 × 4 categories + 5 trends. The fully adjusted all-participant column was **not** re-coded: all 25 values are identical to the Fig 1 rows `_001`–`_025` (checked programmatically). |
| Suppl Table S4 | 48 | Men and women, fully adjusted: 5 exposures × 4 categories × 2 sexes = 40 category rows + 8 trend rows. The red-and-processed per-50 g trends for men/women were already coded from the Results text (`_047`, `_048`) and were not duplicated. |
| Suppl Table S8 | 50 | Colon and rectum, fully adjusted: 5 × 4 categories × 2 outcomes + 10 trends. |
| Suppl Table S9 | 50 | Proximal and distal colon, fully adjusted: 5 × 4 categories × 2 outcomes + 10 trends. |

Also added: 40 `dose_conversions` rows (`bradbury2020_c6`–`_c45`), one per new category set, with the category mean g/day printed in the table (`portion_source = paper`, `midpoint_rule = paper_mean`; sex-specific sets use the sex-specific means). `study.csv`: `cases_colon = 1718`, `cases_rectum = 858` (sums of red-meat category cases in S8); proximal 865 + distal 755 (S9) noted. No new adjustment sets: minimally adjusted = m1, fully adjusted = m2.

### Judgment calls
1. **is_main_model.** Fully adjusted category rows in S4 (men, women), S8 (colon, rectum) and S9 (proximal, distal colon) are `yes`. This follows the existing convention for this study: the category rows are main, and every per-increment trend row is `is_calibrated = yes`, `is_main_model = no`. Minimally adjusted rows and the diet-change exclusion rows are `no`.
2. **Trend rows.** All 38 new per-increment rows are `is_calibrated = yes`. The trend uses the re-measured 24-h means as scores. `n_cases` is left empty on the trend rows because the supplement prints no case count per trend.
3. **p_trend.** The value goes on the top category row and on the trend row. It is the P for the calibrated trend.
4. **Sex-specific model.** The sex-specific rows reuse m2, because the footnote lists the same covariates. In men, the women-only covariates (parity, menopause, OCA, HRT) do not apply.
5. **Heterogeneity P values** (by sex, colon vs rectum, proximal vs distal) are recorded in `notes`, not in `p_value`.
6. **Participants column in S8/S9.** It is the whole cohort per intake category, shared by both subsites. It is entered as `n_in_category` on both outcomes' rows.
7. **Not coded (outside the assignment):** Suppl Table S5 (oily and non-oily fish: categories; minimally adjusted; diet-change exclusion). Only its fully adjusted per-25 g values are already in the file (`_049`, `_050`). Tables S1–S2, S6, S7 and S10 are not meat.

### Contradictions and possible typos
- **Main-text Table 3 vs Suppl Table S3 (minimally adjusted, red and processed meat per 50 g).**
  - Table 3 prints 1.26 (1.12–1.42) (row `_026`).
  - S3 prints 1.30 (1.10–1.53) (row `_055`).
  - 1.26 (1.12–1.42) is exactly the S3 minimally adjusted value for **red meat** (row `_065`).
  - Either Table 3's first row uses the wrong exposure, or S3 is wrong. Both are recorded as printed, and a note is appended to `_026`.
  - The fully adjusted end of Table 3 (1.17, 1.04–1.32) agrees with S3.
- **The main-text "red-meat" label in the sex-specific sentence is confirmed as a misnomer.**
  - S4's per-50 g trends of 1.39 (1.17–1.64) in men and 0.99 (0.83–1.19) in women are the **red and processed meat** trends.
  - Red meat alone is 1.47 (1.17–1.84) in men and 0.94 (0.73–1.19) in women.
  - The `red_total` coding of `_047`/`_048` is correct. A confirming note is appended to both rows.
- **Possible typo, S4 women, processed meat ≥ 2.0 times/week: 1.03 (0.79–1.24)** (row `_127`).
  - The CI is clearly asymmetric on the log scale (checks.py asym = 0.30).
  - Recorded as printed and flagged in the row notes.
- **The red-meat definition is now documented.** Supplementary methods (`supplements/bradbury2020_File005.txt`, not assigned, read for definitions only) state that red meat = summed frequencies of beef, pork and lamb/mutton. Red and processed meat = the same plus processed meat. This resolves judgment call 3 above: `includes_processed = no` is now quoted rather than inferred. study.csv was not changed beyond the case counts.

### checks.py (scratch copy)
- Flag 2: 1 row (`_127`, see above).
- Flag 9: unverified, expected.
- No other flags.


---
# brink2005
# Brink 2005 (Netherlands Cohort Study, meat and K-ras): extraction notes (opus-H2, 2026-10-30)

Source: Br J Cancer 2005;92:1310-20 (PMC2361976 XML, flattened), `historisk/brink2005.txt`. Estimates are in Table 2 (overall colon and rectum), Table 3 (K-ras wild-type vs mutated) and Table 4 (G>A transitions vs G>T/G>C transversions). The rows were generated by parsing the table cell sequences from the txt, and spot-checked against the text.

## New vocabulary
- `subgroup`: `kras_wildtype`, `kras_mutated`, `kras_g_a_transition`, `kras_g_t_or_g_c_transversion` (tumour subtype; the outcome is still colon or rectum).
- `category_set_id` exposure tokens: `freshmeat`, `beef`, `pork`, `minced`, `liver`, `chicken`, `othermeat`, `meatproducts`, `fish`. Model tokens: `ase` (age + sex), `mv`.
- `cup_role = pre2010`. `source_page = 1310-1320` (article range; the XML has no page breaks).

## Scope coded (492 rows)
- Table 2: 9 exposures × 2 outcomes × 2 models, categories + per-SD continuous = 164 rows.
- Table 3: 9 exposures × 2 outcomes × 2 K-ras strata, multivariate only = 164 rows.
- Table 4: 9 exposures × 2 outcomes × 2 mutation types, multivariate only = 164 rows.

## Judgment calls
1. **Exposure mapping (follows the gilsing2015 NLCS precedent).** Total fresh meat → `total_meat`, includes_processed `no`; it includes chicken and excludes meat products and fish. Beef → `beef`; pork → `pork`; liver → `organ`; chicken → `poultry`; meat products → `processed`; fish → `fish`. **Minced meat → `red_unprocessed`, `is_main_model = no`.** There is no aggregate fresh red meat variable in this paper, so minced meat must not stand in for red meat. **"Other meat (i.e. sausages)" → `red_undefined`, includes_processed `unclear`, `is_main_model = no`.** The paper classes it as fresh meat, but its composition is unclear.
2. **is_main_model = yes** for the Table 2 multivariate model (category and continuous rows) of each exposure except minced and other meat. All K-ras subgroup rows are `no`.
3. **Doses.** Sex-specific quartiles of subcohort intake. Cut-points are not printed; medians are printed **separately for men and women**, so `dose_point` is empty and both medians are in each row's notes. Liver and other meat are non-user vs user. Chicken and fish use fixed categories from the text (p. 1312).
4. **Chicken "median" row.** Table 2 prints 0 / 5.3 / 13.2 / 22.8 for men/women, which equal the category bounds in the text rather than medians. Bounds were coded from the text; flagged on the rows. The text's first user category (5.3-13.2) leaves >0-5.3 g/day unaccounted for.
5. **Continuous rows.** "Per one SD increase in intake" from the subcohort SD in Table 1 (`dose_unit = per_sd`, SD in g/day in `dose_point` and notes): fresh meat 42.2, beef 22.5, pork 30.3, minced 17.3, liver 4.4, chicken 15.6, other meat 6.4, fish 15.0. Meat products are per 15 g/day (footnote e: one sandwich filling).
6. **Denominators.** Table 2 prints subcohort person-years per category (`person_years`). Tables 3-4 print only cases per subtype. I reused the Table 2 person-years on those rows, because the case-cohort denominator (subcohort person-years) is the same; noted on each row.
7. **Case counts.** The analysis is restricted to cases with tumour tissue and a determined K-ras status (448 colon, 160 rectal; rectosigmoid excluded). It is therefore smaller than other NLCS meat papers, and it is the same cohort as gilsing2015 and others (never pool together).
8. **Adjustment (m2).** Age, sex, BMI (QI), smoking, energy, family history. No other meats, alcohol or fibre.

## Typos / inconsistencies (recorded as printed)
- Table 2, pork, colon, age-sex Q4: "0.86 (0.76–1.37)", strongly log-asymmetric. The multivariate Q4 is 0.77 (0.57–1.04), so the lower bound is probably a typo. Row brink2005_124.
- Table 3, other meat, rectum, K-ras wild-type: "0.90 (0.63–2.23)", asymmetric (possibly 1.23 or 1.30). Row brink2005_353.
- Table 4, chicken, colon, G>T/G>C, Q3: "0.74 (0.36-.53)". The upper bound is printed as ".53", which does not contain the point (probably 1.53). Recorded as ".53". Row brink2005_329.
- Table 1 N subcohort 3,048 vs 2,948 in the analyses (100 missing BMI), as explained in the paper.


---
# butler2008
# NOTES – butler2008 (Singapore Chinese Health Study)

Extractor: opus-D · 2026-10-30 · Source: `Understudier WCRF/butler2008.txt` (Br J Cancer 2008;99:1511–1516). Every number was typed from this text file. The study card was not used for numbers.

## New vocabulary
None.

## Contents
**estimates.csv – 3 rows.** Table 1 (p. 1512): HR for the 4th vs 1st quartile, colorectal, one multivariate model, sexes combined:
- red meat
- preserved meat
- fish

**adjustments.csv – 1 row:** m1 = Table 1 multivariate.

**dose_conversions.csv – 3 rows.** `g_day_assigned` is empty because the paper prints no quartile doses.

## What the assignment expected but the paper does not contain
- **Quartile series.** Only Q4 vs Q1 is printed. There are no Q2/Q3 estimates, no reference row, no cut-points, no medians, and no per-quartile cases or person-years. The rows are therefore coded `contrast_type = hvl` with no reference row. They still get a `category_set_id` so they can be referenced.
- **Colon and rectum.** Single foods are reported **only for colorectal cancer**. Colon and rectum appear only for the meat–dim sum dietary pattern (text p. 1513), which is a factor score and out of scope (R1). Not coded. Cohort case totals: 591 colon and 370 rectal/rectosigmoid (p. 1512). study.csv `cases_colon`/`cases_rectum` are left empty, because no meat estimate exists for them.
- **Poultry.** Not reported anywhere.
- **Heme iron.** Not reported.
- **Sex-specific estimates** for single foods: not reported.

## Judgment calls
1. **Red meat = `red_undefined`, `includes_processed = unclear`.** The paper never defines "Red meat": no food list in the methods, and Table A1 lists only dietary-pattern foods. The "Preserved meat" row is separate, which suggests red meat may exclude preserved meat, but this is not stated.
2. **Preserved meat = `processed`.** It is not defined. In this population it may include preserved poultry or fish products (e.g. lup chong, a Chinese sausage, appears as a pattern food). Whether it is red meat only is not stated (row note).
3. **Fish** = `fish` (fresh vs salted/preserved not stated). It is coded as the negative control under R1.
4. **`is_main_model = no` on all three rows**, following OPPDRAG_tillegg 2: "reported only as highest-vs-lowest" means `no`.
   - This leaves Butler 2008 with no main-model row at all, even though these are the paper's only, fully adjusted estimates.
   - **This is the row CUP used as HvL** (orientation from the task list: `cup_role = hvl_only`). `cup_extraction` should point to butler2008_001 regardless of the main-model flag.
5. **`n_cases = 961`** on each row is the total number of colorectal cases in the analysis (Table 1 header "Cases (N = 961)"), not the cases in Q4. `denominator_type = none`.
6. **Dose context.** Each row note gives the paper's 5th percentile, median and 95th percentile of intake (g/day) among cases and noncases. For red meat the median is 24 g/d in cases and 25 g/d in noncases. Quartile cut-points cannot be derived from these.
7. **Adjustment** (Table 1 footnote a):
   - Covariates: age, sex, dialect group, interview year, baseline diabetes, smoking (never/light/heavy), BMI (4 categories), alcohol (3 categories), education (3 categories), weekly physical activity, family history and total energy (kcal).
   - The text file prints "X" for ≥ and "o" for <; restored in `covariates_text`.
   - No mutual adjustment between meats. No fibre, calcium, NSAID or screening adjustment.
8. **Typos / inconsistencies:**
   - **Table 1 "Total fat (g)"** for noncases prints "25, 16, 34" (5th, 50th, 95th percentile), which is not monotone; it is a probable typo. It is a nutrient row, not coded; noted only.
   - **Alcohol HR** is ≥7 drinks/week vs nondrinker (footnote b), not quartiles. Not coded.
   - No inconsistencies in the meat or fish rows.
9. **study.csv:**
   - `n_participants = 61321`
   - `followup_years = 9.8` (mean: "an average of 9.8 years")
   - baseline 1993–1998, age 45–74
   - `diet_items = 165`
   - `outcome_ascertainment = registry` (cancer registry plus death registry linkage)


---
# chan2005
# NOTES – chan2005 (Nurses' Health Study, nested case-control)

Extractor: opus-D · 2026-10-30 · Source: `Understudier WCRF/chan2005.txt` (Int J Cancer 2005;115:648–652, short report). Every number was typed from this text file. The study card was not used for numbers.

## New vocabulary
- **subgroup:**
  - `nat2_slow_acetylator`
  - `nat2_rapid_acetylator`
  - `joint_nat2rapid_smoked_before30_vs_slow_nonsmoker`
  - `joint_nat2rapid_gt35packyears_vs_slow_le35`

No new exposure, outcome or unit values.

## Contents
**estimates.csv – 17 rows.**
- **Table II (p. 650), "Beef, pork or lamb as a main dish":** 2 categories × 2 models (age-adjusted, multivariate) × 3 strata (all women, slow acetylators, rapid acetylators) = 12 rows. Counts are cases/controls per category.
- **Results text (p. 649):** 3-category multivariate analysis, all women = 3 rows (the reference row is implied by the text).
- **Results text (p. 649) and abstract:** 2 joint-effect estimates (genotype × smoking × meat) = 2 rows.

**adjustments.csv – 2 rows:**
- m1 = age-adjusted
- m2 = multivariate, meat analyses

**dose_conversions.csv – 3 rows.** The paper gives no gram portion size, so `g_day_assigned` is empty.

## THE KEY FLAG: the meat row duplicates a smoking row
Table II, **All women, beef/pork/lamb as main dish, >0.5 serving/day**, is printed as:
- age-adjusted 1.15 (0.82–1.63)
- multivariate 1.21 (0.85–1.72)

The **All women, "Any smoking before age 30"** row in the same table has exactly the same numbers: 1.15 (0.82–1.63) and 1.21 (0.85–1.72).

Evidence that the meat row's numbers are the smoking row's numbers, copied in by mistake:
- **Crude OR from the meat row's own counts** = (17/30) / (166/413) = **1.41**. That is far from 1.15.
- **Crude OR from the smoking row's counts** = (99/226) / (84/217) = **1.13**. That matches 1.15.
- **The text's 3-category analysis** (same women, same multivariate model) gives **1.42 (0.74–2.74)** for ≥0.5 serving/day vs ≤1 serving/week. That is consistent with a crude OR of about 1.4 and a much wider CI (17 exposed cases cannot give a CI as narrow as 0.85–1.72).
- **The stratum rows are plausible.** Slow and rapid acetylators each give crude ORs close to the printed age-adjusted ORs (slow 0.92 vs 0.91; rapid 2.27 vs 2.40). Only the All-women meat row is off.

**How it is coded:** exactly as printed (rows chan2005_002 and _004), with the flag in `notes`. These rows are `is_main_model = no`.

If CUP's high-vs-low input for Chan 2005 was 1.21 (0.85–1.72), CUP used a number that almost certainly belongs to smoking, not meat. That should go into `cup_extraction.issue_category` (`row_choice`, or a new value `source_typo`) when that table is filled.

## Other judgment calls
1. **Lost symbols.** The text file drops ≤/≥ glyphs, so labels such as "0.5 serving/day" and "35 pack-years" have lost their comparison sign. Where ">" survived (">0.5", ">35"), the lost symbol is read as ≤.
   - Table II: reference ≤0.5 serving/day vs >0.5 serving/day.
   - The text describes the same split as "≥0.5 serving/day compared to <0.5 serving/day". **The cut-point side is therefore inconsistent between table and text.** Bounds are recorded as `dose_high = 0.5` (ref) and `dose_low = 0.5` (top).
   - Footnote 2 says the smoking models are adjusted for "beef, pork or lamb as a main dish (≤0.5 servings/week and >0.5 servings/week)". The "/week" there is a typo for "/day", or a third version. Noted, not coded.
2. **`is_main_model = yes` is on the 3-category text analysis**, not on Table II. This is a judgment call. Reasons:
   - It is the paper's overall, unstratified multivariate meat analysis.
   - It uses the "previously described categories".
   - The Table II two-category split was introduced for the genotype-stratified analysis ("We therefore examined risk associated with eating ≥0.5 serving/day…").
   - The Table II All-women meat numbers are a probable copy error.

   The 3-category rows have no counts, so `denominator_type = none`.
   - Category bounds were converted to servings/week for one unit across the set: 0.5 serving/day = 3.5 servings/week. This is unit harmonisation, not dose imputation; the note on each row says so.
   - The covariates are assumed to be the same as Table II multivariate (m2). The text says only "multivariate ORs".
3. **Genotype-stratum rows** are coded as subgroups, `is_main_model = no`. P for interaction = 0.07.
4. **Joint-effect rows (5.85 and 17.6)** compare rapid acetylators who smoke and eat ≥0.5 serving/day with slow acetylators who do not smoke and eat <0.5 serving/day.
   - They are not meat effects. They are coded only for completeness, with a "never pool" note.
   - They are coded as `contrast_type = hvl`: each is a single printed contrast, not part of a category series, and it has no reference row.
   - Their adjustment set is not restated; m2 is assumed.
   - The abstract and the text differ slightly on the reference for the pack-years contrast: the abstract has "<0.5 serving/day", the text has "0.5" with the symbol lost.
5. **Exposure** = `red_main_dish`, `includes_processed = unclear`. The paper says only "beef, pork or lamb as a main dish". In the NHS FFQ this item excludes hamburger and processed meats, but that is not stated in this paper, so it is not coded as `no`.
6. **Adjustment** (Table II footnote 2):
   - Covariates: age (5-year categories), BMI (tertiles), family history, postmenopausal hormones, previous endoscopy, multivitamin use and aspirin. Meat analyses are additionally adjusted for pack-years (≤35 / >35).
   - **No energy adjustment** (`energy_method = none`), and no alcohol, physical activity, fibre, calcium or folate.
   - Analysis uses unconditional logistic regression, adjusted for matching factors. The age-adjusted model's covariate is read as 5-year age categories.
7. **Outcome:** colorectal only. No colon/rectum split. `cases_colorectal = 183`; colon and rectum are empty.
8. **Study fields:**
   - `design = nested_cc`.
   - `n_participants = 626` (183 cases, 443 controls).
   - `followup_years` is empty. Cases arose after blood draw (1989–1990) through 1 June 2000; no mean or median is printed.
   - `diet_items = 61` comes from "among over 61 foods included in the baseline dietary questionnaire". That sentence refers to the earlier whole-cohort analysis, so treat it with caution.
   - `diet_repeated = unclear`. FFQs from 1980–1994 exist, and meat was taken "from the questionnaire prior to diagnosis". Whether this means cumulative averages or the most recent FFQ is not stated.
9. **Cohort overlap:** these are NHS cases, also covered by Wei 2004 (nhs). `cohort_id = nhs`; never pool the two together.


---
# chao2005
# NOTES – chao2005 (CPS II Nutrition Cohort)

Extractor: opus-I · 2026-10-30 · Source: `post2015/chao2005.txt` (JAMA 293:172–182; byte-identical to Historikk 29_Chao2005.txt).

## New vocabulary
- **Subgroup tags:** `site_rectosigmoid_junction_only`, `site_rectum_excl_rectosigmoid`, `long_term`, `energy_adjusted_residual`. These are free text, as the vocabulary allows.

## Contents (184 rows)
- **Table 2 (pp. 176–177), colon, by sex: 3 exposures × 2 sexes × 3 models × 5 quintiles = 90 rows.**
  - Exposures: red meat, processed meat, poultry and fish.
  - Model 1 and Model 2 are printed **without CIs**, so `ci_low`/`ci_high` are empty. `checks.py` flags this as `1_mangler_ci` (48 rows), which is expected.
  - Men and women combined: Model 3 only, 3 × 5 = 15 rows. Cases per quintile are not printed for the combined analysis.
- **Table 3 (p. 178), proximal colon, distal colon and rectosigmoid+rectum, sexes combined, Model 3:** 3 exposures × 3 outcomes × 5 = 45 rows.
- **Table 4 (p. 179), long-term intake (low in both 1982 and 1992/93; all other; high in both), Model 3:** 3 × 3 × 3 = 27 rows.
- **Text: 7 HvL rows** (pp. 177, 179):
  - rectosigmoid junction 2.40
  - long-term rectosigmoid 1.75
  - long-term rectum proper 1.31
  - residual-energy-adjusted processed meat in men 1.35
  - residual-energy-adjusted red meat, rectum 1.31
  - Comment-section age+energy colon estimates 1.41 (red) and 1.33 (processed)

## Not coded
- **"Ratio of red meat to poultry and fish."** It is a ratio, not a meat amount, and has no exposure value in the vocabulary. It has 4 Table 2 blocks, 3 Table 3 blocks and 3 Table 4 blocks. It can be added later as a new exposure value if wanted.
- **Beef/pork/lamb as a main dish and doneness.** "Data not shown".
- **Mutual adjustment for other meats.** "Results not shown".
- **No combined colorectal outcome is reported anywhere.** `cases_colorectal = 1667` in study.csv is the total.

## Judgment calls
1. **is_main_model = yes on Model 3** (the most adjusted; the paper's tables 3–4 use it):
   - Table 2 colon rows by sex and combined.
   - Table 3 subsite rows.

   Models 1 and 2 are `no`. **Table 4 long-term rows are `no`.** They use a different exposure construct (tertile combinations over 1982 and 1992/93) with a non-ordered middle group. Table 3 is the main dose analysis for the same exposure × outcome. Text-only rows are `no`.
2. **Rectum outcome = "Rectosigmoid and rectum" (C19.0 + C20.9, n = 470),** coded `rectum`. Separate rectosigmoid (214) and rectum-proper (246) estimates appear only in the text and are coded with a `subgroup` tag.
3. **Exposure mapping:**
   - **Red meat → `red_total`.** The definition explicitly includes bacon, sausage, hot dogs, ham/bologna/salami/lunchmeat, and liver.
   - Processed meat → `processed`.
   - **Poultry and fish → `white_meat`.** It is a combined variable (chicken/turkey, fried chicken, fried fish, tuna, other fish). Fried items are included, and `includes_processed = no` (no processed items listed).
4. **Dose bounds.**
   - Quintiles are sex-specific (g/week, footnote of Tables 2–3). Sex-specific rows carry `dose_low`/`dose_high` as printed.
   - **Combined-sex rows have no single bound**, so they are empty and the label gives both ranges. The exception is poultry and fish, whose bounds are common to both sexes.
   - Open bounds are recorded as `>800` → `dose_low = 800`, `dose_high` empty.
   - **Processed-meat Q1 = "0"** → `dose_low = 0`, `dose_high = 0`; Q2 = "≤60" → `dose_high = 60`, `dose_low` empty.
5. **dose_point.**
   - Table 1 gives median red meat per red-meat quintile by sex (men 100/253/398/612/999; women 43/168/278/416/712 g/wk). These are used on the sex-specific red-meat rows (`paper_median`). They are converted to g/day in dose_conversions (÷7).
   - Table 1 also gives median processed meat and poultry+fish **by red-meat quintile**, not by their own quintiles, so they were not used.
6. **Denominators.**
   - Participants per red-meat quintile by sex (Table 1) are put in `n_in_category` (`n_participants`) on the sex-specific Table 2 red-meat rows only.
   - All other rows: `denominator_type = none`.
   - **Person-years are not printed anywhere**, and neither is mean follow-up time.
7. **Text rows, assumptions.**
   - Rectosigmoid 2.40 is assumed Model 3, Q5 vs Q1. The sentence follows the Table 3 "highest quintile" result.
   - Residual-energy rows: covariates not restated. A separate adjustment set m4 was made, with flags copied from Model 3 as an assumption.
   - **Comment-section 1.41/1.33 ("adjusting for age and energy intake") = Model 1.** Sex is not stated. The Model 1 values in Table 2 are sex-specific and do not match (men 1.70/1.39), so these are probably sexes-combined Model 1 estimates that are not in any table. **Flag for verification.**
8. **High-fiber grain foods are a food covariate, so `adj_fiber = no`;** `adj_fruit_veg = yes` in Model 3. Multivitamin use and beer/wine/liquor are coded under `adj_alcohol`.
9. **diet_repeated = yes,** because the long-term analysis uses the 1982 and 1992/93 questionnaires. The main analyses use the 1992/93 FFQ only.
10. **DOI.** Not printed in the txt. 10.1001/jama.293.2.172 follows the JAMA pattern; verify.

## Printed anomalies (recorded as printed)
- **Table 2, processed meat, men, Model 3:** Q4 and Q5 are identical, "1.11 (0.80-1.54)", with p trend .03. A possible duplication error.
- **Table 3, poultry and fish, distal colon:** Q4 and Q5 are identical, "0.73 (0.53-1.01)". A possible duplication error.
- **Table 2 (cont), ratio, men, Model 2 Q2 printed "107"** (= 1.07). Not coded, since ratio rows are out of scope.
- **Table 2 footnote * says "Proportions standardized to the age distribution"** on an RR table. This is boilerplate copied from Table 1 and has no effect on the coding.
- **Abstract vs tables:** rectal 1.71 (1.15–2.52), P = .007 matches Table 3. Long-term processed meat, distal 1.50 (1.04–2.17), and red meat, rectum 1.43 (1.00–2.05), match Table 4.


---
# chen1998
# Chen 1998 (Physicians' Health Study, nested case-control): extraction notes (opus-H2, 2026-10-30)

Source: Cancer Res 1998;58:3307-11. Text file `historisk/chen1998.txt`. Tables 2 (p. 3309) and 3 (p. 3310) are garbled in the txt and the right-hand cells are cut off. I downloaded the same paper's PDF from Drive (`Chen1998.pdf`, the file the txt was made from), rendered pages 4-5 as images and read the printed table cells. Every value from the image is flagged on its row. Printed numbers were copied; nothing was read off a curve.

## New vocabulary
- `subgroup`: `nat1_slow_acetylator`, `nat1_rapid_acetylator`, `nat2_slow_acetylator` (already used), `nat2_rapid_acetylator` (already used), `nat1_nat2_nonrapid`, `nat1_nat2_rapid`, `age_ge60`, joined with `+` (e.g. `age_ge60+nat2_rapid_acetylator`).
- `cup_role = pre2010`.

## Scope coded (42 rows)
- Table 2: red meat (3 categories) for all men and for 6 NAT1/NAT2 genotype strata (21 rows).
- Table 3: the same for men aged ≥60 (21 rows).
- Not coded: Table 1 genotype main effects (not meat). Chicken and fish: the text says they were "not related", with no numbers. Interaction P values are listed here only: Table 2 P interaction 0.19 (NAT1), 0.56 (NAT2), 0.16 (NAT1/NAT2); Table 3 0.48, 0.25, 0.25. Age interaction P = 0.03.

## Judgment calls
1. **Exposure = `red_total`, includes_processed `yes`.** The FFQ asked about "beef, pork, or lamb as a main dish, as a mixed dish or sandwich, and hot dogs". Hot dogs are the only processed item. Bacon, ham and other processed meats were not asked about, so `partial` was also defensible. I chose `yes` because a processed item is explicitly included.
2. **Doses.** Servings/day; ≤0.5, >0.5-1, >1. The paper's category medians (0.27, 0.77, 1.46) are used as `dose_point` with `paper_median`. The text says the "median value of meat intake in each category" was used for modelling.
3. **is_main_model.** `yes` only for Table 2 "All men". Genotype strata and the older-men table are `no`.
4. **Effect measure.** Table 2 labels the estimates "RR" and Table 3 "OR". Both come from conditional logistic regression and were coded as printed.
5. **Denominators.** Controls per category → `n_controls`. Category cases sum to 208 of 212 and controls to 217 of 221 (missing intake). In Table 3, controls sum to 115, while the text says 116.
6. **Adjustment.** Matching on age and smoking, plus BMI, physical activity and alcohol (Methods). The table footnotes do not restate the covariates, so I assumed the same model for Tables 2 and 3.
7. **Design.** `nested_cc`. Follow-up is "13 years" (abstract), coded `followup_type = max`.

## Values not in the txt, read from the PDF image
- Table 2, >1 serving/day: NAT2 slow 1.01 (0.48-2.13) (txt cut at "0.48-2"); NAT2 rapid 18/17, 1.51 (0.63-3.63); NAT1/NAT2 nonrapid 32/30, 0.93 (0.49-1.77); NAT1/NAT2 rapid 11/9, 2.35 (0.77-7.12).
- Table 3: NAT2 slow >1 17/13, 1.46 (0.52-4.09); NAT2 rapid >1 9/5, 4.10 (0.96-17.5); NAT1/NAT2 nonrapid >1 19/15, 1.56 (0.62-3.93); NAT1/NAT2 rapid ≤0.5 5/14 (reference) and >1 7/3, 5.82 (1.11-30.6). The text gives 4.10, 5.82 (1.11-30.6) and "56%" for the nonrapid group, which agrees with the image values.
- Table 3, NAT1 rapid >0.5-1: the txt prints "0.64-^.47"; the image shows 0.64-4.47.

## Typos / inconsistencies
- None in the printed estimates. checks.py raised no flags for this study.


---
# cross2010
# NOTES – cross2010 (NIH-AARP Diet and Health Study)

Extractor: opus-D · 2026-10-30 · Source: `Understudier WCRF/cross2010.txt` (Cancer Res 2010;70(6):2406–2414). Every number was typed from this text file. The study card was not used for numbers.

## New vocabulary
- **exposure** (not in KODEBOK 4.1; coded because the assignment asked for nitrate/nitrite and HCA rows):
  - `nitrate_processed_meat`
  - `nitrite_processed_meat`
  - `nitrate_nitrite_processed_meat` (one text row)
  - `hca_phip`
  - `hca_meiqx`
  - `hca_dimeiqx`

  checks.py will flag these under `V_exposure`. That is expected. `heme_iron` is already in the vocabulary.
- **dose_unit:**
  - `ug_per_1000kcal_day` (heme iron, nitrate, nitrite)
  - `ng_per_1000kcal_day` (HCAs)

  `g_per_1000kcal_day` is used for meat (allowed by OPPDRAG_tillegg 3).
- **subgroup:** `excl_first_2y_followup` (lag analysis).

## Contents
**estimates.csv – 159 rows:**
- **Table 2 (p. 2409):** red meat, white meat and processed meat × colorectal/colon/rectum × 5 quintiles = 45 rows. Multivariate (nutrient density), `is_main_model = yes`.
- **Table 2 footnotes † and ‡:** residual energy-adjustment model, 12 rows. For red meat and processed meat × 3 outcomes:
  - Q5 vs Q1 in g/d (`hvl`)
  - per 100 g/d (`continuous`)
- **Results text, p. 2409:** 5 rows. Q5 vs Q1, colorectal, for processed red meat, nonprocessed red meat, chicken, turkey and fish.
- **Results text, p. 2411 ("data not shown"):** 7 rows.
  - Proximal and distal colon for red meat and processed meat (4 rows)
  - Lag analysis excluding the first 2 years, colorectal, red and processed meat (2 rows)
  - Combined nitrate + nitrite, colorectal (1 row)
- **Table 3 (pp. 2410–2411):** heme iron, nitrate from processed meat, nitrite from processed meat, PhIP, MeIQx and DiMeIQx × 3 outcomes × 5 quintiles = 90 rows. `is_main_model = yes` (only model).

**adjustments.csv – 7 rows:**
- m1 = Table 2 red meat (mutually adjusted for white meat)
- m2 = Table 2 white meat (mutually adjusted for red meat)
- m3 = Table 2 processed meat (adjusted for non-processed meat)
- m4 = Table 3 compounds (no meat adjustment)
- m5, m6 = residual-method footnote models
- m7 = text meat sub-type models

**dose_conversions.csv – 9 rows**, one per Table 2 meat category set. `g_day_assigned` is empty in every row (see 4).

## Covariate list (recorded exactly)
Table 2 and Table 3 share the same footnote *. It is copied verbatim into `covariates_text`:

> gender, education (3 categories), BMI (6 categories incl. unknown), smoking (5 categories), and intake of total energy (kcal/d), fiber (g/1,000 kcal), and dietary calcium (mg/1,000 kcal).

The methods (pp. 2407–2408) give the same list of final-model covariates.

Table 2 adds:
- "Red meat and white meat were mutually adjusted for each other."
- "Processed meat was adjusted for non-processed meat."

Table 3 has no meat adjustment.

## Judgment calls
1. **Age is not in the covariate list.**
   - The Cox time metric is person-years. The paper says "analyses using age as the underlying time metric yielded almost identical HRs".
   - `adj_age = no` as printed in all adjustment sets, flagged in notes.
   - Alcohol, physical activity, NSAIDs, family history, HRT and screening are also not adjusted. The paper says the final model kept only variables that changed the HR by ≥10% or were established risk factors.
2. **Red meat = `red_total`, `includes_processed = yes`.**
   - The definition lists "all types of beef, pork, and lamb, including bacon, beef, cold cuts, ham, hamburger, hot dogs, liver, pork, sausage, and steak", plus meat in mixed dishes.
   - The variable therefore also contains liver (organ).
3. **Processed meat** includes processed poultry: poultry sausage, red- and white-meat luncheon meats and cold cuts, and low-fat poultry hot dogs. **White meat** = chicken, turkey (incl. poultry cold cuts) and fish, coded `white_meat`, `exposure_includes_processed = yes`.
4. **Doses.**
   - Table 2 gives only quintile medians in g/1,000 kcal (recorded as `dose_point`, `paper_median`). No cut-points are printed, so `dose_low` and `dose_high` are empty.
   - Converting to g/day needs energy per quintile. Table 1 gives mean energy only by red-meat quintile (1685–1978 kcal/d) and mean red meat (8.9–66.5 g/1,000 kcal; means, not the Table 2 medians).
   - `g_day_assigned` is left empty: the conversion is an analysis step.
   - The residual-method footnote gives g/d medians only for Q1 and Q5 of the residual quintiles:
     - red meat: 15.7 and 104.1
     - processed meat: 2.7 and 38.0
5. **Main model.**
   - Table 2 body (nutrient-density model) = `yes` for each exposure × outcome.
   - The residual-method footnote model (m5/m6) = `no`. The paper presents it as a check ("resulted in similar risk estimates (given in table footnote)").
   - **Consequence:** the paper's **only continuous estimates (per 100 g/d) are `is_main_model = no`**, because they come from the residual model. For pooling they are still the obvious per-100 g input; this is an analysis choice.
6. **Text-only rows are all `is_main_model = no`** (OPPDRAG_tillegg 2: reported only as highest vs lowest). This covers:
   - nonprocessed red meat 1.13 (0.98–1.30)
   - processed red meat
   - chicken, turkey, fish
   - proximal and distal colon
   - the lag analysis
   - combined nitrate + nitrite

   As a result, `red_unprocessed`, `poultry`, `fish`, `proximal_colon` and `distal_colon` have **no** main-model row.
7. **Model details for text rows are assumed.**
   - The covariates are not restated, so adjustment set m7 assumes the Table 2 covariates.
   - The methods say "processed and nonprocessed meat" were in the same model (additive models summing to total meat). Mutual adjustment of processed red meat and nonprocessed red meat is therefore likely but not stated: `is_mutually_adjusted_processed = unclear`.
   - The comparison is not stated for chicken, turkey and fish. "Q5 vs Q1" is inferred from context.
8. **Proximal/distal rows** use m1 (red) and m3 (processed) on the assumption that the model is the Table 2 model. Cases per quintile are not printed. Total cases: 1,150 proximal, 787 distal; 58 colon cases lack subsite.
9. **Denominator.** No per-category person-years are printed, so `denominator_type = none`. Cases per quintile are printed in Tables 2 and 3. They sum exactly to 2,719 / 1,995 / 724 in every category set (checked by script).
10. **DiMeIQx quintiles are very unequal** (Q1 922 cases, Q2 105 cases, median Q1 0.0). Recorded as printed. Quintiles were presumably formed with many tied zero intakes.
11. **Not coded** (out of scope, or not asked for):
    - total iron, dietary iron
    - B(a)P (a PAH, not an HCA)
    - mutagenic activity
    - total dietary nitrate / nitrite from all foods (text p. 2411)

    The paper's interaction tests are also not coded: by gender, P = 0.385 (red) and 0.138 (processed); subsite heterogeneity P = 0.485 / 0.320 (colon vs rectum) and 0.432 / 0.497 (proximal vs distal). Sex-specific estimates are not printed.
12. **Follow-up.**
    - `followup_years = 7.2`, `followup_type = max` ("After up to 7.2 years of follow-up"; abstract: "During 7 years").
    - Follow-up starts at receipt of the risk factor questionnaire (RFQ), about 6 months after the 1995–1996 baseline, so `baseline_start`/`baseline_end` = 1995/1996.
    - The meat-type and cooking data come from the RFQ, not from the 124-item baseline FFQ.
13. **Typos / inconsistencies:** none found in the meat rows. Table 2 and the text agree on every number quoted.
    - checks.py flags `2_asymmetrisk_ci` on white meat Q5 colorectal, 0.85 (0.76–0.97), asym = 0.15. This is borderline and consistent with rounding; the text (p. 2409) prints the same numbers. Not a typo.
    - The `V_exposure` flags (76 rows) are the new compound exposures listed under "New vocabulary".
14. **`card_file`** points to `kort/14_vedlegg_hvl.md`, the appendix that covers this study. It was not used for numbers.


---
# dankner2024
# NOTES – dankner2024 (Israeli historical cohort, 7 pooled studies)

Extractor: opus-H · 2026-10-30 · Sources:
- `post2015/dankner2024.txt` (Int J Cancer 155:2009–2020).
- `/home/claude/pdf_in/dankner2024.pdf`, journal page 2015, for Table 4a.

**Important about the source:** Table 4a (and 4b) are images. The `.txt` file contains only their titles. I rendered PDF page 7 at 200 and 400 dpi and transcribed the **printed** numeric columns (HR, 95% CI, weight, cases/participants). Nothing was read off the plotted markers.
- Supplement rule 6 is satisfied: the numbers are printed.
- The pooled values match the abstract and Results text exactly (1.07, 1.15, 1.46, 0.93, 1.06).
- The per-cohort values should get priority in double-coding.

## New vocabulary
- **cohort_id per sub-cohort:** `israel_nicccs`, `israel_hds`, `israel_mabat`, `israel_ovary`, `israel_negev`, `israel_goh`, `israel_iihd`. Pooled rows use `israel_hist` (as assigned in the brief). These follow tillegg item 4 (`<name>_pooled` pattern, with the given pooled id). **None is in cohorts.csv yet.**
- **subgroup values:**
  - `cohort_<name>` on per-cohort rows.
  - `processed_poultry_only`, `processed_nonpoultry_only`.
  - `diet_tool_24h_recall_as_printed`.
- **study.csv `design = pooled_cohorts`**, `diet_instrument = mixed` (FFQ / SQFFQ / 24-h recall).

## Contents
- **estimates.csv: 43 rows.** All colorectal, all continuous. The paper has no categorical analysis.
  - **Table 4a (p. 2015):** 5 exposures × (7 cohorts + pooled) = 40 rows.
    - Exposures: total meat, red meat and beef per 100 g/d; processed meat per 50 g/d; poultry per 100 g/d.
  - **Results text:**
    - Processed poultry per 50 g/d, 0.97 (0.75–1.27) (p. 2013).
    - Processed non-poultry per 50 g/d, 0.95 (0.70–1.28) (p. 2014, "data not shown").
    - Beef by questionnaire type, 1.59 (1.02–1.78) (p. 2014; see typo below).
  - **Not coded:**
    - Table 4b (GI-tract cancer, not colorectal).
    - Table 5 and S6 PAFs (not HRs).
- **adjustments.csv: 1 row.**
- **dose_conversions.csv: header only.** Every estimate is already per g/day, so there are no category sets.

## Missing (supplement not available)
- **Table S4** (by questionnaire type: FFQ vs 24-h recall), except the one printed beef number.
- **Table S5a/b** (sensitivity analysis with unimputed IIHD). The text says results "persisted".
- **Tables S1–S3:** imputation, OR-vs-HR validation, processed poultry by cohort.
- **No sex-specific or subsite (colon/rectum) estimates** exist in the paper. Sex and ethnicity splits appear only for PAFs.

## Judgment calls
1. **is_main_model = yes** on the 5 pooled random-effects rows (one per exposure). Per-cohort rows and text-only rows are `no`.
2. **IIHD per-cohort rows: `effect_measure = OR`.** IIHD was analysed with logistic regression on multiply imputed meat intake (Methods 2.1–2.2), even though the Table 4a column is headed "HR". The pooled rows stay HR, as the paper labels them, but they mix HRs and one OR. This is noted in the row notes.
3. **Exposure codes.**
   - Red meat = `red_unprocessed`: "all mammalian muscle meat"; processed meat and organ meat are separate groups; kosher salting does not count as processing.
   - Beef = `beef`.
   - Total meat = `total_meat`, `includes_processed = yes`: red + processed + poultry (Table 3 footnote). **No fish.**
   - Poultry: `includes_processed = unclear`.
   - Processed meat includes processed poultry, which is the **majority** of processed meat in these cohorts. It is not comparable to Western processed (red) meat. The closest is the processed non-poultry row (0.95).
4. **Processed poultry and processed non-poultry are both coded `exposure = processed`**, distinguished by `exposure_text` and `subgroup`. Neither belongs in a standard processed-meat pool by default.
5. **Denominators.** Per-cohort "Cases/participants" from Table 4a go in `n_cases` / `n_in_category` (`n_participants`). Pooled rows carry 813 / 26,889.
6. **Sex field for single-sex cohorts.** Ovary = `women` (controls from an ovarian cancer study). IIHD = `men`. All others = `all`.
7. **Adjustment.**
   - Energy, sex and age (time axis) in every cohort. Origin, education and smoking where available.
   - BMI and physical activity are **excluded** from the pooled models ("adjusted for all but physical activity and BMI").
   - Covariate availability differs between cohorts, so per-cohort models are not identical. One adjustment set was used, with a note.
8. **`followup_years` is empty** (`followup_type = unclear`). Follow-up is reported only per cohort (mean 8.2–28.4 y). `baseline_start`/`baseline_end` = 1963/2014 (years of nutritional assessment across cohorts).

## Inconsistencies and probable typos (recorded as printed)
- **Red meat CI.** The Results text (p. 2013) gives the CRC red-meat CI as "0.97–1.52". Table 4a, the abstract and the Discussion all give **0.87–1.52**, which is the coded value. Flagged in the row note.
- **Beef sensitivity row (043): "HR = 1.59 (95% CI: 1.02, 1.78) … for the 24-HR nutritional assessment type only".**
  - The CI is identical to the preceding GI red-meat FFQ estimate ("1.35 (95% CI: 1.02, 1.78)") and is grossly asymmetric around 1.59 (checks.py flag 2, asym = 0.75). It is probably a copy error.
  - The "24-HR" label also conflicts with the Discussion (p. 2018): "when stratifying the cohorts according to the nutritional intake tool, no association was found among studies using the 24-h recall with any type of meat". This row should not be used without Table S4.
- **Case and participant counts.** The Abstract and Results give 839 CRC among 27,754 participants. Table 4a gives 813 / 26,889 (analysis set). Table 1's per-study CRC cases (20 + 14 + 53 + 26 + 543 + 142 + 41 = 839) do not line up with Table 4a's per-cohort cases. Apparently IIHD is 543 vs 537 and NICCCS 142 vs 122, but the column mapping is uncertain because the Table 1 text extraction is scrambled. study.csv uses 839.
- **GI red meat HR.** Results text gives "1.27; 95% CI: 1.02–1.68"; the Discussion gives "1.27, 95% CI: 1.02, 1.58". Not colorectal, so not coded; noted for completeness.

## Supplement rows (30.10)

Extractor opus-S2, 2026-10-30. Sources: `/home/claude/drive/supplements/dankner2024_suppl.txt` and, for Table S5a (forest-plot images with printed numbers; the txt has only the cases column), `/home/claude/suppl_in/dankner2024_suppl.pdf` pp. 8-9, rendered at 300 dpi. Only printed numbers were transcribed (supplement rule 6).

## New vocabulary (supplement)
- `dose_unit = per_1g`: Suppl Table S2 prints no increment. The values (about 1.001) imply per 1 g/day, so the unit is assumed, as stated in the row notes.
- subgroups: `cohort_<x>_unimputed`, `diet_tool_ffq`, `iihd_unimputed`. `diet_tool_24h_recall` is the same value already used on row 043.
- adjustment set `dankner2024_m2` (S2 models: adds BMI and physical activity).

**Added: 26 rows (dankner2024_044 – 069); 1 adjustment set.**

| Suppl table | Rows | Content |
|---|---|---|
| S2 | 6 | Total meat, OR and HR side by side for NICCCS, Mabat and IIHD (unimputed). Method check, not for pooling. |
| S4 | 10 | CRC meta-analysis by interview type: FFQ (746/24,232) and 24-h recall (67/2,657) × 5 exposures. |
| S5a | 10 | IIHD unimputed (50/1,002 men) per exposure (5), plus the pooled estimate with IIHD unimputed (326/18,034) (5). |

- **S5a: the six non-IIHD cohort rows are identical to Table 4a** (only the RE weights differ), so they were not re-coded.
- Not coded: S5b (GI-tract cancer, not CRC), S4's GI half, S1 (imputation model coefficients), S3 (intakes), S6 (PAFs, not HRs).
- All new rows have `is_main_model = no`.

**Disputed row dankner2024_043.** Suppl Table S4 gives the 24-h recall beef estimate as **1.59 (1.11, 2.28)**. The text's "1.59 (1.02, 1.78)" took its CI from the GI-cancer FFQ red meat estimate, which S4 prints as 1.35 (1.02, 1.78).
- The correct estimate is coded as **dankner2024_059**, whose notes reference 043.
- Row 043 itself was not edited and remains `disputed`.
- S4 also confirms that this subgroup really is 24-h recall (Negev + Mabat).

**Contradictions with the main text**
- The Discussion (p. 2018) says no association was found with any meat type in the 24-h recall studies. S4 shows unprocessed beef 1.59 (1.11, 2.28) in exactly that subgroup.
- S4 labels the exposure "Unprocessed Beef"; Table 4a labels it "Beef".
- The main text says the unimputed sensitivity results "persisted". S5a supports this: pooled red meat 1.12 (0.85, 1.48) vs 1.15, and beef 1.61 (1.17, 2.22) vs 1.46.
- The IIHD unimputed estimates differ from the imputed ones in Table 4a. Examples: beef 3.35 (0.92, 12.21) vs OR 0.60; processed 0.35 (0.11, 1.05) vs OR 0.32.
- S5a heads the IIHD column "HR", but the model type for unimputed IIHD is not stated. Coded HR as printed, with a note.


---
# english2004
# English 2004 (MCCS) – extraction notes (opus-A, 2026-10-30)

Source: `Understudier WCRF/english2004.txt` (CEBP 2004;13(9):1509–14). Table 1 is on p. 1511, Table 3 on p. 1512, and the mutually adjusted results are in the Results text on p. 1511. No study card was used.

## New vocabulary
- `dose_unit = ratio`: the category rows for the ratio of fresh red meat frequency to chicken + fish frequency.
- `dose_unit = per_unit_ratio`: the ratio's continuous estimate (per one-unit increase in the ratio).

## Scope coded (81 estimate rows)
- **Table 3, definitive model (m1).** 5 exposures × 3 outcomes (colorectal, colon, rectum). Each block has 4 quarters (reference included) plus 1 continuous row, so 75 rows.
  - The exposures are fresh red meat, processed meat, chicken, fish, and the ratio of fresh red meat to chicken and fish.
- **Mutually adjusted model (m2), from the text.** Fresh red meat and processed meat were modelled together, per serve/week, × 3 outcomes = 6 rows.
- **Not coded:**
  - Proximal/distal, stage, sex and country-of-birth subgroups. The paper prints no estimates for them, only "no persuasive evidence".
  - The sensitivity analysis excluding the first 2 years. It is reported as "no material difference" with no numbers.
  - Homogeneity p-values (colon vs rectum trend) are not estimates, so they are not coded. Read in context, they are: fresh red meat P = 0.07, processed meat P = 0.5, chicken P = 0.8, ratio P = 0.2.

## Judgment calls
1. **Fresh red meat = `red_unprocessed`, `includes_processed = no`.** The definition lists veal/beef schnitzel, roast beef/veal, steak, rissoles/meatloaf, mixed beef dishes, lamb, pork and rabbit/game. Processed meat is a separate variable (salami, sausages/frankfurters, bacon, ham, corned beef, luncheon meats). Rissoles/meatloaf may contain minced meat with some processing, but the paper classes them as fresh.
2. **Continuous unit.** The HR is "for increase of one time per week" (Table 3), and the text calls it "each additional serve per week".
   - As instructed, it is coded `dose_unit = per_serving`, with the serving definition in the row notes.
   - The FFQ had **no portion sizes**, so a "serve" is one reported eating occasion. Nutrients were computed with mean sex-specific portion sizes from weighed records in 810 Melburnians, but those gram values are not printed.
   - The variable is pseudo-continuous: each person is assigned the median frequency of their quarter, and those medians are not printed.
   - `per_serving_week` would describe the unit more exactly. The instruction to use `per_serving` was followed.
3. **Main model.** Table 3 / m1 is `yes` for fresh red meat, processed meat, chicken and fish, on both the category and continuous rows (same model).
   - The paper calls the Table 3 covariate set the "definitive analyses". The mutually adjusted model (m2) appears only in the text, so it is `no`, although it adds a covariate.
   - The ratio rows are all `no`. The ratio is a derived substitution-type variable that shares `exposure = red_unprocessed` with fresh red meat. Its category rows are `contrast_type = substitution`.
4. **m2 flags.** On the fresh red meat rows, `is_mutually_adjusted_processed = yes`. On the processed meat rows it is `no`, because they are adjusted for fresh red meat, not for processed meat.
   - The text does not restate m2's other covariates. They are assumed equal to Table 3 (see adjustments notes).
5. **Reference quarter.** Table 3 does not print it. It is coded with point 1 and empty CI.
6. **Denominators and cases.**
   - Table 1 gives colorectal cases and the number of participants per quarter. These go in `n_cases` and `n_in_category` (`n_participants`).
   - For colon and rectum, cases per quarter are not printed, so `n_cases` is empty there and `n_in_category` repeats the participants per quarter.
   - No person-years are printed.
   - Continuous rows carry the outcome's total cases and the cohort N (37,112).
   - The colorectal case sums check out: 451 for every exposure.
7. **p_trend** is placed on both the Q4 row and the continuous row. It is the same test, computed from the pseudo-continuous variable.
8. **Adjustment.** Sex, country of birth, energy, fat and cereal products, with age as the time metric.
   - Fat is *total* fat, so `adj_saturated_fat = no`.
   - Fiber, BMI, alcohol, physical activity, education, folate, calcium, HRT, fruit and vegetables were tested by the ≥5% change-in-estimate rule and dropped, so all are `no`.
9. **weight_basis = unclear.** Frequency data only. The quartiles of amount (57/86/126 g/d fresh red meat; 9/18/29 g/d processed) do not state raw or cooked.

## Typos and inconsistencies (recorded as printed)
- **Table 1 chicken categories overlap: "1.5 – 2.4" and "2.0 – 3.4".** This is probably a typo; 2.5 – 3.4 fits the other blocks. Recorded as printed on rows english2004_031–045 (chicken Q2/Q3).
- **Fresh red meat colorectal per time/week.** Table 3 prints 1.03 (0.98–1.08). The mutually adjusted text figure is 1.02 (0.98–1.08). These are different models, so it is not an error. However, the text figure "1.02 (0.98–1.08)" is log-asymmetric (flag 0.30); possibly 1.03 or 0.97 was intended.
- **Fresh red meat colon per time/week.** Table 3 prints 1.00 (0.94–1.07). The m2 text figure is 1.00 (0.94–1.06). Again, different models.
- **Homogeneity p-values.** The two-column layout in the text file interleaves paragraphs. From context, P = 0.5 belongs to processed meat and P = 0.8 to chicken (not to fresh red meat, which has P = 0.07). Not coded.
- **Abstract vs Table 3.** The abstract figures (rectal fresh red meat 2.3 (1.2–4.2), p 0.07; processed 2.0 (1.1–3.4), p 0.09; colon 1.1 (0.7–1.6), 1.3 (0.9–1.9); chicken 0.7 (0.6–1.0), p 0.03) match Table 3.
- The other checks.py asymmetry flags (0.15–0.57) are on one-decimal values and consistent with rounding. For example, chicken Q4 colorectal "0.7 (0.6–1.0)" fits 0.74 (0.55–0.99).

## Doses / conversions
- 12 conversion rows (4 exposures × 3 outcomes). All have `g_day_assigned` empty: the paper prints frequency bounds only, with no medians and no grams per serve.
- Cohort-level anchors are recorded in the notes: quartiles of grams consumed and median weekly frequencies by sex.
- The ratio variable is not convertible to grams.

## Study-level
- The DOI is not printed in the text file, so it is left empty.
- PMID 15342453 is taken from the reference list in lee2009.txt (ref 9), not from this paper; verify it.
- `validation_r` is empty. Only reproducibility kappas are reported: fresh red meat 0.42, processed 0.60, chicken 0.44, fish 0.48.
- `in_cup2016 = yes` and `cup_role = dose_response` are taken from the brief's list.


---
# etemadi2018
# NOTES – etemadi2018 (NIH-AARP + PLCO + AHS)

Extractor: opus-I · 2026-10-30 · Source: `post2015/etemadi2018.txt` (accepted-article manuscript, pages "x of 17"; the PDF `pdf_in/etemadi2018.pdf` was also checked for the figures). The figures contain no printed numbers.

## New vocabulary
- **`dose_unit = per_50g_per_1000kcal`** (continuous increment of 50 g per 1000 kcal/day, energy density). The vocabulary has `g_per_1000kcal_day` for categories but no per-increment density unit.
- **`exposure = nitrate_processed_meat`** (nitrate from processed meat). It is not in KODEBOK 4.1, and `checks.py` flags it under V_exposure. It was coded because the assignment asks for nitrate/nitrite rows. If the vocabulary is not extended, drop row 039.
- **`cohort_id = aarp_plco_ahs_pooled`** for every row (see below).

## Contents (39 rows)
- **Table 3 (ms p. 16): 7 exposures × 5 outcomes = 35 continuous rows.** The exposures are total red, processed red, unprocessed red, white meat, poultry, fish and total processed meat. The outcomes are colorectal, colon, proximal colon, distal colon and rectum. HR per 50 g/1000 kcal/day, random-effects meta-analysis of the three cohorts.
- **Results text: 4 highest-vs-lowest-quintile rows for meat compounds (pooled individual data, Fig 2 model).**
  - Heme iron: colorectal 1.14 (1.05–1.24), distal 1.20, rectum 1.27.
  - Nitrate from processed meat: colorectal 1.18 (1.08–1.28).

## Not available in the file, so not coded
- **Per-cohort rows (nih_aarp, plco, ahs_ag).** These are only in Supplementary Table 1, which is not in the txt and has no supplement file. **No per-cohort estimate is printed anywhere in the main text**, so the cohort-specific cohort_ids are unused. Per-cohort denominators are recorded in study.csv notes (Table 2: participants, person-years, cases by subsite).
- **Pooled quintile rows for meats** (Suppl Table 2). Fig 1 plots them without printing numbers, and Rule 6 forbids reading values off a plot.
- **Quintile rows for heme, nitrate and nitrite** (Suppl Table 3), apart from the four HRs given in the text.
- **Nitrite.** The text says only "weaker than nitrate", with no number.
- **HCAs and B(a)P.** These are out of scope (R1).
- **Lagged sensitivity analysis and residual-energy sensitivity analysis.** Both are "data not shown".

## Judgment calls
1. **is_main_model.** The Table 3 model (substitution model adjusted for total meat, density method) is the paper's main analysis, so it is `yes`. Two exposures needed a choice:
   - "Processed red meat" and "Total processed meat" both map to `processed`. To keep one main row per exposure × outcome × sex, **Total processed meat = yes** and **Processed red meat = no**. Total processed meat is the paper's broader "processed meat" variable.
   - The reverse choice is defensible too: processed red meat is the variable that fits the red/processed split. The analyst can flip it.
   - The meat-compound HvL rows are `no`. They come from a different model and are reported only as highest vs lowest.
2. **Exposure mapping:**
   - Total red meat → `red_total` (includes processed red meat).
   - Unprocessed red meat → `red_unprocessed`. It **includes liver**.
   - White meat → `white_meat`. It includes processed poultry products, so `includes_processed = yes`.
   - Poultry → `poultry`, `includes_processed = unclear`.
   - Fish → `fish`, `includes_processed = no`.
3. **is_mutually_adjusted_processed = unclear** on the Table 3 rows. The models adjust for *total meat*, not specifically for processed meat. Each estimate is a substitution against the other meat in total meat.
4. **Denominators on continuous rows.** n_cases and person_years are the pooled totals for that outcome (Table 2: 6,640 / 4,997 / 3,060 / 1,807 / 1,643 cases; 4,605,311 PY). Person-years are not outcome-specific.
5. **design = `pooled_cohorts`.** The dose-response estimates are a random-effects meta-analysis of three cohort-specific models. The HvL estimates come from pooled individual data with cohort as a covariate. `adj_stratified_center = yes` stands for cohort-specific modelling and cohort adjustment respectively.
6. **energy_method = `density`.** All nutrient variables are divided by energy, and total energy is also a covariate.
7. **in_cup2016 = no, cup_role = excluded**, from the OPPDRAG_tillegg list. The NIH-AARP part overlaps cross2010 and zouiouich2025 (the same cohort).

## Printed anomalies (recorded as printed)
- **The CIs are symmetric on the linear scale, not the log scale.** For example, 1.30 (1.10, 1.49) and 0.73 (0.37, 1.08) are both ±0.19–0.36.
  - The meta-analysed HRs appear to have been reported as HR ± 1.96·SE(HR), not exp(β ± 1.96·SE).
  - `checks.py` therefore flags 19 rows for log-asymmetry. These are a feature of the paper's method, not single typos.
  - Any GL or pooling script must back-transform with care. The SE implied on the log scale differs depending on which side of the CI is used.
- **Asterisks that disagree with the printed CI.** Footnote "*p<0.001" is attached to three estimates whose CI reaches or crosses 1:
  - processed red meat, rectum: 1.41 (0.99, 1.83)*
  - total processed meat, colorectal: 1.14 (1.00, 1.30)*
  - total processed meat, colon: 1.16 (1.00, 1.36)*

  They are recorded as printed and flagged in the row notes.
- **The text matches Table 3** for total red meat (1.35, 1.24, 1.34, 1.53), white meat (0.74), poultry (0.73) and fish (0.79). No text–table disagreement was found.

## Dose
- **No conversion to g/day.** One dose_conversions row explains why. At ~2000 kcal/day, 50 g/1000 kcal ≈ 100 g/day, but the paper gives no overall mean energy (only by quintile per cohort in Table 1). The conversion was not made.


---
# flood2003
# Flood 2003 (BCDDP follow-up cohort): extraction notes (opus-H2, 2026-10-30)

Source: Am J Epidemiol 2003;158:59-68, `historisk/flood2003.txt`. Meat estimates are in Table 4 (p. 64), Table 6 (p. 65) and Table 7 (p. 66).

## New vocabulary
- `cohort_id = bcddp` (Breast Cancer Detection Demonstration Project follow-up cohort).
- `subgroup`: `fat_q1`, `fat_q2_4`, `fat_q5` (strata of total fat in the Table 7 cross-classification).
- Model tokens in `category_set_id`: `energy` (energy-adjusted, nutrient density), `fat` (adds total fat), `totmeatadj` (adds total meat), `xclass` (Table 7).
- `cup_role = pre2010`.

## Scope coded (49 rows)
- Table 4: total meat (energy-adjusted), and red, white and processed meat in two models each (energy-adjusted; energy + total meat). 7 sets × 5 quintiles = 35 rows.
- Table 6: total meat adjusted for total fat (5 rows).
- Table 7: total meat × total fat cross-classification, 9 cells (participants and cases printed). Only the fat-Q1 stratum (3 cells) forms a within-stratum meat contrast with a set id. The other 6 cells have a cross-stratum reference and carry no set id or rank (singh1998 precedent).
- Not coded: fat and fat-subtype rows (Table 5), and sensitivity or stratified analyses reported as "data not shown" (NSAID strata, exclusion of early cases, ethnicity/BMI/smoking strata).

## Judgment calls
1. **is_main_model.** The energy-adjusted model (m1) is `yes` for each exposure. The models that add total meat (m3) or total fat (m2) are `no`. Reasons: the abstract reports the m1 red-meat estimate (1.10, 0.83-1.45); m3 is a within-meat substitution model; total fat is a potential mediator (KODEBOK 4.2). For total meat, m2 is technically "more adjusted", but its point estimates are the same as m1.
2. **Red meat = `red_total`, `yes`.** The definition includes bacon, ham/lunch meat, hot dogs and sausage, and also liver and the meat in mixed dishes. **Processed = `processed`**. **White meat = `white_meat`** (chicken and fish, including fried). **Total meat**: includes_processed `yes` (it includes all 17 meat line items).
3. **Doses.** Unit g/1,000 kcal/day (`g_per_1000kcal_day`). Quintile medians are printed and used as `dose_point` (`paper_median`). Cut-points are printed only for total meat (Table 2: <26.5, 26.5-39.3, 39.4-53.7, 53.8-77.7, ≥77.8). Subtype bounds are empty.
4. **No per-quintile cases or person-years** are printed (only 487 total), so `denominator_type = none`, except Table 7, where participants and cases per cell are printed (`n_participants`).
5. **Table 7 model** is not stated (m4, energy flag `unclear`).
6. **is_mutually_adjusted_processed = yes** on the m3 rows for red and white meat, because total meat (which contains processed meat) is in the model.

## Typos / inconsistencies
- Total meat P trend: 0.27 in the text (p. 62) vs 0.28 in Table 4. Table value coded.
- Table 6 total meat Q5: 1.05 (0.79-1.38), vs Table 4 1.05 (0.80-1.38), although both claim nearly the same model (Table 6 adds fat). Both coded as printed.
- White meat (m1): the P trend (0.47) is printed on the CI line. Coded on the Q5 row.


---
# fraser1999
# Fraser 1999 (Adventist Health Study 1): extraction notes (opus-H2, 2026-10-30)

Source: Am J Clin Nutr 1999;70(suppl):532S-8S, `historisk/fraser1999.txt`. This is a review and summary paper of AHS-1. Colon cancer estimates are in Table 7 (p. 536S), Table 8 (p. 537S) and the text (p. 535S).

## New vocabulary
- `subgroup`: `white_meat_lt1_week`, `red_meat_lt1_week` (as in singh1998), `legume_infrequent`.
- `cup_role = pre2010`.

## Scope coded (8 rows)
- Table 7: colon, nonvegetarian vs vegetarian, 1.88 (1.24-2.87), age/sex adjusted. Coded `total_meat`, `hvl`.
- Table 8: red meat (in subjects with white meat <1/wk) and white meat (in subjects with red meat <1/wk), 3 categories each, including reference rows.
- Text: red meat 2.68 (1.24-5.78) among those with infrequent legume intake. Coded `hvl`, `is_main_model = no`.
- Not coded: the legume estimate (0.33) and the other cancers and diseases.

## Judgment calls
1. **Overlap with singh1998.** Same cohort and follow-up. Table 8 corresponds to Singh 1998 Table 4, but the numbers differ: red meat 1.37/1.86 here vs 1.40/1.90 in Singh; white meat 1.50/3.00 vs 1.55/3.29. The subset sizes are identical (112 and 82 cases). The model may differ, or this is an earlier run. This paper is a secondary report; singh1998 should be preferred.
2. **White meat reference row** is not printed in Table 8. I added it as a structural reference (never = 1.0) and flagged it on the row.
3. **is_main_model.** Table 7 (`total_meat`) and Table 8 (red and white) are each the only estimate for their exposure in this paper, so they are `yes`. This holds even though Table 7 is effectively highest-vs-lowest (supplement point 2 would say `no` when a fuller model exists, and none exists here) and Table 8 is a subset. Downstream pooling should use singh1998 instead.
4. **Table 7 cases = 107.** The comparison excludes semivegetarians. singh1998 reports 157 colon cases (incl. rectosigmoid) in the full analytic cohort, so 107 is presumably vegetarians + nonvegetarians only. `study.cases_colon = 107` (cases in this paper's meat analysis).
5. **Adjustment.** Table 7: age and sex. Table 8 and the text: "multivariate analysis (15)" with no covariates listed, so every flag is `unclear`. Reference 15 as printed is Singh & Lindsted, Epidemiology 1998 (a BMI paper), probably meant as Singh & Fraser 1998.
6. **Outcome = `colon`.** As in singh1998, the endpoint probably includes the rectosigmoid junction; this paper does not say.

## Typos / inconsistencies
- Table 7, "Uterine 1.16" in the incidence (n) column (not a meat row).
- n = 34,192 (abstract) vs 34,198 (text).


---
# gilsing2015
# NOTES – gilsing2015 (NLCS-MIC)

Extractor: opus-F · 2026-10-30 · Source: `post2015/gilsing2015.txt` (Europe PMC full-text XML converted to text; Sci Rep 5:13484, PMID 26316135). The XML has no journal page numbers, so `source_page = "Sci Rep 5:13484 (PMC text)"`. Tables were parsed from the pipe-delimited txt by script.

## New vocabulary
- **`category_set_id` suffixes for the Table 2 contrasts:** `_group5`, `_vegconf`, `_vegself`, `_nomeat`, `_le1day`. Also `_minced` for minced meat, which shares `red_unprocessed` with fresh red meat.

## Contents (336 rows)
- **Table 2 (meat consumption groups): 5 contrasts × 3 outcomes × 2 models = 30 sets, 84 rows.** Exposure = `total_meat` ("meat consumption group").
  - The 5 groups: vegetarian, pescetarian, 1, 2–5 and 6–7 days/week, with 6–7 d/wk as reference.
  - Confirmed vegetarian vs non-vegetarian.
  - Self-defined vegetarian vs non.
  - No-meat consumers vs meat consumers.
  - ≤1 vs >1 day/week.
- **Table 4: 9 exposures × 3 outcomes × 2 models = 54 category sets (198 rows) + 54 continuous rows.** Exposures: total fresh meat, fresh red meat, beef, pork, minced meat, liver, chicken, processed meat, fish.
- **Table 3** (percentage change in HR after single-covariate adjustment) prints HRs without CIs, so it was **not coded**. Proximal/distal, lag and substitution results are "data not shown".

## Judgment calls
1. **Design and denominator: this departs from the brief.** The brief calls this an "NLCS case-cohort" with a subcohort person-years denominator. The paper says: "The full-cohort approach is used for analyses of NLCS-MIC" (Methods). NLCS-MIC is the random NLCS subcohort *plus* all self-reported vegetarians and 1 day/week meat eaters from the full 120,852 cohort, i.e. an enriched analytic cohort.
   - So `design = cohort`. The person-years are the printed NLCS-MIC person-years per category (171,875 in total), which are not subcohort-only.
   - The analysis is not weighted case-cohort. Because of the enrichment, the cohort is not a random sample.
2. **is_main_model:**
   - `yes` = Table 4 multivariable model (category and continuous rows) for fresh meat, fresh red meat, beef, pork, liver, chicken, processed meat and fish.
   - `no` = minced meat. It is a subset of fresh red meat and maps to the same `red_unprocessed` code, so one main row per exposure was kept.
   - `no` = all Table 2 group contrasts, since `total_meat` main = Table 4 total fresh meat. The group analysis is the paper's own headline analysis, so analysts may want it as the "vegetarian contrast".
   - `no` = all age/sex-adjusted rows.
3. **Exposure mapping:**
   - Fresh red meat → `red_unprocessed`, `includes_processed = no`. It is defined as "beef, pork, minced meat, liver and other meat", raw weight, and processed meat is a separate variable.
   - Total fresh meat → `total_meat`, `no`. It includes chicken but excludes processed meat and fish.
   - Liver → `organ`. Chicken → `poultry`.
   - Meat consumption groups → `total_meat`, `yes`.
4. **Table 4 MV model** "if applicable, additionally adjusted for complementary meat groups holding total meat constant". Which groups is not stated, so the meat flags in m3 and `is_mutually_adjusted_processed` are `unclear` for the individual meat types. Total meat and processed rows are `no`.
5. **Dose:**
   - Tertiles of consumers are sex-specific, and the paper prints men's and women's medians separately. `dose_point` is filled only where the two are equal (non-consumers = 0; chicken/fish C1–C2). Otherwise it is empty, and both medians are in `category_label` and dose_conversions.
   - Chicken and fish have fixed bounds (fn d/e), which are recorded. The Table 4 title says "quintiles", but tertiles/categories are used.
   - Weight basis: raw (fresh meat).
6. **Table 2 group sets have the reference = the highest meat group** (6–7 d/wk = rank 1), as the paper does. Dose fields are empty. These sets are not usable for dose-response.

## Discrepancies and typos in the paper
- **Fresh red meat T3 person-years printed 20,904.** The category PYs then sum to 141,875 vs 171,875 for every other exposure. Probably a misprint of 50,904. Recorded as printed and flagged.
- **Table 2 5-group person-years** sum to 169,873, vs 171,875 for the ≤1/>1 day contrast. The 2–5 + 6–7 d/wk sum is 130,716 vs 132,717.
- **Fish, colon:** the non-consumer case count (57) is printed in the P-trend row (layout shift). Recorded as 57 on the non-consumer row; colon cases then sum to 307.
- **Fish, rectum continuous:** printed "0.76–1.32)" without an opening parenthesis.
- **Pescetarian, colorectal MV:** CI printed with an em dash "(0.51—1.51)".
- **Chicken C3 median printed 22.8**, equal to the lower bound (≥22.8) of an open top category. Implausible as a median. Footnote d also leaves a gap between 22.5 and 22.8.
- **checks.py log-asymmetry flags on 8 continuous rows** (asym 0.17–0.58). Examples: pork rectum age-adjusted 1.14 (0.95–1.76); beef rectum age-adjusted 0.87 (0.47–1.22); total fresh meat rectum 1.04 (0.89–1.32). All are recorded as printed and flagged in notes. Several look like typos in the published table.
- **Cases:** 477 eligible vs 437 analysed (after the multivariable-complete restriction). Proximal + distal: Results text 129 + 169 + 9 unspecified = 307, but Methods "184 proximal; 142 distal; 10 unspecified" for the 336 eligible.


---
# giovannucci1994
# Giovannucci 1994 (HPFS) – extraction notes (opus-H1, 2026-10-30)

Source: Cancer Res 1994;54:2390–2397, text file `Historikk 1965-2015/Historikk/txt/22_Giovannucci1994.txt`. This is a two-column OCR with heavy table garbling. Numbers come from Table 2 (p. 2392), the Results text (pp. 2391 and 2393) and the abstract (p. 2390). The study card was not used.

## New vocabulary
- `cup_role = pre2010`.
- `subgroup` values: `never_smoked_before_30`, `smoked_before_30`.
- category_set_id exposure tokens: `red`, `redmaindish`, `processed`, `poultry`, `fish`, `ratio`.

## Scope coded (41 rows)
- **Table 2**, age-adjusted, 30 rows with reference rows:
  - red meat, quintiles with medians;
  - beef/pork/lamb as main dish, 5 frequency categories;
  - processed meats, 5 frequency categories;
  - poultry, quintiles;
  - fish, quintiles;
  - ratio of red meat to chicken + fish, quintiles (substitution, not main).
- **Multivariate text model (p. 2391)**, 2 rows: red meat Q5 vs Q1 1.66 (1.04–2.65); main dish ≥5/wk vs <1/mo 3.07 (1.35–6.98).
- **Subsites and colorectal (p. 2393), age- and energy-adjusted**, 5 rows:
  - red meat, distal colon 1.78 (0.97–3.25);
  - red meat, proximal colon 0.87 (0.43–1.76);
  - red meat, rectum 1.22 (0.36–4.14);
  - red meat, colorectal 1.66 (1.14–2.42);
  - ratio, colorectal 1.81 (1.22–2.67).
- **Smoking strata (p. 2393)**, 4 rows: red meat and main dish, each among men who never smoked before age 30 (75 cases) and men who smoked before 30 (126 cases).
- **Not coded:**
  - Tables 1, 3 and 4: fat, protein incl. "red meat protein", and fibre. These are not meat exposures.
  - Fat from red meat, 1.39 (0.82–2.36): a nutrient, not meat.
  - Fat from chicken, 0.60.
  - Item-level P-values without estimates: hamburger P = 0.04, bacon P = 0.11, ham, hot dogs.
  - Adenomas (per brief).

## Judgment calls
1. **OCR digit corrections.** This text file systematically renders the digit 5 as 3. The decimal point is also often lost. The pattern is confirmed where the abstract repeats a number: Table 2 prints "337 (138–8.06)" and the abstract gives 3.57 (1.58–8.06); Table 2 prints "1.71 (1.15–235)" and the abstract gives 1.15–2.55.
   - Values corrected in this way are recorded with the corrected value, and every one carries "OCR-corrected" and the raw string in its row `notes`:
     - red meat Q2 upper CI 1.54 (raw "134");
     - red meat Q3 upper CI 1.56 (raw "136");
     - red meat Q5 upper CI 2.55;
     - main dish ≥5/wk 3.57 and lower CI 1.58;
     - poultry lower CIs 0.54/0.50/0.52/0.54 (raw "034"/"030"/"032"/"034");
     - fish Q4 lower CI 0.51 (raw "031");
     - red meat medians 88.3 and 129.3 (raw "883", "1293").
   - Each correction restores log-symmetry of the CI. The uncorrected reading would be log-asymmetric.
   - **Every OCR-corrected cell must be verified against the PDF.** This deviates from "numbers as printed": the printed paper almost certainly carries the corrected values, and only the OCR carries the raw strings.
2. **Column-5 displacement.** In every Table 2 row, the OCR moved the highest-category Cases/PY cell to the left margin. Two checks confirm its position:
   - It must be column 5 for main dish, because 16/14,906 gives the 3.57 contrast.
   - The crude rates are consistent only with column 5 for poultry and fish.
   - The same placement was applied to red meat and processed meat.
3. **Values left empty because they are unreadable:**
   - Red meat Q5 person-years (raw "529,689"; about 52,969 by subtraction from the main-dish total of 262,990).
   - Ratio Q3 person-years (raw "428,232").
   - Ratio Q2 median (raw "036": 0.36 or 0.56).
4. **The lowest frequency category for main dish and processed meat** is printed "0" in the OCR header. It is coded "<1/month", following the abstract and text ("less than once per month").
5. **is_main_model.**
   - Colon: the Table 2 age-adjusted rows are `yes` for every exposure. The text multivariate model is more adjusted, but it is reported only as high vs low. It is `no` per supplement rule 2.
   - Distal colon, proximal colon, rectum and colorectal: the age- and energy-adjusted HvL red-meat rows are the **only** estimates for those outcomes. They are set `yes` so that each outcome has one main row. This is a judgment call that departs from a literal reading of supplement rule 2, and it can be flipped.
   - Ratio and smoking-stratum rows are all `no`.
6. **Exposure codes.**
   - Red meat = `red_total`, `yes` (hot dog, preserved meats, bacon).
   - Main dish = `red_main_dish`, `partial` (examples include ham).
   - Poultry = `poultry` (chicken/turkey with and without skin).
   - Ratio = `red_total` with `contrast_type = substitution` and `dose_unit = ratio` (same treatment as Willett 1990).
7. **Adjustment sets.**
   - m1: age-stratified, with energy-adjusted (residual) intake. Used for red meat, poultry, fish and ratio.
   - m2: age-stratified, with energy by stratification. Used for main dish and processed.
   - m3: the multivariate model. Smoking is coded `yes` although the printed covariate list omits it, because the next sentence attributes the confounding to "cigarette smoking before the age of 30" in "the full multivariate model".
   - m4: the smoking-stratum model, which is not described.
   - The text calls the multivariate model "multiple logistic", while the methods say proportional hazards. `effect_measure` is kept as RR, as printed.
8. **Subsite rows are assumed to use m1.** "Age and energy-adjusted" is stated for the distal estimate and is assumed for proximal, rectum and colorectal in the same paragraph.
9. **Category doses.** Main-dish and processed categories have `dose_low` and `dose_high` empty, because the labels mix /month and /week. Quintile variables carry the paper's medians (`paper_median`). No quintile bounds are printed.
10. **Cases do not sum to 205** in Table 2 (red meat 201, main dish 201, processed 202). The paper says so itself (fn b: missing food items). The ratio analysis is restricted (172 cases).

## Text–table agreement
- The abstract red meat 1.71 (1.15–2.55), P 0.005, matches Table 2 Q5 after correction.
- The abstract main dish 3.57 (1.58–8.06), P 0.01, matches Table 2.

## Cohort id
`hpfs` already exists in database/cohorts.csv; no new cohort id needed.

## checks.py (scratch copy, 4 studies combined)
Only expected flags: missing CI on point-only rows (Goldbohm text frequency rows, all Phillips rows), dose rule 4 on Goldbohm 0 / 0-10 categories, and rule 9 (unverified). No log-asymmetry flags.


---
# goldbohm1994
# Goldbohm 1994 (NLCS) – extraction notes (opus-H1, 2026-10-30)

Source: Cancer Res 1994;54:718–723 (Maastricht repository PDF, OCR text `Historikk 1965-2015/Historikk/txt/23_Goldbohm1994.txt`). Numbers come from Table 5 (p. 721), Table 6 (p. 722) and the Results text (p. 720). The study card was not used.

## New vocabulary
- `dose_unit = per_15g`: Table 6 continuous estimates are per 15 g/day increment, "equivalent to one standard sandwich filling".
- `cup_role = pre2010`.
- category_set_id model tokens: `t5` (Table 5 models) and `freq` (text frequency analysis). Exposure tokens: `freshmeat`, `processed`, `fish`, `totalmeat`.

## Scope coded (57 rows)
- **Table 5**, 39 rows, by men, women and both sexes:
  - fresh meat (incl. chicken), 5 quintiles;
  - processed meat, nonuser + 3 categories;
  - fish, nonuser + 3 categories.
- **Table 6**, continuous per 15 g/day, both sexes, 13 rows:
  - model a: total fresh meat;
  - model b: beef, pork, minced meat, liver, chicken, other meat;
  - model c: total processed meat 1.17 (1.03–1.33), the abstract's headline figure;
  - model d: ham, bacon, lean meat products, cooked liver, other processed meats (mainly sausages).
- **Results text p. 720**, 5 rows: frequency of meat consumption (days/week): 0.65, 0.56, 0.78, 0.81 vs 0–2 days/week. **No CI** is printed. These rows are point-only and `no`, and checks.py will flag them as missing CI.
- **Not coded:**
  - Tables 3–4 (fat, protein, meat fat, meat protein). These are nutrients, not meat.
  - "Introduction of fat from meat ... strengthened the association ... (P = 0.01)": no estimate.

## Judgment calls
1. **Outcome = colon only.** The brief says "colon and rectum", but this paper analyses only colon cancer (cecum through sigmoid; p. 718). There are no rectal estimates. `cases_rectum` and `cases_colorectal` are empty.
2. **Denominators.**
   - The brief expected subcohort person-years. The paper does **not** print subcohort person-years or subcohort counts per category, only case counts.
   - `denominator_type = none` on all rows.
   - For both sexes, cases per category are not printed. They could be summed from the men and women columns (given in the row notes) but are left empty.
   - The subcohort sizes analysed are 1525 men and 1598 women, followed for 3.3 years. Per-category person-years would have to be estimated from the subcohort distribution, which is not published.
3. **Fresh meat = `total_meat`, `exposure_includes_processed = no`.** The variable is "all types of meat (except processed meat) and chicken" (Table 5 fn c). It includes poultry and excludes processed meat. It is therefore neither `red_unprocessed` (which would exclude chicken) nor true total meat.
   - The red_meat_definition in study.csv describes this variable.
   - Flag: an analyst using `total_meat` should know that processed meat is excluded.
4. **is_main_model.**
   - Fresh meat, processed meat and fish: the Table 5 categorical models are `yes` for each sex. Men and women use age + energy (m1). Both sexes use age + energy + sex + fibre (m2).
   - The Table 6 continuous estimates for total fresh meat (0.98) and total processed meat (1.17) are `no`. They are less adjusted (no fibre), although the 1.17 is the abstract's headline figure. Flip this if the per-15 g estimate is wanted as the primary dose–response row.
   - Beef, pork, minced meat (`red_unprocessed`), liver (`organ`) and chicken (`poultry`) have only the Table 6 decomposition estimate, which is `yes`.
   - "Other meat" (`red_undefined`) is `no`, because it is an undefined residual category.
   - Processed subtypes (model d) are `no`, because total processed meat holds the processed slot.
5. **Cooked liver** (a sandwich-filling item) is coded `processed` in model d, not `organ`. The fresh liver in model b is `organ`.
6. **Model d rows** are `is_mutually_adjusted_processed = yes`, meaning adjusted for the other processed subtypes. Adjustment set m5 has `adj_processed_meat = yes` with that meaning.
7. **Processed-meat and fish category doses** are coded as printed: 0 / 0–10 / 10–20 / >20 g/day. Because ranks 1 and 2 both have `dose_low = 0`, checks.py rule 4 may flag them as non-rising. This is a printed-boundary artefact, not an error.
8. **Text frequency rows.** Sex and model are not stated. They are coded `sex = all` with adjustment set m6 (all `unclear`).
9. **First-year cases excluded.** Cases diagnosed in the first year are excluded throughout (the paper's own choice), leaving 215 colon cases (105 men, 110 women) from 293 cases with usable diet.

## OCR / printed anomalies
- **Women, processed meat 0–10 g/d: point printed "5.22 (0.66–2.26)" in the text file.** The CI is log-symmetric about 1.22 (0.614 vs 0.616), so it is recorded as **1.22**. It is flagged in the row notes and needs checking against the PDF. If the printed journal page really says 5.22, it is a typo in the paper.
- Men, fish 10–20 g/d: cases printed "It" in the OCR. Recorded as 11, which makes the column sum 105.
- Women, fish 10–20 g/d: point printed "114", recorded as 1.14.
- Table 6, minced meat: mean/SD printed "6 18 {7", read as mean 18, SD 17 (uncertain). The CI is printed "0,801.04" and read as 0.80–1.04. Cooked liver mean is printed "i", read as 1.
- The abstract's 1.17 (1.03–1.33) matches the Table 6 continuous estimate and the text.

## Portion sizes
- Fresh meat: the portion is based on the reported quantity of fresh meat usually purchased per person per meal.
- Processed meat: the number of sandwiches filled. 15 g corresponds to one standard sandwich filling (paper).
- Chicken and fish: standard serving sizes, with the grams not printed.
- Sex-specific medians are printed for fresh-meat quintiles and assigned in dose_conversions. No medians are printed for the processed-meat and fish categories.

## Cohort id
`nlcs` already exists in database/cohorts.csv; no new cohort id needed.

## checks.py (scratch copy, 4 studies combined)
Only expected flags: missing CI on point-only rows (Goldbohm text frequency rows, all Phillips rows), dose rule 4 on Goldbohm 0 / 0-10 categories, and rule 9 (unverified). No log-asymmetry flags.


---
# hoang2023
# NOTES – hoang2023 (UK Biobank, diet × PRS)

Extractor: opus-H · 2026-10-30 · Source: `post2015/hoang2023.txt` (Europe PMC full-text XML of BMC Cancer 23:993). Every number comes from this file, transcribed into a generator script. No study card was used.

## New vocabulary
- `outcome_ascertainment = unclear` (study.csv). The paper never says how CRC cases were identified. It gives only the ICD-10 codes and the end date of follow-up.
- `source_page = "e-only (BMC Cancer 23:993, no pagination)"`. This online-only article has no page numbers.

## Contents
- **estimates.csv: 72 rows**, all colorectal, sex = all, categorical, unit `times_week`.
  - **Table 2:** 4 exposures (red meat, processed meat, poultry, total fish) × 2 models (crude, adjusted) × 3 categories = 24 rows. Cases, participants and person-years are given per category.
  - **Table 3 (joint diet × PRS), low-PRS column only:** 4 × 3 = 12 rows. Cases and person-years are given.
  - **Table 4 (stratified by PRS tertile):** 4 × 3 tertiles × 3 categories = 36 rows. No cases or denominators are printed.
- **adjustments.csv: 4 rows** (m1 crude; m2 Table 2 adjusted; m3 Table 3 joint; m4 Table 4 stratified).
- **dose_conversions.csv: 24 rows**, one per category set. `g_day_assigned` is empty in every row.
- **Not coded:** WCRF score, IV-weighted score, milk, cheese, fruit, vegetables, coffee, tea and alcohol, which are outside R1. Intermediate- and high-PRS cells of Table 3, which mix diet and PRS effects. Cumulative risks. Attributable fractions.

## Missing estimates (supplement not available)
- Additional file 1 is not in the drive: Tables S4 (by sex), S5 (colon / rectum), S7–S8 (joint effects by sex and subsite) and S9–S10 (stratified by sex and subsite).
- The text says red and processed meat were associated with both colon and rectal cancer (S5) and with CRC in men only (S4). **No colon, rectum or sex-specific meat estimates could be coded.**

## Judgment calls
1. **Red meat = `red_undefined`, `exposure_includes_processed = unclear`.**
   - The methods list beef, lamb/mutton, pork and processed meat as separate touchscreen items, then say "we grouped single items to obtain the consumption of red meat (times/week)", citing Bradbury et al.
   - Processed meat is analysed as its own exposure, so red meat is very probably unprocessed beef + lamb + pork. The paper never says so, though, so it is coded as undefined (R6).
   - Change to `red_unprocessed` / `no` if the team accepts the inference.
2. **is_main_model = yes** goes on the Table 2 "Adjusted HR" rows (m2) for each of the 4 exposures. This is the paper's primary diet–CRC analysis. Crude rows, Table 3 joint rows and Table 4 PRS-stratified rows are `no`: they are secondary or subgroup analyses of the gene–diet question.
3. **Table 3 low-PRS column.** These are pure diet contrasts within the lowest PRS tertile, against a common reference, and come from a different model (adds household income, joint categories).
   - The intermediate- and high-PRS cells use the low-PRS/low-intake reference, so they mix diet and PRS effects. They were not coded.
   - In Table 3, **poultry and fish categories run in reverse order**: the reference is the highest intake (≥ 2 / > 2 times/week). `category_rank` follows the printed order, so rank 1 = the reference = the highest intake. checks.py therefore flags `4_dose_ikke_stigende` for these two sets. The flag is expected and is documented in the row notes.
   - The `p_interaction` values are put in the notes, not in `p_trend`.
4. **Bounds for "1" (processed meat, poultry)** are coded `dose_low = dose_high = 1`. For "≤ 1" / "< 1" only `dose_high` is set. For open top categories only `dose_low` is set.
5. **Denominators (Table 2).** Both person-years (`person_years`, `denominator_type = person_years`) and "No. participants" (`n_in_category`) are filled. The brief allows only one `denominator_type`, so person-years was chosen.
6. **Age adjustment is unclear.** No footnote or methods passage lists age, and the Cox time scale is not stated. So `adj_age = unclear` for m2–m4.
7. **No energy adjustment** (`energy_method = none`). The touchscreen questionnaire gives frequencies only.
8. **is_mutually_adjusted_processed = no** on every row. Foods were entered one at a time, and no other meat appears in the covariate list.

## Inconsistencies (recorded as printed)
- **Covariate lists disagree.** The methods (Statistical analysis) and the Table 3/4 footnotes include household income. The Table 2 footnote omits it. m2 follows the Table 2 footnote, and the omission is noted in adjustments.csv.
- **WCRF score typo in the Results text.** "HR = 1.12, 95% CI = 1.05–1.09" (the Table 2 value is 1.05–1.19). This row is out of scope and not coded.
- **Case totals.** Table 2 category cases sum to 4,681 (red meat), 4,680 (processed), 4,678 (poultry) and 4,679 (fish), against 4,686 CRC in total (complete-case analysis). study.csv keeps the paper's total, 4,686.
- **Table 1 typo.** "12,2550" for BMI < 25 (out of scope).
- **checks.py flag 2 (log-asymmetry):** rows 014 (1.03, 0.97–1.11; asym 0.20) and 024 (0.96, 0.89–1.05; asym 0.16). Both come from rounding to two decimals near 1.0. They are not typos.

## Supplement rows (30.10)

Extractor: opus-S3 · 2026-10-30 · Source: `supplements/hoang2023_MOESM1.txt` (Additional file 1, Tables S1–S11). `hoang2023_MOESM2.txt` contains only figure captions and has no numbers. This section supersedes "Missing estimates (supplement not available)" above.

**192 new rows** (`hoang2023_073`–`_264`; file now 264 rows). Each analysis has 4 exposures (red meat, processed meat, poultry, total fish) × 3 frequency categories, `dose_unit = times_week`.

| Table | Rows | Content |
|---|---|---|
| Suppl Table S4 | 48 | By sex: men and women, crude (m1) and adjusted (new **m5** = m2 without sex). Cases per category only. |
| Suppl Table S5 | 48 | By site: colon and rectum, crude (m1) and adjusted (**m2**; the footnote is identical to the Table 2 footnote). Cases per category only. |
| Suppl Table S7 | 24 | Joint diet × PRS by sex. **Low-PRS column only** (`subgroup = prs_low_joint_model`), new **m6** = m3 without sex. Cases and person-years given. |
| Suppl Table S8 | 24 | Joint diet × PRS by site. Low-PRS column only, **m3** (footnote includes sex). Cases and person-years given. |
| Suppl Table S9 | 24 | Stratified by PRS tertile, by sex. **Low-PRS stratum only** (`subgroup = prs_low`), new **m7** = m4 without sex. No cases or person-years; the cumulative risk (%) per cell is put in notes. |
| Suppl Table S10 | 24 | Stratified by PRS tertile, by site. Low-PRS stratum only, **m4**. |

Supporting files:
- 3 new adjustment sets (m5–m7) and 64 new `dose_conversions` rows (one per new category set, `g_day_assigned` empty, frequency-only questionnaire).
- study.csv notes updated.
- Scope: the caller asked for red and processed meat. Poultry and total fish rows were also coded from the same tables as negative controls (KODEBOK 3.3/R1), because they sit in the same tables and models.

### Judgment calls
1. **is_main_model.**
   - `yes` on the S4 adjusted rows (men, women) and the S5 adjusted rows (colon, rectum). These are the paper's main diet model applied to each sex and site, so they are main for that exposure × outcome × sex.
   - `no` on crude rows, joint-model (S7/S8) rows and PRS-stratified (S9/S10) rows. This matches the rule already used for Tables 2–4.
2. **S7–S10 diet rows at low genetic risk are separable**, so they were coded.
   - In the joint tables (S7/S8), the low-PRS column is a pure diet contrast against a common low-PRS reference.
   - In the stratified tables (S9/S10), the low-PRS stratum is a within-stratum diet contrast.
   - Intermediate/high-PRS cells were not coded. In S7/S8 they mix diet and PRS effects. In S9/S10 they would be valid within-stratum contrasts, but they were outside the assignment (low genetic risk only).
   - The S7/S8 P-interaction values are in notes.
3. **Category order in S7/S8 for poultry and fish is reversed**: the reference is the highest intake (≥ 2 or > 2 times/week), as in main-text Table 3. `category_rank` follows the printed order, so checks.py flag 4 (`dose_ikke_stigende`) fires on 8 new sets. That is expected and noted in the rows. S9/S10 use ascending order with the lowest intake as reference.
4. **New adjustment sets m5–m7.** The S4, S7 and S9 footnotes omit sex because the analyses are sex-stratified. The covariate lists therefore differ from m2–m4, and new sets were created (adj_sex = no). S5, S8 and S10 footnotes include sex, so m2, m3 and m4 are reused.
5. **The red-meat definition is kept as `red_undefined` / `unclear`**, for consistency with the 72 main-text rows.
   - Suppl Table S1 now shows the questions:
     - beef: "Do not count processed meats"
     - lamb/mutton: the same
     - pork: "Do not count processed meats such as bacon or ham"
     - processed meat is its own item.
   - Bradbury 2020's supplementary methods, which Hoang cites (ref 23) for the grouping, define red meat as the summed beef + pork + lamb/mutton frequencies.
   - Together this strongly supports `red_unprocessed` / `no`. The team can switch all hoang2023 red-meat rows in one step. I did not edit existing rows (supplement brief).
6. **`denominator_type`.**
   - S4/S5 print cases only → `none`.
   - S7/S8 print cases and person-years → `person_years`.
   - S9/S10 print neither → `none`.

### Contradictions and oddities (recorded as printed)
- **S5 rectal processed meat.**
  - The adjusted top category is 1.16 (1.03–1.32), yet the adjusted P-trend is printed as 0.45.
  - The crude P-trend for rectal processed meat (0.004) is identical to the colon crude P-trend.
  - This looks like a copy error in the P-trend row. It is flagged on row `_144`.
- **S4 women: crude and adjusted P-trends are identical** for red meat (0.12/0.12) and processed meat (0.45/0.45), while the HRs differ slightly. Flagged in notes.
- **Main text vs S5.** The Results text says high intakes of red and processed meats were associated with an increased risk of both colon and rectal cancer.
  - Supported at the top category: colon processed ≥ 2: 1.11 (1.01–1.21); rectum processed ≥ 2: 1.16 (1.03–1.32).
  - But the printed P-trends for processed meat are 0.08 (colon) and 0.45 (rectum).
- **Main text vs S4.** "Red meat, processed meat … associated with an increased risk of CRC in men only". This is consistent with S4: men red ≥ 3: 1.20 (1.10–1.32); men processed ≥ 2: 1.20 (1.09–1.32); women not significant.
- **S7 (joint, low-PRS) and S9 (stratified, low PRS) are nearly identical** for the same cells, e.g. women red meat 1.12 (0.91–1.39) and 1.21 (0.96–1.53) in both. They are separate analyses with separate model ids. Do not use both in one pooling.
- **S8 person-years** for the low-PRS cells are identical in the colon and rectal sections, and identical to main-text Table 3. This is plausible, since the whole low-PRS cohort is at risk for both sites.
- **Site totals.** S5 colon red-meat cases sum to 3,127 and rectum to 1,554, against 3,131 and 1,555 in study.csv (complete-case differences, as for Table 2).

### checks.py (scratch copy)
- Flag 2: only the 2 pre-existing rows (`_014`, `_024`).
- Flag 4: 10 sets, 8 of them new. All are the expected reversed-order joint tables.
- Flag 9: unverified, expected.
- No new flags otherwise.


---
# islam2019
# NOTES – islam2019 (pooled Japanese cohorts)

Extractor: opus-E · 2026-10-30 · Source: `Understudier WCRF/oppfolginger/islam2019.txt`, converted from XML. The main text has Tables 1–5. **Supplementary Tables S1–S4 are not in the file**: the txt ends at "Click here for additional data file". No `_suppl` file exists. Values the Results text quotes from S2/S3 are coded as text rows. All table values were parsed by script from the pipe-separated rows. No study card was used.

## New vocabulary
- `subgroup = excl_cases_first_3y` and `subgroup = excl_takayama`. Both are free text.
- No new controlled values.

## Cohort ids
- All pooled rows have `cohort_id = japanese_pooled`. This applies to both the frequency pool (Tables 2–3) and the quantity pool (Tables 4–5).
- **No per-cohort estimates are printed in the main text.** Study-specific HRs were computed but not shown. The ids jphc, jacc, miyagi, ohsaki and takayama are therefore not used for table rows.
- **One exception:** the sensitivity analysis "excluding the TAKAYAMA study" (women, beef Q4 vs Q1, Results text) leaves only JPHC-5y in a 2-cohort pool. It is a single-cohort estimate and is coded `cohort_id = jphc` (2 rows).
- **The two pools are disjoint sets of cohorts:**
  - Frequency pool: JPHC I, JPHC II, JACC, MIYAGI, OHSAKI. 232,403 participants, 5,694 CRC cases.
  - Quantity pool: JPHC-5y, TAKAYAMA. 123,635 participants, 3,550 CRC cases.
  - Downstream users may want to separate them with distinct ids, e.g. `japanese_pooled_freq` and `japanese_pooled_qty`. I did not invent new ids, because the brief fixes `japanese_pooled` for pooled rows. The pool is identifiable from `category_set_id` (`_freqmv_` / `_qtymv_`) and from `model_label`.
- **Overlap warning (important for the "Takachi → Islam" and "Oba → Wada" version analyses):**
  - The quantity pool contains TAKAYAMA (the same cohort as oba2006 and wada2017) and JPHC-5y (the JPHC questionnaire used by takachi2011).
  - The frequency pool contains JPHC I/II baseline data, which is also JPHC.
  - Islam 2019 must therefore never be pooled together with takachi2011, oba2006 or wada2017.

## How red meat is defined, and whether processed meat is separated
- **Frequency pool.** Beef, pork, "processed red meat" (ham, sausage) and chicken were each asked about separately. There is **no aggregated red-meat variable** in this pool. Beef and pork are separate, and processed meat is separate.
- **Quantity pool.** "Unprocessed red meat (beef and pork), beef, pork, chicken, and processed meat (ham, sausage)" were quantified in grams.
  - "Unprocessed red meat" is coded `red_unprocessed` with `exposure_includes_processed = no`. The paper calls it unprocessed and lists processed meat separately.
  - The paper does not say whether offal or liver are included. Wada 2017 says the Takayama red-meat items include grilled offal and liver.
- **Processed.** "Processed red meat" in the tables equals "processed meat (ham, sausage)" in the Methods. Coded `processed`.
- **Mutual adjustment.** Processed meat is never adjusted for. Each meat type was modelled separately: `is_mutually_adjusted_processed = no`, `adj_processed_meat = no`.
- In study.csv, `includes_processed = no` refers to the unprocessed red-meat variable.

## Contents
- **estimates.csv: 401 rows.**

| Source | Design | Rows |
|---|---|---|
| Table 2 (men, frequency) | 4 meats × 3 outcomes × 4 categories, plus 4 meats × 2 subsites × 3 categories | 72 |
| Table 3 (women, frequency) | same layout | 72 |
| Table 4 (men, quantity) | 5 meats × 5 outcomes × (4 quartiles + 1 continuous) | 125 |
| Table 5 (women, quantity) | same layout | 125 |
| Results text | (a) beef DCC women, age/area model; (b) 4 values quoted from Suppl Tables S2/S3 (excluding cases within 3 years); (c) 2 excl-TAKAYAMA rows | 7 |

  - The 7 Results-text rows are coded `contrast_type = hvl`.
- **Reference rows** are included for every category set (`point = 1.00`). Check: 144 + 250 + 7 = 401.
- **adjustments.csv: 5 rows.**
  - m1–m4 = multivariable model per pool × sex (Tables 2–5 footnotes).
  - m5 = age- and area-adjusted.

## Judgment calls
1. **is_main_model**
   - The quantity pool (Tables 4–5) is `yes`, for both the quartile rows and the continuous rows.
   - The frequency pool (Tables 2–3) is `no`.
   - **Reason:** the brief allows only one `yes` per exposure × outcome × sex, and beef, pork, processed and chicken appear in both pools. The paper does not rank the pools. I chose the quantity pool because:
     - it is the only pool with gram-based intake and continuous per-unit estimates;
     - it is the only pool with the red-meat aggregate;
     - its text is the basis of the abstract's beef findings.
   - The frequency pool is a **separate, larger set of cohorts**. An analyst can legitimately treat it as an independent main estimate. Re-flag this if the database adopts separate pool ids.
2. **Continuous unit.** The footnote says "Per 100 g of unprocessed red meat, beef, pork, or chicken and per 50 g of processed meat". I coded `per_100g` (and `per_50g` for processed), assuming g/day; "/day" is not printed.
3. **Frequency categories.** Coded `dose_unit = times_week`, with `dose_low`/`dose_high` as printed:
   - <1/wk → high 1
   - 1‐2 → 1–2
   - 3‐4 → 3–4
   - "almost every day" → no bounds
   - For proximal and distal colon, the top two categories were combined ("3‐4 times/wk or more", footnote b). This gives 3 categories, with dose_low 3 and an open top.
4. **Quantity quartiles.** Quartiles were formed within each cohort. No medians, bounds, cases or person-years are printed. `dose_unit = g_day`, with dose fields empty and `denominator_type = none` throughout.
5. **Heterogeneity** (Cochran P, I²) for the highest category is recorded in `notes` on the top-category row.
6. **Women, beef, distal colon, age/area-adjusted (1.48, 1.03–2.11).** The text paragraph is about women (Table 3), though it does not say "women" in that sentence. I coded `sex = women`, and the notes say so.
7. **Text values from Supplementary Tables S2 and S3** are coded as `hvl` rows with the subgroup `excl_cases_first_3y`. The adjustment set is assumed to be the same as the corresponding main table.
8. **source_page.** There are no page markers in the txt. Every row has "page not marked in txt", and the line numbers are in notes.

## Typos and inconsistencies (flagged)
- **Table 4, men, distal colon, processed red meat, Quartile 2: "0.58 (0.70‐1.04)".** The point estimate lies outside its own CI, so the printed value is impossible. It is probably 0.85 or 0.88 transposed. Recorded as printed and flagged in the row notes; checks.py flags it (check 1).
- **Chicken, women, CRC, excluding cases within 3 years (Table S2 via text).** The text says chicken "was associated with a decreased risk of CRC (pooled HR … was 1.04 [95% CI, 0.66‐1.63; P trend = .03])". An HR of 1.04 is not a decrease. Either the HR or the wording is wrong; the P trend may reflect an inverse trend across categories. Recorded as printed and flagged.
- **Abstract vs Methods: number of cohorts.** The title and Discussion say 6 cohorts, but 7 studies are listed: JPHC I, JPHC II, JACC, MIYAGI, OHSAKI, JPHC‐5y and TAKAYAMA. JPHC I/II and JPHC‐5y belong to one cohort (JPHC), which presumably explains "6".
- **Table 1 vs text, participant totals.** Table 1 sizes for the frequency pool: men 107,777 + women 124,626 = 232,403. This matches the text. Quantity pool: 57,672 + 65,963 = 123,635, which also matches.
- **Case totals.** Frequency pool: 3,428 + 2,266 = 5,694. Quantity pool: 2,108 + 1,442 = 3,550. Total 9,244, matching the Discussion. Colon and rectum totals are not printed, so `cases_colon` and `cases_rectum` are empty.
- **Text vs table.** Women processed red meat, CRC, almost every day: text "1.33 (95% CI, 1.001‐1.76; P trend = .12)" matches Table 3 (the cell is split over two lines in the txt; handled). The beef DCC men, beef colon women, per-100 g beef, and pork/processed DCC women values in the text all match the tables.
- **Table 4, P for trend formatting.** Some cells are printed with a leading zero ("0.51", "0.02"), others without (".31"). Copied as printed.
- **TAKAYAMA participants** in Table 1: 14,224 men + 16,575 women, with 449 + 352 CRC. These differ from Wada 2017 (13,957 + 16,374; 429 + 343) for the same follow-up end (2008/03/31). The exclusion criteria differ: Islam excluded participants with missing covariates; Wada excluded those with adenoma history. Noted for the followups table.

## Not coded
- Table 1 cohort descriptors, except as study-level notes.
- Supplementary Tables S1 (men excl. 3 y), S2–S4 beyond the text-quoted values. **The supplement is not available. Please obtain it:** it would supply the study-specific and sensitivity estimates.

## Study-level
- `design = pooled_cohorts`; `baseline 1988–1999`.
- `followup_years` is empty: per-cohort means range from 10.9 to 20.0 years and no overall value is given.
- **The journal name, DOI and PMID are not printed in the txt.** All three are left empty rather than filled from memory; please verify them against the PDF.
- `in_cup2016 = no` and `cup_role = post_2016` come from the tillegg list.

## Supplement rows (30.10)

Extractor opus-S2, 2026-10-30. Source: `/home/claude/drive/supplements/islam2019_S1-S4.txt` (from `suppl_in/islam2019_S1-S4.docx`). Parsed by script from the pipe-separated rows; every printed cell checked by regex.

**What the supplement is (contradicts the brief's premise).** S1-S4 are NOT per-cohort tables. They are the same four *pooled* tables as main Tables 2-5 (S1 frequency men, S2 frequency women, S3 quantity men, S4 quantity women), expanded with (a) number of subjects and cases/person-years per category, (b) an age- and area-adjusted model, (c) the multivariable model, (d) the multivariable model excluding cases diagnosed in the first 3 years. **No study-specific HRs are printed anywhere** (JPHC I/II, JPHC-5y, JACC, MIYAGI, OHSAKI, TAKAYAMA). So no rows with cohort_id jphc/jacc/miyagi/ohsaki/takayama were added; all new rows are `japanese_pooled`. The JPHC-5y-only unprocessed red meat estimate (direct successor of takachi2011) is not in the supplement; the only single-cohort JPHC numbers remain islam2019_400/401 (beef, excl. TAKAYAMA, from the main text).

**Added: 788 rows (islam2019_402 – islam2019_1189), 180 dose_conversions rows (c091–c270).**

| Suppl table | Age/area-adjusted | Multivariable excl. <3 y | Total |
|---|---|---|---|
| S1 (men, frequency) | 72 | 72 | 144 |
| S2 (women, frequency) | 72 | 72 | 144 |
| S3 (men, quantity; incl. continuous) | 125 | 125 | 250 |
| S4 (women, quantity; incl. continuous) | 125 | 125 | 250 |

- Multivariable rows in S1-S4 were compared cell by cell (point, CI, P trend) with the existing Table 2-5 rows: **all 304 non-reference estimates (plus P trends) identical**, so they were not re-coded (no duplicates).
- category_set_id: `islam2019_{freq|qty}{age|mvexcl3y}_<outcome>_<sex>_<exposure>`. Age/area rows use `islam2019_m5`; excl-3y rows use m1–m4 with `subgroup = excl_cases_first_3y`. All `is_main_model = no`.
- Denominators: `n_cases` and `person_years` from "Cases/person-years", `n_in_category` = "Number of subjects", `denominator_type = person_years` (both filled, as in wada2017/hoang2023). Continuous rows have no denominators.
- **The case/person-year/subject counts also belong to the existing main-model rows** (Tables 2-5), which have them empty. Not edited per the brief; a later pass may back-fill them from the matching age/area rows (same category_set suffix, same rank).
- p_trend on the top category only; heterogeneity (P, I²) in notes of the top row, as in the main-text rows.

**Judgment calls**
1. Age/area model for the quantity pool reuses `islam2019_m5`, although m5's covariate text describes area handling in the frequency-pool cohorts; the supplement does not say how area was handled in JPHC-5y/TAKAYAMA.
2. **Duplicates of earlier Results-text rows.** Five supplement cells are the same estimate as hvl rows coded from the text: age/area beef DCC women (=395), excl-3y processed CRC women (=396), chicken CRC women (=397), chicken PCC women (=398), excl-3y beef DCC men quantity (=399). The full category sets were coded (needed for dose-response) and the top-category row carries a "DUPLICATE VALUE ... do not count both" note.
3. islam2019_397 notes appended (allowed exception): the "decreased risk" wording is explained by the S2 series 1.00 / 0.93 / 0.85 (0.72-1.00) / 1.04, P trend 0.03.

**Typos and inconsistencies (recorded as printed, flagged in row notes)**
- S3 men DCC processed Q2 multivariable is printed **0.58 (0.70-1.04)** again in the supplement, so the typo on islam2019_261 is not resolved. Neighbouring models (age/area 0.81, excl-3y 0.84) suggest roughly 0.85.
- S1 men colon processed, excl-3y, 1-2/wk: **0.91 (0.81-0.02)** (islam2019_455), upper limit garbled.
- S4 women rectal beef, age/area, Q2: **1.07 (0.82-0.40)** (islam2019_1051), upper limit garbled.
- S4 women DCC chicken, age/area, Q3: "1.10 (0.82-1.47" is missing its closing parenthesis; the numbers are unaffected (islam2019_1182).
- Asymmetric CIs (checks.py 2, asym > 0.3): islam2019_502 1.03 (0.79-1.13), 1072 1.11 (0.67-1.53), 1161 1.07 (0.80-1.14).
- Subject counts that differ within an exposure: S1 men DCC pork prints 41,292 / 44,608 / 18,026 subjects, while every other pork outcome prints 34,182 / 49,928 / 21,971. S2 women rectal chicken prints 49,611 / 51,727 / 16,581 / 2,051, while every other chicken outcome prints 43,721 / 57,032 / 19,141 / 1,893. Recorded as printed. These are probably copy errors in the supplement.
- Case totals per exposure (e.g. men frequency beef CRC 2,105+988+192+22 = 3,307) are below the pool totals in the main text (3,428), presumably because of missing values for each item. This is not an error.


---
# jarvinen2001
# Järvinen 2001 (Finnish Mobile Clinic, fmches): extraction notes (opus-B, 2026-10-30)

Source: Br J Cancer 85(3):357–361, full text `Understudier WCRF/jarvinen2001.txt`. All numbers come from Table 3 (p. 359) and the methods/results text (pp. 357–358). No supplement exists. The study card was not opened.

## New vocabulary
None. Liver is coded `organ`, and poultry yes/no has an empty `dose_unit` (see 5).

## Scope coded (42 estimate rows)
- Table 3 has one multivariate model, sexes combined, and 3 outcomes (colorectal n=109, colon n=63, rectum n=46):
  - "Meat, all" (`total_meat`): 4 quartiles × 3 outcomes = 12 rows
  - "Red meat" (`red_undefined`): 4 × 3 = 12
  - "Poultry" (no/yes): 2 × 3 = 6
  - "Liver" (`organ`): 4 × 3 = 12
- Not coded:
  - Eggs (out of scope).
  - Table 2 nutrients (out of scope).
  - The text estimate "0.78 (0.42–1.44)". It belongs to the energy-intake paragraph, not to meat.
- The paper prints no age-adjusted model, sex-specific estimates, continuous estimates, cases per category, person-years or medians for meat.

## Quartile bounds (recorded as asked; they matter for dose assignment)
| Quartile | Meat, all – men | Meat, all – women | Red meat – men | Red meat – women |
|---|---|---|---|---|
| 1 | <101 | <67 | <94 | <61 |
| 2 | 101–151 | 67–101 | 94–141 | 61–92 |
| 3 | 152–220 | 102–145 | 142–206 | 93–134 |
| 4 | >220 | >145 | >206 | >134 |

All values are g/day. Liver quartiles are <1 / 1 / 2–5 / >5 g/day for men and <1 / 1–2 / 3–5 / >5 g/day for women.

**Relation between the two variables.**
- Every red-meat cut-point is 91–94% of the matching "Meat, all" cut-point (men 0.93/0.93/0.94; women 0.91/0.91/0.92).
- So "Red meat" is nearly all of "Meat, all" in this population. Poultry (consumers vs non-consumers only) and liver (Q4 >5 g/d) are small.
- Table 1 reports "Meat and meat products" as 153.9 g/d in cases and 145.3 g/d in non-cases, and the text calls the Table 3 variable "total consumption of meat and meat products".
- With red meat at about 92% of that, red meat very probably contains meat products (sausages, cold cuts). The paper never defines it, so `exposure = red_undefined` and `exposure_includes_processed = unclear` (R6). This is the key exposure-rule issue for Järvinen in any CUP reconstruction.

## Judgment calls
1. **Sex-combined estimates with sex-specific cut-points.**
   - The paper determined quartile ranges separately for men and women (p. 358) but reports RRs for men and women together.
   - One estimate row therefore has two sets of bounds, so `dose_low`/`dose_high` are left empty and both sets are written in `category_label` (e.g. "Q2 (men 94–141 g/d; women 61–92 g/d)").
   - `dose_point_source = none`.
2. **sex = `all`** on every row. The category sets are `jarvinen2001_mv_<outcome>_all_<exposure>`.
3. **Red meat = `red_undefined`, Meat, all = `total_meat`.** `exposure_includes_processed = unclear` for both (see above).
4. **Liver = `organ`**, `exposure_includes_processed = no`.
5. **Poultry** is a 2-level consumer/non-consumer variable with no amount. `dose_unit` is left empty because no vocabulary value fits (yes/no). Ranks are 1 = no, 2 = yes. It is not usable for dose-response.
6. **is_main_model = yes** on all rows. It is the paper's only model for meat (Table 3 fn a). Adjustment set m1:
   - Adjusted for age, sex, BMI, occupation, smoking, geographic area (6 regions, as a covariate, so `adj_stratified_center = no`), energy, and vegetables (without potatoes), fruits and cereals (`adj_fruit_veg = yes`).
   - Not adjusted for alcohol, physical activity, fibre or education. Occupation is a socioeconomic proxy but was not coded as education.
   - `energy_method = covariate`.
7. **Denominators.** Neither cases nor person-years per category are printed, so `denominator_type = none`. Only the outcome totals are known (109/63/46). For GL, the KODEBOK 4.3.5 equal-denominator approach applies (the quartiles are quantile-based, but sex-specific).
8. **dose_conversions.**
   - `g_day_assigned` is left empty for all sets. A sex-combined dose per quartile needs the men/women split per quartile, which is not printed. Only the total sex split of cases is given (54 men, 55 women), and the cohort sex split is not in the paper.
   - The notes list CUP-rule midpoints per sex for reference (bottom open category from 0; top open = lower bound + half the neighbour's width). Any single dose CUP used must have come from outside the paper or from an averaging assumption.
9. **study.csv.**
   - `followup_years = 32`, `followup_type = max` ("up to 32 years", p. 360; baseline 1967–72, follow-up to late 1999).
   - `diet_instrument = diet_history` (interviewer-administered dietary history, structured questionnaire of >100 foods). `diet_items` is empty because the paper says only "more than 100".
   - `age_range` is empty because it is not printed.
   - `validation_r` is empty: reproducibility ICCs exist for nutrients only, not meat.
   - `weight_basis = unclear`.
   - `in_cup2016 = yes`, `cup_role = dose_response` (from OPPDRAG_tillegg).

## Typos / anomalies (recorded as printed)
- **Red meat Q2, colorectal: "1.06 (0.67–2.01)"** (row jarvinen2001_014). Its log-asymmetry is 0.28, and checks.py flags it.
  - The point is close to the lower limit. The geometric mean of the CI is 1.16, so "1.06" may be a typo for 1.16, or "0.67" for 0.56.
  - The corresponding colon (0.71) and rectum (2.18) values make a colorectal value around 1.1–1.2 plausible.
  - Flagged in the row notes. Needs checking against the PDF.
- Table 3 header says "Quartile of daily intake (g)", but the poultry row has no quartiles (no/yes).
- No text–table disagreement for meat: the text only says the associations were "not significantly associated".


---
# jin2023
# NOTES – jin2023 (UK Biobank, diet-wide association study)

The first pass was opus-H (2026-10-30). It used the main text only: `post2015/jin2023.txt`, the Europe PMC full-text XML of Nutrients 15(22):4801, and found 0 meat rows. The supplement pass was opus-S3 (2026-10-30). It used `supplements/jin2023_supplementary.txt` (On-line Supplementary Material, Tables S1–S5).

## New vocabulary
- `subgroup`: `poultry_type_breaded_battered_chicken`, `fish_type_white_fish_tinned_tuna`, `fish_type_breaded_battered_fish`, `fish_type_shellfish`. `fish_type_oily_fish` already exists from bradbury2020.
- `dose_unit = per_sd` is in the KODEBOK vocabulary. Nothing else is new.

## Main text (opus-H): no meat estimates
- **The main text has no meat numbers.** Main-text Table 1 (tertiles: colorectal, colon and rectum) and Table 2 (by PRS) cover only the 8 FDR-significant items: carbohydrate, fibre, calcium, magnesium, phosphorus, manganese, alcohol and white bread.
- **Figure 1 is a volcano plot.** It prints no meat numbers, so it was not coded (supplement rule 6).
- **Tertile analyses for meat are mentioned in Methods but never printed.** "Food or nutrient intake was also analyzed as categorical variables by dividing into tertiles". There are no category rows for any meat item anywhere.

## Supplement rows (30.10)

**55 rows** (`jin2023_001`–`_055`), all `contrast_type = continuous` and `dose_unit = per_sd`, one model (`jin2023_m1`). 11 Oxford WebQ items × 5 strata:

| Table | Rows | Strata |
|---|---|---|
| Suppl Table S2 | 11 | colorectal, both sexes |
| Suppl Table S3 | 22 | colon, rectum |
| Suppl Table S4 | 22 | women, men (S4 prints the Female column first) |

The items, with their exposure codes:

| WebQ item | exposure | subgroup |
|---|---|---|
| Beef | `beef` | |
| Lamb | `lamb` | |
| Pork | `pork` | |
| Other meat, offal | `organ` | |
| Processed meat | `processed` | |
| Poultry | `poultry` | |
| Breaded/battered chicken | `poultry` | breaded/battered chicken |
| Oily fish | `fish` | oily fish |
| White fish and tinned tuna | `fish` | white fish and tinned tuna |
| Breaded/battered fish | `fish` | breaded/battered fish |
| Shellfish | `fish` | shellfish |

Other files:
- `dose_conversions.csv`: 1 row, saying the SD in grams is not printed.
- `study.csv`: notes and the red-meat definition updated, and the supplement path added.
- `adjustments.csv`: m1 kept. Its notes now record that the S2–S4 footnotes give the same covariates, including ethnicity.

### Judgment calls
1. **The SD in g/day is not printed** anywhere, in the main text or the supplement. There is no table of intake distributions. `dose_point` is empty, and the per-SD HRs cannot be rescaled to per-100 g without outside data on the UK Biobank WebQ SD.
2. **There is no red-meat aggregate.** The paper analyses beef, lamb and pork separately. No `red_*` row exists.
3. **Heme iron is not reported.** The only iron item is total iron, which is not coded (R1: only *computed heme iron* is in scope).
4. **Out of scope:**
   - "Sushi" (mixed dish).
   - "Meat substitutes – soy/vegetarian".
   - "Animal protein" and "Animal fat" (nutrients, not foods).
5. **"Other meat, offal" → `organ`.** The WebQ item mixes offal with unspecified other meats. `organ` is the closest vocabulary value. This is flagged in the row notes.
6. **Shellfish is coded under `fish`**, with the subgroup separating it. It is flagged in the row notes.
7. **is_main_model.**
   - `yes` for whole-exposure items: beef, lamb, pork, organ, processed and poultry. The paper has only one model, so these are main for each outcome × sex.
   - `no` for the sub-items: breaded chicken and the 4 fish types. The paper gives no total-fish estimate and no poultry-including-breaded-chicken estimate. Marking four fish rows as main for one outcome × sex would break "one main row per exposure × outcome × sex". **Jin 2023 therefore has no main `fish` row.** A pooling script that needs fish must choose a sub-item explicitly.
8. **exposure_includes_processed.**
   - `yes` for processed meat.
   - `unclear` for beef, lamb, pork, organ, poultry, breaded chicken and breaded fish: the paper never defines the items.
   - `no` for oily fish, white fish/tuna and shellfish.
9. **n_cases / denominators.** Only totals are printed, so continuous rows carry them:
   - colorectal 1,466, colon 842, rectum 359, each with 118,210 participants;
   - men 831 cases and 52,664 participants (Table S1).
   - Women's counts are not printed (they would only be differences), so women rows have `denominator_type = none`.
10. **P values.** The printed P goes in `p_value`. FDR-adjusted P and P-heterogeneity (site or sex) go in `notes`.

### Inconsistencies (recorded as printed)
- **Processed meat in men (S4): 1.10 (1.03–1.17), P = 0.003, FDR P = 0.050.** The Results text lists processed meat as a CRC risk factor in men. It does so in the passage that reports FDR-corrected findings ("after multiple corrections"), but the printed FDR P is not < 0.05. The text implies significance after correction that the table does not show.
- **Colon 842 + rectum 359 = 1,201 of 1,466 CRC.** The remaining 265 cases are unexplained, as noted by opus-H.
- **Table S5 (PRS) has 115,898 participants and 1,428 cases**, against 118,210 and 1,466 in the diet analysis. These are the genotyped participants. The table has no meat rows.
- **checks.py flag 2 (log asymmetry) on 5 rows:** `_020`, `_034`, `_035`, `_047`, `_052`. Asymmetry is 0.19–0.24, for example 1.01 (0.94–1.07). Each is a narrow CI near 1.0 printed to two decimals, so it is rounding, not a typo.

## Earlier judgment calls (opus-H, still valid)
1. **`diet_instrument = 24h_recall`, `diet_repeated = yes`.** At least two Oxford WebQ recalls were averaged. They were not repeated over follow-up.
2. **The Methods covariate list omits ethnicity**, which the Table 1/2 and S2–S4 footnotes include. adj flags follow the footnotes. Alcohol is **not** adjusted. There is no mutual adjustment between foods.
3. **Same cohort as hoang2023, knuppel2020 and bradbury2020** (`ukbiobank`). The analytic sample (≥ 2 WebQ recalls, n = 118,210) overlaps theirs heavily. Never pool them together.


---
# kabat2007
# Kabat 2007 (Canadian National Breast Screening Study): extraction notes (opus-H2, 2026-10-30)

Source: Br J Cancer 2007;97:118-22 (PMC2359661 XML, flattened), `historisk/kabat2007.txt`. Estimates are in Table 2 (heme iron and red meat × colon, rectum, colorectum) and Table 3 (heme iron × colorectum by alcohol and HRT).

## New vocabulary
- `cohort_id = cnbss`.
- `dose_unit = mg_day` (heme iron).
- `subgroup`: `alcohol_nondrinker`, `alcohol_1_lt20g`, `alcohol_ge20g`, `postmenopausal+hrt_never`, `postmenopausal+hrt_ever`.
- `cup_role = pre2010`. `source_page = 118-122` (article range; the XML has no page breaks).

## Scope coded (55 rows)
- Table 2: heme iron (5 quintiles × 3 outcomes) and red meat (5 × 3) = 30 rows. `is_main_model = yes`.
- Table 3: heme iron × colorectal in 3 alcohol strata and 2 HRT strata (postmenopausal women) = 25 rows. `is_main_model = no`.
- Not coded: total iron, meat iron and non-heme iron (not meat or heme). Proximal and distal colon, continuous estimates and the exclusion of the first 3 years are "data not shown".

## Judgment calls
1. **Red meat = `red_undefined`, `unclear`.** The paper gives no definition. Meat iron came from 22 meat items and 2 mixed dishes.
2. **Heme iron, includes_processed = `yes`.** It is computed from all meats, including ham, bacon and pork luncheon meats (Balder proportions). The paper says the alternative 40% (Lee) method gave similar results; only the first method is printed.
3. **Doses.** Quintile bounds as printed: red meat in g/day ("28.74 to 40.30" then "40.30+"), heme in mg/day. No medians. No per-category cases or person-years (`denominator_type = none`).
4. **Adjustment.** Table 2 (m1) includes HRT, education, physical activity, total fat, fibre and folate, but no other meats. Table 3 (m2) drops physical activity from the footnote and models alcohol as continuous.
5. **Energy method.** Residual for the iron variables, with total calories also in the model. For red meat the method is not stated; coded under the same set.

## Typos / inconsistencies
- Table 3 fn c: P for interaction printed "=016" (presumably 0.16). Noted on the row.
- Red meat rectum Q3 1.79 (1.11-2.88) > Q4 1.42: as printed, not an error.
- The alcohol strata sum to 589 of 617 cases.


---
# kato1997
# Kato 1997 (NYU Women's Health Study): extraction notes (opus-H2, 2026-10-30)

Source: Nutr Cancer 1997;28:276-81, full text `historisk/kato1997.txt` (pdftotext of Drive PDF). Meat estimates only in Table 3 (p. 279).

## New vocabulary
- `cohort_id = nyuwhs` (NYU Women's Health Study; not yet in cohorts.csv). Women recruited at breast-screening clinics in New York City (Guttman Institute) and Florida (Strax Institute), 1985-1991.
- `cup_role = pre2010` (as assigned in the task brief).

## Scope coded (20 rows)
- Table 3 food groups: Red meat, Ham/sausages, Poultry, Fish/shellfish. Each has 4 quartiles with reference, 16 rows. One model only (calories, age, place, education). `is_main_model = yes`.
- Table 3 "Red meat/poultry + fish, shellfish" ratio quartiles (4 rows). Coded `contrast_type = substitution`, `dose_unit = ratio`, `is_main_model = no`, following the english2004 precedent.
- Not coded: the nutrient rows, and the fish-derived protein/fat/calcium sub-rows (nutrients from fish, not a meat intake). Text statement that associations "remained significant" in the 73 colon-only cases has no numbers.

## Judgment calls
1. **Red meat = `red_undefined`, includes_processed `unclear`.** The paper gives no food list. "Ham, sausages" is a separate row, which suggests that red meat excludes them, but this is not stated.
2. **Ham, sausages = `processed`, `yes`.**
3. **Doses.** Quartiles of calorie-adjusted intake. No cut-points, medians, units, per-quartile cases or person-years are printed, so dose fields and `dose_unit` are empty (ratio rows: `ratio`). `denominator_type = none`.
4. **Reference cells printed ".00".** The PDF text drops the leading "1" in most reference cells (Red meat, Ham/sausages, Poultry, ratio). Coded 1.00 and noted on the row.
5. **cup_role conflict.** The task brief says `cup_role = pre2010`, `in_cup2016 = no`. The OPPDRAG_tillegg CUP list says kato1997 is `hvl_only` with `in_cup2016 = yes` ("not coded"). I followed the task brief; this needs a decision.
6. **Adjustment.** Age, place at enrolment (in no flag), education, total calories (covariate; foods were also calorie-adjusted). No BMI, smoking, alcohol, etc. Smoking, BMI and aspirin were not associated with CRC in Table 2 and were not entered.

## Typos / inconsistencies
- None for meat rows. checks.py raised no asymmetry flags for this study.


---
# key2014
# NOTES – key2014 (EPIC-Oxford + Oxford Vegetarian Study)

Extractor: opus-I · 2026-10-30 · Source: `post2015/key2014.txt` (Am J Clin Nutr 2014;100(suppl):378S–85S).

## New vocabulary
- **`category_set_id` suffixes `_3grp`, `_4grp`, `_meatqty`.** Three different diet-group analyses exist for the same outcome and model.

## Why `exposure = red_undefined` (per assignment)
- **The paper has no red-meat variable.** The exposure is **diet group**, self-classified from four yes/no questions (does the participant eat meat / fish / dairy / eggs).
  - "Meat eaters" eat any meat, irrespective of type or amount.
  - The reference category is meat eaters, the *exposed* group, so RRs < 1 mean lower risk in non-meat-eaters.
- **As the assignment instructs:** `contrast_type = category`, the diet group goes in `category_label`, and `exposure = red_undefined` with exposure_text "meat eaters / fish eaters / vegetarians …".
- **This is a placeholder.** The contrast is *any meat vs no meat*, not red meat. "Meat" includes poultry and processed meat, so `exposure_includes_processed = unclear`.
- **Analysts should not pool these rows** with red-meat dose estimates.
- **The `_meatqty` set (text, p. 381S–383S) really uses total meat intake categories** (≥100, 50–99, <50 g/day) plus fish eaters and vegetarians. `total_meat` would be the more accurate code. It was kept `red_undefined` to follow the assignment, and flagged in the row notes.

## Contents (36 rows, colorectal / colon / rectum only)
- **Table 2 (p. 382S), 3 groups** (meat eaters ref, fish eaters, vegetarians+vegans) × 3 outcomes × 2 models (Basic, +BMI) = 18 rows.
- **Table 3 (p. 383S), 4 groups** (meat eaters, fish eaters, vegetarians, vegans), colorectal × 2 models = 8 rows.
- **Text, meat-quantity analysis**, colorectal × 2 models × 5 categories = 10 rows. Reference ≥100 g/d; then 50–99, <50, fish eaters, vegetarians.

## Judgment calls
1. **is_main_model = yes only on Table 2, Basic model** (3-group, all 3 outcomes). It is the paper's main analysis: the authors deliberately left BMI out as a potential mediator. +BMI, Table 3 (4-group) and the meat-quantity rows are `no`.
2. **category_rank follows the paper's column order:** reference = meat eaters = rank 1. For the meat-quantity set the order descends in meat intake. **`checks.py` flag `4_dose_ikke_stigende` is therefore expected** (reference is the highest dose). The diet-group sets carry no dose values.
3. **n_cases** is printed once per site, on the Basic row. The +BMI rows leave it empty, since the same cases apply. No person-years or participants per group by outcome are given, so `denominator_type = none`. The groups have 32,491 / 8,612 / 20,544 participants (18,298 vegetarians + 2,246 vegans) overall.
4. **p_value** on the last category row = the printed P-heterogeneity across diet groups.
5. **Adjustment.** Smoking, alcohol and physical activity. Stratified by sex and study/recruitment method (coded `adj_sex = yes` and `adj_stratified_center = yes`). Age is the time scale. No energy or dietary adjustment, so `energy_method = none`.
6. **cohort_id = `epic_oxford`** for all rows, as assigned, although the data pool EPIC-Oxford with the Oxford Vegetarian Study (2,842 people are in both; clustered variance). Overlap: spencer2010 (UK DCC includes both) and EPIC papers.
7. **cases_colorectal/colon/rectum in study.csv** (579/364/215) = sums of the Table 2 diet-group counts.

## Printed anomalies (recorded as printed)
- **Fish eaters, colorectal, Basic: Table 2 prints 0.66 (0.48, 0.92), Table 3 prints 0.67 (0.48, 0.92).** Same 43 cases, same reference, same covariates; only the vegan split differs, which should not change the fish-eater estimate. The abstract and text use 0.66. Flagged on row key2014_020.
- **Meat-quantity text, <50 g/d: Basic 1.02 (0.79, 1.31), +BMI 1.01 (0.79, 1.31).** Plausible, not flagged.
- **Outside scope but noted:** Table 2 All sites +BMI, vegetarians "0.90 (0.93, 0.96)". The CI excludes the point estimate, an obvious typo (likely 0.83 or 0.84). Not coded.


---
# knuppel2020
# NOTES – knuppel2020 (UK Biobank)

Extractor: opus-F · 2026-10-30 · Sources: `post2015/knuppel2020.txt` (advance article), `post2015/knuppel2020_suppl.txt`, and for Figures S1–S5 the rendered `pdf_in/knuppel2020_supplement_publisert.pdf` (the figure numbers are not in the txt). Every number from Tables S3–S7 was checked against the supplement text by script (0 mismatches).

## Which supplementary table is which (checked against headers, increments and category means)
| Table | Exposure | Categories (times/week, mean g/day) | Increment |
|---|---|---|---|
| S3 | Total meat | <3 (33.7), 3–<5 (84.7), 5–<7 (99.2), ≥7 (116.2) | 100 g |
| S4 | Red **and** processed meat | ≤1 (10.5), >1–<3 (48.7), 3–<5 (65.0), ≥5 (79.3) | 70 g |
| S5 | **Red meat** (unprocessed beef, lamb/mutton, pork) | <1 (6.5), 1–<2 (32.6), 2–<3 (45.1), ≥3 (55.1) | 50 g |
| S6 | Processed meat | 0 (4.1), >0–<1 (15.6), 1–<2 (21.3), ≥2 (29.1) | 20 g |
| S7 | **Poultry** (3 categories) | <1 (12.2), 1–<2 (27.4), ≥2 (39.4) | 30 g |
| S8 | Sex-specific per-increment HRs, five meat types in that order | | |

S5 Model 2 colorectal 1.22 (1.05–1.42), colon 1.36 (1.13–1.64) and rectum 0.99 (0.77–1.27) match main-text Figure 3 and the Results text, which confirms that S5 is red meat.

## New vocabulary
- `dose_unit`: `per_70g`, `per_20g`, `per_30g` (per_50g and per_100g exist).
- `subgroup`: `excl_first_2y_followup`, `never_smokers`.

## Contents (276 rows)
- **Tables S3–S7: 5 exposures × 3 outcomes × 3 models (0, 1, 2) = 45 category sets** (171 category rows) **+ 45 per-increment rows.**
- **Table S8:** 5 exposures × 3 outcomes × 2 sexes = 30 per-increment rows.
- **Figures S1–S5:** 5 exposures × 3 outcomes × 2 sensitivity analyses = 30 per-increment rows.

## Judgment calls
1. **The per-increment trend is coded `is_calibrated = yes` and `is_main_model = no`.** The trend assigns WebQ re-measured category means "to reduce measurement error including regression dilution" (Suppl Methods p. 2). Under R5, calibrated rows are not main. So `is_main_model = yes` goes to the **Model 2 category rows** (15 sets). This is the same rule the brief gives for Bradbury.
   - **Caveat for analysts:** the paper's headline estimate (e.g. red meat 1.22 per 50 g) is therefore `no`. This differs from EPIC regression calibration: it is the same Cox model, with re-measured means used as the dose scores. Flip this if the project treats it as the primary continuous estimate.
2. **dose_point = category mean g/day** (`paper_mean`), from the WebQ subsample, with `dose_unit = g_day`. The frequency bounds stay in `category_label`. The dose_conversions rows give the same means with `original_unit = times_week`.
3. **Denominators.** `n_in_category` = "Total n" per category (all participants in that intake category, the same for every outcome); `denominator_type = n_participants`. Person-years are not printed.
4. **Exposure mapping:**
   - Red meat → `red_unprocessed`, `includes_processed = no`. The questions say "Do not count processed meats".
   - Red and processed meat → `red_total`, `yes`.
   - Processed meat → `processed`. Its question lists chicken nuggets, so it includes processed poultry.
   - Total meat → `total_meat`.
5. **Table S8 and Figures S1–S5 use a different covariate list (m4).** Their footnotes omit cheese, milk and oily/non-oily fish, which are in Model 1/2 of Tables S3–S7. Coded as printed, with a separate adjustment set. The project note `UK Biobank/knuppel_preprint_vs_publisert.md` suggests this is a footnote not updated from the preprint. That is unverified, so the set is kept separate.
   - None of these rows is main: S8 and S1–S5 give only per-increment trends, which are calibrated.
   - **So no main-model row exists for sex = men/women.**
6. **Main-text figures (Figures 1–5)** repeat the Model 2 per-increment values of Tables S3–S7. They are not coded twice; the row notes say "Same value printed in main-text Figure".
7. **Figure 5 vs Table S7 (poultry):** the main-text Figure 5 footnote omits cheese/milk/fish, but the Table S7 footnote includes them. I followed the table footnote (m3).
8. **Region (10 assessment-centre regions)** is coded as `adj_stratified_center = yes`. Total energy is not available. Fibre = estimated cereal fibre only.

## Discrepancies and typos in the paper
- **WebQ subsample size:** 69,076 (main text and Suppl Methods) vs 69,073 (Table S1 header).
- **Lung row (S7)** uses comma-separated CIs, unlike the other rows. Not in scope.
- **The Figure S1/S2 footnotes** contain two † notes (22 and 13/8 cases). Cosmetic.
- **CRC totals differ by exposure** (3194–3228) because of exposure-specific missingness. study.csv uses the red-meat analysis: 3201 / 2114 / 1109. The text gives 3235 + 4 colorectal (diagnosis + death certificate).


---
# larsson2005
# Larsson 2005 (SMC) – extraction notes (opus-P1, 2026-10-30)

Source: Int J Cancer 113:829–834, full text `Understudier WCRF/larsson2005.txt`. All numbers from the full text (Table I p. 830, Table II p. 831, Results text p. 830–831). The study card was read for orientation only.

## Scope coded
- Table II, one multivariate model, 6 exposure blocks × 4 outcomes (colorectum, proximal colon, distal colon, rectum), reference rows included: red meat (4 cats), processed meats (4), beef and pork as a main dish (4), blood pudding (2), fish (4), poultry (3) = 84 rows.
- Continuous per 100 g/day red meat: colorectal 1.20 (0.99–1.45), distal colon 1.70 (1.31–2.21) (text p. 831). No continuous estimates printed for proximal colon, rectum or other exposures.
- Sensitivity, distal colon excluding the 27 cases from the first 3 years: 2.04 (1.17–3.54), p trend 0.01 (text p. 831).
- Secondary analysis adding smoking, HRT and aspirin (1997 questionnaire), top vs bottom red-meat quartile: proximal 1.01, distal 2.20, rectum 1.27 (text p. 831). No colorectal estimate is printed for this model.
- Not coded: distal colon + rectum combined, blood pudding 1.26 (1.02–1.55) (text p. 831). "Distal colon + rectum" is not in the outcome vocabulary. It needs a decision on whether to add it.
- Not coded: the χ² heterogeneity p-values (proximal vs distal p = 0.02; distal vs rectum p = 0.11). They are not estimates, but they are recorded here.
- Not coded: Figure 1 spline, which is graphic only. No age-adjusted model is reported. There are no supplementary tables.

## Judgment calls
1. **Sex = `women`** on every row (women-only cohort). Category sets are named `larsson2005_mv_<outcome>_women_<exposure>`. The exposure suffix is added because 6 exposures share one model and outcome; R3 alone would give colliding IDs.
2. **Red meat = `red_total`**, `exposure_includes_processed = yes`. The definition lists bacon, hot dogs, ham/lunch meat and blood pudding (p. 830; Table I fn 1).
3. **Beef and pork as a main dish = `red_main_dish`**, `includes_processed = no`. Footnote 4 defines it as whole beef, chopped meat and minced meat. Category bounds and medians are not described in the methods. The text says only that red meat and fish were analysed in quartiles.
4. **Blood pudding = `processed`**, exposure_text "Blood pudding". The paper groups it with processed meats (p. 830). It is a separate 2-category variable, not a subset estimate of the processed-meat block. The unit is printed as servings/month and coded `times_month`, because `servings_month` is not in the vocabulary. Footnote 5 adjusts it for beef/pork main dish, fish and poultry. No p for trend is printed.
5. **is_main_model = yes on all Table II rows and on both continuous rows.** The paper has a single "multivariate" model, and each exposure is a separate analysis. The continuous rows use the same model (Fig 1 legend: Table II variables plus fish and chicken). With 6 exposures, "exactly one model per outcome × sex" holds per exposure, not per outcome. The sensitivity and secondary (1997-covariate) rows are `no`. Note that the secondary model is *more* adjusted. It was not made main because it relies on a 70%-response follow-up questionnaire and only reports top vs bottom contrasts. The paper itself presents it as secondary.
6. **Adjustment sets split by exposure (m1–m6)**, because footnotes 3 and 5 apply to different rows:
   - The processed-meats row has no fn-3 marker, so it is not listed as adjusted for fish, poultry or red meat (m2).
   - For fish and poultry, the footnote says they are adjusted for "red meat (or beef and pork as a main dish)". Which of the two was used is not stated, so `adj_processed_meat = unclear` (m5, m6).
   - No meat model is adjusted for processed meat, so `is_mutually_adjusted_processed = no` for the red-meat, beef/pork and processed rows.
7. **Energy method = `covariate`.** Total energy enters as quartiles. Nutrients are additionally energy-adjusted by the residual method (p. 830). Whole-grain foods are adjusted, but not fibre, so `adj_fiber = no`.
8. **Denominators.** The only per-category denominator is the number of women per red-meat quartile (Table I: 15,442 / 15,410 / 15,335 / 15,246). It is put in `n_in_category` (`denominator_type = n_participants`) on the red-meat rows for all 4 outcomes. Cases per category are not reported for any exposure, so `n_cases` is empty on category rows. Person-years per category are not reported either; the total is 855,585. Continuous rows carry the outcome's total cases and the cohort's total person-years.
9. **Sensitivity row 087 (`excl_cases_first_3y`).** The implied number of cases is 155 − 27 = 128. It is not printed, so `n_cases` is left empty.
10. **Secondary model m7** assumes that fish and poultry carry over from the red-meat Table II model. The text says "in addition to the same variables as in the multivariate model in Table II".

## Probable typos and printed anomalies (recorded exactly as printed)
- **Processed meats 12–21 g/d, colorectum: "0.89 (0.72–1.90)"** (row 018). The upper limit is implausible: log-asymmetry is 0.72, and the neighbouring subsite CIs are narrow. It is most likely 1.09 or 1.10. checks.py flags it.
- **Processed meats 22–31 g/d, rectum: "1.02 (0.75–1.55)"** (row 031). Log-asymmetric (0.27); possible typo.
- **Beef and pork 3.0–<4.0, proximal colon: "0.78 (0.45–1.17)"** (row 039). Log-asymmetric (0.26); possible typo. The lower limit is the likely error.
- **Beef and pork 3.0–<4.0: median printed as "(4.0)"**, which lies on the excluded upper bound. It may be rounding of a value ≥3.95 or a typo.
- **Fish "<0.5 (median, 0.5)" and poultry "<0.5 (median, 0.5)"**: the medians sit on the open upper bound. This is probably rounding of FFQ frequency values (e.g. 0.46/week).
- The abstract and Results text match Table II for red meat (1.32, 2.22, 1.03, 1.28; p trend values). No text–table disagreement was found.
- The methods state that poultry was split into 3 groups and blood pudding into 2, and that red meat and fish were analysed in quartiles. Fish categories in Table II are fixed cut-points (servings/week), not g/day quartiles. The beef/pork and processed-meat categorisations are not described in the methods.

## Portion size / grams per serving
- **No grams per serving are given anywhere in the paper.** The methods (p. 829) say: "We used age-specific (<53, 53–65, ≥66 years) portion sizes that were based on mean values obtained from 213 randomly chosen women … whose food intake for 5,922 days was weighed and recorded." The gram values are not printed in the methods, Table I or the Table II footnotes.
- The red-meat and processed-meat variables are already in g/day, with paper medians. The beef/pork, fish, poultry and blood-pudding variables are in servings, and `g_day_assigned` is left empty for them.
- Weight basis (raw vs cooked) is not stated → `weight_basis = unclear`.
- The only portion-related numbers in the paper are heme iron per serving (blood pudding about 15 mg; beef about 1.5 mg; Discussion p. 832). These give no gram weight.

## Study-level
- `in_cup2016 = yes` and `cup_role = dose_response` come from the study card/project context, not from the paper.
- PMID is not printed in the paper and is left empty. DOI 10.1002/ijc.20658.
- `validation_r` is left empty because no single value exists for a meat aggregate. Item-level values are in study.notes.


---
# lee2009
# Lee 2009 (SWHS) – extraction notes (opus-A, 2026-10-30)

Source: `Understudier WCRF/lee2009.txt`, NIHPA author manuscript (PMC2810117) of Nutr Cancer 2009;61(2):194–205. The text file has no journal page numbers, so `source_page` = "ms, no page nos (journal pp. 194-205)". Each row's notes give the text-file line instead. No study card was used.

## New vocabulary
- `dose_unit = ever_never` for the binary rows "Smoked" and "Salted fish" (Table 4).

## Scope coded (129 estimate rows)
- **Table 2, one multivariable model (m1).** 7 exposure blocks × 3 outcomes (colorectal, colon, rectum) × 5 quintiles = 105 rows. The blocks are total meat, red meat, "white meat" (= poultry), total fish, marine fish, fresh water fish and eel.
- **Discussion cut-point analysis.** HRs with 80, 90 and 100 g/day red meat as the reference: 3 `hvl` rows, model m2 (covariates not stated).
- **Table 4 preserved-food rows (model m3, without NSAID and fiber).** 21 rows:
  - smoked meat/bacon (ever/never)
  - salted meat (never, <1/month, ≥1/month)
  - salted fish (ever/never)
- **Not coded:**
  - shrimp and shellfish: crustaceans/molluscs, not fish
  - eggs, milk, fats and cholesterol (Tables 2–3)
  - Table 4 deep-fried, stir-fried and roasted rows: cooking frequency for meat *or* fish, not a meat-intake variable
  - Table 1 (non-diet covariates)
- **No continuous (per-unit) estimates are printed.** The text says trend tests modelled intake as continuous, but it prints only p-values.

## Judgment calls
1. **Sex = `women`** on every row (women-only cohort). Category sets are named `lee2009_<model>_<outcome>_women_<exposure>`.
2. **Red meat = `red_undefined`, `includes_processed = unclear`.**
   - The paper never defines red meat.
   - The Appendix 1 FFQ items are pork chops, ribs, pig's feet, fresh pork, liver, other organ parts and beef/lamb. None of these is processed.
   - Smoked meat/bacon and salted meat were asked separately "as preserved foods".
   - So red meat is probably unprocessed and probably includes organ meat, but this is not stated. I did not upgrade it to `red_unprocessed`.
3. **"White meat" coded as `poultry`.** The Table 2 label is "White meat", but the Results text calls the same estimate "poultry intake (Ptrend = 0.23)". The FFQ poultry items are chicken, duck and goose, and fish is a separate block. If the database wants the paper's label, recode it to `white_meat`.
4. **is_main_model.** It is `yes` on Table 2 for total meat, red meat, poultry and total fish (one model, per exposure × outcome).
   - Marine fish, fresh water fish and eel share `exposure = fish` with total fish. They are set to `no` so that each exposure × outcome × sex has exactly one main set. They are subtypes of total fish.
   - The Discussion cut-point rows are `no` (post hoc).
   - The Table 4 rows are `no`. The paper presents them as cooking/preservation methods, and they are frequency or ever-use measures, not intake. They are the only estimates for smoked or salted meat; recode them if processed meat needs a representative.
5. **Q2–Q4 CIs are not printed in Table 2.** Only Q5 has a CI. Those rows carry the point estimate with empty CI cells, so checks.py flags `1_mangler_ci` 63 times. This is expected.
6. **Quintile bounds.** The table prints only upper bounds ("<24, <36, <49, <67, ≥67"). `dose_low` is filled with the previous upper bound, which the quintile structure implies.
   - Eel Q1 = 0 (non-consumers), with bounds 0/0.
   - Eel Q2 "<0.3" has an empty `dose_low`. Its implied lower bound is >0.
7. **Denominators.** Person-years per quintile are printed once per exposure. They are copied to the colorectal, colon and rectum rows (`denominator_type = person_years`).
8. **Effect measure = RR** as printed. The Methods use Cox regression, and the Discussion calls the cut-point estimates "HR"; those 3 rows are coded HR.
9. **Discussion cut-point rows.** The text says only "with 80g/day as the reference group". The direction (presumably ≥X vs <X), the covariates and the case counts are not stated.
10. **Repeated diet.** The cumulative average of baseline and first follow-up FFQ is used for eligible women (`diet_repeated = yes`).
11. **weight_basis = raw.** The Discussion speaks of "median of raw red meat intake … 42.3g/day".
12. **outcome_ascertainment = mixed.** Active biennial follow-up is combined with registry and death-certificate linkage.

## Typos and inconsistencies (recorded as printed)
- **Table 4, salted meat <1 time/month, rectal: "0.7 (0.6–1.3)"** (row lee2009_122). The point is far from the log-centre (asym 0.75), so this is a probable typo.
- **Table 2, total meat Q5 colorectal "0.9 (0.7–1.4)"** (lee2009_005, asym 0.43). This can arise from rounding (e.g. 0.94 (0.65–1.36)), so it is not flagged as a typo. The other asymmetry flags (0.15–0.32) all have one-decimal values consistent with rounding.
- **Marine fish rectal case counts sum to 157**, not 158 (Table 2). Recorded as printed.
- Spelling "Person-yeasr" in the marine fish block. It is cosmetic.
- **Out of scope, but noted:**
  - Table 1 vegetable/fruit Q3 colon "1.2 (0.9-1.0)" is an impossible CI.
  - The Table 2 shellfish Q3 rows print only a CI, with no point estimate.
  - The Table 2 and 3 footnote "Range of fat intake (g/day)" is mislabelled for the food rows.
- The Results text and Table 2 agree on the p-trends for total meat (0.30), red meat (0.53) and poultry (0.23).

## Doses / conversions
- The unit is g/day (FFQ grams). No category medians or means are printed, so open Q1/Q5 need a midpoint rule; this is not done here. `g_day_assigned` is left empty in all 30 conversion rows.
- The cohort median for red meat is 42.3 g/d raw, and for fish 50.6 g/d (Discussion).

## Study-level
- PMID 19235035 and DOI 10.1080/01635580802419780 come from the PMC header in the text file.
- `diet_items` is empty: the FFQ total item count is not given, and 19 animal-origin items are mentioned.
- `validation_r` = 0.52 (red meat FFQ vs 24-h recalls).
- `in_cup2016 = yes` and `cup_role = dose_response` are taken from the brief's list.


---
# mehta2020
# Mehta 2020 (Sister Study) – extraction notes (opus-G, 2026-10-30)

Source: /home/claude/drive/post2015/mehta2020.txt. This is the NIH author manuscript (PMC6954313), not the typeset journal version (Cancer Epidemiol Biomarkers Prev 29(1):141-150). It has no journal page numbers, so `source_page` reads `ms (author manuscript, no page nos.); txt l.<line>`. No supplement file exists (Supplemental Tables 1-5 are referred to but not available).

## New vocabulary
- `exposure = white_meat` is used for "White meat" (seafood + poultry). This value is already in KODEBOK 4.1 and is listed here only for visibility.
- `contrast_type = hvl` is used for the four text-only "Q4 vs. Q1" sensitivity values. This is existing vocabulary.
- Subgroup labels: `age_lt_55`, `age_ge_55`, `bmi_normal`, `bmi_overweight`, `bmi_obese`, `sens_organ_meat_adjusted`, `sens_nutrient_density`.

## Scope coded
- **Table 2, full**: 13 exposures × 2 models (Crude, Adjusted) × (1 continuous + 4 quartiles) = 130 rows. The exposures are total meat, unprocessed red, processed, white meat, beef, pork, poultry, seafood, and the specific products hamburgers, ham/boloney/lunch meat, bacon, hot dogs/dinner sausages and breakfast sausages. The products are inside R1 scope as processed/red meat items, coded under `processed` or `red_unprocessed`.
- **Table 5, full**: processed meat plus 4 processed-meat products × 5 strata (age <55 / 55+, BMI normal / overweight / obese) × (1 continuous + 3 tertiles) = 100 rows.
- **Results text (txt l.213)**: 4 sensitivity values (organ meat as covariate, shellfish, and nutrient density for red meat and for bacon).
- Total: 234 estimate rows.

## Not coded
- **Tables 3 and 4 (cooking method / doneness).** The brief says "cooking/doneness only if in same table". These are separate tables from the red/processed meat table (Table 2), so they were left out. Examples: grilled red meat per 50 g 1.20 (0.83-1.73); steak grilled 2.23 (1.20-4.14). Table 3 also has broken parentheses in the printed CIs, e.g. "(0.91-1.88" and "0.87-1.92)".
- **Suppl Tables 1-5.** These are not available. They hold colon/rectum results (rectal N=30), medically confirmed cases only, mutual adjustment, exclusions, and nutrient density. Only the values quoted in the text are coded.
- Table 1 mean intakes are descriptive and not coded.

## Judgment calls
1. **Red meat = `red_unprocessed`, includes_processed = no.** Methods: FPED unprocessed red meat (beef, veal, pork, lamb, game) + FPED organ meat. Processed meat is a separate FPED "cured meat" variable.
2. **Beef and pork subtypes: `exposure_includes_processed = unclear`.** They are FFQ-based ("Other meat subtypes were examined using the FFQ, including pork and beef"). The paper does not say whether ham, bacon or sausages count toward pork/beef.
3. **Poultry includes_processed = no.** FPED puts cured poultry products in the processed (cured) meat variable. This is an inference from the FPED definition and is not stated per se.
4. **Hamburgers → `red_unprocessed`.** The paper lists them among "specific unprocessed red meat and processed meat products". Hot dogs, ham/lunch meat, bacon and breakfast sausages → `processed`.
5. **is_main_model.** `yes` on the Adjusted (HRadj) rows, continuous and quartiles, for the 8 aggregate/subtype exposures. Crude rows are `no`. Specific products are `no` even in the adjusted model, because they share an exposure code (`processed` / `red_unprocessed`) with the aggregate. "One main per exposure × outcome × sex" therefore points to the aggregate. All Table 5 subgroup rows and all text sensitivity rows are `no`.
6. **Two case counts.** Table 2 prints cases as "N cases (N adjusted)", e.g. "51 (51)". Crude rows take the first number and adjusted rows the parenthesised one. All sets sum to 216 (crude) and 210 (adjusted).
7. **Doses.** Only quartile medians are printed (`dose_point`, `paper_median`). There are no cut points, so `dose_low`/`dose_high` are empty. For Table 5, the g/day in the "Tertile k (x g/day)" labels is taken as the tertile median (fn b says trend uses medians). It is not explicitly called a median.
8. **Denominators.** No per-category person-years or Ns are printed, so `denominator_type = none`. The cohort total of 420,574.35 person-years is recorded in study notes.
9. **BMI-stratified rows use adjustment set m3** (BMI dropped; Table 5 fn a). Age-stratified rows use m2.
10. **Shellfish** is coded as `fish` with exposure_text "Shellfish", `is_main_model = no`. Its model is assumed to be the Table 2 adjusted model; the text does not restate it.
11. **Organ-meat sensitivity row.** Its exposure differs from the main red meat variable (organ meat removed from the aggregate and adjusted as a covariate). It is kept as `red_unprocessed` with subgroup `sens_organ_meat_adjusted`.
12. **Nutrient density rows (m5).** Whether total kcal was also kept as a covariate is not stated, so `adj_energy = unclear`.
13. **Sensitivity covariates.** Smoking, alcohol, NSAID, HRT, colonoscopy, fibre, calcium, folate and fruit/veg are listed only as sensitivity additions with "no difference in the estimated HRs". No estimates are printed for them, and they are not flagged in m2.

## Printed anomalies (recorded as printed)
- **White meat, adjusted Q2: "1.12 (0.77-1.79)".** The CI is identical to the adjusted Q4 CI "1.17 (0.77-1.79)" and is asymmetric around 1.12 (log asymmetry ≈ 0.20). This may be a copy error in the table. It is flagged in the row notes; checks.py flags it (2_asymmetrisk_ci).
- **Table 5, hot dogs/dinner sausages, age 55+.** Tertile cases 62+35+50 = 147, but the continuous row N is 148. All other strata sum correctly.
- **Follow-up.** The abstract and Discussion give a median follow-up of 8.7 years. Results (txt l.203) say "216 women had incident CRC over a median 4.8 years of follow-up". The Discussion explains that 4.8 y is the median time from enrolment to diagnosis for cases. study.csv uses 8.7 (median).
- **Subgroup Ns.** Table 5 age-group Ns sum to 48,706, not 48,704.
- **Case-confirmation counts.** Methods give 121 medical + 15 NDI + 69 self-report + 11 next-of-kin = 216. Table 1 gives 136 medical/NDI and 80 self/NOK, which is consistent.

## checks.py (scratch copy, 2026-10-30)
- 2_asymmetrisk_ci: mehta2020_038, white meat adjusted Q2 "1.12 (0.77-1.79)", asym 0.20. This is the suspected copy error described above.
- 9_uverifisert: 234 rows (expected).
- No other flags. Reference rows = 1.0, doses rise within every set, and ranks are complete.

## Supplement rows (30.10)
Extractor opus-S4, 2026-10-30. Source: /home/claude/drive/supplements/mehta2020_suppl.txt (Supplemental Tables 1-5). This file corrects the earlier note above that "Suppl Tables 1-5 are not available". Rows mehta2020_235 to mehta2020_550 were added (316 rows). source_page = `suppl`.

### New vocabulary
- dose_unit `per_25g_per_1000kcal` and `per_10g_per_1000kcal` (Suppl T5 continuous; analogous to the existing `per_50g_per_1000kcal`).
- Subgroups `dx_medical_or_ndi_confirmed`, `dx_self_or_nok_reported` (Suppl T2); `sens_mutually_adjusted` (Suppl T3); `excl_prior_cancer`, `excl_family_history_crc`, `excl_dx_within_1y`, `excl_dx_within_2y` (Suppl T4).
- Adjustment sets mehta2020_m6 to m11 (new). m2 is reused for Suppl T1/T2 (footnote identical to Table 2) and m5 for Suppl T5.

### Rows added per table
- **Suppl Table 1** (colon / rectum): 80 rows. Covers total meat, unprocessed red, processed, white meat and 4 processed products × 2 outcomes × (continuous + Q1-Q4). Beef, pork, poultry, seafood and hamburgers are not in this table.
- **Suppl Table 2** (by diagnosis source): 80 rows, with the same exposures as T1, in two subgroups.
- **Suppl Table 3** (mutual adjustment, Q4 vs Q1 only): 7 hvl rows.
- **Suppl Table 4** (4 exclusion sensitivities): 84 rows. Covers red, processed, white meat and 4 products × 4 columns × (continuous + Q1 ref + Q4). Total meat is not in this table.
- **Suppl Table 5** (nutrient density): 65 rows. Covers 13 exposures × (continuous + Q1-Q4).

### Judgment calls
1. **is_main_model.** Suppl T1 colon and rectum rows for the 4 aggregates (total meat, unprocessed red, processed, white meat) are set to `yes`. They are subsite analyses in the paper's main model (fn a = Table 2 adjusted model) and are the only colon/rectum estimates. The 4 specific products are `no` there, for consistency with judgment 5 above (they share the exposure code with the processed aggregate). Every row in Suppl T2-T5 is `no` (subgroup or sensitivity).
2. **Suppl T3 is_mutually_adjusted_processed.** Set to `yes` for unprocessed red meat, white meat and the 4 products. The products are adjusted for the *other* processed products, not for the processed aggregate; this is stated in the row notes and in m9. Processed meat itself is `no`, because its own exposure is processed meat. Only Q4 is printed, so these are hvl rows with no reference row. n_cases = cases in Q4.
3. **Suppl T4 has only Q1 and Q4.** The Q1 HR cell is blank and the Q4 HR is printed. These are coded as `contrast_type = hvl`, with category_rank 1 (Q1, point 1.0 entered as the implied reference) and 4 (Q4), under a `_hvl` set id. This keeps the quartile identity and avoids false dose-response sets. The continuous rows are `continuous`.
4. **Suppl T3/T4/T5 footnotes omit total calories.** T1/T2 footnotes include calories. Methods (l.195) call the mutual-adjustment and exclusion models "final models", which include calories. adj_energy is therefore `unclear` in m6-m11. For T5 the omission is consistent with the density method; m5 is unchanged except for an appended note.
5. **Suppl T5 duplicates the two text values.** Unprocessed red meat Q4 1.17 (0.78-1.77) and bacon Q4 1.22 (0.81-1.82), p-trend 0.32, were already coded from the Results text as hvl rows mehta2020_233/234. I coded them again as category rows mehta2020_495 and mehta2020_540 so that the T5 category sets are complete for dose-response. Both pairs are cross-referenced in the notes (233/234 got an appended note). **Do not use both rows of a pair in one analysis.** Suppl T5 also supplies the red meat p-trend (0.81), which the text did not give.
6. **Suppl T5 doses** are in g/1000 kcal/day (`g_per_1000kcal_day`, paper medians). The quartiles are re-formed on the density scale, and their case counts differ from Table 2. dose_conversions rows dc38-dc45 (8 aggregates/subtypes) leave g_day_assigned empty, because energy intake per quartile is not printed.
7. **Suppl T1/T2 quartile medians** are identical to Table 2, so the same overall quartiles were used. dose_conversions dc22-dc37 were added for the 4 aggregates in each of the 4 new sets. Following the earlier pattern, the products get no dc rows.
8. **study.csv** has `cases_colon = 116` (Suppl T1), and a note was appended. `cases_rectum = 30` was already set.
9. Exposure codes and includes_processed follow the main-text coding: hamburgers → `red_unprocessed`, products → `processed`, beef/pork `unclear`, seafood → `fish`.

### Printed anomalies and contradictions with the main text (recorded as printed)
- **Colon + rectum = 146, not 210.** Suppl T1 gives colon 116 and rectal 30 cases, while the adjusted CRC analysis has 210. The site of 64 cases is not stated (unspecified site or excluded?). The main text gives only the rectal N=30.
- **Suppl T4, red meat, "Exclude previous cancer" column: Q1 cases printed "4".** This is implausible: Q1 is 43-51 in the other columns and the Q4 count is 52. It is likely a typo and is flagged in row mehta2020_403.
- **Suppl T4 title** lists "(4) a CRC diagnosis made within 1 year of baseline" twice. The column header says 2 years for the fourth column, and that is what was coded.
- **Suppl T4 case totals vs Methods exclusion Ns.** Family-history exclusion 183 = 210 − 27 ✓. The within-1-year exclusion has 195 cases (Methods N=17 → expected 193) and the within-2-year exclusion has 174 (N=38 → expected 172). Both are off by 2. These were not altered.
- **Suppl T5 processed meat Q2: "1.29 (1.09-2.40)".** The CI is identical to Q4 "1.61 (1.09-2.40)" and log-asymmetric (checks.py asym 0.73). This is a likely copy error (row mehta2020_498).
- **Suppl T5 seafood:** Q2 and Q4 are both printed "0.95 (0.64-1.40)", a possible copy error (rows mehta2020_523/525). The continuous value 0.96 (0.70-1.39) is mildly asymmetric (below the 15 % threshold).
- **Suppl T5 bacon overall median** is printed "028". It is presumably 0.28, is not a coded value, and is shown as "[sic]" in the continuous row's note.
- **Suppl T5 fn c** defines total meat as "red meat (including organ meat)". Elsewhere it is "unprocessed red meat (including organ meat)".
- No contradictions were found with the main-text numbers that were checked: the T5 text values match, and the T1/T2 quartile medians match Table 2.

### checks.py (scratch copy, 30.10)
Ran on a scratch copy with estimates, adjustments and study (as studies.csv). Only 3 flags:
- 2_asymmetrisk_ci: mehta2020_038 (pre-existing, Table 2 white meat Q2).
- 2_asymmetrisk_ci: mehta2020_498 (Suppl T5 processed Q2, described above).
- 9_uverifisert: 550 rows (expected).
- Case sums were verified by hand: every Suppl T1/T2/T5 quartile set sums to its continuous N (116, 30, 130, 80, 210).


---
# mejborn2021
# Mejborn 2021 (DANSDA) – extraction notes (opus-G, 2026-10-30)

Source: /home/claude/drive/post2015/mejborn2021.txt (Europe PMC full text; Nutrients 13(1):32; epub 24 Dec 2020). The txt has no journal page numbers, so `source_page` names the table (PMC table id). No supplement file is available. Suppl Tables S1-S2 are baseline characteristics only.

## New vocabulary
- None. Subgroup labels used: `dgc_low`, `dgc_high` (Dietary Guideline Compliance Score <3.1 / ≥3.1).

## Scope coded (colorectal only, as instructed)
- **Table 3**: red meat, processed meat and poultry × 2 models (sex-adjusted; multivariable) × (2 categories + 1 continuous) = 18 rows.
- **Table 7**: the same 3 exposures × 2 DGC strata × (2 categories + 1 continuous), multivariable only = 18 rows.
- Total: 36 estimate rows.
- **Not coded**: Tables 4, 6 and 8 (all-cause mortality, excluded per brief) and Table 5 (DGC vs CRC; not a meat exposure). Total meat vs CRC is "data not shown".

## Judgment calls
1. **Red meat = `red_unprocessed`** (includes_processed = no). Methods 2.1 defines it as unprocessed muscle tissue from beef, veal, pork and lamb plus a small amount of unprocessed offal. Processed meat (red meat or poultry that is smoked, dried, cured or fermented) is a separate variable.
2. **Poultry includes_processed = no.** Processed poultry falls in the processed-meat definition.
3. **is_main_model = yes on the multivariable (fn 3) rows of Table 3**, both the 2 categories and the continuous row, per exposure. Sex-adjusted rows and Table 7 strata are `no`.
4. **Two-category analysis.** Cut points are at the median of the *mortality* cohort (n=9848), not the CRC cohort: red <65 / ≥65, processed <35 / ≥35, poultry <16 / ≥16 g/day. The paper itself says this split is somewhat arbitrary. The rows are kept as `category` with rank 1 = Low (reference) and rank 2 = High. They are not recoded as `hvl`, because the paper presents a full 2-level categorical analysis rather than a highest-vs-lowest extract. checks.py does not flag 2-category sets, but they are not usable for GL dose-response. dose_conversions has no assigned doses because both categories are open and no medians are printed.
5. **p for trend.** One value is printed per exposure, in the last column of the continuous row. It is attached to the multivariable continuous row only.
6. **p for interaction (Table 7).** It is printed once per exposure per contrast type. It is recorded in `p_value` on both strata's High row (categorical) and continuous row, and labelled in notes. It is not a p-value for the estimate itself.
7. **Denominators.** Only incidence rates per 100,000 PY are printed, not person-years per category. `denominator_type = none`; the IR is kept in notes. Person-years could be back-calculated (cases / IR × 100,000), but that was not done in the CSV.
8. **adj_age = yes on both models.** Age is the Cox timescale (Methods 2.6), even though Table 3 fn 2 says only "Adjusted by sex".
9. **diet_instrument = `mixed`.** The instrument is a 7-day pre-coded food diary (food record). The vocabulary has no `food_record` value. Suggest adding `food_record`, or decide whether `diet_history` is preferred.
10. **year = 2021.** Journal issue 2021 (13(1)), epub 24 Dec 2020. The study_id follows the brief.
11. **weight_basis = cooked.** "Values for meat intake were expressed as cooked meat" (Methods 2.1).

## Printed anomalies / inconsistencies
- **Outcome codes.** Methods say CRC = ICD-10 C18 and C20; C19 (rectosigmoid junction) is not listed. This is recorded in study notes. It may be an omission in the text.
- **CRC follow-up rules.** Follow-up starts at the later of interview or age 50. Participants younger than 50 at the end of follow-up were excluded. 127 cases.
- **Funding.** Promilleafgiftsfonden for Landbrug (Danish agricultural levy fund). This is recorded for the database user. Authors declare no conflict.
- No numeric inconsistencies were found between text and tables. Text quotes poultry High 1.62 (1.13–2.31) and per 100 g 1.39 (0.69–2.77), p 0.34, matching Table 3.

## checks.py (scratch copy, 2026-10-30)
- Only 9_uverifisert (36 rows). No CI, reference, dose or rank flags.


---
# norat2005
# Norat 2005 – pilot (fable)
- Table 3 col † (sex+energy, stratified center) and ‡ (full) both coded for red meat; ‡ = is_main_model.
- Red meat ≥80 g/d, model †: printed '1.28 (1.1 to 1.64)'. Recorded as printed (ci_low 1.1). Likely 1.01. Flag for control.
- Red and processed meat category labels printed '<10, 20–40, 40–80, 80–160, ≥160' – the second category presumably 10–20 in error? No: cut points for red+processed differ (doubling from 10: <10,10-20?). Printed text has no 10–20 row; recorded as printed with note.
- No person-years per category; denominator_type none. Total person-years 2 279 075.
- Table 4: observed and calibrated per 100 g for red, red+processed, processed, fish, poultry; red-meat rows fully coded, others CRC only (processed, poultry, fish continuous).
- Sex-specific analyses were done but not reported ('only the results for both sexes combined are presented').
- Not coded in pilot: red+processed and processed category rows for colon/rectum/subsites, fish and poultry category rows. These belong in the full extraction.

# Completion (opus-N, 2026-10-30)

## New vocabulary
- `subgroup` values (free text, listed for consistency): `folate_subset`, `excl_cases_first_2y`, `joint_rp_high_fish_low`, `joint_rp_high_fiber_high`, `joint_rp_high_fiber_medium`, `joint_rp_high_fiber_low`, `joint_rp_medium_fiber_low`, `center_<name>` (12 Fig 2 centres), `fig2_all_epic`.
- No new controlled-vocabulary values. `per_10g` and `pork`/`lamb`/`beef` are already in KODEBOK.

## What was added (rows norat2005_050–223 = 174 rows)
- **Table 3 (110 rows)**: all remaining category rows. Red+processed: model † colorectal plus ‡ colon/right/left/rectum. Red meat: nothing left. Processed, fish, poultry: † colorectal and ‡ colon/right/left/rectum; fish and poultry ‡ colorectal. Every set has 5 categories, reference row included. Numbers were parsed by script from the text and asserted to give 6 columns per row. N* per exposure sums to 1329 in all 5 blocks.
- **Table 4 (21 rows)**: observed and calibrated per 100 g for red+processed, processed, fish and poultry × colorectum/colon/rectum, minus the 3 observed CRC rows already in the pilot.
- **Text (17 rows)**:
  - pork, lamb, beef/veal hvl
  - ham, bacon and other processed meats hvl
  - folate subset, R&P and fish, before and after folate adjustment (4)
  - exclusion of the first 2 years, R&P and fish (2)
  - joint classification: high R&P + low fish 1.63 (1.22–2.16); the four R&P × fibre cells (1.09, 1.20, 1.50, 1.38)
- **Fig 2 (26 rows)**: centre-specific calibrated HRs (12 centres + All EPIC) for R&P and for fish.
- **dose_conversions**: c2–c30, one per new category set (29). **adjustments**: m4 (‡ + folate/multivitamins), m5 (Fig 3A), m6 (Fig 3B).
- **study.csv**: added `cases_colorectal=1329, cases_colon=855, cases_rectum=474` after `weight_basis`. in_cup2016/cup_role were already yes/dose_response, which matches OPPDRAG_tillegg.

## Judgment calls
1. **is_main_model.** Model ‡ is `yes` for all Table 3 ‡ sets: 5 exposures × 5 outcomes, which gives exactly one main set per exposure × outcome × sex. Table 4 observed rows stay `no` to match the pilot's convention on rows 031/033/035/047–049. Calibrated rows are `no` (KODEBOK 4.2). Note that ‡ and the Table 4 model have the same covariates. "Main" therefore marks the category set and not the per-100 g row. The CUP rows use the continuous observed rows (see c1 notes). Someone should decide whether the main flag should sit on the Table 4 observed rows instead. All text, Fig 2 and Fig 3 rows are `no` (hvl only, subsets, sensitivity or calibrated).
2. **n_cases for subsite sets is empty.** The Table 3 N* column is "distribution of colorectal cancer cases by category". The pilot copied these colorectal counts onto the colon, proximal, distal and rectum red-meat rows (see review below). I did not repeat that, because checks.py test 5 would compare colorectal counts against 855/474.
3. **Red+processed reference category.** It is printed "<10", but the abstract says "lowest [<20 g/day]". The cut points double (10, 20, 40, 80, 160), the second row is 20–40, and the five rows hold all 1329 cases. The reference is therefore almost certainly <20 g/day. The rows are kept as printed (dose_high 10) with a note. dose_conversions for the R&P sets use midpoint 10, not 5.
4. **Open top category midpoints (cup_rule)**: R&P ≥160 → 200; red, processed and fish ≥80 → 100; poultry ≥40 → 50; open bottom <x → x/2. The pilot's c1 gives red meat ≥80 the value 120, using width 40. That is not the CUP rule (see review below).
5. **Adjustment set for text estimates.** Pork/lamb/beef, ham/bacon/sausages, the folate "before" rows and the 2-year exclusion rows do not name their model. I assigned ‡ (m2) because their numbers match the ‡ column where comparable (R&P 1.35 before exclusion; fish 0.69). Text estimates without a CI have empty ci_low/ci_high. They are coded as hvl rather than dropped, so checks.py does not flag them as missing CI.
6. **Folate rows.** m4 = ‡ + dietary folate + multivitamin use. The "before" rows (1.27, 0.68) are the ‡ model in the subset, so they use m2 with subgroup `folate_subset`. The denominators disagree: 407 959 non-cases (Results) vs 409 135 (Methods, Table 2).
7. **Joint-classification rows** are coded as contrast_type `hvl` with exposure `red_total`. They are cell-vs-reference contrasts, not dose contrasts, and not usable in dose-response pooling. The text says "high red meat and low fish" (1.63). Fig 3A cross-classifies red **and processed** meat, so the rows are coded red_total. The Fig 3 legend omits fibre from the covariates; m5 has adj_fiber=no. The other Fig 3 cell values (1.28, 1.20, 1.46, 1.33, 1.56, 1.63, 1.12; 1.30, 0.93, 1.22, 1.00, 1.09, 1.20, 1.38, 1.50) are printed in the figure without CIs. Only the cells with CIs in the text are coded.
8. **Fig 2 is coded per 10 g/day** (dose_unit `per_10g`). The panel header says "HR (95%CI) for 10 g/day", and the legend says "per 100-g increase". The fish All-EPIC value 0.93 (0.88–0.97) ≈ Table 4 calibrated 0.46 (0.27–0.77) to the 0.1 power (0.925), so per 10 g fits fish. For R&P, All-EPIC 1.02 (0.99–1.06) does **not** match calibrated 1.55 per 100 g (≈1.045 per 10 g). See inconsistencies below.
9. **Not coded:**
   - absolute 10-year risks (1.71 %, 1.28 %, 1.86 %)
   - P-heterogeneity values: left vs right R&P .29, red .72, processed .87; centres R&P .82, fish .03 (in notes)
   - the mutually adjusted continuous model (only P-trends printed: fish <.001, R&P .02)
   - the mutually adjusted pork P-trend .03 (no HR)
   - the Fig 1 curves (graphic only)
   - Spearman correlations
   - sex-specific results (the paper says they were done but not presented)

## Inconsistencies / probable typos in the paper (recorded as printed)
- **Fig 2 "All EPIC" n = 1389.** The 12 centres sum to 1263 and the cohort total is 1329. Heidelberg (48 cases) is shown although the legend excludes centres with <50 cases. The R&P All-EPIC estimate is inconsistent with Table 4 calibrated (see 8). Rows 198–223 note this.
- **R&P reference category "<10"** vs abstract "<20" (see 3).
- **Abstract/Results attribute the 10-year absolute risks** (1.71 % vs 1.28 %) to R&P in one place and to "red meat" in the Discussion (p. 912). Not coded; noted.
- **Discussion (p. 912) says the joint estimate is "high red meat and low fish"**, but Fig 3A is red and processed meat.
- **Results text (p. 910) gives processed meat calibrated colon HR 1.68 (0.87–3.27)**, which matches Table 4. Red meat calibrated colon 1.36 (0.74–2.50) also matches. No text–table conflicts were found for Table 3/4 values quoted in the text (1.57, 1.35, 1.17, 1.42, 0.69, 1.25, 1.55, 0.70, 0.46).
- **checks.py log-symmetry flags** on new rows are listed in the report section below.

## Review of hand-coded rows (001–049)
Values (point/CI/p_trend) of all 49 rows were compared to a script parse of Table 3 and Table 4. **No numeric errors were found.** Issues:
- 011–030 (red meat colon/right/left/rectum): `n_cases` holds the colorectal N* (132/138/323/486/250). These are colorectal cases per category, not colon/subsite/rectum cases, so they sum to 1329 against the outcome totals of 855/474. They should be empty, or flagged as colorectal counts.
- 007, 014, 015, 017–019, 023, 025, 027, 029, 038, 040, 043, 045, 033–036, 047–049: trailing zeros were dropped (e.g. printed "1.00 (0.78 to 1.28)" coded `1.0`; "0.90" coded `0.9`; "1.30" coded `1.3`). This is a minor departure from R2 ("every decimal"). Values are numerically identical. New rows keep the printed form.
- 001–030, 042–046: `source_page` "910-911". Table 3 begins on p. 911: the text file's "910 ARTICLES" footer comes before the table. Same for 037–041 coded "910". Table 4 is on p. 912 (after the "911" page marker), not "911" as coded in 031–036 and 047–049. New rows use 911 (Table 3), 912 (Table 4) and 913 (Fig 2). Please confirm against the PDF.
- 031–036: `denominator_type=person_years`, but `person_years` is filled only on 031–032 and empty on 033–036. 047–049 use `denominator_type=none` for the same kind of row. This is inconsistent. New Table 4 rows fill 2279075 on every row, with a note that it is the cohort total.
- 037–041 note: "category labels as printed: '<10' then '20–40' (10–20 absent in print)". This is correct as a description. The abstract's "<20" explains it (see judgment call 3). The pilot NOTES line 3 leaves the question open.
- 042–046: is_main_model=yes is fine. The pilot NOTES says processed CRC rows were "CRC only". That is correct.
- dose_conversions c1: `portion_source=paper` is wrong. There is no portion; the unit is g/day and no medians are printed, so the field should be empty. The top-category midpoint 120 (80 + width 40) does not follow KODEBOK 4.3/cup_rule. The neighbour category 40–80 has width 40, so the rule gives 80 + 40/2 = 100 as midpoint. The pilot appears to have added the full width. GL with top = 100 gives 1.22 (0.99–1.52) vs the paper's 1.21 (1.02–1.43). With top = 120 it gives 1.17 (0.98–1.41), which is the 1.17 cited in KODEBOK 4.3 point 6. **KODEBOK's pilot conclusion (deviation caused by the top-category dose) depends on this choice.**
- Pilot NOTES line 3 ("presumably 10–20 in error?") is superseded by judgment call 3.
- adjustments m3: covariates match the Table 4 footnote. m2 adj_fiber=yes is correct (‡ includes dietary fiber). The abstract also lists "folate" among covariates, but Table 3 ‡ and the Table 4 footnote do not include it. Folate is only in the subset analysis (m4).

## checks.py (scratch copy, 2026-10-30): 12 flags
- 2_asymmetrisk_ci: 005 and 023 are the pilot's known flags. 200, 206, 208, 210, 218, 219 and 223 are Fig 2 per-10 g rows. Their HRs are near 1 with CIs printed to 2 decimals, so rounding alone produces the asymmetry. They are not treated as typos.
- 5_tilfeller_summerer_ikke: the pilot's red-meat colon and rectum sets (colorectal N* on subsite rows; see review above). New sets leave subsite n_cases empty and are not flagged.
- 9_uverifisert: 223 rows, as expected.


---
# nothlings2009
# Nöthlings 2009 (Multiethnic Cohort, nested case-control): extraction notes (opus-H2, 2026-10-30)

Source: Cancer Epidemiol Biomarkers Prev 2009;18:2098-106 (PMC2771770 XML, flattened), `historisk/nothlings2009.txt`. Meat estimates are in Table 2, Table 3 and the Results text.

## New vocabulary
- `subgroup`: `nat2_slow_intermediate_acetylator`, `nat2_rapid_acetylator`, `nat1_no_10_allele`, `nat1_10_allele_carrier`.
- `cup_role = cup2010_superseded` (as assigned). `source_page = 2098-2106` (article range; the XML has no page breaks).

## Scope coded (41 rows)
- Table 2: red meat and processed meat quartiles × 2 models (age-sex-ethnicity; multivariate) = 16 rows. `is_main_model = yes` for the multivariate model.
- Table 3: red and processed meat tertiles cross-classified by NAT2 (slow/intermediate vs rapid) and NAT1 (*10 non-carrier vs carrier), age-sex-ethnicity adjusted = 24 rows. Each genotype pair shares one common reference (lowest tertile in the "low-risk" genotype). Only the reference genotype's three cells form a within-stratum contrast with a set id. The rapid/*10 cells carry no set id or rank.
- Text: multivariate OR 1.35 (0.96-1.91) for the top processed-meat tertile in NAT2 rapid acetylators vs the slow/intermediate lowest tertile (1 row).
- Not coded (outside brief R1): HCA (PhIP, MeIQx, DiMeIQx, total), doneness preference, "meat and fat" dietary pattern, smoking and genotype main effects.

## Judgment calls
1. **Red meat = `red_undefined`, `unclear`.** The paper does not define red meat. The Methods list "red meat" and "processed red meat" as separate exposures, so red meat is probably unprocessed (as in ollberding2012), but this is not stated.
2. **Processed meat = `processed`, `yes`** ("processed red meat" in the Methods).
3. **Mutual adjustment.** The multivariate model includes "smoking status and pack-years of smoking or meat intake, as appropriate". It is unclear whether red and processed meat adjust for each other, so `is_mutually_adjusted_processed = unclear` on the multivariate red-meat rows and `adj_processed_meat = unclear`.
4. **Denominators** are controls (`n_controls`), per the brief. Quartiles and tertiles are cut on the controls' distribution.
5. **Doses.** Density g/1,000 kcal/day. Bounds as printed; no medians. The top processed-meat quartile is printed as "110.+", an obvious typo for 11.0+. `dose_low = 11.0`, and the label keeps "110.+ (sic)".
6. **Superseded.** The full-cohort MEC analysis (ollberding2012) supersedes this paper for meat. Same `cohort_id = mec`; never pool them together.
7. **Effect measure OR** (unconditional logistic regression).

## Typos / inconsistencies
- "110.+" label (above).
- Text vs Table 3: the text gives the age-sex-ethnicity OR 1.48 (1.06-2.07) for NAT2 rapid, top processed tertile, which matches the table.


---
# oba2006
# Oba 2006 (Takayama, takayama): extraction notes (opus-B, 2026-10-30)

Source: Cancer Letters 244:260–267, full text `Understudier WCRF/oba2006.txt`. Estimates come from Table 2 (p. 263) and the Results text (p. 264). No supplement exists. The study card was not opened.

## New vocabulary
None.

## Scope coded (37 estimate rows)
- Table 2 covers 3 exposures × 2 sexes × 2 models (age-adjusted "a", multivariate "b") × 3 tertiles = 36 rows, for colon only:
  - Total meat
  - Red meats
  - Processed meats
- Every row carries the tertile median (g/day) and cases. Cases sum to 111 (men) and 102 (women) for every exposure, which matches the totals.
- There is 1 sensitivity row: processed meat in men, high vs low tertile, excluding cases diagnosed in the first 3 years: 2.26 (1.26–4.04), p trend <0.01 (text p. 264).
- **Rectum: no estimates.** The 68 male and 44 female rectal cancers were excluded from all analyses as too few (p. 261). There is no colorectal outcome either.
- **Poultry and fish: none printed.** The brief listed them "if present"; the paper reports no poultry or fish rows.
- Not coded: fat, protein and energy rows, and coffee/tea (Table 3). These are out of scope.

## Judgment calls
1. **"Red meats" = `red_unprocessed`**, `includes_processed = no`. The methods (p. 261) define red meat as beef and pork, and define ham, sausage, bacon and yakibuta (Chinese-style roasted pork) separately as processed meat.
2. **"Total meat" = `total_meat`**, `includes_processed = unclear`. It is not defined in the paper.
   - Its medians (men 33.3/63.1/102.2; women 22.4/49.9/80.8) are well above red + processed (men about 23/44/77), so it probably also includes poultry and/or other meats.
   - Whether processed meat is included is not stated.
3. **is_main_model**: multivariate (b) = `yes`, age-adjusted (a) = `no`, per exposure × sex.
   - The multivariate model adjusts for age, height, BMI, pack-years, alcohol (continuous ethanol) and physical activity (METs).
   - It has no dietary covariates and no mutual meat adjustment, so `is_mutually_adjusted_processed = no`.
4. **Energy.** Intakes were log-transformed and energy-adjusted by Willett's residual method before tertiles were formed (p. 262), so the medians are energy-adjusted intakes. `energy_method = residual`, `adj_energy = yes` for both models.
5. **Tertiles on all subjects, medians by sex.** The methods say tertiles were formed "according to the distribution … by all subjects" (p. 262), yet Table 2 prints *different* medians for men and women.
   - Either the tertiles were in fact sex-specific, or these are medians within sex-pooled tertiles.
   - The printed sex-specific medians are recorded as given. This needs checking if cut-points matter.
6. **Sensitivity row (oba2006_037).**
   - `subgroup = excl_cases_first_3y` and `contrast_type = hvl`.
   - The model is not restated, so it is assumed to be multivariate (m2).
   - `n_cases` is empty because it is not printed (111 − 33 = 78 male cases overall).
   - `is_main_model = no`.
   - The text gives no comparable sensitivity numbers for red or total meat ("substantially unchanged").
7. **Denominators.** Only cases per tertile are printed, so `denominator_type = none`. Person-years are not printed in total or by category. The cohort sizes are 13,894 men and 16,327 women.
8. **p-values.** The text extraction renders "<" as "!" (font glyph), so "!0.01" is recorded as `<0.01`. The age-adjusted processed-meat p trend for men is printed "0.01*" and recorded as 0.01.
9. **dose_conversions.** Paper medians are used as `g_day_assigned` for all 12 sets (`paper_median`). No bounds are printed.
10. **study.csv.**
    - `sex = all`: men and women are analysed separately in one paper.
    - `cases_colon = 213` (111 men + 102 women). `cases_colorectal` and `cases_rectum` are empty because there are no analyses for them.
    - `outcome_ascertainment = mixed`: cases came from the two main Takayama hospitals, cross-checked against prefectural registry reports, with about 90% coverage.
    - `followup_type = max` (1 Jan 1993 – 31 Dec 2000).
    - `baseline_start = baseline_end = 1992` (questionnaire Sept 1992).
    - `age_range = 35-101` (men 35–98, women 35–101).
    - `validation_r` is empty in the field because the values are sex-specific. Spearman vs 12 daily records (Table 2 note):
      - red meat: men 0.54, women 0.21
      - processed meat: 0.58 / 0.69
      - total meat: 0.18 / 0.62
    - The methods text gives the same red/processed values.
    - `in_cup2016 = yes`, `cup_role = dose_response` (from OPPDRAG_tillegg).

## Typos / anomalies
- No log-asymmetry flags from checks.py.
- **Text–table inconsistency (minor):** the Discussion (p. 265) says total meat and red meats "tended to increase the risk of colon cancer among men". Yet red meats in men are 1.14 and 1.03 in Table 2 (flat), and only total meat (1.56) shows a positive tendency.
- **Validation inconsistency:** the methods text says the Spearman for red meat is 0.54 (men) / 0.21 (women). The Discussion says "0.54" without specifying sex. These agree, but women's red-meat validity is very low (0.21) and is not discussed.


---
# ollberding2012
# NOTES – ollberding2012 (MEC)

Extractor: opus-P3 · 2026-10-30 · Sources: `Understudier WCRF/ollberding2012.txt` (Early View, pp. 1–9) and `ollberding2012_supplement.txt` (Suppl Table 1). Every number was parsed directly from these two text files by a script. The study card was used only for orientation.

## Contents
- **estimates.csv – 120 rows.**
  - Table 2 (p. 5): 4 meat exposures × 2 models (basic, multivariable) × 5 quintiles = 40 rows.
  - Suppl Table 1: 4 exposures × 4 ethnic groups × 5 categories, multivariable only = 80 rows.
- **adjustments.csv – 3 rows:**
  - m1 = basic model
  - m2 = multivariable model
  - m3 = multivariable model fitted within each ethnic group
- **study.csv – 1 row.**
- **dose_conversions.csv – 24 rows**, one per category set. `g_day_assigned` is empty in every row (see below).

## Codebook addition
- **`dose_unit = g_per_1000kcal_day`** is new to the KODEBOK 4.x vocabulary, added as the brief instructs. All meat exposures in the paper are energy densities: "Meats and HCAs were examined as energy densities (per 1,000 kcal) in all models" (p. 3). The paper gives no g/day values.

## Main model (R5)
- **`is_main_model = yes`** is set on Table 2's "Multivariable model" (adjustment set m2) for each of the four exposures (colorectal, all). The paper calls it the multivariable model, and the abstract reports it ("In multivariable models … RR 1.02 [0.91–1.16]"). Because this is set per exposure, there are 4 category sets with `yes`, one per exposure × outcome × sex.
- **Basic-model rows** and all Suppl Table 1 ethnic-subgroup rows are `no`.
- **Which red-meat row is "the" main one** is an analysis choice, not a coding one. The paper reports `red_total` and `red_unprocessed` side by side without ranking them.

## Judgment calls
1. **Category bounds for the Table 2 rows come from Suppl Table 1.** Table 2 prints only quintile medians. Suppl Table 1 prints the cut-points ("< 12.3", "12.3 - 20.5" …), and its footnote says "Cut-points based on the exposure distribution of all eligible participants". So these are the overall quintile cut-points.
   - I put them in `dose_low`/`dose_high` for the Table 2 rows and named the source in `notes`.
   - Every Table 2 median falls inside the matching supplement interval for all four exposures.
   - The bounds have rounding gaps as printed (e.g. Q2 ends at 32.7 and Q3 starts at 32.8). They are kept exactly as printed.
2. **`dose_point`** = the Table 2 "Quintile median" (`paper_median`). The supplement gives no medians, so those rows have `dose_point_source = none`.
3. **Denominator.** The paper gives "Cases/no. at risk", not person-years, so `denominator_type = n_participants` with the count in `n_in_category`. `person_years` is empty because the paper does not report it.
4. **`exposure_includes_processed`:**
   - **"Total red meat"** = `yes` (study.csv `includes_processed = yes`). The paper gives no food list. It is inferred from the paper reporting a separate row, "Red meat excluding processed red meat". The Q5 medians (47.99 vs 34.86) are consistent with this.
   - **"Red meat excluding processed red meat"** = `no`, exposure `red_unprocessed`.
   - **"Total meat"** = `unclear`. The paper does not say what it contains (processed, poultry, fish?).
   - **"Processed meat"** = `yes`. Whether it includes processed poultry is not stated.
5. **`exposure` for "Total red meat" = `red_total`**, not `red_undefined`, because the paper names the processed component explicitly.
6. **Out of scope (R1), not coded:**
   - "Meat and fat dietary pattern" (factor score)
   - "Total meat cooked dark brown" (a doneness subset from the 1999–2000 HCA subcohort; no fitting exposure value in the vocabulary)
   - Total HCA, PhIP, DiMeIQx, MeIQx
   - Pack-years
   - Table 3 joint effects

   The codebook allows heme iron only, not HCAs. "Cooked dark brown" can be added later as `total_meat` with a subgroup tag if wanted. It has 5 Table 2 rows per model plus 20 supplement rows.
7. **Adjustment flags (m2):**
   - `adj_energy = yes`: log total energy is a covariate on top of the density exposure. `energy_method = density`.
   - `adj_physical_activity = yes` covers vigorous activity only.
   - Polyp history, vitamin D and multivitamin have no flag. They are recorded in `notes`.
   - Ethnicity is a Cox stratum. There is no ethnicity flag, and `adj_stratified_center = no`.
   - **m1:** `adj_energy = no`, since the basic model has no energy term even though the exposure is a density.
8. **Suppl Table 1 model (m3).** It is coded as a separate adjustment set because its footnote lists the same covariates as m2 but omits ethnicity, since it is fitted within ethnic groups. `model_label` says it is the multivariable model.
9. **`subgroup` values:** `ethnicity_african_american`, `ethnicity_japanese_american`, `ethnicity_latino`, `ethnicity_white`. The `category_set_id` is suffixed `_afram`/`_japam`/`_latino`/`_white` so each subgroup set is unique.
10. **No sex-specific, subsite (colon/rectum), lag, adenocarcinoma-only or continuous estimates** are printed. All are "data not shown" (p. 6), so none were coded. No sex subgroups are reported.
11. **`p_heterogeneity`** across ethnic groups (Table 2) is recorded in the `notes` of each Q5 row. `p_trend` is on the Q5 row only.
12. **`source_page`:** the Early View page number (Table 2 = p. 5; methods = p. 3). The final journal pagination is not in the file. Supplement rows use `suppl p. 1`.
13. **`in_cup2016` / `cup_role` in study.csv** were taken from the study card, not from the paper.

## Discrepancies and typos in the paper
- **Covariate list, methods vs Table 2 footnote:**
  - The methods (p. 3) list **multivitamin use** but not HRT.
  - Table 2 footnote 4 and Table 3 footnote 1 list **HRT (females only)** but not multivitamin.
  - The exclusion criteria (p. 2) require complete data on both.
  - I coded `adj_hrt = yes` from the footnote. Whether multivitamin was in the model is unclear; this is noted in adjustments.csv.
- **Pack-years** is in the methods, the Table 2 footnote and the Suppl footnote. It is missing from the Table 3 footnote, but Table 3 is not coded.
- **Suppl Table 1, in-scope typo:** African American, processed meat, Q2 prints "1.1 (0.85-1.44)" with one decimal. It is recorded as printed ("1.1") and flagged in that row's notes.
- **Suppl Table 1, typos outside the coded scope (HCA rows, for information):**
  - PhIP, African American, Q4: "1.20 (0.85-1.07)". The CI does not contain the point estimate.
  - PhIP, Latino, Q5: "10/9470" cases. This is implausible against the column; probably 100 or 110.
  - MeIQx cut-points: "10.4 - 33.9" then "40.0 - 68.5", a gap.
  - Japanese American, "cooked dark brown" Q2: CI "0.8-1.25" with one decimal.
- **Consistency checks (all pass):**
  - The abstract and results text match Table 2: MV Q5 total meat 0.93 (0.83–1.05), red 1.02 (0.91–1.16), processed 1.06 (0.94–1.19). Basic Q5 total red 1.26 (1.13–1.41), unprocessed 1.17 (1.05–1.31), processed 1.25 (1.12–1.40), with p-trends <0.001 / 0.004 / <0.001.
  - Table 1's total red meat Q1/Q3/Q5 cases (619/680/697) and numbers at risk (33,144/33,144/33,143) match Table 2.
  - Table 1's Q1/Q3/Q5 medians (7.4/24.6/48.0) match Table 2 (7.41/24.55/47.99) after rounding.
- **Case sums:** each Table 2 category set sums to 3,404 cases and 165,717 at risk, which equals the totals on pp. 1–2. The four ethnic groups sum to 3,182 cases and 153,501 at risk. The remainder (222 cases, 12,216 at risk) is Native Hawaiians, whom the supplement leaves out ("number of cases was too small").

## Doses (dose_conversions.csv)
- `original_unit = g_per_1000kcal_day`. The paper gives no portion sizes and no energy intake per quintile of any meat exposure.
- Table 1 gives mean energy only for **total red meat** Q1/Q3/Q5: 1962 / 2178 / 2269 kcal/day, overall 2149. Q2 and Q4 are missing.
- So `g_day_assigned` is left empty everywhere. A g/day conversion needs an energy assumption from outside the paper (e.g. interpolation), which belongs in a script, not in coding.
- For the other exposures, Table 1's energy values do not apply, because Table 1 is stratified by total red meat.

## Other study-level gaps
- PMID is not in the text.
- The number of FFQ items is not given.
- There is no validation coefficient for meat. The paper says only that correlations improved after energy adjustment (p. 3, ref. 28).
- `weight_basis` (raw or cooked) is not stated, so it is `unclear`.
- The diet was measured once (baseline 1993–1996), so `diet_repeated = no`.


---
# papadimitriou2022
# NOTES – papadimitriou2022 (EPIC diet-wide association study)

Extractor: opus-E · 2026-10-30 · Source: `EPIC/papadimitriou2022.txt`, a PDF-to-text conversion of Clin Gastroenterol Hepatol 2022;20:864–873 including the online supplement (pp. 873.e1–e13). The supplementary tables are in the same file, so no separate supplement file is needed. Values were parsed by script from Supplementary Table 2, which has a two-column layout, and from the Pork rows of Supplementary Tables 3–9. Every parsed value was checked by eye against the txt. No study card was used.

## New vocabulary
- `cohort_id = nlcs` for the Netherlands Cohort Study replication rows. This id already exists in cohorts.csv.
- No new controlled values.

## Scope (per caller's instruction)
- Only rows for red meat, beef, pork, lamb, processed meat, poultry, fish and offal are coded, plus liver (see 3).
- Other fish subtypes in Suppl Table 2 are **not coded**, following the instruction: fatty fish, lean fish, fish products, crustaceans.
- The other 80+ foods and nutrients are not coded.
- **No categorical estimates exist:** every DWAS estimate is continuous per 1 SD.
- **Subsite and sex analyses were run only for the 20 FDR-significant factors.** Of the meats, only pork is FDR-significant (q = 0.001). Red meat, processed meat, beef, lamb, offal, poultry and fish therefore have **colorectal × all only**. No colon, rectum, proximal, distal or sex-specific estimates exist for them in the paper.

## Contents
- **estimates.csv: 22 rows.**

| Source | Content | Rows |
|---|---|---|
| Suppl Table 2 (EPIC, CRC, both sexes) | Red meat, Processed meat, Beef, Pork, Lamb, Offal, Liver, Poultry, Fish | 9 |
| Suppl Tables 3, 4, 5 (EPIC, pork) | Colon, rectum, proximal, distal, men, women | 6 |
| Suppl Tables 6–9 (NLCS replication, pork) | CRC; colon, rectum; proximal, distal; men, women | 7 |

  - The EPIC pork column of Suppl Table 6 (1.06, 1.03–1.09) duplicates Suppl Table 2 and is not coded twice.
- **adjustments.csv: 2 rows.** m1 = EPIC DWAS model; m2 = NLCS model.
- **dose_conversions.csv: 9 rows**, one per exposure, giving the SD in g/day.

## Judgment calls
1. **p_value = FDR q value** (Suppl Table 2 "FDR" column), as instructed. The nominal P value is in `notes`. Suppl Tables 3–9 print no P per estimate, only P for heterogeneity between columns, which is in `notes`.
2. **SD → dose fields.**
   - `dose_unit = per_sd` and `dose_point` = the SD as printed. Values: red meat 36.2, processed 31.5, beef 19.2, pork 17.5, lamb 7.9, offal 6.2, liver 4.7, poultry 19.8, fish 31.
   - The gram unit is **confirmed only for red and processed meat**, by the Discussion (p. 870): "HR per 36.2 g of red meat intake daily … HR per 31.5 g of processed meat intake daily". For the other meats the SD column has no unit; g/day is assumed and flagged in notes and in dose_conversions.
   - The SD is of residual energy-adjusted intake ("adjusted for energy intake using the residual method and standardized prior to modeling"). A per-100 g conversion, HR^(100/SD), is therefore approximate.
   - For pork, the same SD (17.5) is put on the EPIC subsite and sex rows. The paper does not say whether subsite and sex models were re-standardized within the subgroup; the sex-specific SD is probably different. This is flagged in notes.
   - NLCS rows have no SD; it is not printed, and the NLCS used its own 150-item FFQ, so `dose_point` is empty.
3. **Liver.** Liver is listed under "Meat and meat products" next to Offal. It is coded `organ` (R1 includes organ meat), but `is_main_model = no`, so that Offal, which the caller named, is the single main `organ × colorectal × all` row. Offal intake is missing for Norway and liver for the Netherlands, Norway and Sweden, so the two variables are not nested in any known way.
4. **Exposure definitions.** The paper defines none of the meat variables.
   - Red meat → `red_undefined`, with `exposure_includes_processed = unclear`. Processed meat is a separate variable in the same table, which suggests red meat excludes processed meat, but this is not stated. The Discussion quotes the WCRF definition only for context.
   - Beef, pork, lamb, poultry and fish are also `unclear`.
   - Offal and liver are `no`.
5. **is_main_model.**
   - `yes` on all EPIC rows except Liver.
   - Each exposure × outcome × sex has one EPIC model only. These are the paper's primary DWAS models.
   - NLCS rows are `no`. They are replication rows, and they share exposure × outcome × sex with the EPIC rows; the brief allows one `yes` per combination within a study. NLCS has its own meat publication (gilsing2015, batch F), which is where NLCS meat estimates belong.
   - **Note:** this model is minimally adjusted for diet. It has no alcohol, fibre, calcium, family history or NSAID terms. It is "most adjusted" only within this paper.
6. **Denominators and cases.**
   - EPIC rows with complete-cohort exposures (red meat, processed, pork, poultry, fish) have `n_cases` = the outcome total from the main text and Suppl Table 1, and `n_in_category = 386792`, coded as `denominator_type = n_participants` because person-years are not printed. Sex rows use 112,788 / 274,004.
   - For **beef, lamb, offal and liver**, intake is missing for some countries (6.1 %, 22.9 %, 6.4 % and 20.7 % of participants respectively). The analysis N and case counts are not printed, so these fields are left empty with `denominator_type = none`.
   - The paper does not say whether participants with missing red meat, processed meat, poultry or fish intake existed. Footnotes list missingness only for the items shown.
7. **Effect measure:** HR. **contrast_type:** continuous.

## Typos and inconsistencies (flagged)
- **EPIC alcohol is 1.07 (1.04–1.10) in Suppl Table 2 but 1.07 (1.04–1.09) in the abstract.** The abstract figure is the EPIC–NLCS meta-analysis, so this is not an error. Alcohol is not a coded row.
- **Supplementary Figure 1** shows red and processed meat HRs by cumulative year of follow-up, with a trend toward smaller HRs as follow-up increases. **No numbers are printed**, so nothing was coded (tillegg rule 6).
- Fish SD is printed as "31", without a decimal. Copied as printed.
- The Suppl Table 2 heading says "Fish and seafood" for a group containing Fish, Fatty fish, Fish products, Crustaceans and Lean fish. "Fish" seems to be the aggregate, but whether it includes the others is not stated.
- The main-text CRC case split is 3,143 colon (1,495 proximal + 1,435 distal + 213 unspecified, which sums to 3,143) + 1,715 rectum = 4,858. That is 211 fewer than the 5,069 CRC cases; the remainder is presumably overlapping or unspecified sites. This is not explained in the paper.
- checks.py raised no asymmetry flags.

## Relation to Norat 2005 (same cohort)
- `cohort_id = epic`. It must never be pooled with norat2005.
- The "Norat → Papadimitriou" version comparison (KODEBOK §7) is not like-for-like:
  - Norat used g/day categories plus per-100 g (observed and calibrated) estimates, with dietary covariates.
  - Papadimitriou uses per 1 SD of residual energy-adjusted intake, with no dietary covariates.
  - Greece is excluded in Papadimitriou, and mean follow-up is 14.1 years vs 4.8.

## Study-level
- `diet_instrument = mixed`: country-specific FFQs and diet histories, interviewer-administered in Ragusa and Spain, plus a food record combined with an FFQ in Malmö.
- `outcome_ascertainment = mixed`.
- `followup 14.1 (mean)`.
- PMID not printed.
- `in_cup2016 = no` and `cup_role = post_2016` come from the tillegg list.


---
# papier2025
# Papier 2025 (Million Women Study, diet-wide) – extraction notes (opus-G, 2026-10-30)

Source: /home/claude/drive/post2015/papier2025.txt. This is a PDF-to-text conversion of Nat Commun 16:375, with two-column layout interleaved and journal page footers kept. `source_page` uses the journal page (Table 3 = p. 7; Results text = p. 2; Discussion = p. 8; Methods = p. 9). No supplement file exists. Supplementary Data 1-6 and the Supplementary Methods are not available.

## New vocabulary
- `dose_unit = per_30g` (per 30 g/day). This is the paper's increment for red/processed meat, recorded exactly as printed.

## Scope coded
The only meat, poultry or fish estimates with numbers printed in the main text are for **red/processed meat combined**, per 30 g/day:
- Table 3, main model: RR 1.08 (1.03, 1.12).
- Table 3, further adjusted for calcium 1.06 (1.01, 1.11), dairy milk 1.07 (1.03, 1.12), fruit 1.06 (1.02, 1.11), and wholegrains 1.06 (1.02, 1.11).

Total: 5 estimate rows.

## Not coded (not available or not printed)
- **Separate red meat, processed meat, poultry and fish results** (Supplementary Data 1, all 97 factors). The Discussion says red and processed meat separately "were not robust to correction for multiple testing" but gives no numbers.
- **Categorical results.** Fig 3 shows red/processed meat by intake category, but the txt holds no printed numbers for it (graph only). Per supplement rule 6, values are not read off a figure.
- **Subsite** (Suppl Data 4), **strata** (Suppl Data 5), **sensitivity** (Suppl Data 3) and **sequential confounder adjustment** (Suppl Data 2).
- MR results (milk, not meat).

## Judgment calls
1. **Exposure = `red_total`** (red and processed meat combined; includes_processed = yes). This follows the Norat 2005 convention for "red and processed meat". The component list is only in the Supplementary Methods.
2. **is_calibrated = yes on all 5 rows**, as the brief instructs for measurement-error-corrected rows. The per-30 g/day trend is computed by assigning each baseline category the mean intake re-measured by Oxford WebQ in a 7% subsample. The paper says this "reduces the impact of regression dilution bias and other forms of measurement error". No uncorrected per-unit trend is printed.
3. **is_main_model = yes on the main model row**, even though it is calibrated. This deviates from R5, which excludes calibrated models. Here the corrected trend is the only per-unit estimate the paper reports, and it is the paper's "Main model". If the controller applies R5 strictly, set papier2025_001 to `no`; the study then has no main row. The four further-adjusted rows are `no`.
4. **p_value "<0.01" (main model row only).** Results p. 2 prints "per 30 g/day = 1.08, 1.03–1.12, p < 0.01". Fig 3 lists red/processed meat among the "nine less FDR-significant dietary factors (p < 0.01)". The FDR threshold is stated as "FDR corrected p-value < 0.009". It is ambiguous whether "p < 0.01" is the FDR-corrected or raw p. It is recorded as printed and flagged. No exact FDR p is printed in the main text.
5. **Effect measure = RR.** The paper calls its Cox HRs "relative risks". Coded `RR`, as printed.
6. **Denominator.** n_in_category = 542,778 (analysis cohort) with `denominator_type = n_participants`; n_cases = 12,251. Total person-years are not printed; the mean is 16.6 y.
7. **adj_stratified_center = yes**, for stratification by region of residence (10 regions). **adj_age = yes**, via stratification by year of birth.
8. **Further-adjusted models.** m4 (+fruit) sets `adj_fruit_veg = yes` although only fruit was added. m3 (+dairy milk) and m5 (+wholegrains) have no matching flag, which is noted in adjustments.csv.
9. **diet_repeated = no.** The single WebQ recall in 7% of women is used only to assign category means. It is not a repeated exposure measurement in the Cox model.
10. **cohort overlap.** MWS overlaps Spencer 2010 (UK Dietary Cohort Consortium) and the EPIC-Oxford note in cohorts.csv. This is already listed there.

## Printed anomalies (not in coded rows, but in the same table)
- Table 3, Magnesium + wholegrains: "0.80 (0.99,4.69)". The CI does not contain the point; it is an obvious typo.
- Table 3, Magnesium + calcium: "0.83 (0.83,1.01)". The point equals the lower bound.

These are not meat rows and are not coded. They are recorded because they indicate copy-editing errors in Table 3. The red/processed meat row itself looks internally consistent.

## Derived value not coded as an estimate
- Discussion p. 8: "this is equivalent to a 29% higher risk per 100 g/day". This is a rescaling of 1.08 per 30 g/day (1.08^(100/30) ≈ 1.29). No CI is given, so it was not coded as a row.

## checks.py (scratch copy, 2026-10-30)
- 2_asymmetrisk_ci on 4 of 5 rows (asym 0.17-0.23). The cause is two-decimal rounding of narrow CIs, e.g. 1.08 (1.03,1.12) has arms ln 0.047 vs 0.037. These are not typos.
- 9_uverifisert: 5 rows (expected).

## Supplement rows (30.10)

Extractor: opus-S1 · 2026-10-30 · Source: `/home/claude/drive/supplements/papier2025_SupplData1.txt` (Supplementary Data 1–6 as 6 sheets). Rows papier2025_006–055 (50 rows), source_page = `suppl`. The earlier statement in these notes that "No supplement file exists" is superseded.

### New vocabulary
- `dose_unit`: `per_10g` and `per_20g` (`per_20g` is already listed).
- `subgroup`:
  - `self_reported_good_excellent_health`
  - `excl_first_5y_followup`
  - `smoking_never` / `smoking_ever`
  - `bmi_lt_25` / `bmi_ge_25`
  - `deprivation_highest` / `deprivation_remainder`
  - `alcohol_lt_7_drinks_wk` / `alcohol_gt_7_drinks_wk`
- Adjustment sets m6 (Model 1), m7 (Model 2) and m8 (Supp Data 5 footnote).

### What was added
| Sheet | Rows | Content |
|---|---|---|
| Supp Data 1 | 5 | red meat per 20 g (_007, **main**), processed meat per 10 g (_006, main), chicken per 20 g (_010, poultry, main), non-oily fish per 10 g (_008) and oily fish per 10 g (_009). Red+processed per 30 g = existing _001, not duplicated. |
| Supp Data 2 | 2 | red+processed per 30 g, Model 1 (_011, m6) and Model 2 (_012, m7). The fully adjusted column = _001. |
| Supp Data 3 | 17 | red+processed quintiles + trend. All participants: 5 quintile rows (main model, _013–017); its trend duplicates _001 and was dropped. Good/excellent health: 5 quintiles + trend. Excluding first 5 y: 5 quintiles + trend. |
| Supp Data 4 | 18 | red+processed quintiles + trend for proximal colon, distal colon and rectum (main model, `yes`). Phet = 0.65. |
| Supp Data 5 | 8 | red+processed per 30 g by smoking, BMI, deprivation and alcohol strata (m8, `no`). Phet is in notes. |
| Supp Data 6 | 0 | WebQ mean intakes only, used for documentation. |

dose_conversions: 6 rows (papier2025_dc02–dc07), one per quintile set. No cut points or category means are printed.

### Judgment calls
1. **Red meat (_007) = `red_unprocessed`, exposure_includes_processed = `no`.** This is inferred, not stated. The paper treats red meat and processed meat as separate factors, and the Supp Data 6 WebQ means add up exactly: 34.6 + 12.8 = 47.4 g/d for red+processed. The explicit definition is only in the Supplementary Methods, which are not available. If the controller wants R6 read strictly, use `red_undefined` / `unclear`. Set as main per the supplement brief.
2. **is_calibrated.**
   - Supp Data 1: `yes`. Its footnote states that the trend uses re-measured category means, the same as the main text.
   - Supp Data 2–5: footnotes do not restate the method. Their per-30 g trends are still coded `yes`, because the all-participants / fully adjusted trend reproduces 1.08 (1.03,1.12) exactly. This is inferred.
   - Quintile rows (baseline categories vs lowest) are `no`.
3. **is_main_model.**
   - Processed meat (_006) and chicken (_010) are the only estimates for their exposure in the paper's main model, so they are `yes`, calibrated like _001. This is the same KODEBOK 4.2(b) exception already documented for _001.
   - Fish is reported only as oily and non-oily, with no total. Both rows are `no`, to avoid two main rows for fish × colorectal × women. Choose at analysis.
   - The Supp Data 3 all-participants quintiles (_013–017) are `yes`, being categories of the main model, as in the Norat convention. The Supp Data 4 subsite quintiles and trends are `yes`.
4. **Poultry = chicken only.** No total-poultry variable exists.
5. **n_cases on trend rows** = the sum of the printed quintile cases: colorectal good health 9,664; excluding first 5 y 10,025; proximal 5,224; distal 3,164; rectum 3,352. The all-participants quintiles sum to 12,251, matching the main text. Supp Data 1 rows carry 12,251 / 542,778 as _001 does. Supp Data 5 rows carry the stratum N as n_in_category (n_participants) and no cases.
6. **Distal** is coded `distal_colon`, because rectum is a separate column.
7. **p_value.** Supp Data 1 prints exact p values, which are recorded. They are unadjusted: red meat 0.0302, processed 0.0231, not FDR-significant.

### Contradictions, typos and anomalies
- **Row _001 p value.** Supp Data 1 prints p = 0.00161454 for red+processed per 30 g. This resolves the main-text ambiguity: "p < 0.01" is the raw p. A note has been appended to _001.
- **Supp Data 5 adjustment footnote** omits current menopausal hormone therapy. It is in the main model and in the Supp Data 3/4 footnotes. Coded as m8 with adj_hrt = `unclear`; probably a footnote omission.
- **Supp Data 5 header** prints "N=264.632" for BMI 25+, with a decimal point instead of a thousands separator. Recorded as 264632. The BMI strata sum to 506,129, below 542,778 (missing BMI). The alcohol strata are printed "<7" and ">7" drinks/wk, so 7 itself is not assigned.
- **Supp Data 3/4 "Fruit pw" row** shows a spreadsheet date artefact ("2024-10-14 00:00:00", probably "10-14"). It is not a meat row. The text conversion also loses the Fibre block header (the fruit block runs straight into fibre's "highest quintile" and "Trend per 5 g/day"). Supp Data 4 labels the Calcium trend "Trend per 50g/day" (a mislabel; Supp Data 3 says per 300 mg/day). Neither is coded; this is noted as evidence of copy-editing errors.
- **Supp Data 4 footnote** lists smoking categories without "current 1–4, 5–9". This is treated as the same model (m1).
- **checks.py** (scratch copy) flags 6 new rows (_007, _012, _015, _022, _048, _053) for log-asymmetry of 0.17–0.23. All are two-decimal rounding of narrow CIs. None are typos.
- **study.csv** is not changed. Subsite totals now available from Supp Data 4: colon is not given as one number (proximal 5,224 + distal 3,164); rectum 3,352. The controller may fill `cases_rectum = 3352`.


---
# phillips1975
# Phillips 1975 (Adventists) – extraction notes (opus-H1, 2026-10-30)

Source: Cancer Res 1975;35:3513–3522 (conference paper), OCR text `Historikk 1965-2015/Historikk/txt/14a_Phillips1975.txt`. Numbers come from Table 5 (p. 3519) and the Summary (p. 3513). The study card was not used.

## New vocabulary
- `design = case_control`. The meat estimates come from a hospital-based case-control study, which is not in the design vocabulary (cohort / nested_cc / case_cohort / pooled_cohorts / meta_analysis).
- `cup_role = pre2010`.
- category_set_id model token `crude`. Kind suffix `_dich` (the dichotomy column) and `_ext` (high vs low extremes column). Exposure tokens: `meat20y`, `beefproducts`, `hamburger`, `lamb`, `fish`.

## Scope coded (16 rows = 8 two-category sets)
Table 5 colon cancer, 41 cases and pooled controls, with each contrast coded as a reference row plus an exposed row:

| Exposure | Dichotomy | High vs low extremes |
|---|---|---|
| Meat, any type, 20 years ago (any vs none) | 2.8* | – |
| Beef products index (any vs none) | 2.3* | 3.1* |
| Beef hamburger | 2.5* | 2.3 |
| Lamb (any vs none) | 2.7* | – |
| Fish (any vs none) | 1.6 | 3.4* |

\* marked significant (p < 0.05 by continuity-corrected χ²).

**No confidence intervals are printed anywhere in the paper.** `ci_low` and `ci_high` are empty, `p_value = <0.05` where the significance marker is printed, and `ci_level` is empty.

**Not coded:**
- Table 6: "meat, poultry or fish (current use)", beef steak, other beef and poultry are listed only as "not associated", with no numbers.
- "High saturated fat foods" index, 2.1 / 2.7. It is a composite of cheese, eggs and all meats and poultry, not a meat exposure.
- Fried foods, dairy, pepper and the other foods.
- Breast cancer (Table 7).
- All SMRs (Charts 1–8): Adventists vs the general population, LLU vs USC physicians. These compare religious or professional groups, not meat intake.

## Judgment calls
1. **Design and cohort.** The meat × colon estimates are from a small case-control study of Adventist hospital patients (1969–73). They are not from Adventist cohort follow-up. The prospective AHS was "2 years into a 6-year" study and had no results. `cohort_id = ahs` is kept as the brief instructs. `design = case_control`. **Flag:** this row should not be pooled as a cohort estimate.
2. **Effect measure.** The paper calls it "relative risk", but it is computed as ad/bc, i.e. an odds ratio, from pooled controls. Per the brief, `effect_measure = RR` as printed.
3. **Outcome = colon.** Table 5 and its legend say "colon cancer cases". The Results text says "41 Adventist colon-rectal cancer ... patients". The table is followed.
4. **Denominators.**
   - The reference row carries the low/none-exposed cases (`n_cases`) and controls (`n_in_category`). The exposed row carries the high/any-exposed cases and controls.
   - `denominator_type = n_controls`.
   - The printed raw-data order is (case+, case−, control+, control−). It was verified by recomputing ad/bc for every coded row: 2.83, 2.25, 3.12, 2.51, 2.26, 2.69, 1.63 and 3.37 all match the printed RRs.
5. **Table 5 is scrambled in the OCR**, in particular the "Meat, any type, 20 yr ago" row. Its value and raw data are printed next to the Pepper row. The raw set (26, 9, 51, 50) gives 2.83, which is the abstract's "2.8 for past use of meat". No other printed raw set gives 2.8, so the assignment is considered reliable. The remaining stray values (2.2, 3.6, 2.1 with (7,34,9,97), (9,9,14,50), (7,26,4,31)) belong to pepper and other non-meat rows.
6. **Beef products RR is printed "2.Y" in the OCR.** It is read as 2.3, from the abstract ("2.3 for beef") and the recomputed 2.25.
7. **Exposure codes.**
   - Meat 20 years ago = `total_meat`. Footnote e ("includes meat, poultry, and fish") appears to attach to this row. `includes_processed = unclear`.
   - Beef products index and beef hamburger = `beef`.
   - Lamb = `lamb`; fish = `fish`.
   - Hamburger could count as processed under some definitions. It is left `unclear` here, because there is no red-meat aggregate.
8. **is_main_model.** Within each exposure, the dichotomy is `yes`: it is the first and primary column, and the abstract quotes it. The extremes are `no`. For beef, the beef-products index is `yes` and hamburger (one item of the index) is `no`.
9. **Adjustment.** Cases were matched by age, sex and race, but the analysis pooled all controls and computed a crude ad/bc. `adj_age` and `adj_sex` are therefore `unclear`, and everything else is `no`.
10. **Current vs past use.** The paper notes that current meat use was not associated, while use 20 years ago was. Current use of beef, lamb and fish is reported (the dichotomy wording is "any vs none"). The 20-years-ago row is distinguished in `exposure_text`.

## Portion sizes
None. The beef-products index weights reported usage by "the weight of an average serving for beef" (fn h), but the grams are not printed. None of the sets can be used for dose–response.

## Cohort id
`ahs` already exists in database/cohorts.csv; no new cohort id needed.

## checks.py (scratch copy, 4 studies combined)
Only expected flags: missing CI on point-only rows (Goldbohm text frequency rows, all Phillips rows), dose rule 4 on Goldbohm 0 / 0-10 categories, and rule 9 (unverified). No log-asymmetry flags.


---
# pietinen1999
# Pietinen 1999 (ATBC, atbc): extraction notes (opus-B, 2026-10-30)

Source: Cancer Causes Control 10:387–396, full text `Understudier WCRF/pietinen1999.txt`. Meat estimates come from Table 5 (p. 393); methods are on pp. 387–389. No supplement exists. The study card was not opened.

## New vocabulary
None.

## Scope coded (40 estimate rows)
- Table 5 covers 5 exposures × 2 models (age-adjusted base model, multivariate) × 4 quartiles, for the colorectal outcome in men only:
  - Beef, pork, lamb
  - Processed meat
  - Total red meat
  - Poultry
  - Fish
- Every row carries the quartile median (g/day) and the cases per quartile. Case counts sum to 185 for every exposure, which matches the total.
- Not coded:
  - "Ratio of meat/(poultry + fish)": a ratio, not an exposure in the vocabulary.
  - "Fried meat, frequency per year": a cooking-method frequency variable, not a meat amount. It would need new vocabulary if wanted.
  - Table 2 "Meat protein (g)": a nutrient, not a meat variable.
- **No heme iron or iron rows** exist anywhere in the paper. Nitrite is mentioned in the Discussion without numbers.
- No colon/rectum split, no continuous estimate, and no subgroup estimates. The sensitivity analysis excluding the first 2 years is described only as "did not alter the results", with no numbers.

## Judgment calls
1. **Exposures.**
   - "Beef, pork, lamb" = `red_unprocessed`, `includes_processed = no`. The text (pp. 390–391) analyses "beef, lamb and pork together and processed meat separately and then combined them as total red meat".
   - "Total red meat" = `red_total`, `includes_processed = yes`. Total red meat is the sum of these two variables: medians 79 ≈ 35+26 … 203 ≈ 99+122 (approximately; medians are not additive).
   - "Processed meat" = `processed` ("mostly sausages", p. 394).
   - study.csv `includes_processed = yes` refers to "Total red meat", the variable most likely used as "red meat" downstream. Note that processed meat is more than half of total red meat in the top quartile (122 vs 99 g/d medians).
2. **is_main_model**: multivariate = `yes`, age-adjusted base model = `no` for every exposure. The multivariate model is the most adjusted.
   - **Text–table inconsistency:** the text (p. 391) says "since multivariate adjustment did not change the results, only the base model adjusting for age and supplement group is shown", yet Table 5 prints both models.
   - The table is coded as printed. This is noted on every row.
3. **Energy.** The quartiles are of *energy-adjusted* intakes (residual method on log-transformed values, pp. 388–389), so the medians are medians of residual-adjusted intake, not crude g/day.
   - `energy_method = residual` and `adj_energy = yes` for both models. Energy is not a covariate.
   - Downstream dose-response analyses should know that the doses are energy-adjusted values.
4. **Adjustment sets.**
   - m1 (base): age in 5-year categories plus ATBC supplement group.
   - m2 (multivariate): adds smoking years (<35/≥35), BMI tertiles, alcohol tertiles, education, occupational physical activity and calcium intake.
   - There is no dietary fibre, fruit/vegetable or meat-mutual adjustment, so `is_mutually_adjusted_processed = no` on every row.
   - The trial supplement group has no flag. It is mentioned in covariates_text.
5. **Denominators.** Only cases per quartile are printed (Table 5), so `denominator_type = none`. Quartiles are cohort-based (27,111 men), so roughly 6,778 men per quartile can be assumed under KODEBOK 4.3.5. Person-years are not printed.
6. **One-decimal rounding.** The paper prints RRs and CIs to one decimal. checks.py flags 8 rows as log-asymmetric (002, 006, 016, 019, 022, 023, 034, 038). All are consistent with rounding of one-decimal values (e.g. 0.6 (0.4–1.0); 1.1 (0.8–1.7)), so they are not treated as typos. Each row has a note.
7. **dose_conversions.** Paper medians are used as `g_day_assigned` for all 10 sets (`midpoint_rule = paper_median`). No conversion is needed. No category bounds are printed.
8. **study.csv.**
   - `diet_instrument = diet_history`: the paper calls it a "self-administered modified dietary history method", 276 foods and mixed dishes plus a picture booklet of portion sizes. Functionally it is a quantitative FFQ.
   - `validation_r` is empty: only fat 0.52, fibre 0.73 and calcium 0.66 are given, none for meat.
   - `baseline_start`/`baseline_end` are empty because recruitment years are not printed. The trial ended 30 Apr 1993, follow-up ran to 30 Apr 1995, mean 8 years.
   - `cases_colon`/`cases_rectum` are empty. 114 colon and 86 rectal cancers were identified *before* exclusions (3 carcinoids, 3 anal canal, 9 without diet data). The post-exclusion split of the 185 is not printed.
   - `in_cup2016 = yes`, `cup_role = dose_response` (from OPPDRAG_tillegg).

## Typos / anomalies
- No apparent typos in the Table 5 meat rows.
- Elsewhere in the paper there are unrelated anomalies:
  - Table 4 vegetables Q3 shows "244" cases, which should be 44. It is not a meat row and was not coded.
  - Table 2 sour milk Q4 multivariate shows "1.1 (0.7–1.3)".


---
# sellers1998
# Sellers 1998 (Iowa Women's Health Study, by family history): extraction notes (opus-H2, 2026-10-30)

Source: Cancer Causes Control 1998;9:357-67, `historisk/sellers1998.txt` (Drive file bazyk1998.pdf). Meat estimates are in Table 3 (p. 362).

## New vocabulary
- `subgroup`: `family_history_negative`, `family_history_positive` (first-degree relative with colon cancer, reported on the 1992 survey).
- `cup_role = pre2010`.

## Scope coded (48 rows)
- Table 3 meat block: total meat, red meat, white meat and nitrate meat × 2 family-history strata × 2 models (age-adjusted, multivariate) × 3 categories, reference rows included.
- Not coded: dairy, sucrose, vegetables and micronutrients (not meat).

## Judgment calls
1. **No unstratified estimates.** The paper reports meat only within family-history strata. `is_main_model = yes` was set on the multivariate model **within each stratum**, so each exposure has two `yes` sets, distinguished by `subgroup`. Analyses that need one row per cohort must choose (or combine) the strata, and must not use this paper together with bostick1994.
2. **Red meat = `red_unprocessed`, `no`.** Footnote g lists "liver, hamburger, beef stew, beef, and venison". Processed meat is the separate "nitrate meat" variable (footnote i: bacon, hot dogs, processed meats). The red-meat variable contains liver (organ) and venison.
3. **Nitrate meat = `processed`, `yes`.** **White meat = `white_meat`** (chicken, tuna, fish, shrimp). **Total meat = `total_meat`, `unclear`**: it is not defined, and its Table 1 mean (13.5 servings/wk) is larger than the sum of the three subtypes (11.3).
4. **Age-adjusted rows have no CI** (only the multivariate column has CIs). They are coded point-only, as in the bostick1994 precedent; checks.py flags them `1_mangler_ci`.
5. **Doses** as printed, in servings/week (e.g. "≤ 3.5" → high 3.5; "3.6-7" → 3.6/7; ">7" → low 7, open). No medians and no grams.
6. **P for trend** is printed once per stratum under the multivariate column. It was put on the multivariate top-category row.
7. **Adjustment (m2).** Age, energy (tertiles) and history of colorectal polyps. No BMI, smoking or other meats.
8. **Overlap with bostick1994.** Same cohort (IWHS) and the same 127-item FFQ. Bostick 1994 followed to 1990 (212 colon cases); Sellers 1998 to 1995 (241 cases), restricted to responders of the 1992 survey. Both carry `cohort_id = iwhs` and must never be in the same pooled analysis.

## Typos / inconsistencies
- No printing errors in the meat block. (Outside scope: Table 3 low-fat dairy prints "2.6-9" and ">7"; Table 4 total vitamin C top age-adjusted RR "0.1" is probably 0.7. Not coded.)
- RRs and CIs have one decimal only. checks.py flags 2 rows as log-asymmetric (sellers1998_005 0.9 (0.7-1.4); sellers1998_011 1.2 (0.7-2.3)); this is consistent with rounding to one decimal, and they are recorded as printed. The 16 `1_mangler_ci` flags are the age-adjusted point-only rows.


---
# singh1998
# Singh 1998 (Adventist Health Study): extraction notes (opus-C, 2026-10-30)

Source: Am J Epidemiol 148:761–774, full text `Understudier WCRF/singh1998.txt`. All numbers come from the full text: Table 3 p. 766, Table 4 p. 767, Results text p. 764–770, Appendix p. 774 (values for Figures 1–3). The study card was opened only to locate tables. No supplement exists.

## New vocabulary
- `subgroup` values (free text, listed for consistency): `white_meat_lt1_week`, `red_meat_lt1_week`, `legume_lt1_week`, `legume_1_2_week`, `legume_gt2_week`, `legume_ge1_week`, `bmi_ge25`, `bmi_lt25`. They are joined with `+` for joint strata. Sensitivity suffixes follow a `;`: `excl_cases_first_2y`, `excl_current_past_smokers_alcohol_consumers`, `physical_activity_high_moderate`, `physical_activity_none_low`.
- `category_set_id` model tokens: `mv` (Table 3/4 covariates), `mv4cat` (four-level categorisation in the text), `fig1`/`fig2`/`fig3` (interaction models). Exposure tokens: `totmeat`, `red`, `white`. For subset analyses the subgroup string is appended after the exposure.
- `source_table = Appendix (Figure N)` for estimates printed in the Appendix. Supplement item 6 applies: the numbers are printed, so they were coded. Nothing was read off the figures.

## Scope coded (72 rows)
- **Table 3, whole population** (9 rows). Total meat, red meat and white meat, each in 3 categories (never, >0 to <1/week, ≥1/week), with cases and person-years. `is_main_model = yes`.
- **Table 4, restricted subsets** (6 rows). Red meat among subjects with white meat <1/week (112 cases), and white meat among subjects with red meat <1/week (82 cases). `is_main_model = no`.
- **Text p. 764/766: "further categorization"** into 4 levels (never, >0–<1, 1–4, >4 times/week) for red and white meat (8 rows, reference rows included). `is_main_model = no`.
- **Appendix: Figure 1** (total meat × legume, 9 cells), **Figure 2** (red meat × legume and white meat × legume, 12 cells), **Figure 3** (red meat × legume × BMI for total, men and women, 24 cells). All of these use the reduced model (age, sex, parental history). `is_main_model = no`.
- **Sensitivity estimates in the text** for the Figure 3 top cell (4 rows): first 2 years of cases excluded; smokers and drinkers excluded; high-moderate vs none/low physical activity strata.
- **Not coded:** legumes, nuts, dairy and the other Table 3 foods. They are not meat (the brief said "legumes if alongside meat"; legumes appear only as a stratifier in the joint cells, which were coded). Nondietary Table 2 factors. Statements without numbers, such as exclusion of the first 2 years "did not substantially alter" Table 3/4 results. No rectum outcome is studied. No poultry-only or fish-only estimates are given; they are combined as white meat.

## Judgment calls
1. **Outcome = `colon`.** The endpoint is primary adenocarcinoma of the colon (ICD-9 153) **including the rectosigmoid junction** (ICD-9 154.0): 135 colon + 22 rectosigmoid = 157 cases. The vocabulary has no "colon + rectosigmoid" value. Note that 22 of the 157 cases (14%) are rectosigmoid.
2. **Red meat = `red_undefined`, `exposure_includes_processed = unclear`.** Table 3 fn # defines it as "Current intake of beef or pork", and the meat questions were "beef (hamburger, steak, other), pork, poultry (chicken, turkey), and fish" (p. 762). Processed meats are neither listed nor excluded, and the Discussion says there are no data on processing (p. 771), so the flag is `unclear` per R6. In practice the exposure is mostly beef: nonvegetarians averaged 14 beef and 1 pork times/month (Table 1).
3. **Total meat = `total_meat`, includes_processed `unclear`.** The meat index is beef, pork, poultry, fish and/or the any-meat question (Table 3 fn ¶). **White meat = `white_meat`** (poultry or fish), includes_processed `no` (no processed meat is mentioned for poultry or fish).
4. **is_main_model.** For each exposure × colon × all, `yes` is the Table 3 whole-population model, which is the paper's fully adjusted model on the full analytic population. Table 4 uses the same covariates but restricts the sample to subjects with low intake of the other meat type. The authors use this restriction in place of mutual adjustment, and the abstract reports the red/white meat results from Table 4 (1.90; 3.29). Even so, it is a subset analysis, and CUP's HvL used Table 3 (1.41). Table 4 is therefore `no`, and the choice is recorded here for the multiverse. **The choice matters**: red meat ≥1/week is 1.41 (0.90–2.21) in Table 3 and 1.90 (1.16–3.11) in Table 4.
5. **Case counts: model vs known intake.** The Cox models keep all 157 cases, because subjects with missing values were retained by the method of Woodward et al. (p. 763). Per-category cases in Table 3 count only subjects with known intake: **total meat 140, red meat 127, white meat 138**. Every Table 3 row notes this. `study.cases_colon = 157` (cases in the model). checks.py's check 5 compares against cup_extraction, so it is not triggered here. Table 4 prints only subset totals (112 and 82), so per-category `n_cases` is empty there and the subset total is in `notes`.
6. **Doses.** `dose_unit = times_week`. Bounds as printed: never = 0/0; ">0 to <1/week" = dose_low empty (the bound is an exclusive 0), dose_high 1; "≥1/week" = 1/open; 4-level "1–4" = 1/4 and ">4" = 4/open. No category medians are printed. The trend test used "the median frequency of consumption for a given intake level" (p. 763), but the values are not given.
7. **Joint-classification cells (Figures 1–3).** Only cells whose reference lies **in the same stratum** form a meat contrast. That is: Figure 1 at legume <1/week; Figure 2 at legume <1/week (within the relevant subset); Figure 3 at legume <1/week and BMI <25. Those cells get a `category_set_id` and rank. All other cells are coded with `contrast_type = category`, an empty set and rank, and a note naming the cross-stratum reference. This keeps every printed estimate without inventing within-stratum contrasts.
8. **Figure 3 (Total), BMI ≥25, red <1/week, legume <1/week, printed "RR = 1.00, 95 percent CI 0.52–1.95".** This is an estimate, not the referent; the referent is BMI <25. Recorded with its CI.
9. **Four-level text estimates (model m3).** The text calls them "further categorization of the red meat … and white meat … variables to higher intake levels" right after describing Table 4. I coded them in the Table 4 subsets. The covariates are not restated, so adjustment set m3 has every flag `unclear`.
10. **Sensitivity rows** use `adjustment_set_id = m2` (Figure 3 model), on the presumption that the covariates are unchanged. Not stated.
11. **Adjustments (m1).** Age, sex, BMI, physical activity, parental history, current and past smoking, alcohol, aspirin → `adj_nsaid = yes`. No energy, fibre, other meats, screening or education. `energy_method = none`.
12. **Study-level.** `followup_years = 6`, `followup_type = unclear`: the follow-up runs from questionnaire return in 1976–77 to 1 Jan 1983, about 6 years; the mean is not printed. `outcome_ascertainment = mixed`: hospitalisation questionnaires with chart review, plus linkage to tumour registries. `validation_r` is empty because no coefficient matches the "red meat" variable exactly. The beef index is 0.49 and the meat index 0.83 (p. 763); both are in the notes. Age range "25+": the questionnaire went to persons aged 25 or older, and the mean age was 52–54.

## Typos and text–table disagreements (recorded as printed)
- **Total meat ≥1/week**: the abstract prints "1.85, 95% CI 1.19–2.87"; Table 3 prints "1.85 (1.16–2.87)". The Table 3 value was coded (row `singh1998_003`), and the disagreement is noted on the row. On the log scale the abstract CI is the more symmetric one (1.19 → asymmetry ≈0.05 vs 1.16 → ≈0.13), so 1.16 may be the misprint.
- **Abstract vs table, category label**: the abstract writes ">1 time/week" for the top category; the tables use "≥1/week" (OCR shows "2:1", "a 1", "i1"). Table labels were used.
- **Abstract, BMI**: the abstract says "fertile" for "tertile". Not a meat row.
- **Sex distribution**: the text (p. 764) says the meat-intake groups did not differ by sex, while Table 1 shows 39%/37%/55% male across vegetarian/occasional/nonvegetarian. Not a meat estimate, but noted.
- **White meat >4 times/week**: "2.74, 95 percent CI 0.37–20.19". The CI is extremely wide but internally consistent, so it is recorded as printed.
- checks.py raised no CI-symmetry flags.

## Portion size / grams
- The FFQ is "semiquantitative" (55 items), but **no portion sizes in grams** are printed and no category medians are given. `g_day_assigned` is left empty in all 13 dose_conversions rows. The only quantitative intake information is Table 1: mean times/month of beef, pork, poultry and fish by meat group (nonvegetarians 14/1/3/2).
- `weight_basis = unclear`.


---
# spencer2010
# NOTES – spencer2010 (UK Dietary Cohort Consortium)

Extractor: opus-I · 2026-10-30 · Source: `post2015/spencer2010.txt`. The "Table 2 continued" page (fatty fish, p. 1423) is printed rotated, and the txt layout is scrambled. Those numbers were read from the rendered PDF page `pdf_in/spencer2010.pdf` p. 7 and agree with the fragments in the txt.

## New vocabulary
- **`cohort_id = uk_dcc`.**
- **`category_set_id` gets a suffix `_whitefish` / `_fattyfish`,** because two fish variables share the `fish` exposure code.

## Contents (93 rows)
- **Table 2 (pp. 1422–1423): 6 exposures × 3 outcomes × (4 categories + 1 per-50 g/day row) = 90 rows.**
  - Exposures: red meat, processed meat, red and processed meat, poultry, white fish, fatty fish.
  - Outcomes: colorectal, colon, rectum.
- **Results text (p. 1420): total meat (red + processed + poultry) per 50 g/day,** colorectal 0.90, colon 0.94, rectum 0.82 = 3 rows.

## Not coded
- **Sensitivity analyses in subsets with extra covariates** (education, SES, physical activity, family history, aspirin): "no material difference", no numbers.
- **Fibre-stratified analyses:** only a p-trend range, 0.18–0.89.
- **Exclusion of the Oxford Vegetarian Study:** "did not alter the results".

## Judgment calls
1. **Exposure mapping:**
   - **Red meat → `red_unprocessed`.** The paper explicitly excludes processed red meat and offal (p. 1419).
   - **"Red and processed meat" → `red_total`.**
   - **White fish and fatty fish → `fish`** (shellfish excluded).
   - Poultry → `poultry`, `includes_processed = unclear`. It includes "the flesh component of products made with poultry".
2. **is_main_model = yes on all Table 2 rows (category and per-50 g) and the total-meat text rows.** The paper has a single multivariable model. Within each exposure × outcome, the category set and its continuous row come from the same model. For `fish`, two variables (white, fatty) are both `yes`, because they are distinct exposures that share a code. The analyst must choose between them.
3. **Denominator = controls** (`n_controls`, `n_in_category`), as instructed. Cases/controls are printed per category. Sums: colorectal 579/1996; colon 380/1316; rectum 199/680 for every exposure. The colon and rectum totals are not printed as such; they are derived and agree across all 6 exposures.
4. **Dose.**
   - Bounds as printed: "<5" → `dose_high = 5`; "5–<25" → 5/25; "≥50" → `dose_low = 50`.
   - Medians per category (`paper_median`) are printed, including for open categories, so `dose_conversions` uses them directly (`g_day_assigned`).
   - **Intakes are disaggregated meat weights** from composite foods. The paper notes these are 50–70% lower than whole-dish estimates for red meat (Discussion).
5. **p_trend.** It is computed on the continuous variable (Table 2 **), so the same p is on the top-category row and the per-50 g row.
6. **Total-meat text rows.** The model is assumed to be the Table 2 model. Cases and controls per outcome are taken from the Table 2 totals.
7. **Adjustment.**
   - Height and weight are in categories, not BMI, so `adj_bmi = no`.
   - Matching on cohort is coded `adj_stratified_center = yes`.
   - Diary coding program is controlled by design.
   - `energy_method = covariate` (sex-specific fifths).
8. **Study fields.**
   - **design = `nested_cc`; diet_instrument = `mixed`.** Food diaries of 4, 5 or 7 days; the vocabulary has no "food diary" value.
   - baseline_start/end = 1985–2003 (span of diary completion).
   - followup_years empty. Only per-cohort mean time to diagnosis is given (3.0–8.5 y).
9. **Overlap.** EPIC-Norfolk and EPIC-Oxford are EPIC sub-cohorts (norat2005). EPIC-Oxford and the Oxford Vegetarian Study are also in key2014.

## Printed anomalies
- **None found.** Every CI is roughly log-symmetric (`checks.py` gives 0 flags apart from unverified). Text numbers (abstract and Results) match Table 2: red 1.01, processed 0.88, red+processed 0.97, poultry 0.80, white fish 0.92, fatty fish 0.89, rectal processed ≥30 0.50, fatty fish ≥30 0.73.


---
# takachi2011
# takachi2011 – coding notes (extractor opus-P2, 2026-10-30)

Source: `Understudier WCRF/takachi2011.txt` (Asia Pac J Clin Nutr 2011;20(4):603–612). All numbers come from the full text. I opened the study card only for orientation and copied no numbers from it.

## Coverage
- Table 2 (p. 607): 6 exposures (total meat, red meat, beef, pork, processed meat, chicken) × 2 sexes × 2 outcomes (colon, rectum) × 5 quintiles = 120 rows.
- Table 3 (p. 608): the same 6 exposures × 2 sexes × 2 sub-sites (proximal, distal colon) × 5 quintiles = 120 rows.
- Text-only Q5-vs-Q1 or D10-vs-D1 estimates (contrast_type `hvl`, is_main_model `no`) = 19 rows:
  - heme-iron-adjusted and SFA-adjusted models (p. 605), 4 rows
  - age strata (p. 606), 4 rows
  - smoking strata for processed meat (p. 606), 2 rows
  - invasive colon only (p. 607), 3 rows: men, women and sexes combined
  - decile analyses (pp. 607–608), 6 rows
- Total: 259 estimate rows.
- Not reported in the paper, so not coded: a combined colorectal outcome, any continuous (per-g) estimate, any substitution estimate, any sex-combined quintile analysis except invasive colon ("data not shown", p. 605), the age+area model, and the model without dried/salted fish.

## Exposure definitions
- **Red meat** (p. 604): "3 beef dishes …, 6 pork dishes … (incl. pork liver), 4 processed meat products (ham, sausage or Weiner sausage, bacon, and luncheon meat), and chicken liver."
  - Table 1 also lists Processed meat as a sub-row under "Red meat".
  - Coding: `red_total`, `exposure_includes_processed = yes`, `studies.includes_processed = yes`.
  - The variable also contains two organ meats, pork liver and chicken liver (chicken liver is poultry offal).
- **Total meat**: no explicit definition. The FFQ has 16 meat items: 14 "red meat" items plus 2 chicken meals. I assume total meat = all 16. It includes processed meat, so it is coded `yes`.
- **Beef** = 3 beef dishes and **Pork** = 6 pork dishes (incl. pork liver). Both coded `exposure_includes_processed = no`, because ham and bacon are listed as separate processed items. Note that pork includes liver.
- **Chicken** (coded `poultry`) = grilled and deep-fried chicken only. Chicken liver sits in red meat.
- **Heme iron** is used only as a covariate (p. 605). No meat-style heme-iron exposure estimates are reported, so none are coded.
- **Fish**: only "dried and salted fish" appears, as a covariate. No fish exposure estimates.

## Doses: watch the variable-specific medians
- Table 2 prints a separate quintile-median column for each meat variable and each sex. The men's median sits left of the men's columns. The women's median sits mid-row: in the text file the women header line is shifted, but the values align.
- Red meat medians: men 15/31/46/65/102 and women 14/29/43/60/93 g/day.
  - These match Table 1 exactly.
  - Text p. 605 gives Q1 more precisely as 15.4 (men) and 13.6 (women) g/day. Rows use the table values.
- Total meat medians differ: men 20/39/56/77/117 and women 18/36/52/70/107. They must not be attached to red meat.
- Bounds (`dose_low`/`dose_high`) exist only for red meat, from Table 1 (men <24.1, 24.1–38.8, 38.8–54.6, 54.6–78.7, ≥78.7; women <22.0, 22.0–35.8, 35.8–50.4, 50.4–71.8, ≥71.8). For the other variables the bounds are empty because the paper does not print them.
- Table 3 prints no medians. Table 3 rows carry the Table 2 medians for the same variable and sex (stated in notes), on the assumption that Table 3 uses the same sex-specific quintiles. The paper implies this ("further analysis") but does not state it.
- Discussion p. 609 gives "corrected median" Q5 values of 120 (men) and 105 (women) g/day, based on weighed dietary records. These are given only for Q5, so they are recorded in `dose_conversions.notes` and not in estimates.
- Medians are of energy-adjusted (residual-method) intake (pp. 605, 607 footnote).
- `weight_basis = unclear`. Grams come from dish-based standard portions, and the paper does not say raw or cooked.

## Cases and denominators
- Totals (p. 604), and every Table 2/3 category set sums exactly to its total:

  | | Colon | Rectum | Proximal colon | Distal colon |
  |---|---|---|---|---|
  | Men | 481 | 233 | 200 | 257 |
  | Women | 307 | 124 | 179 | 110 |

- Proximal + distal (457 men, 289 women) is less than total colon (481, 307). That leaves 24 and 18 colon cases with unspecified or overlapping sub-site. The paper does not explain this.
- Men's red meat colon cases by quintile: 103/103/90/94/91. Women's: 63/67/39/68/70.
- Person-years are reported only per sex (354,987 men and 403,129 women), not per quintile. `person_years` is therefore empty everywhere.
- For red meat only, `n_in_category` = "No. of subjects" per quintile from Table 1:
  - men 7,692/7,693/7,692/7,693/7,692
  - women 8,439/8,439/8,440/8,439/8,439
  - `denominator_type = n_participants`
  - Judgment call: these are persons, not person-years. Equal-sized quintiles make this nearly equivalent for Greenland–Longnecker.
- Other exposures use `denominator_type = none`. Quintiles are presumably equal-sized, but the paper does not print counts.
- Age strata (p. 606): stratum colon totals are men ≥60 = 259, <60 = 222; women ≥60 = 152, <60 = 155. These are recorded in notes, because no per-quintile cases are given. The 259 figure is the ≥60 stratum, not men's total colon cases (481).
- Invasive colon: 269 men + 186 women (p. 607). The combined row's 455 is my sum.

## Models and is_main_model
- Methods (p. 605) describe three steps:
  - m1: age + area
  - m2: "second multivariate model" with BMI, smoking, alcohol, PA, diabetes, screening, and quintiles of energy, calcium, vitamins D and B-6, folate and fibre
  - m3: m2 + quintiles of dried and salted fish
- The Table 2/3 footnotes list the m3 covariates, so Tables 2 and 3 are m3. m3 is `is_main_model = yes` for every outcome × sex: colon, rectum, proximal and distal, each by sex. m1 and m2 results are not reported. m2 appears only as "data not shown" (associations among women were weaker without the fish adjustment).
- m4 (+ heme iron) and m5 (+ saturated fat) are mediator sensitivity models. Both are `is_main_model = no`, per KODEBOK 4.2. How heme iron and SFA were entered (quintiles or continuous) is not stated.
- The model for the stratified, invasive and decile estimates is described only as "multivariate", so I assume m3 and note this on each row.
- `adj_fish = yes` in m3–m5 refers only to dried and salted fish (a proxy for N-nitroso compounds), not total fish.
- `adj_sex = no`: all analyses are sex-specific, apart from the one sex-combined invasive estimate, where the paper does not say whether sex was adjusted for.
- `adj_stratified_center = yes`: PHC area entered as a covariate (10 districts).
- `energy_method = residual`. Energy quintiles were also entered as a covariate.
- Not adjusted for education, family history, NSAIDs or fruit/vegetables. HRT and cholesterol-lowering medication were tried in a sensitivity analysis whose results are "data not shown" (p. 606), so they are coded `no` in m3.
- `is_mutually_adjusted_processed = no` throughout. Processed meat is inside the red meat variable, and no meat type is adjusted for another.

## Contrast assumptions for text estimates
- Age strata: the text says "Corresponding HRs" right after describing the highest-vs-lowest framing. I coded Q5 vs Q1, but the quintile basis is assumed.
- Smoking strata (processed meat, men): the contrast is not stated. I assumed highest vs lowest quintile.
- Deciles: highest vs lowest decile is explicit. Decile medians and cases are not given. The decile result for red meat and colon is not reported, only processed meat for colon and red/processed meat for rectum.
- Sex-combined invasive colon (1.30; 0.94–1.78): the paper does not say whether quintiles were sex-specific or combined. `dose_point` is left empty.

## Inconsistencies, typos and format notes
- Start of baseline: methods say 1995–1999 (p. 604), the abstract says 1995–1998, and the table titles say "1995 and 1998". `baseline_start`/`baseline_end` = 1995/1999, following the methods.
- Follow-up length is not reported. 758,116 / 80,658 ≈ 9.4 y (my computation, not coded; `followup_years` is empty).
- Discussion p. 609 compares "lowest quartile groups (15 and 14 g)" and "our highest quartiles of processed meat" (p. 610). The analysis uses quintiles, so "quartile" is a wording slip. The numbers match the quintile medians.
- Table 3: two CI bounds are printed with one decimal, total meat women distal Q3 "(0.55, 2.1)" and Q4 "(0.96, 3.3)". They are recorded as printed and flagged in notes.
- Table 1 prints saturated fat for men Q4/Q5 as 17.89/22.28, with inconsistent decimals. This is irrelevant for coding.
- checks.py found no CI-asymmetry flags, no reference or dose-order problems, and no missing adjustment sets.
- The abstract numbers match Table 2: women red meat colon 1.48 (1.01, 2.17), p = 0.03; men total meat colon 1.44 (1.06, 1.98), p = 0.07.
- DOI and PMID are not in the full text, so those fields are left empty.
- `in_cup2016` and `cup_role` come from the study card, not from the paper.


---
# tammi2024
# Tammi 2024 (pooled Finnish cohorts) – extraction notes (opus-G, 2026-10-30)

Source: /home/claude/drive/post2015/tammi2024.txt (Europe PMC full text; Eur J Epidemiol 39(4):419-428). The txt has no journal page numbers, so `source_page` gives the txt line (`txt l.N`). No supplement file exists. Online Resources 1-5 (quintile tables, cohort-specific HRs, the excluding-ATBC table) are not available.

## New vocabulary
- `dose_unit`: `per_100g_week`, `per_50g_week` and `per_200g_week`. The paper's increments are per WEEK. Using `per_100g` / `per_50g` would silently mean per day, so new values are needed.
- `cohort_id = finnish_pooled` on all rows (already in cohorts.csv). No per-cohort (ATBC etc.) estimates are printed in the main text, so no `atbc` rows exist.
- Subgroups: `excl_atbc`, `wg_lt_median`, `wg_ge_median` (total-population median whole grain intake 587 g/week).

## Scope coded
- **Direct meat–CRC estimates (Results text, txt l.312; tables in Online Resource 4)**: red meat Q5 vs Q1 (model 2); processed meat Q5 vs Q1 (model 2); red meat per 100 g/week (model 2); processed meat per 50 g/week (model 1). That is 4 rows.
- **Table 3 substitutions**: red meat (100 g/wk) and processed meat (50 g/wk) replaced by whole grains, vegetables, fruits or the three combined, each under model 1 and model 2. That is 2 × 4 × 2 = 16 rows.
- **Excluding ATBC** (text l.342): 4 red meat substitutions, model 2.
- **Doubled substitutions** (text l.344): red meat 200 g/wk with vegetables, fruits or combined (3 rows), and processed meat 200 g/wk with vegetables or fruits (2 rows).
- **Whole-grain interaction** (text l.346): red and processed meat → whole grains, in the < median and ≥ median strata. That is 4 rows.
- Total: 33 estimate rows.

## Not coded
- Legume, fruit, whole grain and vegetable single-food estimates (not meat).
- Excluding-ATBC processed-meat substitutions ("essentially the same"; no numbers).
- Processed meat 100 g/week substitutions ("borderline 2%"; no numbers).
- Sensitivity analyses excluding low consumers / first 2 years, interactions by sex/age/BMI/HRT/follow-up ("data not shown" or P only).

## Judgment calls
1. **Red meat = `red_unprocessed`.** The paper defines it as beef, pork and lamb, with processed meat (sausages, cold cuts) a separate group; red and processed meat are studied separately. Online Resource 2 holds the full food list, which is not available.
2. **Direct estimates use `hvl` for Q5 vs Q1.** Only the top-vs-bottom quintile is printed in the main text; the full quintile series is in Online Resource 4.
3. **is_main_model for the direct estimates.**
   - Red meat: both model-2 rows (Q5 vs Q1, and per 100 g/week) are `yes`. They come from the same model and are different contrast types.
   - Processed meat: the per-50 g/week value is printed only for **model 1** ("statistically significant only in model 1"). That row is `no`, and the model-2 Q5 vs Q1 row is `yes`.
   - This deviates from supplement rule 2, which makes an HvL-only model `no`. The deviation is deliberate: the model-2 HvL is the paper's most-adjusted printed estimate for processed meat, and the model-2 per-unit value is not printed. If the controller prefers strict application, set tammi2024_002 to `no`.
4. **Substitution rows.** Model 2 Table 3 rows are `is_main_model = yes` (8 rows). This is the paper's primary substitution model, one per meat × substitute. All other substitution rows (model 1, excluding ATBC, doubled, whole-grain strata) are `no`. Any pooling must filter on `contrast_type = substitution`, so substitution rows never compete with the direct-association main rows.
5. **category_set_id for substitutions**: `tammi2024_<m3|m4>_colorectal_all_<red|proc>_sub_<substitute>_<amount>[_<subgroup tag>]`. Here m3 = model 1 and m4 = model 2 in substitution form.
6. **Adjustment sets.** m1/m2 cover the single food-group models and m3/m4 the leave-one-out substitution models, with the same covariates. `adj_family_history = unclear`: only ATBC had family history, and the Methods say ATBC substitution analyses were adjusted for it, while the Results describe it as a check ("data not shown"). `adj_stratified_center = yes` because it is a two-stage pooled analysis with each cohort analysed separately.
7. **n_cases / denominator.** Pooled rows carry the 1124 cases and 43,788 participants (`denominator_type = n_participants`). Excluding-ATBC and whole-grain stratum rows leave n_cases empty because no count is printed. Table 1 implies 175 non-ATBC cases.
8. **P-values.** `p_value` holds the printed P for the estimate. `p_trend` is used for the red meat Q5 vs Q1 "P-trend = 0.041". The processed-meat Q5 vs Q1 sentence prints "P = 0.026" without "trend"; it is placed in `p_trend` by analogy and flagged.
9. **weight_basis = raw.** Mixed dishes were "decomposed into ... uncooked red meat"; processed meat is counted "as such".
10. **Doubled-substitution rows.** These are a rescaling of the Table 3 model-2 estimates; the P-values are identical. They are coded because they are printed, but they are not independent information.

## Printed anomalies
- **Excluding ATBC, red meat → combined: "0.97, 0.93 − 0.99, P = 0.004".** The CI is asymmetric around 0.97 (lower arm 0.04, upper arm 0.02). Given P = 0.004, the point is probably 0.96. Recorded as printed. checks.py may flag it.
- **Processed meat per 50 g/week (model 1) "P = 0.027".** This is identical to the red meat model-2 P in the same sentence. It may be correct or a copy; recorded as printed.
- **Units.** The abstract and text speak of "1% risk reductions" for processed meat; printed HRs are 0.99 (0.98–1.00). These CIs touch 1.00 yet are reported as significant (P 0.029/0.036), which is a rounding effect and not a typo.
- **Median follow-up 28.8 y.** This is the pooled median, which is ATBC-dominated. Non-ATBC cohort medians are 7.8–15.2 y.

## checks.py (scratch copy, 2026-10-30)
- 2_asymmetrisk_ci on 9 rows (007, 010, 011, 013, 022, 024, 025, 026, 029).
  - All except 024 are explained by two-decimal rounding of very narrow CIs around HRs near 1. For example, 0.97 (0.94-0.99) is asymmetric only because each arm is 0.02-0.03 wide.
  - tammi2024_024 (excluding ATBC, red meat → combined, "0.97, 0.93 − 0.99", asym 0.52) is the real anomaly noted above.
- 9_uverifisert: 33 rows (expected).

## Supplement rows (30.10)

Extractor opus-S2, 2026-10-30. Source: `/home/claude/drive/supplements/tammi2024_OnlineResources.txt` (pdftotext of `suppl_in/tammi2024_OnlineResources.pdf`). OR1-OR3 hold flow chart, food lists and model formula (no estimates). Meat × CRC estimates are in OR4 and OR5.

**Added: 26 rows (tammi2024_034 – 059); 6 dose_conversions rows (dc05–dc10).**
- **OR4 (14 rows).** Quintile sets for red and processed meat under models 1 and 2 (12 rows). **OR4 prints only Q1, Q3 and Q5** (Q2 and Q4 are absent), so `category_rank` = 1, 3, 5 (checks.py 4_rank_hull flags this, as expected). Medians (g/week) are in `dose_point` (`paper_median`), IQR in notes, and cases per quintile in `n_cases`. No person-years or participants per quintile (`denominator_type = none`). Two continuous rows were not in the main text: red meat per 100 g/week **model 1** 1.04 (1.01, 1.07) and processed meat per 50 g/week **model 2** 1.01 (1.00, 1.02), P 0.1.
- **OR5 (12 rows).** Substitutions in ATBC alone: 8 rows, `cohort_id = atbc`, `sex = men`, new subgroup `atbc_only`. Processed-meat substitutions in the remaining 4 cohorts: 4 rows, `finnish_pooled`, `excl_atbc`. The main text gave no numbers for these. The 4 remaining-cohorts red-meat rows in OR5 are identical to tammi2024_021–024 and were not re-coded.
- Whole grains, vegetables, fruits and legumes rows in OR4 are not meat and were not coded.

**Judgment calls**
1. **is_main_model.** Model-2 quintile sets (038–040, 044–046) = `yes`, since this is the paper's most-adjusted model for the category contrast. The new processed meat model-2 per-50 g/week row (047) = `yes`, since it is the most-adjusted per-unit estimate; 004 (model 1) stays `no`. The existing hvl rows 001/002 remain `yes`. Their Q5-vs-Q1 values are the same estimates as rows 040/046, and the row notes say "do not count both". Substitution rows remain `no` (K8 harmonisation).
2. **ATBC substitution rows:** `sex = men` and `category_set_id` uses `_men_`. n_cases is empty (949 ATBC cases from main Table 1 are given in notes only).
3. **Dose conversions.** Quintile medians are divided by 7: red meat 33.4 / 66.7 / 122.9 g/d; processed meat 15.3 / 51.3 / 130.9 g/d. Red meat is raw weight.

**Flags resolved by the supplement (notes appended to existing rows, allowed exception)**
- tammi2024_002: 0.026 is printed in OR4's **Ptrend** column, so placing it in p_trend was correct.
- tammi2024_004: "P = 0.027" is genuine. Processed meat model-1 per-unit and red meat model-2 per-unit both have P 0.027.
- tammi2024_024 (excl. ATBC, red → combined, 0.97 (0.93-0.99), P 0.004) is printed identically in OR5, so the asymmetry is in the source and not resolved.

**Contradictions with the main text:** none found. The OR4 model-2 Q5 values and the per-unit values match the Results text exactly.


---
# thun1992
# Thun 1992 (CPS-II mortality cohort) – extraction notes (opus-W1, 2026-10-30)

Source: historisk/pdf/thun1992_full.txt (pdftotext -layout). Tables 4–6 were checked against PDF pages 5–6 (journal pp. 1495–1496), rendered at 200 dpi. Every number matches the image. The txt garbles several cells, e.g. ".0" for 1.0, "0.72-130", "131", "039-0.86"; the image values were used.

## New vocabulary
- `cohort_id` = `cps2_mortality` (proposed row in `cohort_row.csv`).
- `exposure` = `total_fat` (Tables 5–6). This is outside KODEBOK R1 and was coded because the caller asked for it. Drop these rows (thun1992_021–040) if fat is not wanted.

## Cohort relationship
- CPS-II is the 1982 American Cancer Society mortality cohort (1,185,124 enrolled; 764,343 in the analytic cohort here).
- The existing `cps2` (CPS-II Nutrition Cohort; Chao 2005) is a later subset of CPS-II participants. This is background knowledge, not stated in Thun 1992.
- Proposed row: `cps2_mortality`, overlaps_with = `cps2`. The two must never be pooled together. One could also set `cps2.parent_cohort_id = cps2_mortality`.

## Contents (40 rows)
- **Table 4** (unadjusted RR by food-group quintile; Q1 = reference): 20 rows.
  - "Fatty meats" and "Chicken and fish", 5 quintiles × men/women.
  - **No CIs are printed.** checks.py flags these as `1_mangler_ci`, which is expected.
- **Tables 5–6** (total fat as nutrient index, quintiles): 20 rows.
  - Unadjusted RR without CI: 10 rows.
  - Adjusted RR with 95% CI: 10 rows. The trend test is printed only as "NS".
- **No multivariable red-meat estimate exists.** Results and Abstract say only "No associations were seen with consumption of red meat or total or saturated fat in either sex", with no numbers.
- Individual meats (beef, pork, ham, processed meats, chicken, fish) are described qualitatively in text ("not shown but available on request").
- Saturated fat has no numbers.
- Outcome is fatal colon cancer (ICD-9 153) in both sexes. There is no rectum or colorectal outcome.

## Judgment calls
1. **"Fatty meats" coded as `red_total`, includes_processed = yes.** The items are beef, pork, ham, liver, smoked meats, fried bacon, fried hamburger and frankfurters/sausage (Table 1). Caveats:
   - It includes liver (organ meat).
   - There is no lamb item.
   - Frankfurters/sausage may contain poultry.
   - The paper's Discussion treats it as an index of red meat consumption.
   - Norat 2002 (synthesis_extraction.csv) transcribed the Q5 values 1.21 (men) and 1.05 (women) as "red meat".
2. **"Chicken and fish" coded as `white_meat`** (Table 1 heading "Low-fat meats"). It is a negative control. It cannot be split into poultry and fish.
3. **effect_measure = OR.** The paper estimates RRs with conditional-logistic odds ratios from incidence-density-sampled controls, and prints them as "RR".
4. **is_main_model = yes on the Table 4 meat rows.** They are the only estimates for these exposures, even though they are crude: matched only on exact age, race and sex, and not adjusted for anything else. Any analysis that requires adjusted estimates must exclude them via adjustment_set_id `thun1992_m1`. For total fat, the adjusted rows (m2) are main and the unadjusted rows are `no`.
5. **Doses.** Quintiles are built on summed weekly frequency (days/week). No cut points, medians, portion sizes or per-quintile case counts are printed for the food groups, so dose_low/high/point are empty and `dose_unit = times_week`. The fat index is in g/week, also without cut points. `g_day_assigned` is empty in every dose_conversions row. Without external assumptions, this study cannot enter a dose-response analysis.
6. **n_cases.** Only the total-fat rows have per-quintile cases (they sum to 611 men and 539 women). Table 4 rows have none.
7. **study.csv**:
   - `n_participants` = 764,343 (analytic cohort). The case-control set is 1150 cases + 5746 controls.
   - `followup_years` = 6, `type` = max (1 Sep 1982 – 31 Aug 1988).
   - `outcome_ascertainment` = `active_followup`: volunteer inquiry plus death certificates.
   - DOI and PMID are not in the text and were left empty.
   - `in_cup2016` = unclear and `cup_role` is empty, because neither can be determined from the paper.
8. **Case count trap for anyone matching CUP or Norat:** 2757 is the number of colon-cancer deaths in the whole cohort before exclusions (Table 2). The analysis uses 1150.


---
# tiemersma2002
# Tiemersma 2002 (MONICA-NL / Monitoring Project on CVD Risk Factors) – extraction notes (opus-A, 2026-10-30)

Source: `Understudier WCRF/tiemersma2002.txt` (Cancer Causes Control 2002;13:383–393). Table 2 is on p. 388 and Table 5 on p. 391; the Results text is on p. 386 and the abstract on p. 383. No study card was used.

## New vocabulary
- `dose_unit = ever_never` for the "Sausage as a snack" yes/no rows.

## Design
- This is a nested case–control study: 102 cases and 537 controls, frequency-matched on sex, 5-year age band and centre.
- The denominators are controls. Every Table 2 row has `n_in_category` = controls and `denominator_type = n_controls`, with `n_cases` from the printed "cases/controls".
- `effect_measure = OR`.

## Scope coded (107 estimate rows)
- **Table 2 (m1).** 6 exposures × 3 sexes (total population, women, men). All rows are colorectal (no subsite tables).
  - Total meat, fresh red meat, poultry and fish have 3 categories each.
  - Sausage as a snack and sandwiches with meat filling have 2 categories each.
  - Total: 4×3×3 + 2×2×3 = 48 rows.
- **Highest-vs-lowest rows from the text/abstract: 5 rows (`hvl`).**
  - fish, colon (all): 0.5 (0.3–0.9)
  - fish, rectum (all): 1.6 (0.7–3.6)
  - fish, colon (women): 0.4 (0.1–0.9)
  - fresh red meat, colorectal, excluding those <50 y at end of follow-up: 2.0 (1.1–3.8)
  - abstract "poultry and fish" in women: 0.5 (0.2–1.07), see below
- **Table 5 genotype strata: 54 rows.** Fresh red meat, poultry and fish (3 categories each) × NAT1 (slow+normal / fast), NAT2 (slow / fast+intermediate) and GSTM1 (present / null).
- **Not coded:**
  - smoking tables (Table 3)
  - genotype main effects (Table 4)
  - smoking × genotype (Table 5, lower half)
  - interaction p-values. GSTM1 × poultry p = 0.01 is recorded in the row notes.
- The two-year-exclusion and 1998-exclusion sensitivity analyses report "only marginally changed" with no numbers, so they are not coded.

## Judgment calls
1. **Fresh red meat = `red_unprocessed`, `includes_processed = no`.** It is the "summation of reported beef and pork intake" frequencies (p. 385). The meat snacks and sandwich fillings were asked separately. The Discussion notes that minced meat (a beef/pork mix) may have been missed.
2. **Total meat = `total_meat`, `includes_processed = unclear`.** It is the sum of frequencies of "all meat types consumed", which includes beef, pork, poultry and fish. Whether meat snacks are added is not stated.
3. **Processed-meat proxies.**
   - "Sausage as a snack" (yes/no) is coded `processed`, `yes`, `ever_never`.
   - "Sandwiches with meat filling (number/day)" is coded `processed`, `partial`, `servings_day`. The paper says this category "comprised processed as well as fresh meats".
   - Both share `exposure = processed`. Sausage is `is_main_model = yes`. Sandwiches are `no`, so that only one processed main set exists per sex. This is a choice; sandwiches could be argued instead.
4. **Main model.** Table 2 (age, sex, centre, energy, alcohol, height) is the paper's only multivariate meat model. It is `yes` per exposure × sex for all, women and men.
   - Rows marked `no`: the text/abstract HvL rows (reported only as highest vs lowest, or as sensitivity/subsite analyses) and all Table 5 genotype rows.
5. **Sex-stratified rows.** These are `sex = women` / `men`. The paper's p-values for trend for each sex are on the top-category rows.
6. **Table 5 joint-reference structure.**
   - Each gene × exposure block has **one common reference**: the "low-risk" genotype and the lowest exposure.
   - I split each block into two category sets, one per genotype, with the genotype in `subgroup`.
   - In the non-reference genotype set, rank 1 is that genotype at lowest exposure *relative to the common reference*, so its point is not 1. checks.py flags this 8 times (`3_referanse_ikke_1`). That is expected and is explained in each row's notes.
   - Cases and controls per cell are not printed, so `denominator_type = none`.
   - Table 5 has no sex strata.
7. **Category bounds as printed.**
   - Red meat 0–3 / 3.1–4.5 / 5+ times/week, with a gap between 4.5 and 5.
   - Poultry and fish 0–1 / 1–4 / 4+ times/month, with overlapping endpoints.
   - Total meat 0–3.9 / 4–5.9 / 6+.
   - Frequencies were assigned FFQ class medians (e.g. 2–4/week → 3), so the values are discrete.
8. **Outcome for "rectum or rectosigmoid" (39 cases)** is coded `rectum` (fish rectum HvL row), with a note.
9. **Study fields.**
   - `n_participants` = 639 (102 + 537 analysed). The parent cohort is >36,000.
   - `followup_type = unclear`: the abstract's "8.5 years of follow-up" is not specified as a mean or median.
   - `validation_r` is empty: it is sex-specific (0.49 men, 0.40 women vs dietary history).

## Typos and inconsistencies (recorded as printed)
- **Abstract "poultry and fish decreased risk among women (OR 0.5; 95% CI 0.2–1.07)"** (row tiemersma2002_053).
  - It matches no Table 2 cell exactly. Women poultry 4+ is 0.5 (0.2–1.1), and women fish 4+ is 0.5 (0.2–1.0).
  - No combined poultry + fish variable is reported anywhere.
  - Coded as `white_meat`, `hvl`, with a flag. It is possibly an unrounded version of one of the two cells.
- **Fish 4+ total population "0.7 (0.4-1.3)"** uses a hyphen where all other cells use an en dash. This is cosmetic.
- **Table 5 GSTM1 present, poultry 4+: "0.4 (0.2–0.98)"** has a two-decimal upper limit (to show significance). Recorded as printed.
- **The red meat median frequencies in the Discussion** ("median intake 4 times a week, interquartile range 2–6" in men, "3.5, 2–4" in women) are descriptive, not category medians.
- The checks.py asymmetry flags (0.15–0.42) are all on one-decimal values with small cells, consistent with rounding.
- The Table 2 case/control sums check out: 102/537 for every exposure and sex. Women 48 cases + men 54 = 102.

## Doses / conversions
- 15 conversion rows (the frequency category sets in Table 2). All have `g_day_assigned` empty: there are no category medians and no gram portions.
- Portion sizes came from the NEVO 1993 table, but the values are not printed.
- Overall mean g/day for controls (Table 1): total meat 80.4, red 42.8, white 25.2, processed 26.9.

## Study-level
- DOI 10.1023/a:1015236701054 and PMID 12074508 are taken from the reference list in lee2009.txt (ref 11). They are not printed in this paper's text file; verify them.
- `in_cup2016 = yes` and `cup_role = dose_response` are taken from the brief's list.


---
# vulcan2017
# Vulcan 2017 (MDCS): extraction notes (opus-V1, 2026-10-30)

Source: /home/claude/drive/post2015/sok2026/vulcan2017.txt. This is Europe PMC XML-stripped text (PMC5533139). The citation is Food Nutr Res 2017;61:1341810, an article number with no page range, so `source_page` names the table. The supplement (Suppl-Meat_processed.docx: S1 correlations, S2 BMI-interaction) is not in the txt and is not coded.

## Transcription
The 105 quintile rows and 21 p-trend rows of Tables 2–4 were typed into a scratch file and checked by script against the token sequence in the txt. They match exactly. The only differences are two printed stray commas in person-years ("84 ,071", "50 ,640").

## New vocabulary
- None. Subgroups used are `excl_dietary_change`, `excl_prevalent_cancer` and `excl_diabetes` (text-only sensitivity rows).

## Scope coded (633 rows)
- **Tables 2 (colorectal), 3 (colon) and 4 (rectum)**: 7 exposures × 3 sexes (all, women, men) × 2 models (basic, full) × 5 quintiles = 630 rows. The 7 exposures are total red meat, beef, pork, unprocessed red meat, processed red meat, poultry and fish. Every set has Q1 as the reference (1.00), cases, person-years and the printed quintile median.
- **Text, Sensitivity analyses**: 3 Q5-vs-Q1 rows (`hvl`, is_main_model = no):
  - pork CRC excluding dietary change: 1.15 (0.86–1.52)
  - beef colon, men, excluding prevalent cancer: 0.56 (0.36–0.88)
  - processed CRC, men, excluding diabetes: 1.05 (0.71–1.56)
- **Not coded** (no numbers printed): the model without BMI, the models with extra dietary confounders, the models with diabetes, and the mutually adjusted meat models (all "data not shown"). The BMI-interaction Suppl Table 2 is not available.
- **No continuous (per-gram) estimates exist.** Only quintiles, with p for trend. That p is recorded on the Q5 row of each set.

## Judgment calls
1. **Exposure coding.** Methods say: "Red meat was defined as pork, beef and game. Total red meat included both processed and unprocessed red meat."
   - Total red meat → `red_total` (yes).
   - Unprocessed red meat → `red_unprocessed` (no).
   - Processed red meat ("sausages and cured meat") → `processed` (yes).
   - Beef and pork → `partial`. They are "mainly based on non-processed meat" because processed items could not always be split into beef or pork. The wording implies that processed meat was assigned where it could be split.
   - Poultry → `unclear` (not defined).
   - Fish → yes (the paper says processed and unprocessed fish).
2. **is_main_model = yes** for the "Full model" (fn b) in every exposure × outcome × sex. For women in Tables 3–4 this is fn b + c (HRT), coded as adjustment set m3. Basic model (fn a) = no. Text sensitivity rows = no.
3. **Adjustment sets.**
   - m1 = basic.
   - m2 = full (all-sex and men rows in Tables 2–4; women rows in Table 2).
   - m3 = full + HRT (women, Tables 3–4).
   - **adj_bmi = unclear.** Methods say the full model includes BMI, and "Excluding BMI ... gave virtually similar results". But all three table footnotes list the full-model covariates without BMI.
   - **adj_hrt = unclear for m2.** Methods say "when appropriate". The Table 2 women column has no HRT footnote.
   - **energy_method = residual.** Intakes are energy-adjusted residuals, and total energy is also a covariate.
4. **Doses.** Exposures are quintiles of energy-adjusted, log-transformed residuals. The tables print one "quintile median" (g/day) per row for the whole cohort ("Quintiles for all"). Sex-specific rows use the same cut points, so they carry the whole-cohort median. Sex-specific medians are not printed. It is also unclear whether the medians are of crude or residual intake. No cut points are printed (dose_low and dose_high are empty). dose_conversions has 126 rows (one per category set), all `paper_median`.
5. **Sensitivity rows.** For the dietary-change exclusion the text names no sex. All-sex is assumed, since the main pork–CRC finding was all-sex. The model is assumed to be the full model for all three.
6. **Blank reference cells** (Table 2 beef all-sex basic; Table 4 processed and poultry women basic) are coded point = 1.00, with a note.
7. **Cohort.** `mdcs` has parent `epic` and overlaps_with `epic`. MDCS is the Malmö centre of EPIC (Norat 2005 Fig 2 lists Malmö with 194 cases), so it must never be pooled with EPIC rows that include Malmö. This is a judgment call: MDCS is a broader pre-existing cohort, and one could instead set parent empty and keep only overlaps_with.
8. **diet_instrument = diet_history.** The method is a modified diet history: 7-day menu book + 168-item questionnaire + interview. diet_items = 168 (the questionnaire only).
9. **validation_r is empty.** Only low-fat meat (0.51 women / 0.43 men) and high-fat meat (0.80 / 0.40) are given, not red meat. These are in the study notes.
10. **Interaction p-values** (sex × food) are kept in the notes of the Q5 full all-sex row, not in `p_value`:
    - CRC: beef 0.068, pork 0.157, processed 0.062
    - colon: pork 0.146, processed 0.127
    - rectum: beef 0.025, fish 0.597

## Printed anomalies (recorded as printed; flagged in row notes)
The tables have an unusual number of apparent errors, concentrated in Tables 3–4. Treat this study's colon and rectum rows with caution.

### Table 2 (colorectal)
- **Unprocessed red meat, all-sex, full model.**
  - Q5 1.08 (1.06–1.09): implausibly narrow.
  - Q3 0.88 against basic 1.07.
  - Q2 CI narrower than basic.
- **Identical cells.**
  - Pork, men, full: Q4 = Q5 = 1.26 (0.87–1.82).
  - Processed, all-sex, full: Q4 = Q5 = 1.20 (0.94–1.53).
- **Poultry.**
  - All-sex cases (141, 147, 150, 146, 144) are identical to the unprocessed red meat column.
  - Men person-years are 19 125 for both Q2 and Q3.
  - Medians for Q1 and Q2 are both 0.0.

### Table 3 (colon)
- **Beef**
  - All-sex cases sum to 460, not 463.
  - Basic Q3 is printed as 0.78 (0.66–1.14); the point does not sit in the middle of the interval. It is probably 0.86.
- **Pork**
  - Women's HRs repeat the Table 2 women's CRC values almost exactly, although case counts differ.
  - Men's basic Q3 and Q4 are identical.
- **Processed meat, all-sex, basic Q2–Q5**: the confidence intervals are garbled. Printed values are 1.32 (1.32–1.20), 1.07 (1.07–1.14), 1.17 (0.42–1.00) and 1.16 (0.35–1.22).
- **Poultry**
  - Men's cases sum to 186, not 216.
  - All-sex basic Q2 is 1.33, against 0.98 in the full model.

### Table 4 (rectum)
- **Medians**
  - Total red meat medians are 12.0–69.2, against 43.6–146.2 in Tables 2–3.
  - Pork medians equal the unprocessed red meat medians (21.3–95.3).
  - Both look misprinted. dose_conversions notes give alternative doses for a sensitivity analysis.
- **Pork**
  - Men's cases sum to 138, not 140.
  - Person-years repeat across Q2 and Q3, both all-sex and men.
  - The all-sex full-model intervals are inconsistent: 1.76 (0.92–2.25), 1.39 (0.69–1.91), 1.43 (0.57–1.86), 1.47 (0.47–2.44).
- **Beef**
  - Men's basic Q2 is printed as 1.37 (0.74–3.53). The upper limit is probably 2.53.
  - All-sex full Q4 is 1.18 (0.75–1.75).
- **Fish**: women's basic Q4 is 0.86 (0.42–1.52), against 0.78 in the full model.
- **Poultry**: women's full Q5 upper limit is printed as "28.2".

### CI width in Tables 3–4
In 65 rows the CI is more than 1.5 times wider than the case counts imply (computed as sqrt(1/a + 1/b)). The intervals widen steadily from Q2 to Q5 for unprocessed red meat, processed meat, poultry and fish. Table 2 does not show this. These rows are flagged in their notes. They are possibly misreported or come from another model.

### Text against tables
All 11 highest-vs-lowest figures quoted in the Results text match the tables.

## checks.py (2026-10-30, run on the work folder)
- **1_ci_omslutter_ikke_punkt (2)**: _337 and _349, the garbled colon processed basic CIs. Kept as printed.
- **2_asymmetrisk_ci (9)**: _116, _253, _355, _461, _488, _494, _500, _506 and _621. All are the misprints listed above.
- **9_uverifisert**: 633 rows.
- No reference, rank or dose flags. The poultry Q1 = Q2 = 0.0 medians are not caught, because the check treats 0 as missing.


---
# wada2017
# NOTES – wada2017 (Takayama Study)

Extractor: opus-E · 2026-10-30 · Source: `Understudier WCRF/oppfolginger/wada2017.txt` (Cancer Sci 108 (2017) 1065–1070, converted from XML). No supplement file exists. All numbers were parsed by script from the pipe-separated table rows in the txt and checked against the abstract and the Results text. No study card was used.

## New vocabulary
- `subgroup = excl_cases_first_2y`. This is a free-text field, so it is not a controlled value. It is listed here for consistency with `excl_cases_first_3y` used in larsson2005.

## Contents
- **estimates.csv: 152 rows**
  - Table 2 (men) and Table 3 (women): 3 exposures (total, red, processed meat) × 3 outcomes (colorectal, colon, rectum) × 4 quartiles × 2 analyses (main; excluding cases in the first 2 years) = 144 rows.
  - Seafood quartiles from the Results text (colorectal, by sex): 8 rows, including implied reference rows.
- **adjustments.csv: 2 rows.** m1 = men (Table 2 footnote); m2 = women (Table 3 footnote).
- **dose_conversions.csv: 38 rows**, one per category set.
- **study.csv: 1 row.**

## Judgment calls
1. **Exposure coding.**
   - "Red meat" → `red_unprocessed`. Methods: "We defined red meat as beef and pork. Food items … beef steak, pork steak, pork cutlet, grilled meat, grilled offal, and liver. Ham, sausage, bacon, and yakibuta … were defined as processed meat." Processed products are explicitly separated, so `exposure_includes_processed = no`.
   - The red-meat items include grilled offal and liver. Organ meat is therefore inside the red-meat variable; this is stated in the notes.
   - "Total meat" → `total_meat`, `includes_processed = yes` ("sum of any kind of meat, including red meat, poultry, and processed meat").
2. **Main model.**
   - Only one adjusted model is printed per sex, so `is_main_model = yes` for the main Table 2/3 rows.
   - The 2-year-exclusion rows are a sensitivity analysis: `no`.
   - The seafood rows (text only) are `yes` because they are the only seafood estimates and the text says seafood was "evaluated similarly". The model is assumed to equal Tables 2/3. This assumption is flagged in every seafood row's notes.
3. **Dose unit.** The column header is "Median intake (g)" with no "/day". Table 1 gives meat in "g/day", and the Methods say the values are energy-adjusted by the residual method. I coded `g_day` with `paper_median`. No category bounds are printed.
4. **Denominators.** Both "No. of subjects" and "Person years" are printed per quartile. I coded `denominator_type = person_years`, with person-years in `person_years` and the number of subjects in `n_in_category`.
   - The brief allows only one denominator_type, so the n_in_category value here is participants while the type says person_years. This is noted on every row.
   - The numbers are copied as printed, with the thin-space thousands separators removed.
5. **Seafood.** These rows are coded `exposure = fish` with exposure_text "Seafood (fish and shellfish)", so shellfish is included.
   - No medians, bounds, cases or person-years are printed, so `dose_unit` and `dose_point` are empty and `denominator_type = none`.
   - The reference rows (Q1 = 1.00) are implied by "vs the Q1" and are not printed rows.
6. **Effect measure.** The table columns are headed "RR†", but footnote † says "Estimated hazard ratio", and the analysis is Cox regression. Coded `HR`.
7. **p_trend** is placed on the Q4 row of each set. It comes from the "Trend P" row, a test with meat as a continuous variable.
8. **source_page.** The txt carries no page markers. Every row has "1065-1070 (page not marked in txt)", and the txt line number is in notes.

## Totals and consistency checks
- **Colorectal cases.** The quartile sums equal the abstract: 429 men and 343 women. Colon: 276 men, 244 women. Rectum: 153 men, 99 women. These totals are identical for all three exposures. study.csv gives cases_colorectal 772, cases_colon 520 and cases_rectum 252; the colon and rectum totals are my sums.
- **Number of subjects.** The sums are 13,957 men and 16,374 women, which match the abstract.
- **2-year exclusion.** The text says 63 cases were excluded. The table sums give 429−393 = 36 men and 343−316 = 27 women, i.e. 63. Consistent.
- **Inconsistency (flag).** In the 2-year-exclusion analysis, several quartiles have *more* person-years than in the main analysis, although only participants were removed. Examples: men total meat Q1 46 270 → 46 272, Q2 45 253 → 45 273; men processed Q1 46 197 → 46 237; women total meat Q2 55 387 → 55 452.
  - This is possible only if follow-up was redefined. For example, the excluded cases' person-time might have been kept until censoring, or start of follow-up might have been shifted.
  - The paper does not explain this. The values are recorded as printed.
- **Covariate scaling (text vs table).** The Methods say fiber, calcium and vitamin D were entered as "energy-adjusted intake … (g/day), (mg/day), (μg/day)". The Table 2/3 footnotes say "the intakes (quartiles) of total fiber, calcium, and vitamin D". This is noted in adjustments.csv.
- **Smoking categories.** The Methods give the men's split as "≤30 years / ≥31 years"; the Table 2 footnote says "30 years or less / 31 years or more". These are equivalent.
- The abstract and Results agree with Table 2: total meat Q4 1.36 (1.03–1.79), p trend 0.022; red meat Q4 1.44 (1.10–1.89), p trend 0.009; red meat colon in the excl-2y analysis, p trend 0.047.
- No log-asymmetric CIs were found by checks.py (see report).

## Relation to Oba 2006 (same cohort)
- Same FFQ (169 items) and same exposure definitions, but different categories: tertiles (Oba) vs quartiles (Wada).
- Follow-up was extended from 2000 to March 2008, registry data were added, and rectum and colorectal outcomes were added.
- The participant counts differ slightly: Oba 13,894 men + 16,327 women; Wada 13,957 + 16,374. Exclusions were changed (adenoma history now excluded).
- `cohort_id = takayama`. The two studies must never enter the same pooled analysis.
- Islam 2019 also re-analyses Takayama, with different counts (14,224 men / 16,575 women, 449 / 352 CRC).

## Not coded
- Discussion meta-analysis of six Japanese cohorts (pooled RRs 1.22 etc.): this is a meta-analysis, not an estimate from this cohort.
- Iron, animal fat and saturated fat ("data not shown").
- Premenopausal/postmenopausal comparison ("data not shown").
- Mortality: 115 men and 107 women died of CRC, but no meat estimates for mortality are given.

## Study-level
- `followup_years = 15.5`, `followup_type = max`, computed from Sept 1992 – March 2008. No mean or median is printed.
- DOI and PMID are not in the txt and are left empty.
- `in_cup2016 = no` and `cup_role = post_2016` come from the OPPDRAG_tillegg list.
- `validation_r` is left empty because the values are sex-specific: red meat 0.21 men / 0.54 women; see study notes.


---
# wang2020
# Wang 2020 (NHS + NHS2 + HPFS, refined subsites) – extraction notes (opus-W1, 2026-10-30)

Sources:
- post2015/sok2026/wang2020.txt (NIH manuscript nihms-1581361; Gastroenterology 159(1):241–256.e13).
- wang2020_suppl.txt.

Table 4 was checked against the rendered PDF (ms page 27, rotated). All 30 values match. The txt splits the two-line CIs of the "Overall"/sigmoid/rectum columns, and the P-for-heterogeneity values for total red meat sit on a different line.

## New vocabulary
- `cohort_id` = `nhs_nhs2_hpfs` (proposed in `cohort_row.csv`, overlaps_with = nhs_hpfs;nhs;hpfs). There is no `nhs2` cohort id yet.
- `dose_unit` = `per_3_servings_week`.
- `subgroup`:
  - Subsites: `subsite_cecum`, `subsite_ascending_colon`, `subsite_transverse_colon`, `subsite_descending_colon`, `subsite_sigmoid_colon`, `subsite_rectosigmoid_junction`, `subsite_rectum`. These follow the zouiouich2025 convention. `subsite_rectum` is used instead of `subsite_rectum_c20` because the paper gives no ICD code.
  - Age at onset: `onset_lt60`, `onset_ge60`.
  - Combined: `subsite_x+onset_y`.

## Contents (96 rows, all continuous HR per 3 servings/week, sexes combined, pooled)
- **Table 4: 30 rows.** 3 exposures (total red `red_total`, processed red `processed`, unprocessed red `red_unprocessed`) × 10 columns:
  - 7 subsites;
  - 3 overall columns: proximal (n=1357), distal (971), and rectum overall (730 = rectosigmoid + rectum).
- **Suppl Table 4: 66 rows.** 3 exposures × younger/older onset (<60 / ≥60 y) × 11 columns: ALL CRC, the 7 subsites and the 3 overall columns.

## Answers to the brief
- **Is there a total-CRC estimate for unprocessed red meat? Not for the whole population.** Main Table 4 has no all-CRC column. The only "ALL CRC" estimates are age-at-onset-specific in Suppl Table 4:
  - unprocessed red meat: younger 1.08 (0.98–1.19), older 1.01 (0.95–1.07);
  - total red meat: 1.05 / 1.03;
  - processed red meat: 1.01 / 1.14.
  - The ALL CRC column includes the 232 cases without a subsite (901 + 2389 = 3290 = 3058 + 232).
  - The closest whole-population numbers are the three overall main-subsite rows. Unprocessed red meat: proximal 1.08 (1.00–1.18), distal 0.95 (0.86–1.05), rectum 1.11 (0.99–1.24).
- **Serving size: not defined anywhere** in the paper or the supplement. The unit is "per 3 serving/week", chosen "based on the literature and to reflect the distribution". Converting to g/day needs an external portion assumption, so g_day_assigned is empty.
- **No cohort-specific or sex-specific red-meat estimates.** All estimates come from one Cox model stratified by cohort (or sex) on the pooled data. They are not a meta-analysis of cohort estimates.
- **No category (quintile) estimates.** Quintile medians were used only to compute Ptrend.

## Judgment calls
1. **is_main_model = yes** on the 9 overall rows of Table 4: proximal, distal and rectum × 3 exposures. Single-subsite rows and all Suppl age-onset rows are `no`. There is no colorectal main row.
2. **Rectum overall → `outcome = rectum`.** It includes the rectosigmoid junction, as defined in the paper; this is compatible with CUP practice. The narrow rectum column is coded as rectum + `subsite_rectum`.
3. **exposure_includes_processed.** Total red = yes; processed red = yes; unprocessed = `unclear`, because the paper lists no food items. Bernstein 2015 in NHS/HPFS lists hamburger under unprocessed, which would make it `partial` under R6/4.2b. The caller may want to harmonise.
4. **Adjustment set.** Table 4 fn a covers age, race, height, family history, endoscopy, BMI, pack-years, physical activity, alcohol and aspirin, with stratification by age, cohort, sex and calendar time.
   - **No energy term** (`energy_method = none`). The Methods' residual energy adjustment applies to nutrients, not to red-meat servings.
   - **No dietary co-adjustment:** no fiber, calcium, other meats or fruit/veg.
   - `adj_stratified_center` = yes, meaning cohort stratification.
   - The Suppl model (m2) has the same covariates, but its footnote says "stratified by sex".
5. **p-values.**
   - `p_trend` holds the per-cell Ptrend.
   - Heterogeneity p-values are kept in notes: within main subsites, overall across 7 subsites, and linear. For processed red meat, P linear heterogeneity = 0.04, which matches the text.
   - The suppl contrast-test P (younger vs older) is also in notes.
6. **n_cases.**
   - Table 4: column totals from the header.
   - Suppl: subsite counts from Suppl Table 1; overall columns summed from their subsites (e.g. younger proximal 88+108+50 = 246).
   - No person-years are printed, so `denominator_type = none`.
7. **Suppl CIs are printed with inconsistent decimals** (e.g. "0.9-1.08", "1-1.33", "0.97-1.1"). They were copied as printed.
8. **checks.py flags (2_asymmetrisk_ci)**, both from rounding to 2 decimals near 1. Both were verified as printed:
   - wang2020_006: total red, sigmoid, 1.04 (0.96–1.11), asym 0.19;
   - wang2020_042: total red, older-onset ALL CRC, 1.03 (0.99–1.08), asym 0.16.
9. **study.csv.** `n_participants` = 223,367 (45,351 men + 178,016 women). `cases_colon` = 2328 (proximal + distal). `cases_rectum` = 730, including the rectosigmoid junction.

## Text vs table
- Results text: "processed red meat (HR per 3 serving/week ranged from 0.96 to 1.23, Plinear heterogeneity=0.04)". This matches Table 4: cecum 0.96, descending 1.23.
- The Abstract groups processed red meat with factors whose "inverse associations increased from cecum to rectum". Table 4 actually shows HRs *rising* toward the distal subsites and rectum, i.e. a strengthening positive association. The abstract wording is inconsistent with the table; the table values were coded.


---
# wei2004
# Wei 2004 (NHS + HPFS): extraction notes (opus-C, 2026-10-30)

Source: Int J Cancer 108:433–442, full text `Understudier WCRF/wei2004.txt`. All numbers come from the full text: Table I p. 436, Table II p. 439 (meat block), Table III p. 441, Methods/Results p. 433–435. The study card was opened only to locate tables. No supplement exists.

## New vocabulary
- `cohort_id` values: `nhs` (women), `hpfs` (men), and `nhs_hpfs` for the "COMBINED COHORT" rows. Per supplement item 4.
- Tokens in `category_set_id`: `redmaindish` (beef, pork or lamb as a main dish) and `processed`. Because the three cohorts map one-to-one onto sex (nhs = women, hpfs = men, nhs_hpfs = all), the sex token already separates them. Format: `wei2004_mv_<outcome>_<sex>_<exposure>`.
- `dose_unit = per_serving_week` on the Table III rows. This value is already in the supplement vocabulary.

## Scope coded (62 rows)
- **Table II, meat blocks.** 2 exposures × 3 cohorts × 2 outcomes (colon, rectum) × 5 categories = 60 rows. The reference rows are included. Only one model exists (MVRR).
- **Table III (polytomous logistic regression), combined cohort.** 2 continuous rows: beef/pork/lamb 1.12 (0.99, 1.27) and processed meat 1.20 (1.06, 1.37) per additional serving. Coded `outcome = colorectal` (see judgment call 4).
- **Not reported in the paper:** poultry, fish, total meat, proximal/distal colon, colorectal-combined categorical estimates, age-adjusted models, and sensitivity analyses. Table II has only one model. The Methods say "age-adjusted and multivariate pooled logistic models", but no age-adjusted RRs are printed. The brief asks for poultry and fish if present. They are **not** present.

## Judgment calls
1. **Exposure `red_main_dish`, `exposure_includes_processed = unclear`.** The paper names the item "beef, pork or lamb as a main dish" (in one place "beef as a main dish", p. 434) and gives no food list. Bostick 1994, which uses the same Harvard FFQ family, prints the item as "beef, pork, or lamb as a main dish (e.g., steak, roast, ham, etc.)". That suggests ham is in it, but the Wei paper does not say so, so the flag is `unclear` per R6. Hamburger and mixed dishes are not mentioned. In this FFQ family they are separate items. Processed meat is a separate covariate in the same model.
2. **Categories and units.** The Table II header says "(servings/day)", but the category labels are "0, <3 per month, 1 per week, 2 to 4 per week, 5 or more per week". I coded `dose_unit = servings_week` from the labels and entered the bounds as printed: 0/0, empty, 1/1, 2/4, 5/open. **For "<3 per month" both bounds are left empty**, because that label is in a different unit and R4 forbids conversion in estimates.csv. checks.py's dose-monotonicity test therefore skips rank 2. `dose_point` is empty: the Methods (p. 434) say category medians were used for trend tests, but they are not printed.
3. **is_main_model = yes** on all Table II rows. Each exposure × outcome × cohort has only one model. The combined-cohort rows use adjustment set m2 (adds gender) and the single-cohort rows use m1.
4. **Table III continuous rows: `outcome = colorectal`, `is_main_model = yes`.** In the polytomous model, the meat betas were fixed equal for colon and rectum by the stepwise procedure (p for difference 0.32 and 0.17), so one estimate covers both sites. It is the only colorectal-level estimate in the paper, which is why it gets main = yes. Caveats:
   - (a) The model enters each variable as the median of its categories, which the paper says puts it "on a different scale" from the pooled logistic models (p. 435).
   - (b) **Unit conflict.** Table III says "one additional serving per week". The Methods (p. 435) say "Red meat and processed meat were modeled in servings per day", and the Table II header says servings/day. I recorded it as printed (`per_serving_week`). If the true unit is per day, the per-100 g/day value changes by a factor of 7. **Flag for control.**
   - (c) `n_cases` = 1478 = 1139 colon + 339 rectum (my sum of printed totals). `person_years` = 2,302,712, the combined total (p. 435).
5. **is_mutually_adjusted_processed.** `yes` for the beef/pork/lamb rows, because processed meat is in the model (Table II fn 1). `no` for the processed rows. For those rows, the main dish is in the model instead.
6. **Adjustments.** Total energy is not a covariate. The Methods say "Nutrient values are adjusted for total energy intake" (p. 434), which applies to calcium and folate and is not a meat adjustment. I therefore set `adj_energy = no` and `energy_method = none`, and say so in the notes. Smoking is entered as pack-years before age 30 (`adj_smoking = yes`). Endoscopy history → `adj_screening = yes`. Height is adjusted but has no flag. Aspirin was deliberately left out (p. 434). In Table III the Methods list fiber among the PLR variables, but fiber is missing from the Table III list and footnote, so `adj_fiber = unclear` in m3 and `no` in m1/m2.
7. **Denominators.** No per-category person-years or participants are printed for any exposure, so `denominator_type = none`. Only the total person-years (2,302,712 combined) are given. Per-cohort person-years are not printed.
8. **Case sums.** In several sets the category cases fall short of the cohort totals. Examples: NHS colon main dish 670 vs 672, NHS colon processed 668 vs 672, combined colon main dish 1137 vs 1139. This is presumably missing meat data. Each affected row has a note. HPFS colon main dish sums exactly to 467.
9. **Study-level `cohort_id = nhs_hpfs`.** `followup_years` is empty and `followup_type = unclear`, because no mean or median is printed. Calendar spans are 1980–May 2000 (NHS) and 1986–Jan 2000 (HPFS). `diet_items` is empty because it is 61 items for NHS 1980 and 131 for HPFS 1986. `diet_repeated = no`, because baseline meat intake was used even though diet was re-assessed every 4 years (p. 434). `outcome_ascertainment = self_report_verified`: self-report, physician review of records, and NDI for deaths.

## Probable typos and printed anomalies (recorded exactly as printed)
- **NHS (women), processed meat, colon, "1 per week": "1.10 (0.81, 1.26)"** (row `wei2004_033`). The point estimate lies far from the centre of the CI on the log scale (log-asymmetry 0.56; checks.py flags it). The neighbouring categories are 0.96 (0.78, 1.18) and 1.21 (0.95, 1.53). Either the point should be about 1.01 or the upper limit about 1.50. This is the Wei typo the KODEBOK refers to ("0.90 (0.92–1.92)" in its example text). **The typo is in the NHS/women block, not in the men's (HPFS) table.** I found no asymmetric or impossible CI in any HPFS meat row, nor in the other meat rows.
- **Unit conflict** servings/day vs per week (judgment call 4b).
- **Text vs table.** The abstract and Results say beef/pork/lamb as a main dish was "significantly associated with colon cancer" in the combined cohort. In Table II, the combined colon p-trend is 0.25, and only the "<3 per month" (1.43, 1.02–2.02) and "≥5/week" (1.43, 1.00–2.05) categories exclude or touch 1. Table III gives 1.12 (0.99, 1.27). No printed estimate for the combined cohort is clearly significant on trend. Recorded as printed. This note is for interpretation only.
- The Discussion (p. 437) describes the variable as "beef as a main dish", while the tables say "beef, pork or lamb as a main dish". These are taken as the same variable.

## Portion size / grams
- The paper gives **no grams per serving** and no category medians. The only intake figures are Table I baseline means in servings/day: main dish women 0.37/0.39/0.35 and men 0.31/0.30/0.26; processed meat women 0.17/0.20/0.18 and men 0.26/0.23/0.25 (noncases/colon/rectum). `g_day_assigned` is left empty in all 12 dose_conversions rows.
- `weight_basis = unclear`.


---
# wie2014
# NOTES – wie2014 (Korean Cancer Screening Examination Cohort, KSEC)

Extractor: opus-D · 2026-10-30 · Sources: `Understudier WCRF/wie2014.txt` (Br J Nutr 2014;112:238–247) and `wie2014_supplement.txt` (Supplements 1–5). Every number was typed from these files. The study card was not used for numbers.

## New vocabulary
- **`diet_instrument = food_record`** (study.csv). Diet was measured with a 3-day food record, which KODEBOK 3.1 has no value for. `24h_recall` would be wrong.
- **`dose_unit = per_50g`** is already in KODEBOK. `per_10g` is also in KODEBOK.

## Contents
**estimates.csv – 9 rows:**
- **Table 3 (p. 244):** red meat ≥43 vs <43 g/d, colorectal, crude and multivariate, each with a reference row = 4 rows.
- **Suppl 1:** red meat continuous, **per 50 g/d**, colorectal, multivariate = 1 row.
- **Suppl 5:** per 10 g/d, colorectal, fresh red meat and processed red meat, crude and multivariate = 4 rows.

**adjustments.csv – 2 rows:**
- m1 = crude
- m2 = multivariate

**dose_conversions.csv – 2 rows** (the two-category sets). `g_day_assigned` is empty.

## Judgment calls and flags
1. **The assignment says "code the continuous per-10 g estimate from the supplement". The supplement has no per-10 g estimate for total red meat.**
   - Suppl 1 gives red meat as a continuous variable. Its footnote states the increment as **"50 g/d for red meat"**: HR 0.98 (0.73, 1.31). This is coded `per_50g`.
   - The per-10 g estimates are in **Suppl 5**, which splits red meat into **fresh red meat** and **processed red meat**, "by 10 grams per day". Both are coded as continuous rows.
   - So there is no per-10 g estimate for the combined red-meat variable. If CUP rescaled a per-10 g figure for Wie, it must have come from one of the Suppl 5 sub-types or been derived from the per-50 g figure. Check this against `cup_extraction`.
2. **Red meat definition (p. 240):** "red meat referred to beef, pork, lamb and goat, and processed meats … bacon, ham and sausage, and the internal organs (offal …)". The variable is coded `red_total`, `includes_processed = yes`. It also includes offal and goat. This breaks CUP's red-meat definition.
3. **Fresh red meat (Suppl 5)** is coded `red_unprocessed`, `exposure_includes_processed = no`, because processed red meat is analysed separately. It is not defined further. Whether offal sits in "fresh" is not stated (row note).
4. **Main model:**
   - The multivariate model gets `is_main_model = yes` for red_total in **both** the category set (Table 3) and the per-50 g continuous row (Suppl 1). They are different contrast types of the same model.
   - The rule says "exactly one model per exposure × outcome × sex". The model is one model (m2), so both rows carry `yes`. An analysis should pick the contrast type it needs.
   - Fresh and processed red meat (Suppl 5): multivariate = `yes`, crude = `no`.
5. **Colorectal cases were largely detected at baseline screening.** The Table 3 colorectal column prints "Person-years 53, Median 0·1, Range 0·0–6·0".
   - Read literally, the 53 colorectal cases had a median of **0.1 years** from enrolment to diagnosis. The same pattern holds for gastric cancer (median 0.3) and thyroid cancer (median 0.7).
   - The cohort was recruited at a cancer screening examination, so most of these "incident" cases were almost certainly found by that screening: they are effectively prevalent at baseline.
   - Flagged on every row and in study.csv notes. It is a design problem, not a typo, so the numbers are coded as printed.
6. **Denominators.**
   - Table 3 prints no per-category cases. Table 1 gives colorectal cases by red-meat category (<43 g/d: 22; ≥43 g/d: 31; sum 53 ✓).
   - Table 1 also gives **whole-cohort** person-years by red-meat category (23049.8 / 30976.8). These are not outcome-specific; noted on the rows.
   - Table 1 also prints, in the colorectal column, red meat "<43 g/d 41·5 %" and "≥43 g/d 58·5 %". This matches 22/53 and 31/53.
7. **Typos and inconsistencies (recorded, not corrected):**
   - **Total person-years:** the text says 54,027; Table 2 says 54,076 (Table 1 total ≈ 54,026.6).
   - **Follow-up:** median 7.0 years (Results) vs "mean follow-up period … 6.7 years" (Discussion). `followup_years = 7.0`, `median`.
   - **Table 1** has visibly garbled columns in places (e.g. the "Gastric and colorectal" column under Income and Education). It does not affect the meat rows.
   - **Table 1 red-meat %** for controls: "<43 g/d 2963 36·6 %" but 2963/7637 = 38.8 %. The two percentages (36.6 + 63.4) still sum to 100. Noted only; not used.
   - **Multivariate HR 1·31 (0·60, 2·61)** is somewhat asymmetric on the log scale (−0.78 / +0.69), but below the checks.py threshold.
   - **Discussion text:** "processed red meat … in men (HR 1·05, 95 % CI 1·00, 1·92)". This is overall cancer, not colorectal; Suppl 5 prints 1.05 (1.00 1.09). An apparent typo (1·92 vs 1·09), noted only, not coded (overall cancer is out of scope).
8. **Not coded (out of scope):**
   - Table 2 (overall cancer)
   - Table 3's thyroid and gastric columns, and "gastric and colorectal combined" (the combined outcome is not colorectal-specific)
   - Suppl 1 rows other than colorectal
   - Suppl 2 (overall-cancer tertiles)
   - Suppl 3 and 4
   - Suppl 5 rows other than colorectal
   - Sex-specific colorectal estimates (not printed)
9. **Adjustment** (all footnotes identical): age, sex, energy intake, BMI, physical activity (yes/no), smoking (yes/no), alcohol (yes/no), income, education and marital status.
   - Energy is a covariate: `energy_method = covariate`.
   - No adjustment for other meats, fibre, calcium, fruit/vegetables, family history, NSAIDs or screening history.
10. **study.csv:**
    - `outcome_ascertainment = mixed`: registry and/or hospital electronic medical record.
    - `age_range` is empty (not printed).
    - `cases_colon` / `cases_rectum` are empty (no split reported).


---
# willett1990
# Willett 1990 (NHS) – extraction notes (opus-H1, 2026-10-30)

Source: N Engl J Med 1990;323:1664–72, text file `Historikk 1965-2015/Historikk/txt/21_Willett1990.txt` (OCR of the NEJM PDF). Numbers come from Table 3 (p. 1668), Table 4 (p. 1668), the Results text (pp. 1667–1669) and the abstract (p. 1664). The study card was not used.

## New vocabulary
- `cup_role = pre2010` (per brief).
- category_set_id exposure tokens: `redmaindish`, `processed`, `poultrynoskin`, `fish`, `liver`, `red`, `white`, `ratio`. Model token `age` (both tables are age-adjusted).

## Scope coded (42 rows)
- **Table 3**, age-adjusted, frequency categories. Coded: beef/pork/lamb as main dish (5 categories), processed meats (5), chicken without skin (4), fish (5) and liver (4); 23 rows in all, reference rows included. Chicken with skin has no estimate printed (P trend 0.65).
- **Table 4**, age-adjusted with intakes energy-adjusted to 1600 kcal. Coded: red meat in g/day quintiles (5 rows), chicken + fish (5 rows) and the ratio of red meat to chicken + fish (5 rows); 15 rows in all.
- **Text**, 4 rows:
  - Difference variable (red meat minus chicken + fish), Q5 vs Q1: 2.44 (1.44–4.14).
  - Mutually adjusted model, highest quintile: red meat 1.61 (1.03–2.53) and chicken + fish 0.63 (0.39–1.00).
  - Colon + rectum combined, ratio Q5 vs Q1: 2.30 (1.48–3.56), P trend < 0.0001.
- **Not coded:**
  - Animal fat and the other nutrients in Tables 1–2 and Fig 1 (not meat).
  - Rectal cancer alone: only "P for trend = 0.08" for the ratio, no estimate.
  - Statements without numbers: physical activity "did not alter", meat doneness "unrelated", and the ratio "changed little" with nutrients added.
- The famous contrast is beef/pork/lamb as a main dish **daily vs < 1/month = 2.49 (1.24–5.03)**. It is row `willett1990_005` (top category of Table 3). It matches the abstract exactly.

## Judgment calls
1. **Table 3 column alignment (main OCR problem).** The header prints 6 frequency columns (<1/mo, 1–3/mo, 1/wk, 2–4/wk, 5–6/wk, ≥1/day), but each food row prints only 5 (or 4) values. The source text does not show which columns are merged or empty.
   - Beef main dish: the reference (<1/mo) and the top category (daily) are confirmed by the abstract and the Results text. Ranks 2–3 are labelled "column inferred". Rank 4 is labelled "2–4/wk or wider (alignment unclear)".
   - Chicken without skin: the reference (<1/mo) and the top (≥2/wk) are confirmed by the text. The middle categories are inferred.
   - Processed meats and fish: only rank order is certain, so they are labelled "category k of 5".
   - Liver: 4 columns, 4 values, no ambiguity.
   - `dose_low`, `dose_high` and `dose_unit` are left empty on all Table 3 rows. The printed labels mix /mo, /wk and /day units, and the bounds are not certain.
   - **Needs checking against the PDF.**
2. **Table 4 case counts.** For red meat, chicken + fish and the ratio, the "Cases" row prints only 4 numbers for 5 quintiles in the text file (red meat: 25 27 26 44; chicken + fish: 38 29 19 25; ratio: 22 26 29 46). One value is lost in each, and it cannot be placed, so `n_cases` is empty on all Table 4 rows. Person-years are complete and recorded.
3. **is_main_model.**
   - Table 3 is the only model for main dish, processed, poultry, fish and liver, so all are `yes`.
   - Table 4 is `yes` for red meat (red_total) and chicken + fish (white_meat).
   - The mutually adjusted text model (m3) is more adjusted, but it is reported only as highest vs lowest. It is `no` per supplement rule 2.
   - All ratio and difference rows are `no`.
   - For **colorectal**, the only estimate is the ratio (substitution, `no`). So colorectal has no main row for any meat exposure.
4. **Ratio and difference variables are coded** as `contrast_type = substitution`, `exposure = red_total` (the numerator), with `dose_unit = ratio` where applicable. This follows the precedent in NOTES_all (fresh red meat:chicken+fish ratio coded as substitution, never main). Another precedent leaves ratios uncoded. These rows can be filtered on `contrast_type`.
5. **Exposure codes.**
   - Beef/pork/lamb as main dish = `red_main_dish`, `partial` (examples include "ham"; Table 4 fn).
   - Red meat (Table 4) = `red_total`, `yes` (hot dogs, preserved meats, bacon).
   - Chicken without skin = `poultry`.
   - Liver = `organ`.
   - Chicken + fish = `white_meat`.
6. **Models.**
   - m1 (Table 3): age only. Food frequencies are not energy-adjusted, so `adj_energy = no`.
   - m2 (Table 4): age, with energy-adjusted intakes (`residual`).
   - m3: red meat + chicken/fish + total energy (age assumed, per methods p. 1666).
   - The text-only difference and colorectal ratio estimates have no stated model. They are assigned m2 and flagged in row notes.
7. **Cases in study.csv**: colon 150, rectum 39, colorectal 189. The colorectal figure is 150 + 39; the paper never prints 189.
8. **Outcome** = `colon` for all tables. Rectal cancer is excluded from the primary analysis (p. 1665).

## OCR / printed anomalies
- Results text: "women who reported daily consumption had 22 times the risk". This is OCR of "2½ times". The abstract and Table 3 give 2.49.
- Liver top category header reads "2=U/WK" in the OCR, interpreted as ≥1/wk.
- No log-asymmetric CIs were noticed in the meat rows. checks.py will confirm.
- The quintile labels "21960", "265", "2134" etc. are OCR of "≥1960", "≥65", "≥134".

## Portion sizes
None are printed in grams. The FFQ used "a commonly used unit or portion size". `g_day_assigned` is empty for every set. The Table 4 g/day variables have bounds only, with no medians.

## Cohort id
`nhs` already exists in database/cohorts.csv; no new cohort id needed.

## checks.py (scratch copy, 4 studies combined)
Only expected flags: missing CI on point-only rows (Goldbohm text frequency rows, all Phillips rows), dose rule 4 on Goldbohm 0 / 0-10 categories, and rule 9 (unverified). No log-asymmetry flags.


---
# yiannakou2022
# NOTES – yiannakou2022 (Black Women's Health Study)

Extractor: opus-H · 2026-10-30 · Source: `post2015/yiannakou2022.txt` (J Nutr 2022;152:1254–1262). Page numbers were checked against `/home/claude/pdf_in/nxab419.pdf` (same article): Table 2 = p. 1257, Table 3 = p. 1258.

## New vocabulary
- **subgroup:**
  - `age_ge_50` (late-onset) and `age_lt_50` (early-onset): these are age at diagnosis.
  - `fruit_veg_ge_5_servings_day`.

## Contents
- **estimates.csv: 73 rows.** Women only.
  - **Table 2 (p. 1257): 36 rows.**
    - 3 exposures (total red meat, processed meat, unprocessed red meat).
    - × 3 age groups (all, ≥ 50 y, < 50 y).
    - × (3 categories + 1 continuous).
    - Cases and person-years per category are given.
  - **Table 3 (p. 1258): 36 rows.**
    - 3 exposures × 3 subsites (proximal colon, distal colon, rectum) × (3 categories + 1 continuous).
    - Cases per category are given; person-years are not.
  - **Results text (p. 1257): 1 row.** Joint-effects contrast: high vs low total red meat among women with fruit and vegetables ≥ 5 servings/day, 1.39 (1.04–1.86).
  - **Not coded:** SFA and MUFA (Tables 4–5), which are not meat. Other joint-effect contrasts (1.41, 1.41, 1.37): these compare combinations of meat with fruit, vegetables or whole grains, so they are not meat-only contrasts.
- **adjustments.csv: 1 row** (a single multivariable model for Tables 2–3).
- **dose_conversions.csv: 18 rows**, one per categorical set.

## Missing
- **No total-colon estimate.** The paper reports only proximal, distal and rectum separately.
- **Supplemental Table S1** (intakes by category) and **Supplemental Figure S1** (joint effects) are not available.
- **No age-adjusted-only model** is reported.

## Judgment calls
1. **Exposures.**
   - **"Total red meat" = `red_total`**, `includes_processed = yes`: processed red meat plus beef, lamb and pork.
   - **"Unprocessed meat" = `red_unprocessed`** with `exposure_includes_processed = partial`. The pork list includes "dinner ham", which is a cured product. The paper itself calls the variable unprocessed. Set to `no` if dinner ham is judged negligible.
   - **"Processed meat" = `processed`**: bacon, sausage, hot dogs, lunchmeats (ham, bologna, salami). It is called "processed red meat" in the text.
2. **is_main_model = yes** on all rows of the single multivariable model, for each exposure × outcome: colorectal "All" in Table 2, and each subsite in Table 3.
   - The age-group rows (Table 2 ≥ 50 / < 50) and the joint-effects row are `no`.
   - **Within each exposure × outcome, both the categorical set and the continuous row carry `yes`.** They are the same model with two exposure parametrisations. Pick one per analysis.
3. **The continuous estimates are NOT linear per-100 g slopes.**
   - Intake was log10-transformed. The HR per 1 unit of log10 intake is what the authors label "per 100 g/d" (or "per 50 g/d" for processed meat).
   - `dose_unit = per_100g` / `per_50g` as printed. The caveat is in every continuous row's notes.
   - Treat these with care in a dose–response pool. A GL reconstruction from the categories is the cleaner alternative.
4. **Continuous-row case counts.** `n_cases` and `person_years` on continuous rows are the sums of the printed categories; the paper prints no separate totals.
5. **p-values.** `p_trend` is put on the top-category row. Continuous-row `p_value` is taken from the Results text where printed:
   - Colorectal all: unprocessed 0.03, processed 0.8, total 0.1.
   - Unprocessed red meat by age: ≥ 50 0.02, < 50 0.6.
   - Subsites: total and unprocessed red meat.
6. **Dose bounds** are in servings/week as printed; the g/week equivalent is in `category_label`. Bottom categories start at 0.
7. **dose_conversions.**
   - Portion = 85 g (`portion_source = paper`).
   - No category medians are printed. The trend tests used medians, but the values are not given.
   - `g_day_assigned` = midpoint servings/wk × 85 / 7, with the open top category at cut-point + ½ × the neighbour width (CUP rule). **These are my computed values.**
   - Overall median total red meat is 34.9 g/d.
8. **Adjustment.**
   - Discretionary fat is adjusted, but this is not saturated fat, so `adj_saturated_fat = no`.
   - Aspirin = `adj_nsaid` yes. Fibre yes.
   - No fruit/vegetables, no family history, no screening (not available, per the Discussion).
   - No mutual meat adjustment.
   - Stratified by age and questionnaire cycle.
9. **`outcome_ascertainment = mixed`**: self-report, registry linkage in 24 states and the National Death Index. Self-reports are kept unless pathology disconfirms them.
10. **`cases_colon` is empty.** There is no total-colon analysis, and proximal + distal (222 + 92 = 314) does not equal all colon cases: 564 − 104 rectal = 460, so ~146 are unspecified or other sites. `cases_rectum = 104` (sum of Table 3 rectal categories).

## Inconsistencies and probable typos (recorded as printed)
- **Joint-effects row (073).** The text says "higher total red meat intake (≥4 servings/d)". The Methods define the joint dichotomy as "<4 or ≥4 servings/wk", so "/d" is almost certainly a typo for "/wk". Coded with `servings_week` and flagged.
- **CRC ICD codes.** CRC is defined to include C21.8 (anorectal overlapping). Rectal = C19.9 + C20.9. The proximal/distal definitions use ICD-10 codes while the CRC definition uses ICD-O-3 (as printed).
- **Out-of-scope typos.**
  - The text calls the saturated-fat estimate an "OR" ("the OR was 0.89"), although the table gives an HR.
  - Table 4 prints "1.06 (0.63, 1.78d)".
  - Not coded; noted for completeness.
- checks.py: no flags apart from the expected `9_uverifisert`.


---
# zouiouich2025
# NOTES – zouiouich2025 (NIH-AARP, long follow-up)

Extractor: opus-E · 2026-10-30 · Source: `Understudier WCRF/oppfolginger/zouiouich2025.txt`, converted from XML. **Figures 1–2 are captions only (no numbers), and Supplementary Tables 1–10 are not in the file.** Only Tables 2–3 and the numbers printed in the Results text could be coded. No study card was used.

## New vocabulary
- `dose_unit = per_50g_per_1000kcal`: continuous per 50 g/1000 kcal/d (nutrient density). This is the same value etemadi2018 already uses; it is not in KODEBOK 3.3/tillegg.
- `subgroup` values (free text):
  - `stage_localized`, `stage_regional`, `stage_distant`: Table 3.
  - `subsite_cecum`, `subsite_ascending_colon`, `subsite_hepatic_flexure`, `subsite_transverse_colon`, `subsite_splenic_flexure`, `subsite_descending_colon`, `subsite_sigmoid_colon`, `subsite_rectosigmoid_junction`, `subsite_rectum_c20`.
  - The controlled `outcome` vocabulary has no single-subsite values. I coded each anatomical subsite as its parent outcome (proximal_colon / distal_colon / rectum) plus a subgroup. Such rows must not be pooled as if they were the parent outcome; they all carry `is_main_model = no`.

## Contents
- **estimates.csv: 91 rows.**

| Source | Content | Rows |
|---|---|---|
| Table 2 | Fish and poultry × 13 sites × {substitution, addition} | 52 |
| Table 3 | 9 meat types × 3 CRC stages, substitution models | 27 |
| Results text (Figure 1 / Supplementary Table 1 values printed with CIs) | Red replacing white meat: CRC all, men, women, proximal, distal, rectal, cecum, transverse, sigmoid, rectosigmoid junction, rectum (11); white meat addition model, CRC (1) | 12 |

- **adjustments.csv: 7 rows**, one per model type: substitution red/white (m1); red subtypes (m2); white subtypes (m3); fish/poultry (m4); processed vs unprocessed (m5); addition red+white (m6); fish/poultry addition (m7). All share the same confounder set; they differ in the meat terms.
- **dose_conversions.csv: 1 row.** There are no category sets (the quintile analyses are in the unavailable Suppl Tables 4–5). The row documents the unit problem.

## Judgment calls
1. **contrast_type.**
   - Substitution models → `substitution`.
   - Addition models → `continuous`. They are per-unit estimates with the other meat types held constant, but without total meat, so they are not substitutions.
   - The substitution direction is written in `category_label`:
     - red replacing white meat (red_total, red subtypes);
     - white, fish or poultry replacing red meat (white_meat, fish, poultry);
     - processed replacing unprocessed (processed, Table 3 "Processed meat").
2. **is_main_model.**
   - The paper's primary approach is the substitution model. It leads the abstract, Results and Discussion, and the addition model is called "complementary". So `yes` is set on substitution rows for colorectal, proximal, distal and rectum, with sex = all and no subgroup.
   - **Exceptions:**
     - `white_meat × colorectal × all`: the only printed estimate with a CI is from the addition model (0.95, 0.91–0.99), so that row is `yes`. The substitution counterpart is printed only in Figure 1 and in Table 3 by stage.
     - Sex-specific CRC rows (Suppl Table 1 values quoted in the text) are `yes` for men and women. They are the only sex-specific estimates.
   - All stage rows and all single-subsite rows are `no`.
   - **Caution for pooling:** the substitution HR (red for white, total meat constant) is a different quantity from the usual "per unit red meat" HR. The addition-model red-meat estimate (16 % for CRC) is printed only as a percentage without a CI and could not be coded. The `red_total` "main" rows here are therefore substitution estimates and should be filtered on `contrast_type` before pooling with ordinary per-100 g estimates.
3. **Exposure mapping.**
   - "Red meat" → `red_total`. It includes processed red meat: total red = unprocessed red + processed red (ham, bacon, hotdogs, beef cold cuts, sausages, meat of pizza).
   - "Red unprocessed" → `red_unprocessed`. Its model includes red processed meat, so `is_mutually_adjusted_processed = yes` for those rows, and m2 has `adj_processed_meat = yes`.
   - "Red processed meat" and "Processed meat" (total processed = red + white processed) → both `processed`. They are distinguished by `exposure_text` and `model_label`.
   - "White meat", "White unprocessed", "White processed" → `white_meat`, distinguished by `exposure_text`.
   - "Poultry" → `poultry`, with `exposure_includes_processed = yes` (poultry cold cuts, low-fat sausages and low-fat hotdogs are included).
   - "Fish" → `fish`, with `exposure_includes_processed = no`. Fish is not itemised; the Discussion says it is mostly canned tuna.
4. **Fish/poultry substitution direction.** The Table 2 footnote says only "additionally adjusted for total meat". The text says "Substituting red meat intake for either fish or poultry was associated with lower incidence", which means fish or poultry replacing red meat, given HR < 1. Which other meat terms were left out is not stated. `adj_fish`/`adj_poultry` are `unclear` in m4 and m7.
5. **Addition model for fish/poultry.** Table 2 fn 3 says "additionally adjusted for total red meat intake". This differs from the Figure 2 addition model, which includes four subtypes. Coded as m7.
6. **Case counts.** Only the overall CRC total (9,461) and person-years (6,896,619) are printed. They are filled only on CRC × all rows that are not stage or subsite rows. Subsite, sex and stage case counts are in the unavailable supplement.
7. **Dose unit.** All estimates are per 50 g/1000 kcal/d. The paper says this "equates to 100 g/2000 kcal/d" and "roughly corresponds to 80th percentile" of red+white meat intake. Converting to g/day needs an energy assumption, so no conversion was made. The Table 1 median energy (1,554–1,846 kcal/d across red-meat quintiles) is noted in dose_conversions.

## Not coded (no CI printed, or figure/supplement only)
- **Percentages without CIs in the Results text:**
  - red-meat addition models (CRC 16 %, proximal 11 %, distal 22 %, rectal 19 %, cecum 13 %, transverse 21 %, sigmoid 24 %, rectosigmoid 41 %);
  - red unprocessed and processed substitution (CRC 19 % / 30 %; proximal 13 % / 25 %; rectal 25 % / 48 %; rectosigmoid 64 % / 67 %; distal 24 % and sigmoid 29 % for unprocessed; cecum 35 %, transverse 59 %, rectum 41 % for processed) and the matching addition results;
  - white-meat subtype substitution and addition percentages;
  - total processed vs unprocessed substitution (CRC 15 %, proximal 18 %, cecum 33 %) and addition (16 %, 18 %, 30 %).
- All of these need Figure 2, Supplementary Tables 1 and 3, or the figure data. **Obtaining the supplement and figure source data would roughly triple the coded rows.**
- Supplementary Tables 4–5 (quintiles), 6 (heterogeneity), 7 (E-values), 8–9 (BMI and race strata) and 10 (follow-up periods): not available.
- Table 3's white-meat substitution for colorectal overall exists only in Figure 1, so it is not coded.

## Typos and inconsistencies (flagged)
- The text says "using estimated 25 g/1000 kg intervals" ("kg" should be "kcal"). This is a typo in the text only, with no numbers affected.
- The text heading says "unprocessed with meat (P = 0.04)" ("with" should be "white"). Text only.
- The Results say "substitution effect of white meat for processed red meat … cecum (35%)". The Discussion repeats "cecum (35%)", but the abstract and Results elsewhere give "cecum (33%)" for total processed vs unprocessed. These are different contrasts, so this is not necessarily an inconsistency.
- In the Discussion, "Fish intake was associated with a 34% lower incidence in the cecum" matches Table 2 fish substitution, cecum 0.66. "40% lower … rectosigmoid" matches 0.60. "Poultry … 39% lower … rectosigmoid" matches 0.61, and "18% lower in the rectum" matches 0.82. Consistent.
- The text gives the white meat addition model for CRC as "HR = 0.95 (0.91, 0.99)", and the Discussion says "(5%)". Consistent.
- checks.py found no CI asymmetry flags.

## Relation to Cross 2010 (same cohort)
- Same cohort, `cohort_id = nih_aarp`. Never pool with cross2010 (or with the NIH-AARP arm of etemadi2018).
- Differences:
  - follow-up runs to 2018, not 2003;
  - adenocarcinoma only;
  - the first 2 years are excluded;
  - exposures are nutrient density (g/1000 kcal) rather than quintiles of g/1000 kcal, and the main estimates are substitution models.
- The "Cross → Zouiouich" version comparison in KODEBOK §7 is **not like-for-like**. Cross 2010 reports quintile HRs for red meat; Zouiouich reports per 50 g/1000 kcal substitution HRs.

## Study-level
- The journal name is not printed in the txt. The DOI 10.1016/j.cdnut.2025.107540 is printed (Footnotes), and the journal is inferred from the DOI prefix (Current Developments in Nutrition). PMID not printed.
- `followup_years = 18.42`, `median`.
- `cases_colon` and `cases_rectum` are empty because they are not printed.
- `validation_r` is empty because it is sex-specific (0.62 men, 0.70 women); the values are in the study notes.
- `in_cup2016 = no` and `cup_role = post_2016` come from the tillegg list.

## Completion 30.10 (opus-Z, 2026-10-30)
Source: PDF-derived full text `/home/claude/drive/post2015/zouiouich2025.txt` (journal pages 5–6 carry Figures 1–2 with printed HRs, 95% CIs and per-site case counts). I checked all 91 existing rows against this text first. Every value matches (Fig 1 text values, Table 2: 52/52, Table 3: 27/27).

### Added: 146 rows, zouiouich2025_092–237 (total now 237)
- **Fig 1, p. 5: 42 rows.** Fig 1 has 13 sites × {red, white} × {substitution, addition}, which is 52 values; 10 were already coded (080, 083–091).
  - 25 addition rows (`continuous`, m6): red meat × 13 sites, plus white meat × 12 sites (white × CRC addition was already 091).
  - 17 substitution rows:
    - white replacing red × 13 sites (m1);
    - red replacing white for the 4 sites the text did not print: ascending colon, hepatic flexure, splenic flexure, descending colon.
- **Fig 2, p. 6: 104 rows.** These are 13 sites × {red unprocessed, red processed, white unprocessed, white processed} × {substitution, addition}.
  - Substitution rows use m2 (red subtypes) and m3 (white subtypes).
  - Addition rows use the **new adjustment set m8**: all four subtypes in one model, no total-meat term (Fig 2 legend).
- **Case counts:**
  - Every new row has `n_cases` = the total cases printed for its site in the figure: CRC 9461, proximal 4565, cecum 1851, ascending 1597, hepatic flexure 428, transverse 689, distal 2437, splenic flexure 238, descending 400, sigmoid 1799, rectal 2208, rectosigmoid junction 618, rectum 1590.
  - `person_years` (6,896,619) is filled only on CRC rows.
  - For existing site rows (Table 2 and text-derived Fig 1 rows), the count is appended to `notes`. The `n_cases` cells were left as originally coded.
- **Notes on each new row:** the source line in the txt, the model, and the reason for `is_main_model`.

### In-place edits to existing rows (only these fields)
- **`is_main_model` yes→no on 18 substitution rows:**
  - fish and poultry, colorectal/proximal/distal/rectum: 001, 002, 005, 006, 025, 026, 041, 042;
  - red_total, colorectal/proximal/distal/rectum and CRC men/women: 080–085.
  - Each row's note gives the reason and the addition row that is now main.
- **`is_main_model` no→yes on the 8 fish/poultry addition rows** (Table 2, m7): 003, 004, 007, 008, 027, 028, 043, 044.
  - This applies the rule "the addition-model row is main for each exposure × outcome" to fish and poultry too.
  - Without it, fish and poultry would have no main row once the substitution rows were set to no.
- **`exposure_includes_processed` no→partial on the 3 red_unprocessed stage rows (056–058).** Methods list hamburger and liver among "unprocessed red meats" (R6). The same value is used on all new red_unprocessed rows.
- **`notes`:** a "Completion 30.10" sentence was appended on 66 existing rows (the main-model change, partial, and/or the site case count). Existing note text is unchanged.

### Other file changes
- **adjustments.csv:** added `zouiouich2025_m8`, the Fig 2 addition model.
  - `adj_processed_meat = yes`.
  - `adj_poultry` and `adj_fish` = unclear, because these enter only via white unprocessed/processed.
- **study.csv:**
  - `cases_rectum = 2208` (Fig 1, "Rectal").
  - `cases_colon` is left empty. Proximal + distal is 7002, and the overall CRC total of 9461 also includes 251 overlapping/NOS cases that are in no subsite.
  - The notes sentence saying subsite counts were not printed is corrected.
- **dose_conversions.csv:** unchanged.

### is_main_model (now one row per exposure code × outcome × sex = all)
| exposure | colorectal / proximal / distal / rectum main rows |
|---|---|
| red_total | 092 / 094 / 111 / 125 (Fig 1 addition, m6) |
| red_unprocessed | 134 / 142 / 182 / 214 (Fig 2 addition, m8) |
| processed | 136 / 144 / 184 / 216 (Fig 2 addition, m8: *red* processed) |
| white_meat | 091 / 095 / 112 / 126 (Fig 1 addition, total white meat, m6) |
| fish | 003 / 007 / 027 / 043 (Table 2 addition, m7) |
| poultry | 004 / 008 / 028 / 044 (Table 2 addition, m7) |

- **No main row for sex-specific estimates** (CRC men 081, women 082). Only substitution estimates are printed by sex; the addition-model sex estimates are in Suppl Table 1, which is unavailable.
- **This supersedes judgment call 2 above** (substitution = main) and the "Caution for pooling" paragraph, which said the red-meat addition estimate was not printed. It is printed in Fig 1.

### Judgment calls (Completion)
1. **Addition model = `continuous`.** Each addition HR is a per-50 g/1000 kcal effect with the other meat types held constant and no total-meat term. This is the closest analogue to other cohorts' per-unit HRs. However, the red-meat addition HRs are adjusted for white meat (m6) or for the other three subtypes (m8). The paper itself treats substitution as primary ("complementary" addition models). Analysts should filter on `contrast_type`.
2. **Fig 2 red unprocessed vs red processed both from m8.**
   - In m8, red unprocessed is adjusted for red processed, so `is_mutually_adjusted_processed = yes`.
   - For red processed (exposure `processed`) it is `no`, since the field means "adjusted for processed meat".
   - White subtype rows in m8 are `yes`, because red processed is in the model.
3. **Two processed-meat variables share `processed`.**
   - "Red processed" (Fig 2) is the main row.
   - "Processed meat" (total red + white processed; Table 3 stage rows, m5) stays non-main. Its CRC/proximal/cecum addition and substitution values exist only as percentages (16%/18%/30%, 15%/18%/33%) without CIs, so they are not coded.
4. **Three white-meat variables share `white_meat`.** Main = total white meat (Fig 1). White unprocessed/processed rows (Fig 2) are `no`, distinguished by `exposure_text`.
5. **Fish/poultry addition (m7) differs from Figs 1–2 addition.** Table 2 fn 3 says these are "additionally adjusted for total red meat". They were still made main (see the in-place edits above), to keep the rule uniform.
6. **Fig 1 rows already coded from the Results text (080–091) were not duplicated.** Their values match the figure exactly. `source_table` was left as "Fig 1 (values from Results text)", and the page was not changed (instruction: no other edits). The new rows carry `source_page` 5 (Fig 1) or 6 (Fig 2).
7. **Subsite rows** keep the existing convention: parent outcome plus a `subgroup` = subsite, with `is_main_model = no`.

### Possible typo / flags
- **Fig 2, descending colon, red processed substitution: 1.32 (0.61 − 2.85).** This is identical to splenic flexure red processed substitution (238 cases), although the addition values differ (descending 1.31 (0.75–2.27) vs splenic 1.34 (0.64–2.80)). The substitution CI is also implausibly wider than the addition CI at that site. It looks like a copy error in the figure. Recorded as printed (row 201) and flagged in its notes.
- **checks.py** flags 138 (white unprocessed addition, CRC, 0.95 (0.91–1.00)) with log-asymmetry 0.16, just over the 0.15 limit. This is consistent with two-decimal rounding; recorded as printed.
- **Fig 2 text:** "unprocessed with meat (P = 0.04)" remains a typo (white).

### Still not coded
- Supplementary Tables 1–10, which are not available. These include sex-specific addition models, total processed vs unprocessed with CIs, the 25 g/1000 kcal analyses, quintiles, follow-up periods, and BMI/race strata.

## Supplement rows (30.10)
Extractor: opus-S5 · 2026-10-30 · Source: `/home/claude/drive/supplements/zouiouich2025_suppl.txt` (Supplementary Tables 1–10, converted from Word; table cells one per line, parsed by script and spot-checked). Existing 237 rows read first; every supplement value was compared against them.

### New vocabulary
- `dose_unit = per_25g_per_1000kcal` (Suppl Table 2).
- `dose_unit = g_per_1000kcal_day` used for the quintile category rows (already in KODEBOK).
- `subgroup` values: `bmi_lt25`, `bmi_25_lt30`, `bmi_ge30` (S8; combined with subsite as `subsite_x+bmi_y`); `race_nh_white`, `race_nh_black`, `race_hispanic`, `race_asian_pi_aian` (S9); `lag_0_5y`, `lag_5_10y`, `lag_10plus_y` (S10).
- `category_set_id` for quintile sets: `zouiouich2025_<s4sub|s5add>_<outcome or subsite>_all_<variable>`, where `<variable>` ∈ red_total, red_unprocessed, red_processed, white_total, white_unprocessed, white_processed, fish, poultry, processed_total. The variable token (not the exposure code) is used because three variables share `white_meat` and two share `processed`. Subsite sets use the subsite name in the outcome slot (e.g. `..._s4sub_cecum_all_fish`).
- estimate_id runs past 999 (zouiouich2025_1000 … _2863); numbering is continuous, ids are not zero-padded to four digits.

### Added: 2,626 rows, zouiouich2025_238–2863 (total now 2,863)
| Table | Content | Rows added | Skipped as exact duplicates |
|---|---|---|---|
| S1 | Substitution, per 50 g/1000 kcal, 13 sites × {overall, men, women} × 9 meat variables (351 values) | 246 | 105 (Fig 1/Fig 2/Table 2 overall rows; text rows 081/082 men/women red) |
| S2 | Same, per 25 g/1000 kcal (`per_25g_per_1000kcal`) | 351 | 0 |
| S3 | Addition, per 50 g/1000 kcal, 13 sites × 9 variables (117 values) | 13 (total processed meat only) | 104 (Fig 1, Fig 2, Table 2 addition rows) |
| S4 | Quintiles, substitution, 9 variables × 13 sites × Q1–Q5 | 585 | 0 |
| S5 | Quintiles, addition, same layout | 585 | 0 |
| S6 | Heterogeneity tests | 0 (notes only, below) | |
| S7 | E-values | 0 (notes only, below) | |
| S8 | Substitution stratified by BMI (3 strata) × 13 sites × 9 variables, cases per stratum | 351 | 0 |
| S9 | Substitution stratified by race/ethnicity (4 strata) × 4 sites (CRC, proximal, distal, rectal) × 9 variables, cases per stratum | 144 | 0 |
| S10 | Lag analysis 0–5, 5–10, 10+ y × 13 sites × 9 variables | 351 | 117 (the "Overall" block is identical to S1 overall, value for value) |

- **S1 men/women** are the first sex-specific estimates for all variables and sites (only CRC red men/women were in the file).
- **Case counts:** S1/S2/S3 overall-sex rows get the site total from Figs 1–2 (`n_cases`, with `person_years` 6,896,619 on CRC rows only), following the Completion convention. Sex-specific, quintile and lag rows have no printed case counts (`denominator_type = none`, `n_cases` empty). S8 and S9 rows carry the stratum's printed case count in `n_cases`.
- **Quintiles (S4/S5):** the supplement prints HRs only — no cut-points, no medians, no cases or person-years per quintile. `dose_low`/`dose_high` are empty. Only for total red meat are quintile medians available, from main-text Table 1 (red-meat quintiles, g/1000 kcal/d): Q1 9.83, Q3 31.30, Q5 62.53 → `dose_point`, `paper_median` on the total-red Q1/Q3/Q5 rows; Q2/Q4 empty. Table 1 medians of other meats are by red-meat quintile, not by the variable's own quintile, so they are not used. `p_trend` sits on the Q5 row. Q1 is printed "1.00" and coded point 1.00 with empty CI. These sets cannot be used for Greenland–Longnecker without dose assumptions; documented in dose_conversions c02–c10.

### Adjustment sets added (11)
- **m9** — addition model for total processed meat (S3, S5). Partner term inferred as total unprocessed meat (Methods: addition-model terms sum to total meat); not itemised.
- **m10–m14** — m1–m5 with BMI removed (S8 footnote omits BMI). `adj_bmi = no`.
- **m15–m19** — m1–m5 with race/ethnicity removed (S9 footnote omits it). No flag column changes (no race flag), but covariates differ, so new ids.
- S1, S2, S4, S10 rows reuse m1–m5; S3/S5 reuse m6, m7, m8 (+ m9).

### Judgment calls
1. **Which model is S1?** The S1 footnote lists total meat among covariates → substitution ("leave-one-out") models, matching Fig 1/Fig 2/Table 2 substitution values exactly. Meat-to-adjustment-set mapping: Red/White → m1; Red unprocessed/processed → m2; White unprocessed/processed → m3; Fish/Poultry → m4; Processed (total) → m5. S10 uses the same model per its footnote.
2. **Exact-duplicate rule:** a supplement value was skipped only if exposure_text, contrast, outcome, subgroup, sex, dose unit and point/CI were all identical to an existing row. All 104 overlapping S3 values and 105 of 106 overlapping S1 values matched; the one mismatch is coded (see flags).
3. **S3 fish/poultry = Table 2 addition (m7)**: values identical, so S3's "corresponding meat groups" for fish/poultry is the Table 2 model (adjusted for total red meat). No change to m7.
4. **is_main_model = no on all 2,626 new rows.**
   - Sex-specific S1 rows: the database's main rows for this study are the addition (continuous) estimates (Completion 30.10). The supplement has no sex-specific addition model (S3 is not split by sex), so men/women still have no main row. Making the S1 sex-specific substitution rows main would mix contrast types between sexes; I did not do that. If analysts want sex-specific estimates, filter `contrast_type = substitution`, `source_table = Suppl Table 1`.
   - S3 total processed meat: `processed` main rows are red processed (Fig 2, m8) per Completion judgment 3.
   - S2 (alternative unit), S4/S5 (categorical, for nonlinearity), S8/S9/S10 (strata/lag): not main.
5. **Exposure mapping** as in the existing file: "Processed" column = total processed meat (red + white processed) → `processed`, exposure_text "Processed meat"; White unprocessed/processed → `white_meat` with distinct exposure_text. Red unprocessed `partial` (hamburger, R6).
6. **S5 adjustment:** the S5 footnote does not mention meat terms at all (S3's says "corresponding meat groups"). Assumed the S3 addition sets (m6/m7/m8/m9); noted on each row.
7. **S10 periods:** Methods say 0–5, 5–10, 10–15, 15+ y; S10 prints 0–5, 5–10, 10+ y. Coded as printed (`lag_10plus_y`). N at risk per period (454,505 / 401,425 / 342,588) is in the row notes, not in `n_in_category` (it is not a per-category denominator).

### Supplement vs main text (contradictions / flags)
- **Fig 2 typo confirmed.** Descending colon, red processed, substitution: Fig 2 prints 1.32 (0.61–2.85) (row 201, already flagged); S1 and S10-Overall print **1.32 (0.74, 2.36)**, and 1.32 (0.61, 2.85) is the S1 value for the splenic flexure. Coded as new row **zouiouich2025_388** (S1 value) and noted on 201 (notes only; values untouched). Analysts should prefer 388.
- No other S1/S3 value contradicts Figs 1–2, Table 2 or the Results text.
- Main-text typo "25 g/1000 kg" confirmed as kcal by S2's title.
- S9 contains extreme-imprecision cells, recorded as printed: e.g. rectal, Asian/PI/AI-AN, white processed 0.07 (0.00, 43.12); proximal, same stratum, white processed 0.28 (0.00, 17.48). ci_low 0.00 is printed so.
- checks.py (scratch copy): 25 log-asymmetry flags (138 existing + 24 new). All are narrow two-decimal CIs (S2 per 25 g mostly) or tiny-count cells (2851: 0.06 (0.01, 0.75)); consistent with rounding, recorded as printed. No other check failed.

### S6 heterogeneity tests (notes only; substitution, per 50 g/1000 kcal; p-values)
- Proximal subsites (cecum, ascending, hepatic flexure, transverse): red 0.6055, red processed 0.4437, red unprocessed 0.8946, white 0.6055, white processed 0.6098, white unprocessed 0.6553, fish 0.5396, poultry 0.5636, processed 0.5227.
- Distal subsites (splenic, descending, sigmoid): red 0.7167, red processed 0.9626, red unprocessed 0.5471, white 0.7168, white processed 0.1719, white unprocessed 0.9150, fish 0.9275, poultry 0.7311, processed 0.5116.
- Rectal subsites (rectosigmoid junction, rectum): red 0.0430, red processed 0.5532, red unprocessed 0.0379, white 0.0430, white processed 0.9850, white unprocessed 0.0355, fish 0.1060, poultry 0.1049, processed 0.6929.
- CRC regions (proximal, distal, rectal): red 0.3555, red processed 0.5337, red unprocessed 0.4534, white 0.3555, white processed 0.0542, white unprocessed 0.6283, fish 0.4266, poultry 0.0754, processed 0.8572.
- Red and white p-values are identical within each grouping (except distal, 0.7167 vs 0.7168), as expected for mirror-image substitution contrasts.

### S7 E-values (notes only; substitution, per 50 g/1000 kcal)
| Site | Red | Red unproc | Red proc | White | White unproc | White proc | Fish | Poultry | Processed |
|---|---|---|---|---|---|---|---|---|---|
| Colorectal | 1.72 | 1.65 | 1.91 | 1.72 | 1.71 | 1.81 | 1.75 | 1.71 | 1.56 |
| Proximal | 1.58 | 1.50 | 1.80 | 1.58 | 1.61 | 1.12 | 1.96 | 1.45 | 1.65 |
| Distal | 1.80 | 1.79 | 1.82 | 1.80 | 1.79 | 1.93 | 1.44 | 1.94 | 1.45 |
| Rectal | 1.93 | 1.80 | 2.31 | 1.93 | 1.84 | 3.46 | 1.78 | 1.99 | 1.53 |
- E-values are for the point estimates (no CI-limit E-values printed).

### Supersedes
- The "Still not coded" list under Completion 30.10 and the Contents note that Suppl Tables 4–5 are unavailable: all ten supplementary tables are now coded or noted. study.csv notes updated with one sentence.
