Update ThothII presentation tour, annotated screenshots and speaker notes

This commit is contained in:
Codex
2026-09-24 12:09:20 +02:00
parent 5217c574e9
commit d5310d5a3f
23 changed files with 402 additions and 57 deletions
+120 -8
View File
@@ -8,7 +8,7 @@
<link rel="stylesheet" href="deck.css?v=41">
<link rel="stylesheet" href="slide-lens.css?v=7">
<link rel="stylesheet" href="ai-callouts.css?v=3">
<link rel="stylesheet" href="screenshot-tour.css?v=1">
<link rel="stylesheet" href="screenshot-tour.css?v=5">
</head>
<body>
<div class="reveal"><div class="slides">
@@ -508,7 +508,7 @@
<div class="sbody">
<div class="kicker">The portal, today</div>
<h2>AritmoLab — a quick tour</h2>
<div class="screenshot-tour" aria-label="AritmoLab tour, screenshots 1 to 7">
<div class="screenshot-tour" data-screenshot-auto-open aria-label="AritmoLab tour, screenshots 1 to 7">
<button type="button" data-screenshot="home" data-screenshot-number="1" data-screenshot-title="Home page" aria-haspopup="dialog"><img src="screenshots/1-HomePage.png" alt="" loading="lazy"><span><b>1</b> Home page</span></button>
<button type="button" data-screenshot="patients" data-screenshot-number="2" data-screenshot-title="Patient list" aria-haspopup="dialog"><img src="screenshots/2-PatientList.png" alt="" loading="lazy"><span><b>2</b> Patient list</span></button>
<button type="button" data-screenshot="profile" data-screenshot-number="3" data-screenshot-title="Patient profile" aria-haspopup="dialog"><img src="screenshots/3-PatientGeneralData.png" alt="" loading="lazy"><span><b>3</b> Patient profile</span></button>
@@ -602,14 +602,111 @@
<div class="sbody">
<div class="kicker">ThothII, step by step</div>
<h2>From question to datamart — the app</h2>
<div class="shots">
<div class="shot">screenshot</div><div class="shot">screenshot</div><div class="shot">screenshot</div>
<div class="shot">screenshot</div><div class="shot">screenshot</div><div class="shot">screenshot</div>
<div class="screenshot-tour screenshot-tour-compact" data-screenshot-auto-open aria-label="ThothII tour, screenshots 1 to 12">
<button type="button" data-screenshot="thothii-start" data-screenshot-number="1" data-screenshot-title="Starting point" aria-haspopup="dialog">
<img src="screenshots/thothii/01-StartingPoint.png?v=4" alt="" loading="lazy"><span><b>1</b> Starting point</span>
</button>
<button type="button" data-screenshot="thothii-disambiguation-1" data-screenshot-number="2" data-screenshot-title="Disambiguation · 1" aria-haspopup="dialog">
<img src="screenshots/thothii/02-Disambiguation01.png?v=4" alt="" loading="lazy"><span><b>2</b> Disambiguation · 1</span>
</button>
<button type="button" data-screenshot="thothii-disambiguation-final" data-screenshot-number="3" data-screenshot-title="Question clarified" aria-haspopup="dialog">
<img src="screenshots/thothii/03-DisambiguationFinal.png?v=4" alt="" loading="lazy"><span><b>3</b> Question clarified</span>
</button>
<button type="button" data-screenshot="thothii-schema-1" data-screenshot-number="4" data-screenshot-title="Schema linking · 1" aria-haspopup="dialog">
<img src="screenshots/thothii/04-SchemaLinking01.png?v=4" alt="" loading="lazy"><span><b>4</b> Schema linking · 1</span>
</button>
<button type="button" data-screenshot="thothii-schema-final" data-screenshot-number="5" data-screenshot-title="Schema confirmed" aria-haspopup="dialog">
<img src="screenshots/thothii/05-CloseSchemaLinking.png?v=4" alt="" loading="lazy"><span><b>5</b> Schema confirmed</span>
</button>
<button type="button" data-screenshot="thothii-cte-plan" data-screenshot-number="6" data-screenshot-title="CTE planning" aria-haspopup="dialog">
<img src="screenshots/thothii/06-CTEPlanning.png?v=4" alt="" loading="lazy"><span><b>6</b> CTE planning</span>
</button>
<button type="button" data-screenshot="thothii-cte-1" data-screenshot-number="7" data-screenshot-title="CTE · 1" aria-haspopup="dialog">
<img src="screenshots/thothii/07-CTE01.png?v=4" alt="" loading="lazy"><span><b>7</b> CTE · 1</span>
</button>
<button type="button" data-screenshot="thothii-sql" data-screenshot-number="8" data-screenshot-title="Final SQL" aria-haspopup="dialog">
<img src="screenshots/thothii/08-FinalSQL.png?v=5" alt="" loading="lazy"><span><b>8</b> Final SQL</span>
</button>
<button type="button" data-screenshot="thothii-datamart" data-screenshot-number="9" data-screenshot-title="Datamart" aria-haspopup="dialog">
<img src="screenshots/thothii/09-DatamartProduction.png?v=5" alt="" loading="lazy"><span><b>9</b> Datamart</span>
</button>
<button type="button" data-screenshot="thothii-memory" data-screenshot-number="10" data-screenshot-title="Saving memory" aria-haspopup="dialog">
<img src="screenshots/thothii/10-MemorySaving.png?v=5" alt="" loading="lazy"><span><b>10</b> Saving memory</span>
</button>
<button type="button" data-screenshot="thothii-finish" data-screenshot-number="11" data-screenshot-title="Final step" aria-haspopup="dialog">
<img src="screenshots/thothii/11-FinalStep.png?v=5" alt="" loading="lazy"><span><b>11</b> Final step</span>
</button>
<button type="button" data-screenshot="thothii-return" data-screenshot-number="12" data-screenshot-title="Back to start" aria-haspopup="dialog">
<img src="screenshots/thothii/12-BackToStartingPoint.png?v=5" alt="" loading="lazy"><span><b>12</b> Back to start</span>
</button>
</div>
<p class="hint">[MP: 6-7 real screenshots of ThothII — ask, review SQL, datamart, dashboard]</p>
<p class="hint">Select a screen to enlarge · Follow the tour from 1 to 12</p>
</div>
<footer class="foot"><span class="g">Role of AI in the Analysis of Unstructured Clinical Databases</span><span class="g">Dr. Marco Pancotti - MultiPhysixLab</span><span class="g">Dr. Sara Paratico - Gruppo San Donato</span><span class="g">San Donato Milanese, Milan, Italy · 2–3 October 2026</span><span class="g num">11 / 13</span></footer>
<aside class="notes">[DRAFT] Let me walk you through ThothII: the researcher asks the question in plain English; the AI proposes the SQL; the query is reviewed; the datamart is assembled; the dashboard comes alive. Six screens, a few minutes. MP: real screenshots.</aside>
<aside class="notes">
<div data-popup-notes="thothii-start"><h3>From a research question to SQL</h3><div data-popup-notes-body><p>The task has changed. We are no longer extracting structured, coded values from the text within clinical records. We are now starting from a natural-language request to retrieve the records that contain the relevant values.</p><p>Research questions are often difficult to express clearly and unambiguously, and their clinical concepts do not map directly to the underlying database structure. As a result, writing the right SQL query can take hours, with repeated testing and refinement before it accurately reflects the intended research question.</p></div></div>
<div data-popup-notes="thothii-disambiguation-1"><h3>Clarifying the question with the researcher</h3><div data-popup-notes-body>
<p><strong>1. Workflow phase.</strong> At the top, the phase indicator shows where we are in the process. Here, phase one is highlighted: clarifying the research question.</p>
<p><strong>2. AI working time.</strong> The timer measures how long the AI has been working, excluding the time the human reviewer spends considering the options and making decisions.</p>
<p><strong>3. Model activity.</strong> On the left, we can follow the AI's running explanation of its analysis: the interpretations it considers, the evidence it consults, and the rationale for its proposals.</p>
<p><strong>4. Proposed interpretations.</strong> In the centre, the AI asks the researcher to choose between alternative interpretations. Here, the question is how to identify an ablation for atrial fibrillation in the database. This choice determines which patients enter the study.</p>
<p><strong>5. Reviewer actions.</strong> The reviewer can select a proposed option, or use <strong>Go back</strong> to revisit the previous step, <strong>Exit</strong> to stop the current workflow, or <strong>Other — specify</strong> to describe a different interpretation in free text.</p>
</div></div>
<div data-popup-notes="thothii-disambiguation-final"><h3>From clarification to an agreed study question</h3><div data-popup-notes-body>
<p><strong>Bringing the decisions together.</strong> The AI combines the original request with the researcher's answers into an explicit study definition. It records what we mean by each clinical concept, which patients to include, the time window, and the result we want.</p>
<p><strong>The clarified question.</strong> In this example: how many distinct patients had their first recorded ablation for atrial fibrillation between 2020 and 2023? We identify the procedure from the treated pathology, and find each patient's first AF ablation across the entire available database history before applying the date filter.</p>
<p><strong>Making the interpretation actionable.</strong> The summary links these choices to the relevant database fields and selection rules, and displays the checks completed during clarification. These agreed criteria guide the subsequent schema linking and SQL construction.</p>
<p><strong>Human confirmation.</strong> The researcher reviews the consolidated definition. <strong>Save and proceed</strong> confirms it and closes phase one; <strong>Reject</strong> sends it back for revision.</p>
</div></div>
<div data-popup-notes="thothii-schema-1"><h3>Finding the data needed to answer the question</h3><div data-popup-notes-body>
<p><strong>Linking clinical meaning to data.</strong> We are now in phase four, schema linking: identifying where the information needed to answer the agreed question is stored. Tables group related records; columns hold specific details, such as a patient identifier, a procedure date, or the condition treated.</p>
<p><strong>Proposed tables.</strong> The AI presents candidate tables and explains why each is relevant. Here, one table provides the ablation episodes and their dates; another identifies the pathology treated, allowing us to distinguish atrial fibrillation ablations from other procedures.</p>
<p><strong>Selecting the columns.</strong> The column controls let the reviewer inspect and adjust the fields selected for the query. We need the information required to identify patients, recognise the relevant procedures, and apply the agreed time criteria.</p>
<p><strong>Review before proceeding.</strong> The researcher and a technical reviewer can check this mapping together, adjust the selection, and confirm it. This establishes which data will support the SQL query; the relationships between the selected tables are reviewed next.</p>
</div></div>
<div data-popup-notes="thothii-schema-final"><h3>Schema linking complete: from clinical meaning to database structure</h3><div data-popup-notes-body>
<p><strong>What schema linking means.</strong> Schema linking connects the concepts in the clarified research question to the database: which tables contain the information, which columns represent each concept, and how records from different tables must be connected.</p>
<p><strong>Our clinical example.</strong> Here, we connect the treated pathology to the corresponding ablation episode, associate that episode with its date and patient, and specify the rules for identifying each patient's first recorded AF ablation and applying the 2020–2023 window. The intended result is a count of distinct patients.</p>
<p><strong>What completion means.</strong> These choices are now consolidated into a documented mapping, with the relationships, selection rules, and validation checks shown for review. We have an explicit specification of where the answer will come from and how the relevant data fit together.</p>
<p><strong>The final approval.</strong> By selecting <strong>Save and proceed</strong>, the reviewer approves this mapping for the next stage: planning and building the SQL query. Query execution and verification of the resulting patient count still follow.</p>
</div></div>
<div data-popup-notes="thothii-cte-plan"><h3>CTEs: building the query step by step</h3><div data-popup-notes-body><p><strong>CTE stands for Common Table Expression.</strong> It is a named intermediate result within an SQL query.</p><p>CTEs break a complex research question into smaller, logical steps—for example, identifying AF ablations, finding the first procedure for each patient, and selecting the study population.</p><p>This makes the query easier to understand, check, and modify, helping us verify that each step reflects the intended clinical criteria.</p></div></div>
<div data-popup-notes="thothii-cte-1"><h3>Reviewing a CTE: purpose, SQL, and results</h3><div data-popup-notes-body>
<p><strong>Purpose and position.</strong> Each CTE is presented as a reviewable step. At the top, we see its name and position in the sequence: here, the first of three. A short explanation describes its clinical purpose and the reasoning behind the selection rules.</p>
<p><strong>The SQL implementation.</strong> The code shows how that purpose is translated into database operations. In this example, it connects the treated pathology to the ablation episode and selects AF ablations, returning the patient identifier, episode identifier, and procedure date.</p>
<p><strong>Tests and a data preview.</strong> The screen reports the test status and execution time, followed by a preview of the returned records. The ten rows shown are a limited preview, not the total study population. Successful execution still requires a check that the results make clinical sense.</p>
<p><strong>Human review.</strong> The reviewer can compare the explanation, code, and sample data before choosing <strong>Save and proceed</strong> or <strong>Reject</strong>. This makes each intermediate step inspectable before it contributes to the final query.</p>
</div></div>
<div data-popup-notes="thothii-sql"><h3>Titolo8</h3><div data-popup-notes-body><p>testo8</p></div></div>
<div data-popup-notes="thothii-datamart"><h3>Reusing the query: daily datamarts or research on demand</h3><div data-popup-notes-body>
<p>Once the query generation and review workflow is complete, the validated SQL query can be reused beyond the current session.</p>
<p><strong>Daily datamart generation.</strong> The query can be integrated into the broader ETL pipeline and scheduled to run every day. This allows the datamart to be rebuilt or refreshed systematically as new source data become available, using the same agreed selection rules.</p>
<p><strong>Reuse by researchers.</strong> Alternatively, the query can simply be saved as an SQL file and made available to researchers, who can inspect it, run it when needed, or adapt it for a subsequent study.</p>
<p>In both cases, the workflow produces a reusable query that captures the reviewed interpretation of the research question.</p>
</div></div>
<div data-popup-notes="thothii-memory"><h3>Saving clinical clarifications for future queries</h3><div data-popup-notes-body>
<p><strong>What we retain.</strong> Clarifying a research question can produce knowledge that is useful beyond the current study: for example, an agreed interpretation of a clinical term or how a procedure is represented in the local data.</p>
<p><strong>The researcher chooses.</strong> At the end of the workflow, ThothII presents candidate clarifications for reuse. The reviewer selects which ones to save as shared knowledge for the workspace.</p>
<p><strong>How this helps next time.</strong> When a related question is asked, ThothII can retrieve these clarifications and propose them to the reviewer. The reviewer checks whether they apply to the new question before using them. This helps avoid repeating the same clarification work while keeping each study's interpretation under human control.</p>
</div></div>
<div data-popup-notes="thothii-finish"><h3>A saved session documents how the result was reached</h3><div data-popup-notes-body>
<p>At the end of the workflow, ThothII finalizes a session that brings together the generated SQL statement and the documented process that led to it.</p>
<p>The session preserves the research question, its agreed interpretation, the mapping to the database, the intermediate query steps, and the recorded validation results.</p>
<p>Human involvement is captured through the recorded clarifications and review decisions: what the reviewer selected, approved, or rejected along the way. These records document how the interaction between the system and the researcher shaped the final query.</p>
<p>Researchers can revisit the session to inspect the SQL and understand the choices behind it. This provides a traceable record of how the original question became the final result.</p>
<p><strong>Time and cost for this example.</strong> The AI processing took less than five minutes, excluding the time spent on human review. Using DeepSeek V4 Flash, the estimated model cost for this run was about five cents.</p>
</div></div>
<div data-popup-notes="thothii-return"><h3>Expert supervision and deployment options</h3><div data-popup-notes-body>
<p><strong>Supervision requires knowledge of the data.</strong> The workflow must be supervised by someone who understands the meaning and content of the database tables and fields. AI can make plausible guesses about what a field represents or how records should be connected, and these guesses can become hallucinations. The reviewer's role is to challenge those assumptions and check them against the actual data and its clinical meaning.</p>
<p><strong>The researcher defines the dataset.</strong> Human judgement is essential to decide which information the study needs, which records meet the required quality criteria, and which time windows and temporal rules should apply. The responsible researcher must confirm these choices so that the resulting dataset addresses the research question. Successful SQL execution alone does not establish that the dataset is suitable for the study.</p>
<p><strong>Server or authorised workstation.</strong> At Policlinico San Donato, ThothII runs on a server. The application can also be installed on the PC of a qualified staff member who is authorised to access the database remotely. The application runs on that workstation, while the database server executes the SQL through the authorised connection.</p>
<p><strong>A local deployment option.</strong> Open models such as Qwen3.8-27B or Gemma 4 26B A4B are candidates for running the AI component on premises. Their suitability for this workflow should be assessed on representative research questions, including the quality of the generated SQL and the reliability of the review steps.</p>
<p><strong>Hardware within reach.</strong> With quantized models, a compact server equipped with a suitable GPU is a practical deployment option. A GPU budget of a few thousand euros is a planning target; the required memory and final cost depend on the model, context length, and number of concurrent sessions.</p>
<p><strong>Where the query runs.</strong> SQL execution takes place on the internal database server through controlled application code. The language model helps construct and review the query; the database engine executes it.</p>
<p><strong>Keeping model processing local.</strong> Hosting the session model on premises allows its prompts and responses to remain within the organisation. With an external model, the information included in prompts and tool results must be checked and filtered to prevent sensitive data from leaving the environment.</p>
<p><small>Model references: <a href="https://huggingface.co/Qwen/Qwen3.8-27B" target="_blank" rel="noopener noreferrer">Qwen3.8-27B model card</a>; <a href="https://ai.google.dev/gemma/docs/core" target="_blank" rel="noopener noreferrer">Gemma 4 models and memory requirements</a>.</small></p>
</div></div>
</aside>
</section>
<!-- ============ 12 · HAPPY ENDING ============ -->
<section class="arit">
@@ -673,7 +770,7 @@
<script src="vendor/reveal/dist/reveal.js"></script>
<script src="vendor/reveal/plugin/notes/notes.js?v=3"></script>
<script src="slide-lens.js?v=4"></script>
<script src="screenshot-tour.js?v=1"></script>
<script src="screenshot-tour.js?v=4"></script>
<script>
Reveal.initialize({
width: 1280, height: 720, margin: 0,
@@ -1029,6 +1126,11 @@
slides: () => Reveal.getSlides().map(slide => ({
title: slide.querySelector('h1, h2')?.textContent.trim() || '',
notes: slide.querySelector('aside.notes')?.innerHTML || '',
popupNotes: [...slide.querySelectorAll('aside.notes [data-popup-notes]')].map(note => ({
key: note.dataset.popupNotes,
title: note.querySelector('h3').textContent,
html: note.querySelector('[data-popup-notes-body]').innerHTML,
})),
popups: [...slide.querySelectorAll(popupSelector)].map(el => {
const id = popupIdentity(el);
if (id.kind === 'screenshot') return { ...id, title: el.dataset.screenshotTitle };
@@ -1048,6 +1150,16 @@
},
closePopup: closePop,
};
// Open the first tour stop only on slide entry, never on hover or focus.
// The thumbnail stays unobstructed; synchronized state can still close or replace the popup.
const openInitialScreenshot = () => {
if (new URLSearchParams(location.search).get('view') === 'thumbnail') return;
const first = Reveal.getCurrentSlide()?.querySelector('[data-screenshot-auto-open] [data-screenshot-number="1"]');
if (first) window.PresentationControls.openPopup(popupIdentity(first));
};
Reveal.on('slidechanged', openInitialScreenshot);
if (Reveal.isReady()) openInitialScreenshot();
else Reveal.on('ready', openInitialScreenshot);
addEventListener('resize', () => {
if (activePopup) window.PresentationControls.openPopup(activePopup);
});
+10 -2
View File
@@ -1,4 +1,4 @@
/* Seven ordered tour stops; screenshot originals keep their full aspect ratio. */
/* Ordered tour stops; screenshot originals keep their full aspect ratio. */
.arit .screenshot-tour {
display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(2, minmax(0, 1fr));
gap: 16px; flex: 1; min-height: 0; margin-top: 10px;
@@ -19,6 +19,12 @@
border-top: 1px solid var(--line); font: 600 16px/1.2 var(--sans);
}
.arit .screenshot-tour b { color: var(--bordeaux); font: 700 22px/1 var(--sans); }
.arit .screenshot-tour-compact {
grid-template-columns: repeat(6, minmax(0, 1fr));
grid-template-rows: repeat(2, minmax(0, 1fr)); gap: 10px;
}
.arit .screenshot-tour-compact span { gap: 8px; padding: 6px 10px; font-size: 14px; }
.arit .screenshot-tour-compact b { font-size: 18px; }
.screenshot-dialog {
box-sizing: border-box; width: calc(100vw - 24px); height: calc(100vh - 24px);
max-width: none; max-height: none; padding: 8px; margin: auto;
@@ -35,6 +41,8 @@
}
.screenshot-dialog button:hover { background: var(--bordeaux-tint); }
.screenshot-dialog button:focus-visible { outline: 3px solid var(--bordeaux); outline-offset: 1px; }
.screenshot-dialog img { width: 100%; height: 0; flex: 1; min-height: 0; object-fit: contain; }
.screenshot-stage { position: relative; flex: 1; min-height: 0; }
.screenshot-stage img { position: absolute; inset: 0; width: 100%; height: 100%; }
.screenshot-stage img { object-fit: contain; }
.screenshot-dialog .screenshot-error { margin: auto; text-align: center; }
@media print { .screenshot-dialog { display: none !important; } }
+8 -3
View File
@@ -3,7 +3,11 @@
const dialog = document.createElement('dialog');
dialog.className = 'screenshot-dialog';
dialog.setAttribute('aria-labelledby', 'screenshot-title');
dialog.innerHTML = '<header><h2 id="screenshot-title"></h2><button type="button" aria-label="Close screenshot">Close · Esc</button></header><img alt=""><p class="screenshot-error" hidden>Screenshot unavailable. Close and reopen to retry.</p>';
dialog.innerHTML = `<header><h2 id="screenshot-title"></h2><button type="button" aria-label="Close screenshot">Close · Esc</button></header>
<div class="screenshot-stage">
<img alt="">
</div>
<p class="screenshot-error" hidden>Screenshot unavailable. Close and reopen to retry.</p>`;
document.body.append(dialog);
const title = dialog.querySelector('h2');
const image = dialog.querySelector('img');
@@ -26,10 +30,11 @@
open(button) {
trigger = button;
active = { kind: 'screenshot', key: button.dataset.screenshot };
title.textContent = `${button.dataset.screenshotNumber} / 7 · ${button.dataset.screenshotTitle}`;
const total = button.closest('.screenshot-tour').querySelectorAll('[data-screenshot]').length;
title.textContent = `${button.dataset.screenshotNumber} / ${total} · ${button.dataset.screenshotTitle}`;
image.hidden = false;
error.hidden = true;
image.alt = `AritmoLab: ${button.dataset.screenshotTitle}`;
image.alt = button.dataset.screenshotTitle;
image.src = button.querySelector('img').src;
if (!dialog.open) dialog.showModal();
window.dispatchEvent(new Event('presentationchange'));
Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 959 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 948 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 925 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

+3
View File
@@ -1,5 +1,8 @@
# Presenter console
For the published AritmoLab site and routine Git updates, see
[Presentation publishing](../../docs/operations/presentation-publishing.md).
Serve `presentation/` using the same local server as the deck:
```sh
+2 -2
View File
@@ -5,8 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AritmoLab | Presenter console</title>
<link rel="stylesheet" href="../deck/fonts.css">
<link rel="stylesheet" href="presenter.css?v=5">
<script src="presenter.js?v=5" defer></script>
<link rel="stylesheet" href="presenter.css?v=6">
<script src="presenter.js?v=22" defer></script>
</head>
<body>
<header class="toolbar">
+1
View File
@@ -37,6 +37,7 @@ h2 { margin: 0; font-size: 16px; font-weight: 600; white-space: nowrap; } #count
.popup-group-lens .popup-buttons:has(> button:nth-child(4):last-child) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.popup-group-screenshot { grid-column: 1 / -1; }
.popup-group-screenshot .popup-buttons { grid-template-columns: repeat(7, minmax(0, 1fr)); }
.popup-group-screenshot .popup-buttons:has(> button:nth-child(12):last-child) { grid-template-columns: repeat(6, minmax(0, 1fr)); }
#popup-controls .popup-group-screenshot button { justify-content: center; }
.popup-group-screenshot button > span { display: none; }
#popup-controls .popup-group-lens button { flex-direction: column; justify-content: center; text-align: center; }
+17 -3
View File
@@ -13,12 +13,13 @@
let nextPreviewReady = false;
let slides = [];
let current = null;
let currentNoteKey = null;
let audience = null;
let lastAudienceSeen = 0;
let lastPreviewSeen = 0;
let notesSize = 25;
let blocked = false;
const urlFor = role => `../deck/index.html?view=${role}&session=${encodeURIComponent(session)}`;
const urlFor = role => `../deck/index.html?v=18&view=${role}&session=${encodeURIComponent(session)}`;
const pad = value => String(value).padStart(2, '0');
function showNoteLens(event) {
const cue = event.target.closest('[data-note-lens]');
@@ -101,7 +102,8 @@
$('notes-number').textContent = `SLIDE ${pad(state.index + 1)}`;
$('notes-title').textContent = slide.title;
// Trusted, same-origin authored notes, never channel-provided HTML.
renderNotes(slide.notes);
if (!slide.popupNotes?.length) renderNotes(slide.notes);
currentNoteKey = null;
$('reading').scrollTop = 0;
$('next-title').textContent = slides[state.index + 1]?.title || 'End of presentation';
updateNextPreview();
@@ -148,6 +150,18 @@
}
}
}
if (slide.popupNotes?.length) {
// Keep the last selected notes readable when its screenshot is closed.
const note = slide.popupNotes.find(note => state.popup?.kind === 'screenshot' && note.key === state.popup.key)
|| slide.popupNotes.find(note => note.key === currentNoteKey)
|| slide.popupNotes[0];
if (note.key !== currentNoteKey) {
currentNoteKey = note.key;
$('notes-title').textContent = note.title;
renderNotes(note.html);
$('reading').scrollTop = 0;
}
}
$('popup-controls').querySelectorAll('button').forEach(button => {
button.setAttribute('aria-pressed', String(state.popup?.kind === button.dataset.kind && state.popup?.key === button.dataset.key));
});
@@ -194,7 +208,7 @@
updateNextPreview();
});
// No session token: the thumbnail must never navigate or publish to the audience.
nextPreview.src = '../deck/index.html?view=thumbnail#/1';
nextPreview.src = '../deck/index.html?v=18&view=thumbnail#/1';
const stage = document.querySelector('.stage');
function sizeCurrentPreview() {
const style = getComputedStyle(stage);
@@ -31,6 +31,7 @@
<body>
<h1>Deck overview — 14 slides · AritmoLab</h1>
<p class="note">Live previews of <b>/deck/index.html</b> · <b>click any slide to open it full-size</b>, then flip with the arrow keys.</p>
<p class="note"><a href="/presenter/">Open presenter console</a> · Speaker notes, interactive preview and a separate audience window.</p>
<div class="grid" id="grid"></div>
<script>
const TITLES = ['Title', 'Where we started', 'What we wanted to build', 'The problem',
+95 -38
View File
@@ -1,44 +1,101 @@
# Outline v3 (FINAL structure — proposal A) — Role of AI in the Analysis of Unstructured Clinical Databases
# Outline v4 — Role of AI in the Analysis of Unstructured Clinical Databases
Updated 2026-09-18 against the actual deck, rather than the earlier proposed structure.
Deck: [`../deck/index.html`](../deck/index.html) — Reveal.js 5.1.0, **14 slides**, 16:9
(1280 × 720), with local fonts and speaker notes on every slide.
Review status: [`../prototype/deck-overview.html`](../prototype/deck-overview.html).
The titles below are the actual slide headings; some overview labels are shorter or older.
Deck: `deck/index.html` (Reveal.js, 15 slides, fonts embedded).
Presenters: **MP** = Dr. Marco Pancotti · **SP** = Dr.ssa Sara Paratico.
The notes explicitly identify Sara on slides 05–08. The final handoff around slide 04
and the remaining speaker allocation should be confirmed during rehearsal.
Per-slide timings and total running time need a new rehearsal; the previous 15-slide
timing estimate no longer describes this deck.
| # | Slide | Master | By | Time | Status |
|----|------------------------------------------------|--------------|----|------|--------|
| 01 | Title | title | MP | 40s | ✅ final |
| 02 | Where we started (4 systems + 2 missing) | interactive | MP | 65s | ✅ final |
| 03 | The project at a glance (flow + brain popups) | architecture | MP | 75s | ✅ final |
| 04 | What the text miner reads (numbers) | stats | SP | 60s | ✅ real data |
| 05 | The hard problems of clinical NLP | concept | SP | 75s | 🟡 draft |
| 06 | Building the clinical ontology | concept | SP | 75s | 🟡 draft |
| 07 | Trust the text: validation & human review | concept | SP | 75s | 🟡 draft |
| 08 | AI as co-engineer (mapping YAMLs) | artifact | MP | 70s | ✅ real |
| 09 | Genetic data — many sources, one patient | architecture | MP | 60s | ⚠️ wording TBD (a/b) |
| 10 | ThothII: ask the warehouse in plain English | concept | MP | 75s | 🟡 draft |
| 11 | From datamarts to predictive statistics & ML | concept | MP | 60s | 🟡 draft |
| 12 | Live demo cue (star schema · Superset · ThothII)| divider | MP | ~2min live | ✅ |
| 13 | Lessons learned | concept | MP | 60s | 🟡 draft |
| 14 | (merged into 15) | — | — | — | — |
| 15 | Thank you + Q&A (+ Substack pointer) | closing | MP | 25s | 🟡 draft |
## Actual slide sequence
Talk ≈ 13.4 min + ~2 min demo. 15 slides = user cap reached.
| # | Actual slide title | Content / format | Slide review status | Speaker notes |
|---|---|---|---|---|
| 01 | Role of AI in the Analysis of Unstructured Clinical Databases | AritmoLab introduction, clinical data platform and presenters | FINAL | Present; no DRAFT marker |
| 02 | Four islands and four missing pieces | Interactive map: Cardioref, Genetic data, Omics Portal and ECG subsystems; Clinical Intelligence, Datawarehouse, ML-ready data and Professional Portal as missing pieces | FINAL | Present; no DRAFT marker |
| 03 | What we wanted to build | Architecture and data flow toward the patient portal and research warehouse; clickable AI contribution cards | FINAL | Present; no DRAFT marker |
| 04 | The clinical truth lives in unstructured columns | Italian clinical sentence with English translation; why free text needs structured interpretation | FINAL | DRAFT |
| 05 | Deterministic AI, audited numbers | Text-mining outputs: 58,438 letters, 73,389 pathologies, 10,908 tests and 2,307 Brugada patients; extraction pipeline | FINAL | DRAFT — Sara |
| 06 | Reading clinical text is not keyword matching | Clinical NLP challenges, including negation and distinguishing family history from the patient's conditions | FINAL | DRAFT — Sara |
| 07 | Two tiers, one clinical order | Clinical ontology: 11 arrhythmic and 5 structural categories; text becomes recorded data | FINAL | DRAFT — Sara |
| 08 | Trusting the text is a process, not a promise | Five centered detail lenses: four validation controls and the three advantages | REFINED | ~120 words; five hover cues |
| 09 | AritmoLab — a quick tour | Portal tour; currently six screenshot placeholders | DRAFT | DRAFT |
| 10 | The warehouse speaks SQL. Research needs more. | Gap between the warehouse and clinical/research use: SQL access, aggregates and research cohorts | DRAFT | DRAFT |
| 11 | Ask the warehouse in plain English | ThothII: natural-language question, SQL proposal, human review and a research-ready datamart | DRAFT | DRAFT |
| 12 | From question to datamart — the app | ThothII walkthrough; currently six screenshot placeholders | DRAFT | DRAFT |
| 13 | One datamart — many questions answered | Multivariate analysis and machine learning; two chart placeholders with an illustrative-data disclosure | DRAFT | DRAFT — charts still to be created |
| 14 | Thank you | Questions and invitation to future technical walkthroughs on Substack | DRAFT | DRAFT |
## Confirmed decisions
- Project named **AritmoLab** everywhere (internal codename never appears).
- Slide 02 (Where we started): map of legacy systems — Cardioref / Genetic data /
Omics Portal / ECG subsystems, each clickable → popup (usage + problem box);
two dashed "MISSING" cards (Health Intelligence, ML-ready datamarts).
- Slide 03 flow: 3 sources + "Future sources" (dashed) → staging → integration 🧠
→ star schema → datamarts 🧠 → AritmoLab (DWH + Portal); brain popups =
The mappings / Reading the clinical text / Datamarts from plain English.
- Text-analysis block (SP): slides 04–07. Scripts to be validated by SP.
- Speaker view (S): Tall layout customized — upcoming 25%, timer bottom-left,
notes 1.45em. Default: upcoming 20%, notes 80%.
- Fonts embedded (Source Sans 3 + Source Serif 4, OFL) — no Google dependency.
`FINAL` and `REFINED` reproduce the overview's recorded review status. They do not imply
that speaker notes or clinical claims have received a separate final validation.
Figures above describe the content currently displayed in the deck.
## OPEN
- Slide 09 genetics wording: (a) deterministic reconciliation [recommended] vs
(b) AI upstream (only if MP confirms it happens outside the ETL).
- Draft slides 05-07, 10-11, 13-15: review one by one.
- Dark theme of the whole deck: final pass.
- "twenty years" (slide 01 script + slide 02): confirm real data span.
## Current presentation behavior
- Slide 02 has four clickable source systems and four clickable missing pieces,
each opening an explanatory popup.
- Slide 03 has clickable brain icons that open AI contribution cards with a connector
to the selected icon.
- Slide 08 has four centered lens popups. In the presenter console, hovering over
a numbered control or its corresponding heading in the notes opens the detail
in both preview and audience view. Escape closes it. Its quality wording separates
the original procedure-accuracy target from pathology coverage. The ~893
false-positive records and v1.3.1 negation fix are confirmed in the ETL sources;
see [source notes](08-validation-sources.md) for precise scope and limitations.
- Its advantages panel highlights on hover and opens a fifth centered lens on
click, explaining speed, precision and determinism. The fifth speaker-note cue
and presenter control open the same popup.
- Slide changes use a fade transition. Popups fade in and their cards move/scale into
place; clickable source icons and brain buttons have hover effects.
- A dropdown on each slide jumps to another slide. Reveal.js provides keyboard
navigation and the overview.
- The `S` key opens the Reveal.js speaker view when served locally. Speaker scripts
live in each slide's `<aside class="notes">` in `deck/index.html`.
- Source Sans 3 and Source Serif 4 are bundled under `deck/fonts/`; the deck does not
depend on Google Fonts.
## Remaining work
- Review slide 08 for final approval and slides 09–14 individually.
- Replace the six placeholders on slide 09 with real anonymized or demo portal
screenshots. The in-slide authoring note still requests 6–7 screenshots; settle
that count when inserting the images.
- Replace the six placeholders on slide 12 with screenshots of the ThothII workflow.
Its authoring note likewise still requests 6–7 screenshots.
- Create the two charts on slide 13, identify the supporting literature, and preserve
the disclosure if the data remain illustrative rather than measured results.
- Validate the speaker scripts on slides 04–14, including Sara's clinical section
on slides 05–08, and confirm the handoff between presenters.
- Confirm the “twenty years” wording, clinical figures, and quality-gate claims before
presenting them as final facts.
- Confirm the closing Substack reference and whether the promised videos will be
available by the talk.
- Rehearse the actual 14-slide sequence and set timings, including popup explanations
and any live demo chosen in addition to the screenshot walkthroughs.
The previous standalone slides on AI co-engineering, genetic reconciliation, lessons
learned and a live-demo divider are not separate slides in the current sequence.
Their old slide numbers, review tasks and timings should not be reused.
## Local preview
From the repository root:
```bash
python3 -m http.server 8000 --bind 127.0.0.1 --directory presentation
```
- Deck: <http://localhost:8000/deck/index.html>
- Review overview: <http://localhost:8000/prototype/deck-overview.html>
- Presenter console: <http://localhost:8000/presenter/> — notes, interactive preview,
popup controls and a separate audience window for an extended HDMI display.
See [`../presenter/README.md`](../presenter/README.md) for operation and scope.
Keep `presentation/` as the server root: the overview uses absolute `/deck/` URLs.
Stop the server with Ctrl+C.