diff --git a/public/images/albums/2026-03-31-post-med3pa-article/featured.png b/public/images/albums/2026-03-31-post-med3pa-article/featured.png new file mode 100644 index 0000000..1af66c7 Binary files /dev/null and b/public/images/albums/2026-03-31-post-med3pa-article/featured.png differ diff --git a/public/images/albums/2026-first-med3pa-presentation/certificat.png b/public/images/albums/2026-first-med3pa-presentation/certificat.png new file mode 100644 index 0000000..d7e6793 Binary files /dev/null and b/public/images/albums/2026-first-med3pa-presentation/certificat.png differ diff --git a/public/images/albums/2026-med3pa-article/featured.png b/public/images/albums/2026-med3pa-article/featured.png new file mode 100644 index 0000000..1af66c7 Binary files /dev/null and b/public/images/albums/2026-med3pa-article/featured.png differ diff --git a/public/images/albums/2026-rsn-med3pa-presentation/presentation.jpeg b/public/images/albums/2026-rsn-med3pa-presentation/presentation.jpeg new file mode 100644 index 0000000..a2221ac Binary files /dev/null and b/public/images/albums/2026-rsn-med3pa-presentation/presentation.jpeg differ diff --git a/public/images/albums/research-medimage/medimage-overview.png b/public/images/albums/research-mediml/mediml-overview.png similarity index 100% rename from public/images/albums/research-medimage/medimage-overview.png rename to public/images/albums/research-mediml/mediml-overview.png diff --git a/public/images/team/moustafa-amine-bezzahi/avatar-128.avif b/public/images/team/moustafa-amine-bezzahi/avatar-128.avif index 210ca36..68ade6f 100644 Binary files a/public/images/team/moustafa-amine-bezzahi/avatar-128.avif and b/public/images/team/moustafa-amine-bezzahi/avatar-128.avif differ diff --git a/public/images/team/moustafa-amine-bezzahi/avatar-128.jpg b/public/images/team/moustafa-amine-bezzahi/avatar-128.jpg index d9eabde..d2fdf81 100644 Binary files a/public/images/team/moustafa-amine-bezzahi/avatar-128.jpg and b/public/images/team/moustafa-amine-bezzahi/avatar-128.jpg differ diff --git a/public/images/team/moustafa-amine-bezzahi/avatar-128.webp b/public/images/team/moustafa-amine-bezzahi/avatar-128.webp index 70123f0..7c490ef 100644 Binary files a/public/images/team/moustafa-amine-bezzahi/avatar-128.webp and b/public/images/team/moustafa-amine-bezzahi/avatar-128.webp differ diff --git a/public/images/team/moustafa-amine-bezzahi/avatar-160.avif b/public/images/team/moustafa-amine-bezzahi/avatar-160.avif index b07f71f..8089f21 100644 Binary files a/public/images/team/moustafa-amine-bezzahi/avatar-160.avif and b/public/images/team/moustafa-amine-bezzahi/avatar-160.avif differ diff --git a/public/images/team/moustafa-amine-bezzahi/avatar-160.jpg b/public/images/team/moustafa-amine-bezzahi/avatar-160.jpg index 2785aab..0348a28 100644 Binary files a/public/images/team/moustafa-amine-bezzahi/avatar-160.jpg and b/public/images/team/moustafa-amine-bezzahi/avatar-160.jpg differ diff --git a/public/images/team/moustafa-amine-bezzahi/avatar-160.webp b/public/images/team/moustafa-amine-bezzahi/avatar-160.webp index 293546d..8737767 100644 Binary files a/public/images/team/moustafa-amine-bezzahi/avatar-160.webp and b/public/images/team/moustafa-amine-bezzahi/avatar-160.webp differ diff --git a/public/images/team/moustafa-amine-bezzahi/avatar-256.avif b/public/images/team/moustafa-amine-bezzahi/avatar-256.avif index 8c10915..b8284cc 100644 Binary files a/public/images/team/moustafa-amine-bezzahi/avatar-256.avif and b/public/images/team/moustafa-amine-bezzahi/avatar-256.avif differ diff --git a/public/images/team/moustafa-amine-bezzahi/avatar-256.jpg b/public/images/team/moustafa-amine-bezzahi/avatar-256.jpg index 3dd5d12..2074ec0 100644 Binary files a/public/images/team/moustafa-amine-bezzahi/avatar-256.jpg and b/public/images/team/moustafa-amine-bezzahi/avatar-256.jpg differ diff --git a/public/images/team/moustafa-amine-bezzahi/avatar-256.webp b/public/images/team/moustafa-amine-bezzahi/avatar-256.webp index e93190c..829f3a6 100644 Binary files a/public/images/team/moustafa-amine-bezzahi/avatar-256.webp and b/public/images/team/moustafa-amine-bezzahi/avatar-256.webp differ diff --git a/public/images/team/moustafa-amine-bezzahi/avatar-80.avif b/public/images/team/moustafa-amine-bezzahi/avatar-80.avif index 0ee63e7..d2480c6 100644 Binary files a/public/images/team/moustafa-amine-bezzahi/avatar-80.avif and b/public/images/team/moustafa-amine-bezzahi/avatar-80.avif differ diff --git a/public/images/team/moustafa-amine-bezzahi/avatar-80.jpg b/public/images/team/moustafa-amine-bezzahi/avatar-80.jpg index 8ab2573..9634e3c 100644 Binary files a/public/images/team/moustafa-amine-bezzahi/avatar-80.jpg and b/public/images/team/moustafa-amine-bezzahi/avatar-80.jpg differ diff --git a/public/images/team/moustafa-amine-bezzahi/avatar-80.webp b/public/images/team/moustafa-amine-bezzahi/avatar-80.webp index 7fe718e..3245534 100644 Binary files a/public/images/team/moustafa-amine-bezzahi/avatar-80.webp and b/public/images/team/moustafa-amine-bezzahi/avatar-80.webp differ diff --git a/public/publications/2025-tcairem-SAHBI-presentation/Poster_MEDfl_T-cairem.pdf b/public/publications/2025-tcairem-SAHBI-presentation/Poster_MEDfl_T-cairem.pdf new file mode 100644 index 0000000..25cd3c7 Binary files /dev/null and b/public/publications/2025-tcairem-SAHBI-presentation/Poster_MEDfl_T-cairem.pdf differ diff --git a/public/publications/2025-tcairem-SAHBI-presentation/TCAIREM_Ouael_SAHBI_MEDfl.pdf b/public/publications/2025-tcairem-SAHBI-presentation/TCAIREM_Ouael_SAHBI_MEDfl.pdf new file mode 100644 index 0000000..d7ea228 Binary files /dev/null and b/public/publications/2025-tcairem-SAHBI-presentation/TCAIREM_Ouael_SAHBI_MEDfl.pdf differ diff --git a/public/publications/2026-first-med3pa-presentation/Lefebvre_olivier_kafefak_2026.pdf b/public/publications/2026-first-med3pa-presentation/Lefebvre_olivier_kafefak_2026.pdf new file mode 100644 index 0000000..bc3c1e4 Binary files /dev/null and b/public/publications/2026-first-med3pa-presentation/Lefebvre_olivier_kafefak_2026.pdf differ diff --git a/public/publications/2026-rsn-med3pa-presentation/Lefebvre_olivier_rsn_2026.pdf b/public/publications/2026-rsn-med3pa-presentation/Lefebvre_olivier_rsn_2026.pdf new file mode 100644 index 0000000..a803f0c Binary files /dev/null and b/public/publications/2026-rsn-med3pa-presentation/Lefebvre_olivier_rsn_2026.pdf differ diff --git a/src/components/FilterMenu/FilterMenu.jsx b/src/components/FilterMenu/FilterMenu.jsx new file mode 100644 index 0000000..ffd99e3 --- /dev/null +++ b/src/components/FilterMenu/FilterMenu.jsx @@ -0,0 +1,74 @@ +import { useEffect, useRef, useState } from "react"; +import { SlidersHorizontal } from "lucide-react"; +import { cn } from "../../lib/utils"; + +/** + * Round glass button that opens a checklist of filter options. + */ +export default function FilterMenu({ options, active, onToggle, label, className }) { + const [isOpen, setIsOpen] = useState(false); + const menuRef = useRef(null); + + useEffect(() => { + const handleClick = (event) => { + if (!menuRef.current) return; + if (menuRef.current.contains(event.target)) return; + setIsOpen(false); + }; + + if (isOpen) { + document.addEventListener("mousedown", handleClick); + } + + return () => document.removeEventListener("mousedown", handleClick); + }, [isOpen]); + + return ( + <> + {isOpen && ( +
diff --git a/src/content/community/research/project-active/medomics_platform/index.md b/src/content/community/research/project-active/medomics_platform/index.md
index 73351fa..6a5d510 100644
--- a/src/content/community/research/project-active/medomics_platform/index.md
+++ b/src/content/community/research/project-active/medomics_platform/index.md
@@ -86,7 +86,7 @@ General
[//]: # 'the following data analysis techniques should increase the impact of the "multi-omics" prediction models that are '
[//]: # "built from these databases:"
[//]: #
-[//]: # "1. _Image analysis_: extraction of radiomic features allows us to better characterize tumor heterogeneity. The [MEDimage](/research/medimage) package is the dedicated component for this task."
+[//]: # "1. _Image analysis_: extraction of radiomic features allows us to better characterize tumor heterogeneity. The [MEDiml](/research/mediml) package is the dedicated component for this task."
[//]: # "2. _Machine learning_: some learning techniques allow us to better combine data from different categories (such as multi-omics)."
[//]: # "3. _Deep learning_: the multitude of deep neural network architectures offers several possibilities for the automatic learning of different tasks in medicine. The performance of some networks is sometimes superior to that of humans."
[//]: # "4. _Automatic text processing_: automatic processing and coding of textual reports from electronic patient records would allow for better integration of information relevant to multi-omics modeling throughout the patient management period."
diff --git a/src/content/community/research/project-completed/radiomics-complexity/index.md b/src/content/community/research/project-completed/radiomics-complexity/index.md
index e6ae67b..f269549 100644
--- a/src/content/community/research/project-completed/radiomics-complexity/index.md
+++ b/src/content/community/research/project-completed/radiomics-complexity/index.md
@@ -35,7 +35,7 @@ increasing complexity in the precision oncology spectrum.
## Issue and objective
-Recent advances in "omics" technology have created opportunities to characterize biological processes correlated with tumor phenotypes. We anticipate that integrative modeling of available oncology data will provide the ability to make accurate tumor phenotype predictions, which in turn would allow for better monitoring and tailoring of patient-specific treatments (i.e. "precision oncology"). To potentially improve radiomic analysis (i.e.: Quantitative extraction of useful data from all types of medical images), radiomic features of the tumor region can be extracted from medical images filtered with different types of filters (e.g.: texture filtering or texture smoothing). These features can be extracted using the [MEDimage](/research/medimage) package, but they expose different levels of complexity, which leads us to investigate in this project, the spectrum of complexity of medical images for the resolving of several problems in precision oncology and study the changes in these different levels of complexity from an image modality to another.
+Recent advances in "omics" technology have created opportunities to characterize biological processes correlated with tumor phenotypes. We anticipate that integrative modeling of available oncology data will provide the ability to make accurate tumor phenotype predictions, which in turn would allow for better monitoring and tailoring of patient-specific treatments (i.e. "precision oncology"). To potentially improve radiomic analysis (i.e.: Quantitative extraction of useful data from all types of medical images), radiomic features of the tumor region can be extracted from medical images filtered with different types of filters (e.g.: texture filtering or texture smoothing). These features can be extracted using the [MEDiml](/research/mediml) package, but they expose different levels of complexity, which leads us to investigate in this project, the spectrum of complexity of medical images for the resolving of several problems in precision oncology and study the changes in these different levels of complexity from an image modality to another.
## Database
diff --git a/src/content/publications/kafefak-presentation-first-publication-award-2026.md b/src/content/publications/kafefak-presentation-first-publication-award-2026.md
new file mode 100644
index 0000000..e0d1c71
--- /dev/null
+++ b/src/content/publications/kafefak-presentation-first-publication-award-2026.md
@@ -0,0 +1,43 @@
+
+
+## Date
+
+2026-04-29
+
+## Authors
+
+- [Olivier Lefebvre](/team/olivier-lefebvre)
+
+## Summary
+
+Olivier Lefebvre received the First Publication Award from the Faculty of Science, which highlights publications that distinguished themselves both within their field and among all entries submitted for the competition. The award was presented during the Kaféfak conference, where he was invited to give a three-minute presentation to make his research accessible to a broad audience. A $200 prize accompanies the award.
+
+## Abstract
+
+**Objectives**
+
+Artificial Intelligence models are increasingly used in health care, yet global performance metrics can mask variations in reliability across individual patients or subgroups with shared attributes, called patient profiles. This study introduces predictive performance precision analysis in medicine (MED3pa), a method that identifies when models are less reliable, allowing clinicians to better assess model limitations.
+
+**Materials and Methods**
+
+We propose a framework that estimates predictive confidence using 3 combined approaches: individualized (IPC), aggregated (APC), and mixed predictive confidence (MPC). Individualized predictive confidence estimates confidence for each patient, APC assesses it across profiles, and MPC combines both. We evaluate our method on 4 datasets: 1 simulated, 2 public, and 1 private clinical dataset. Metrics by declaration rate curves show how performance changes when retaining only the most confident predictions, while interpretable decision trees reveal profiles with higher or lower model confidence.
+
+**Results**
+
+We demonstrate our method in internal, temporal, and external validation settings, as well as through a clinical example. In internal validation, limiting predictions to the 93% most confident cases improved sensitivity by 14.3% and the area under the receiver operating characteristic curve by 5.1%. In the clinical example, MED3pa identified a patient profile with high misclassification risk, demonstrating its potential for safer deployment.
+
+**Discussion**
+
+By identifying low-confidence predictions, our framework improves model reliability in clinical settings. It can be integrated into decision support systems to help clinicians make more informed decisions. Confidence thresholds help balance model performance with the proportion of patients for whom predictions are considered reliable.
+
+**Conclusion**
+
+Better leveraging confidence in model predictions could improve reliability and trustworthiness, supporting safer and more effective use in health care.
+
+## Poster
+
+
+
+## Links
+
+- [Awarded paper in JAMIA](https://doi.org/10.1093/jamia/ocag034)
diff --git a/src/content/publications/predictive-performance-precision-analysis-in-medicine-identification-of-low-confidence-predictions-at-patient-and-profile-levels-med3pa-i-2026.md b/src/content/publications/predictive-performance-precision-analysis-in-medicine-identification-of-low-confidence-predictions-at-patient-and-profile-levels-med3pa-i-2026.md
new file mode 100644
index 0000000..2120a5a
--- /dev/null
+++ b/src/content/publications/predictive-performance-precision-analysis-in-medicine-identification-of-low-confidence-predictions-at-patient-and-profile-levels-med3pa-i-2026.md
@@ -0,0 +1,55 @@
+
+
+## Date
+
+2026-03-31
+
+## Authors
+
+- [Olivier Lefebvre](/team/olivier-lefebvre)1
+- [Félix Camirand Lemyre](https://www.usherbrooke.ca/mathematiques/nous-joindre/personnel/corps-professoral/professeurs/felix-camirand-lemyre)2
+- [Jean-François Éthier](https://www.usherbrooke.ca/recherche/specialistes/details/jean-francois.ethier)3
+- [Ludmila Amriou](/team/ludmila-amriou)4
+- [Lyna Hiba Chikouche](/team/lyna-hiba-chikouche)4
+- [Dan Poenaru](https://www.mcgill.ca/pediatricsurgery/dan-poenaru)5,6
+- [Martin Vallières](/team/martin-vallieres)1,7
+
+1 Computer science department, Université de Sherbrooke, Sherbrooke (QC), Canada
+
+2 Mathematics department, Université de Sherbrooke, Sherbrooke (QC), Canada
+
+3 Medicine department, Université de Sherbrooke, Sherbrooke (QC), Canada
+
+4 Department of Higher Studies (CS), École nationale Supérieure d’Informatique, Alger, 16309, Algeria
+
+5 Department of Pediatric Surgery, Montreal Children’s Hospital, Montreal, QC H4A 3J1, Canada
+
+6 Centre for Outcomes Research and Evaluation, Research Institute of the McGill University Health Centre, Montreal, QC H4A 3J1, Canada
+
+7 Medical Physics Unit, Department of Oncology, McGill University, Montreal, QC H3A 0G4, Canada
+
+## Abstract
+
+**Objectives**
+
+Artificial Intelligence models are increasingly used in health care, yet global performance metrics can mask variations in reliability across individual patients or subgroups with shared attributes, called patient profiles. This study introduces predictive performance precision analysis in medicine (MED3pa), a method that identifies when models are less reliable, allowing clinicians to better assess model limitations.
+
+**Materials and Methods**
+
+We propose a framework that estimates predictive confidence using 3 combined approaches: individualized (IPC), aggregated (APC), and mixed predictive confidence (MPC). Individualized predictive confidence estimates confidence for each patient, APC assesses it across profiles, and MPC combines both. We evaluate our method on 4 datasets: 1 simulated, 2 public, and 1 private clinical dataset. Metrics by declaration rate curves show how performance changes when retaining only the most confident predictions, while interpretable decision trees reveal profiles with higher or lower model confidence.
+
+**Results**
+
+We demonstrate our method in internal, temporal, and external validation settings, as well as through a clinical example. In internal validation, limiting predictions to the 93% most confident cases improved sensitivity by 14.3% and the area under the receiver operating characteristic curve by 5.1%. In the clinical example, MED3pa identified a patient profile with high misclassification risk, demonstrating its potential for safer deployment.
+
+**Discussion**
+
+By identifying low-confidence predictions, our framework improves model reliability in clinical settings. It can be integrated into decision support systems to help clinicians make more informed decisions. Confidence thresholds help balance model performance with the proportion of patients for whom predictions are considered reliable.
+
+**Conclusion**
+
+Better leveraging confidence in model predictions could improve reliability and trustworthiness, supporting safer and more effective use in health care.
+
+## Links
+
+- [Paper in JAMIA](https://doi.org/10.1093/jamia/ocag034)
diff --git a/src/content/publications/scientific-days-rsn-2026.md b/src/content/publications/scientific-days-rsn-2026.md
new file mode 100644
index 0000000..2e554d0
--- /dev/null
+++ b/src/content/publications/scientific-days-rsn-2026.md
@@ -0,0 +1,44 @@
+
+
+## Date
+
+2026-03-31
+
+## Authors
+
+- [Olivier Lefebvre](/team/olivier-lefebvre)
+
+## Summary
+
+Olivier Lefebvre presented his research during the **Réseau Santé Numérique (RSN) Scientific Day** at Université Laval. He delivered a seven-minute presentation highlighting the key contributions of his work and its implications for the development of reliable and trustworthy machine-learning models in healthcare. The talk offered an accessible overview of his methodological advances and their relevance to real-world clinical applications.
+
+## Abstract
+
+**Objectives**
+
+Artificial Intelligence models are increasingly used in health care, yet global performance metrics can mask variations in reliability across individual patients or subgroups with shared attributes, called patient profiles. This study introduces predictive performance precision analysis in medicine (MED3pa), a method that identifies when models are less reliable, allowing clinicians to better assess model limitations.
+
+**Materials and Methods**
+
+We propose a framework that estimates predictive confidence using 3 combined approaches: individualized (IPC), aggregated (APC), and mixed predictive confidence (MPC). Individualized predictive confidence estimates confidence for each patient, APC assesses it across profiles, and MPC combines both. We evaluate our method on 4 datasets: 1 simulated, 2 public, and 1 private clinical dataset. Metrics by declaration rate curves show how performance changes when retaining only the most confident predictions, while interpretable decision trees reveal profiles with higher or lower model confidence.
+
+**Results**
+
+We demonstrate our method in internal, temporal, and external validation settings, as well as through a clinical example. In internal validation, limiting predictions to the 93% most confident cases improved sensitivity by 14.3% and the area under the receiver operating characteristic curve by 5.1%. In the clinical example, MED3pa identified a patient profile with high misclassification risk, demonstrating its potential for safer deployment.
+
+**Discussion**
+
+By identifying low-confidence predictions, our framework improves model reliability in clinical settings. It can be integrated into decision support systems to help clinicians make more informed decisions. Confidence thresholds help balance model performance with the proportion of patients for whom predictions are considered reliable.
+
+**Conclusion**
+
+Better leveraging confidence in model predictions could improve reliability and trustworthiness, supporting safer and more effective use in health care.
+
+## Presentation
+
+
+
+## Links
+
+- [Event Details](https://event.fourwaves.com/jsrsn/pages)
+- [Related paper in JAMIA](https://doi.org/10.1093/jamia/ocag034)
diff --git a/src/data/news.json b/src/data/news.json
index a280f69..c8b6779 100644
--- a/src/data/news.json
+++ b/src/data/news.json
@@ -1,4 +1,20 @@
[
+ {
+ "year": "2026",
+ "months": [
+ {
+ "month": "March",
+ "items": [
+ {
+ "title": "Publication of the article “Predictive performance precision analysis in medicine: identification of low-confidence predictions at patient and profile levels (MED3pa I)”",
+ "slug": "2026-03-31-post-med3pa-article",
+ "contributors": ["Olivier Lefebvre", "Martin Vallières"],
+ "markdown": "community/news/2026-03-31-post-med3pa-article.md"
+ }
+ ]
+ }
+ ]
+ },
{
"year": "2025",
"months": [
diff --git a/src/data/publications.json b/src/data/publications.json
index 7143216..79fa22b 100644
--- a/src/data/publications.json
+++ b/src/data/publications.json
@@ -1,4 +1,44 @@
[
+ {
+ "year": "2026",
+ "items": [
+ {
+ "title": "Kaféfak Presentation - First Publication Award",
+ "slug": "kafefak-presentation-first-publication-award-2026",
+ "contributors": ["Olivier Lefebvre"],
+ "journal": "Université de Sherbrooke, Faculté des sciences",
+ "link": "https://doi.org/10.1093/jamia/ocag034",
+ "markdown": "publications/kafefak-presentation-first-publication-award-2026.md",
+ "type": "Presentations",
+ "date": "2026-04-29"
+ },
+ {
+ "title": "Predictive performance precision analysis in medicine: identification of low-confidence predictions at patient and profile levels (MED3pa I)",
+ "slug": "predictive-performance-precision-analysis-in-medicine-identification-of-low-confidence-predictions-at-patient-and-profile-levels-med3pa-i-2026",
+ "contributors": [
+ "Olivier Lefebvre",
+ "Ludmila Amriou",
+ "Lyna Hiba Chikouche",
+ "Martin Vallières"
+ ],
+ "journal": "Journal of the American Medical Informatics Association (JAMIA)",
+ "link": "https://doi.org/10.1093/jamia/ocag034",
+ "markdown": "publications/predictive-performance-precision-analysis-in-medicine-identification-of-low-confidence-predictions-at-patient-and-profile-levels-med3pa-i-2026.md",
+ "type": "Journal Papers",
+ "date": "2026-03-31"
+ },
+ {
+ "title": "Scientific Days RSN",
+ "slug": "scientific-days-rsn-2026",
+ "contributors": ["Olivier Lefebvre"],
+ "journal": "Réseau Santé Numérique (RSN)",
+ "link": "https://event.fourwaves.com/jsrsn/pages",
+ "markdown": "publications/scientific-days-rsn-2026.md",
+ "type": "Presentations",
+ "date": "2026-03-31"
+ }
+ ]
+ },
{
"year": "2025",
"items": [
diff --git a/src/data/research-projects.json b/src/data/research-projects.json
index 4a7f2fb..11733ea 100644
--- a/src/data/research-projects.json
+++ b/src/data/research-projects.json
@@ -36,14 +36,14 @@
"markdown": "community/research/project-active/medomics_platform/index.md"
},
{
- "title": "Development of the MEDimage package",
- "slug": "medimage",
+ "title": "Development of the MEDiml package",
+ "slug": "mediml",
"summary": "Open-source Python software for medical image processing and IBSI-compliant radiomics extraction.",
"status": "Active",
"track": "General",
"coverImage": {
- "url": "/images/albums/research-medimage/medimage-overview.png",
- "alt": "Schematic diagram of the MEDimage package"
+ "url": "/images/albums/research-mediml/mediml-overview.png",
+ "alt": "Schematic diagram of the MEDiml package"
},
"researchers": [
"clarisse-cheng",
@@ -52,7 +52,7 @@
"martin-vallieres",
"mohammed-benabbassi"
],
- "markdown": "community/research/project-active/medimage/index.md"
+ "markdown": "community/research/project-active/mediml/index.md"
},
{
"title": "Predictive Performance Precision Analysis in Medicine (MED3pa)",
diff --git a/src/data/team.json b/src/data/team.json
index 41175ef..5d85301 100644
--- a/src/data/team.json
+++ b/src/data/team.json
@@ -164,6 +164,42 @@
"cv": ""
}
},
+ {
+ "name": "Mahdi Ait Lhaj Loutfi",
+ "position": "Ph. D. Biological & Biomedical Engineering",
+ "slug": "mahdi-ait-lhaj-loutfi",
+ "email": "mahdi.aitlhajloutfi@mail.mcgill.ca",
+ "image": "/images/team/mahdi-ait-lhaj-loutfi/avatar.jpg",
+ "expertise": ["Python", "Medical imaging", "Radiomics", "Artificial intelligence"],
+ "education": [
+ {
+ "course": "Ph. D. Biological & Biomedical Engineering",
+ "institution": "McGill University, Montreal, Canada",
+ "year": "2026-"
+ },
+ {
+ "course": "M. Sc. Computer science",
+ "institution": "Université de Sherbrooke, Sherbrooke, Canada",
+ "year": "2021-2024"
+ },
+ {
+ "course": "B. Sc. Computer science",
+ "institution": "",
+ "year": ""
+ }
+ ],
+ "bio": "Mahdi Ait Lhaj Loutfi is a Ph. D. student in Biological & Biomedical Engineering at McGill University and a member of the MEDomicsLab, where he works on the development of the MEDomics platform. He completed his master’s degree in 2024, with a research project focused on exploring the complexity of radiomic features. In his Ph. D., he continues exploring the potential of radiomics in improving medical diagnosis and treatments. He is also the main architect and maintainer of the MEDiml package, a vital component of MEDomics.",
+ "note": "PhD Student",
+ "socials": {
+ "linkedin": "https://www.linkedin.com/in/mahdi-ait-lhaj-loutfi-332014253/",
+ "orcid": "",
+ "scholar": "",
+ "researchgate": "",
+ "github": "https://github.com/MahdiAll99",
+ "stackoverflow": "",
+ "cv": ""
+ }
+ },
{
"name": "Elodie Gillard",
"position": "M. Sc. Radiation sciences and medical imaging",
@@ -273,63 +309,32 @@
}
},
{
- "name": "Anthonin Falk",
- "position": "Intern in AI / Imaging",
- "slug": "anthonin-falk",
- "email": "anthonin.falk@gmail.com",
- "image": "/images/team/anthonin-falk/avatar.jpg",
- "expertise": [
- "Medical imaging",
- "Artificial intelligence",
- "Machine Learning",
- "Computer science for healthcare"
- ],
- "education": [
- {
- "course": "General Engineering Diploma",
- "institution": "École Centrale de Nantes, Nantes, France",
- "year": "2022-2025"
- }
- ],
- "bio": "Anthonin Falk is completing an internship in artificial intelligence applied to medical imaging from April to September 2025. He is working on reducing the complexity and improving the interpretability of a predictive model designed to determine which patients are most likely to suffer side effects during radiotherapy treatment.",
- "note": "Research Assistant / Intern",
- "socials": {
- "linkedin": "http://www.linkedin.com/in/anthonin-falk",
- "orcid": "",
- "scholar": "",
- "researchgate": "",
- "github": "https://github.com/S3vy",
- "stackoverflow": "",
- "cv": ""
- }
- },
- {
- "name": "Mahdi Ait Lhaj Loutfi",
- "position": "ML / Imaging",
- "slug": "mahdi-ait-lhaj-loutfi",
- "email": "Mahdi.Ait.Lhaj.Loutfi@USherbrooke.ca",
- "image": "/images/team/mahdi-ait-lhaj-loutfi/avatar.jpg",
- "expertise": ["Python", "Medical imaging", "Radiomics", "Artificial intelligence"],
+ "name": "Moustafa Amine Bezzahi",
+ "position": "M. Sc. Software Engineering",
+ "slug": "moustafa-amine-bezzahi",
+ "email": "moustafa.amine.bezzahi@usherbrooke.ca",
+ "image": "/images/team/moustafa-amine-bezzahi/avatar.jpg",
+ "expertise": ["Deep learning", "Computer vision", "Medical Imaging", "Digital Health"],
"education": [
{
- "course": "M. Sc. Computer science",
+ "course": "M. Sc. Software Engineering",
"institution": "Université de Sherbrooke, Sherbrooke, Canada",
- "year": "2021-2024"
+ "year": "2025-2027"
},
{
- "course": "B. Sc. Computer science",
- "institution": "",
- "year": ""
+ "course": "Engineering Degree, M. Sc. Computer science",
+ "institution": "Higher National School of Computer Science, Algiers, Algeria",
+ "year": "2019-2024"
}
],
- "bio": "Mahdi Ait Lhaj Loutfi is a research professional in the MEDomicsLab, where he works on the development of the MEDomics platform. He completed his master’s degree in 2024, with a research project focused on exploring the complexity of radiomic features. He is also the main architect and maintainer of the MEDimage package, a vital component of MEDomicsLab.",
- "note": "Research Assistant / Intern",
+ "bio": "Moustafa has been a Master’s student in the MEDomicsLab since 2025. Prior to this, he completed a research internship from November 2023 to August 2024. During his internship, he developed a pipeline for the automatic detection and characterization of small renal masses using CT imaging datasets. He is currently focused on identifying optimal segmentation strategies and developing multitask classification models. In addition, he is building an end-to-end application designed to support radiologists and urologists in urological oncology decision-making. This tool is intended to be integrated into the MEDomics platform.",
+ "note": "MSc Student",
"socials": {
- "linkedin": "https://www.linkedin.com/in/mahdi-ait-lhaj-loutfi-332014253/",
+ "linkedin": "",
"orcid": "",
"scholar": "",
"researchgate": "",
- "github": "https://github.com/MahdiAll99",
+ "github": "https://github.com/mus-bz",
"stackoverflow": "",
"cv": ""
}
@@ -385,6 +390,37 @@
{
"year": "2025",
"members": [
+ {
+ "name": "Anthonin Falk",
+ "position": "Intern in AI / Imaging",
+ "slug": "anthonin-falk",
+ "email": "anthonin.falk@gmail.com",
+ "image": "/images/team/anthonin-falk/avatar.jpg",
+ "expertise": [
+ "Medical imaging",
+ "Artificial intelligence",
+ "Machine Learning",
+ "Computer science for healthcare"
+ ],
+ "education": [
+ {
+ "course": "General Engineering Diploma",
+ "institution": "École Centrale de Nantes, Nantes, France",
+ "year": "2022-2025"
+ }
+ ],
+ "bio": "Anthonin Falk completed an internship in artificial intelligence applied to medical imaging from April to September 2025. He was working on reducing the complexity and improving the interpretability of a predictive model designed to determine which patients are most likely to suffer side effects during radiotherapy treatment.",
+ "note": "Former Member",
+ "socials": {
+ "linkedin": "http://www.linkedin.com/in/anthonin-falk",
+ "orcid": "",
+ "scholar": "",
+ "researchgate": "",
+ "github": "https://github.com/S3vy",
+ "stackoverflow": "",
+ "cv": ""
+ }
+ },
{
"name": "Brahim Fakri",
"position": "Research professional",
@@ -679,37 +715,6 @@
"cv": ""
}
},
- {
- "name": "Moustafa Amine Bezzahi",
- "position": "Intern",
- "slug": "moustafa-amine-bezzahi",
- "email": "hm_bezzahi@esi.dz",
- "image": "/images/team/moustafa-amine-bezzahi/avatar.jpg",
- "expertise": [
- "Artificiel Intelligence",
- "Computer vision",
- "Digital Health",
- "Medical Imaging"
- ],
- "education": [
- {
- "course": "Engineering Degree, M. Sc. Computer science",
- "institution": "Higher National School of Computer Science, Algiers, Algeria",
- "year": "2019-2024"
- }
- ],
- "bio": "Moustafa did an internship at MEDomicsLab UdeS from November 2023 till August 2024. He Worked on automatic detection of small renal masses using CHUS Medical Imaging dataset. He was supervised by Dr Patrick Richard and Pr Martin Vallières.",
- "note": "Former Member",
- "socials": {
- "linkedin": "",
- "orcid": "",
- "scholar": "",
- "researchgate": "",
- "github": "https://github.com/mus-bz",
- "stackoverflow": "",
- "cv": ""
- }
- },
{
"name": "Sarah Denis",
"position": "Research professional",
diff --git a/src/lib/memberActivity.js b/src/lib/memberActivity.js
new file mode 100644
index 0000000..2c6b877
--- /dev/null
+++ b/src/lib/memberActivity.js
@@ -0,0 +1,129 @@
+import eventsData from "../data/events.json";
+import newsData from "../data/news.json";
+import publicationsData from "../data/publications.json";
+import researchProjects from "../data/research-projects.json";
+
+/**
+ * Everything a team member shows up in, newest first.
+ */
+
+const MONTHS = [
+ "january",
+ "february",
+ "march",
+ "april",
+ "may",
+ "june",
+ "july",
+ "august",
+ "september",
+ "october",
+ "november",
+ "december",
+];
+
+/** Lowercase, de-accent and strip punctuation so "Guillaume Cléroux" matches "guillaume cleroux". */
+const normalizeName = (value) =>
+ value
+ .normalize("NFKD")
+ .replace(/\p{Diacritic}/gu, "")
+ .toLowerCase()
+ .replace(/[^a-z0-9]+/g, " ")
+ .trim();
+
+const credits = (contributors, name) =>
+ (contributors ?? []).some((contributor) => normalizeName(contributor) === normalizeName(name));
+
+/**
+ * Community slugs are date-prefixed (`2026-03-31-post-med3pa-article`). Fall back to the
+ * year/month headings the item is filed under when a slug carries no date.
+ */
+const resolveDate = (slug, year, month) => {
+ const fromSlug = /^(\d{4})-(\d{2})-(\d{2})/.exec(slug);
+ if (fromSlug) return `${fromSlug[1]}-${fromSlug[2]}-${fromSlug[3]}`;
+
+ const monthIndex = MONTHS.indexOf(String(month ?? "").toLowerCase());
+ if (monthIndex !== -1) return `${year}-${String(monthIndex + 1).padStart(2, "0")}-01`;
+
+ return /^\d{4}$/.test(String(year)) ? `${year}-01-01` : null;
+};
+
+const formatDate = (date) => {
+ if (!date) return null;
+ const parsed = new Date(`${date}T00:00:00Z`);
+ if (Number.isNaN(parsed.getTime())) return null;
+ return parsed.toLocaleDateString("en-CA", {
+ year: "numeric",
+ month: "short",
+ timeZone: "UTC",
+ });
+};
+
+const collectTimeline = (data, name, kind, basePath) => {
+ const entries = [];
+ for (const yearGroup of data) {
+ for (const monthGroup of yearGroup.months ?? []) {
+ for (const item of monthGroup.items ?? []) {
+ if (!credits(item.contributors, name)) continue;
+ entries.push({
+ kind,
+ title: item.title,
+ to: `${basePath}/${item.slug}`,
+ date: resolveDate(item.slug, yearGroup.year, monthGroup.month),
+ });
+ }
+ }
+ }
+ return entries;
+};
+
+const collectPublications = (name) => {
+ const entries = [];
+ for (const yearGroup of publicationsData) {
+ for (const item of yearGroup.items ?? []) {
+ if (!credits(item.contributors, name)) continue;
+ entries.push({
+ kind: "Publication",
+ title: item.title,
+ to: `/publications/${item.slug}`,
+ date: item.date ?? resolveDate(item.slug, yearGroup.year),
+ });
+ }
+ }
+ return entries;
+};
+
+const collectProjects = (slug) =>
+ researchProjects
+ .filter((project) => (project.researchers ?? []).includes(slug))
+ .map((project) => ({
+ kind: "Project",
+ title: project.title,
+ to: `/research/${project.slug}`,
+ date: null,
+ }));
+
+/**
+ * @param {{ slug: string, name: string }} member
+ * @returns {Array<{ kind: string, title: string, to: string, date: string|null, dateLabel: string|null }>}
+ */
+export const getMemberActivity = (member) => {
+ if (!member?.name) return [];
+
+ const entries = [
+ ...collectPublications(member.name),
+ ...collectTimeline(newsData, member.name, "News", "/community/news"),
+ ...collectTimeline(eventsData, member.name, "Event", "/community/events"),
+ ...collectProjects(member.slug),
+ ];
+
+ // Dated entries newest first; undated projects trail them, alphabetically.
+ entries.sort((a, b) => {
+ if (a.date && b.date) return b.date.localeCompare(a.date);
+ if (a.date) return -1;
+ if (b.date) return 1;
+ return a.title.localeCompare(b.title);
+ });
+
+ return entries.map((entry) => ({ ...entry, dateLabel: formatDate(entry.date) }));
+};
diff --git a/src/pages/PublicationsPage/PublicationsPage.jsx b/src/pages/PublicationsPage/PublicationsPage.jsx
index 4b3f690..b6d7739 100644
--- a/src/pages/PublicationsPage/PublicationsPage.jsx
+++ b/src/pages/PublicationsPage/PublicationsPage.jsx
@@ -1,21 +1,26 @@
import { useEffect, useMemo, useRef, useState } from "react";
-import { SlidersHorizontal } from "lucide-react";
import { useTranslations } from "../../lib/translations";
import pubData from "../../data/publications.json";
import { cn } from "../../lib/utils";
import EntryRow, { EntryRowBody, EntryRowTitle } from "../../components/EntryRow/EntryRow.jsx";
+import FilterMenu from "../../components/FilterMenu/FilterMenu.jsx";
import PageShell, { PageTitle } from "../../components/PageShell/PageShell.jsx";
+const PUBLICATION_TYPES = ["Journal Papers", "Conference Papers", "Preprints", "Presentations"];
+
export default function PublicationsPage() {
const { t } = useTranslations();
const [activeYear, setActiveYear] = useState(pubData[0]?.year ?? "");
- const [isFilterOpen, setIsFilterOpen] = useState(false);
const [isFocused, setIsFocused] = useState(false);
const sectionRefs = useRef({});
- const filterRef = useRef(null);
- const publicationTypes = ["Journal Papers", "Conference Papers", "Preprints", "Presentations"];
- const [activeTypes, setActiveTypes] = useState(publicationTypes);
+ const [activeTypes, setActiveTypes] = useState(PUBLICATION_TYPES);
+ // Never let the selection empty out: the last active type stays active.
+ const toggleType = (type) =>
+ setActiveTypes((prev) => {
+ if (!prev.includes(type)) return [...prev, type];
+ return prev.length === 1 ? prev : prev.filter((item) => item !== type);
+ });
const typeOrder = {
"Journal Papers": 0,
@@ -73,30 +78,6 @@ export default function PublicationsPage() {
return () => window.removeEventListener("scroll", handleScroll);
}, [activeYear, filteredGroups]);
- useEffect(() => {
- const handleClick = (event) => {
- if (!filterRef.current) return;
- if (filterRef.current.contains(event.target)) return;
- setIsFilterOpen(false);
- };
-
- if (isFilterOpen) {
- document.addEventListener("mousedown", handleClick);
- }
-
- return () => document.removeEventListener("mousedown", handleClick);
- }, [isFilterOpen]);
-
- const toggleType = (type) => {
- setActiveTypes((prev) => {
- if (prev.includes(type)) {
- if (prev.length === 1) return prev;
- return prev.filter((item) => item !== type);
- }
- return [...prev, type];
- });
- };
-
return (
+
+ {availableKinds.length > 1 && (
+