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