From 96ebee59fade30f8d9600e2f84fbb805a9e81b83 Mon Sep 17 00:00:00 2001 From: Laurent Knoll <laurent.knoll@orange.com> Date: Sat, 10 Dec 2022 22:52:27 +0100 Subject: [PATCH] Closes #14. Fusion des CSV --- docs/README.md | 266 ++++--- docs/images/fusion_button.png | Bin 0 -> 31712 bytes docs/images/fusion_dialog.png | Bin 0 -> 95251 bytes docs/index.html | 44 +- package-lock.json | 96 ++- package.json | 2 + src/data/coords/process/coordsMeasurement.ts | 45 ++ src/data/coords/process/pointMerger.ts | 67 ++ src/data/dataExporter.ts | 226 ++---- src/data/dataImporter.ts | 72 +- src/data/measurement/measurement.ts | 12 + src/data/measurement/measurementWorks.ts | 14 + .../measurement/process/measurementExport.ts | 44 ++ .../measurement/process/measurementImport.ts | 56 ++ .../measurement/process/measurementMerge.ts | 45 ++ src/data/work/process/workInfoFormatter.ts | 22 + src/data/work/process/workInfoParser.ts | 28 + src/data/work/workInfo.ts | 25 + src/lab.tsx | 718 +++++++++--------- src/ui/merger.tsx | 148 ++++ src/ui/steps/downloadStep.tsx | 381 +++++----- src/ui/steps/drawBlobMaskStep.tsx | 158 ++-- src/ui/steps/loadPictureStep.tsx | 96 +-- src/utils/ioUtils.ts | 114 +-- src/utils/objectUtils.ts | 13 + tests/data/dataExporter.test.ts | 58 +- .../process/measurementImport.test.ts | 72 ++ .../process/measurementMerge.test.ts | 88 +++ .../work/process/workInfoFormatter.test.ts | 22 + .../data/work/process/workInfoParser.test.ts | 41 + tests/fixtures/Results_ConJ11Ex.csv | 4 + tests/fixtures/Results_ConJ11ExB1.csv | 2 + tests/fixtures/Results_ConJ11ExB2.csv | 2 + tests/fixtures/Results_ConJ11ExB9.csv | 2 + tests/fixtures/Results_ExpJ1Cr.csv | 2 + tests/fixtures/fixtures.ts | 80 +- 36 files changed, 1972 insertions(+), 1093 deletions(-) create mode 100644 docs/images/fusion_button.png create mode 100644 docs/images/fusion_dialog.png create mode 100644 src/data/coords/process/coordsMeasurement.ts create mode 100644 src/data/coords/process/pointMerger.ts create mode 100644 src/data/measurement/measurement.ts create mode 100644 src/data/measurement/measurementWorks.ts create mode 100644 src/data/measurement/process/measurementExport.ts create mode 100644 src/data/measurement/process/measurementImport.ts create mode 100644 src/data/measurement/process/measurementMerge.ts create mode 100644 src/data/work/process/workInfoFormatter.ts create mode 100644 src/data/work/process/workInfoParser.ts create mode 100644 src/data/work/workInfo.ts create mode 100644 src/ui/merger.tsx create mode 100644 src/utils/objectUtils.ts create mode 100644 tests/data/measurement/process/measurementImport.test.ts create mode 100644 tests/data/measurement/process/measurementMerge.test.ts create mode 100644 tests/data/work/process/workInfoFormatter.test.ts create mode 100644 tests/data/work/process/workInfoParser.test.ts create mode 100644 tests/fixtures/Results_ConJ11Ex.csv create mode 100644 tests/fixtures/Results_ConJ11ExB1.csv create mode 100644 tests/fixtures/Results_ConJ11ExB2.csv create mode 100644 tests/fixtures/Results_ConJ11ExB9.csv create mode 100644 tests/fixtures/Results_ExpJ1Cr.csv diff --git a/docs/README.md b/docs/README.md index ac3464f..a19d520 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,118 +1,148 @@ -# Mode opératoire -## Présentation -**Cet outil vous accompagne** - pas à pas - dans **l'analyse des photos de blobs**, afin de fournir les données nécessaires à l'apprentissage du _Machine Learning_. - -L'analyse se déroule en **5 étapes** : - -[1. Charger une photo](#Étape-1-charger-une-photo) <br> -[2. Positionner la règle](#Étape-2-positioner-la-règle) <br> -[3. Positionner la boîte de Petri](#Étape-3-positionner-la-boîte-de-petri) <br> -[4. Détourer le blob à main levée](#Étape-4-détourer-le-blob) <br> -[5. Télécharger les fichiers de mesures](#Étape-5-télécharger-les-résultats) <br> - -Chaque étape est décrite dans la partie droite du _lab_. Il est possible de revenir à tout moment -en arrière en cliquant sur le titre de l'étape. - -C'est parti... - ---- - -## Étape 1 : charger une photo - -**Charger une photo** à analyser - située sur l'ordinateur - avec le **bouton "Parcourir..."**. - - - -Une fois la photo chargée, **l'étape 2 est automatiquement activée**. - -Mais avant... - -> ### Comment zoomer et déplacer la photo -> Pour prendre les mesures avec le plus de précision, il est possible de : -> * **zoomer/dézoomer (agrandir/rétrécir) la photo** avec la molette de la souris -> * **déplacer la photo** : tout en appuyant sur la touche contrôle (le curseur devient des flèches), cliquer sur la photo et la déplacer avec la souris -> -> La barre de boutons de zoom sur le haut de la page permet d'ajuster l'affichage : -> *  : agrandir la photo -> *  : rétrécir la photo -> *  : ajuster la photo à l'écran et la repositionner au centre (:sparkles: bien utile si l'on perd la photo de vue) -> *  : afficher la photo en taille réelle - -Maintenant au travail ! - ---- - -## Étape 2 : positioner la règle -Cette étape permet au logiciel de déterminer l'échelle de la photo. - -**Déplacer la ligne jaune à l'aide des 2 "poignées"** (petits carrés blancs) à chacune de ses extrémités afin de -**couvrir 10cm de la règle**. - - - -Pour s'assurer que 10 centimètres sont bien couverts, **les petits points "détrompeurs" doivent tomber sur chaque centimètre**. - - - -Si il y a moins de 10cm règle sur la photo, il est possible de modifier la taille à couvrir avec les boutons +/- (en bleu ci-dessous). -Le nombre de détrompeurs sera ajusté. - -Pour placer la règle avec plus de précision, utiliser le bouton  (en jaune ci-dessous). - - - -Une fois la règle placée, **passer à l'étape suivante en appuyant sur le bouton "Terminé !"** (en vert ci-dessus). - ---- - -## Étape 3 : positionner la boîte de Petri - -Tout comme la règle, **placer la boîte de Petri à l'aide des poignées**, et utiliser le bouton  -pour la placer avec précision. - - - -> -> -> Au début on y va à tâtons, mais on prend vite le coup de main. -> -> - - - -Une fois la boîte de Petri correctement positionnée, **passer à l'étape suivante en appuyant sur "C'est fini !"** - ---- - -## Étape 4 : détourer le blob - -Lors de cette étape, **entourer d'une ligne jaune le blob** (dessiner en maintenant le bouton de la souris pressé). - - - -> -> **Oh non !** Si près de la fin -> ->  ->  -> -> Il est possible de revenir en arrière sur les derniers points du tracé avec le bouton  -> ->  -> - -Lorsque l'on a rejoint le point de départ marqué par un carré blanc, **le contour est terminé et colorié en jaune**. - - - -Le bouton  s'active et permet de **passer à l'étape suivante**. - ---- - -## Étape 5 : télécharger les résultats - - - -**Télécharger les fichiers un à un** avec . - -Les fichiers sont stockés dans le répertoire "Téléchargements" du navigateur, **les transmettre par [la plateforme de dépôt de données](https://blob.cnrs.fr/)**. +# Mode opératoire +## Présentation +**Cet outil vous accompagne** - pas à pas - dans **l'analyse des photos de blobs**, afin de fournir les données nécessaires à l'apprentissage du _Machine Learning_. + +L'analyse se déroule en **5 étapes** : + +[1. Charger une photo](#Étape-1-charger-une-photo) <br> +[2. Positionner la règle](#Étape-2-positioner-la-règle) <br> +[3. Positionner la boîte de Petri](#Étape-3-positionner-la-boîte-de-petri) <br> +[4. Détourer le blob à main levée](#Étape-4-détourer-le-blob) <br> +[5. Télécharger les fichiers de mesures](#Étape-5-télécharger-les-résultats) <br> +[5'. Fusionner les .csv ](#Étape-539-fusionner-les-csv) + +Chaque étape est décrite dans la partie droite du _lab_. Il est possible de revenir à tout moment +en arrière en cliquant sur le titre de l'étape. + +C'est parti... + +--- + +## Étape 1 : charger une photo + +**Charger une photo** à analyser - située sur l'ordinateur - avec le **bouton "Parcourir..."**. + + + +Une fois la photo chargée, **l'étape 2 est automatiquement activée**. + +Mais avant... + +> ### Comment zoomer et déplacer la photo +> Pour prendre les mesures avec le plus de précision, il est possible de : +> * **zoomer/dézoomer (agrandir/rétrécir) la photo** avec la molette de la souris +> * **déplacer la photo** : tout en appuyant sur la touche contrôle (le curseur devient des flèches), cliquer sur la photo et la déplacer avec la souris +> +> La barre de boutons de zoom sur le haut de la page permet d'ajuster l'affichage : +> *  : agrandir la photo +> *  : rétrécir la photo +> *  : ajuster la photo à l'écran et la repositionner au centre (:sparkles: bien utile si l'on perd la photo de vue) +> *  : afficher la photo en taille réelle + +Maintenant au travail ! + +--- + +## Étape 2 : positioner la règle +Cette étape permet au logiciel de déterminer l'échelle de la photo. + +**Déplacer la ligne jaune à l'aide des 2 "poignées"** (petits carrés blancs) à chacune de ses extrémités afin de +**couvrir 10cm de la règle**. + + + +Pour s'assurer que 10 centimètres sont bien couverts, **les petits points "détrompeurs" doivent tomber sur chaque centimètre**. + + + +Si il y a moins de 10cm règle sur la photo, il est possible de modifier la taille à couvrir avec les boutons +/- (en bleu ci-dessous). +Le nombre de détrompeurs sera ajusté. + +Pour placer la règle avec plus de précision, utiliser le bouton  (en jaune ci-dessous). + + + +Une fois la règle placée, **passer à l'étape suivante en appuyant sur le bouton "Terminé !"** (en vert ci-dessus). + +--- + +## Étape 3 : positionner la boîte de Petri + +Tout comme la règle, **placer la boîte de Petri à l'aide des poignées**, et utiliser le bouton  +pour la placer avec précision. + + + +> +> +> Au début on y va à tâtons, mais on prend vite le coup de main. +> +> + + + +Une fois la boîte de Petri correctement positionnée, **passer à l'étape suivante en appuyant sur "C'est fini !"** + +--- + +## Étape 4 : détourer le blob + +Lors de cette étape, **entourer d'une ligne jaune le blob** (dessiner en maintenant le bouton de la souris pressé). + + + +> +> **Oh non !** Si près de la fin +> +>  +>  +> +> Il est possible de revenir en arrière sur les derniers points du tracé avec le bouton  +> +>  +> + +Lorsque l'on a rejoint le point de départ marqué par un carré blanc, **le contour est terminé et colorié en jaune**. + + + +Le bouton  s'active et permet de **passer à l'étape suivante**. + +--- + +## Étape 5 : télécharger les résultats + + + +**Télécharger les fichiers un à un** avec . + +Les fichiers sont stockés dans le répertoire "Téléchargements" du navigateur. + +> [!NOTE|label:Attention] +> Ces fichiers ne peuvent pas être tout de suite déposés sur l'espace de dépôt des fichiers d'analyse (https://blob.cnrs.fr/). +> +> En effet, le fichier _.csv_ généré ne contient que les mesures (aire, périmètre, circualirité, etc.) que pour la photo qui vient d'être analysée. +> Le nom du fichier contient le numéro du blob (par exemple: Results_ConJ1Ex*B3*.csv). +> +> L'espace de dépôt des analyses n'attend qu'**un seul fichier** _.csv_ **pour toutes** les photos d'une séquence groupe/jour/expérience (par ex.: Results_ConJ1Ex.csv). +> +> Une étape supplémentaire permet de regrouper les fichiers. + +## Étape 5' : fusionner les .csv + +> :gift: Pour 5 étapes effectuées une étape offerte ! + +Un bouton dans l'étape 5 permet d'ouvrir l'outil de fusion des fichiers. + + + +Une fenêtre comme celle-ci s'affiche : + + + +Pas à pas : +1. \[encadré en vert] Sélectionner des fichiers à fusionner. Plusieurs fichiers peuvent être sélectionnés à la fois. Ils peuvent être sélectionnés en vrac mêmes s'ils font partie de séquences (groupe/jour/expérience) d'analyse différentes. +2. \[marqué en rouge] Les fichiers sont automatiquement triés et regroupés par séquence (groupe/jour/expérience) +3. \[entouré en jaune] Les fichiers résultats sont téléchargeables avec le bouton  + +Maintenant **les fichiers peuvent être transmis par [la plateforme de dépôt de données](https://blob.cnrs.fr/)**. diff --git a/docs/images/fusion_button.png b/docs/images/fusion_button.png new file mode 100644 index 0000000000000000000000000000000000000000..73790a4a96c3fc6c9ec4fcb496a8b5e7dc36991a GIT binary patch literal 31712 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 Z@IMv+UV6fsq@n--002ovPDHLkV1gTw6~6!g literal 0 HcmV?d00001 diff --git a/docs/images/fusion_dialog.png b/docs/images/fusion_dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..7e2094b73fb5553a9d9cce052818f00e7e7aa923 GIT binary patch literal 95251 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ℜ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	xJU+CDm~8xSo23id>9AFVNw8c+w_$n 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 M(#lewB}{_<7jU;>;{X5v literal 0 HcmV?d00001 diff --git a/docs/index.html b/docs/index.html index 7c443aa..ee42b57 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,20 +1,24 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <title>Blob Analysis Lab - Documentation</title> - <link rel="icon" href="favicon.ico" /> - <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/themes/vue.css" /> -</head> -<body> -<div id="doc">Chargement...</div> -<script> - window.$docsify = { - el: '#doc' - } -</script> -<script src="//cdn.jsdelivr.net/npm/docsify@4"></script> -</body> -</html> +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Blob Analysis Lab - Documentation</title> + <link rel="icon" href="favicon.ico" /> + <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/themes/vue.css" /> +</head> +<body> +<div id="doc">Chargement...</div> +<script> + window.$docsify = { + el: '#doc', + 'flexible-alerts': { + style: 'callout' + } + } +</script> +<script src="//cdn.jsdelivr.net/npm/docsify@4"></script> +<script src="https://unpkg.com/docsify-plugin-flexible-alerts"></script> +</body> +</html> diff --git a/package-lock.json b/package-lock.json index f7777b1..65462d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,8 +14,10 @@ "@fortawesome/free-solid-svg-icons": "^6.2.0", "@popperjs/core": "^2.11.6", "@svgr/webpack": "^6.5.0", + "@types/d3-dsv": "^3.0.0", "bootstrap": "^5.2.1", "bootswatch": "^5.2.0", + "d3-dsv": "^3.0.1", "jquery": "3.6.0", "paper": "0.12.15", "react": "^18.2.0", @@ -2498,6 +2500,11 @@ "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", "dev": true }, + "node_modules/@types/d3-dsv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.0.tgz", + "integrity": "sha512-o0/7RlMl9p5n6FQDptuJVMxDf/7EDEv2SYEO/CwdG2tr1hTfUVi0Iavkk2ax+VpaQ/1jVhpnj5rq1nj8vwhn2A==" + }, "node_modules/@types/eslint": { "version": "8.4.6", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", @@ -3903,6 +3910,49 @@ "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", "dev": true }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-dsv/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/date-format": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", @@ -7170,6 +7220,11 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -7193,8 +7248,7 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sass": { "version": "1.55.0", @@ -10523,6 +10577,11 @@ "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", "dev": true }, + "@types/d3-dsv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.0.tgz", + "integrity": "sha512-o0/7RlMl9p5n6FQDptuJVMxDf/7EDEv2SYEO/CwdG2tr1hTfUVi0Iavkk2ax+VpaQ/1jVhpnj5rq1nj8vwhn2A==" + }, "@types/eslint": { "version": "8.4.6", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", @@ -11659,6 +11718,31 @@ "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", "dev": true }, + "d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "requires": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, "date-format": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", @@ -14109,6 +14193,11 @@ "queue-microtask": "^1.2.2" } }, + "rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -14118,8 +14207,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sass": { "version": "1.55.0", diff --git a/package.json b/package.json index 5dd0203..0caa835 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,10 @@ "@fortawesome/free-solid-svg-icons": "^6.2.0", "@popperjs/core": "^2.11.6", "@svgr/webpack": "^6.5.0", + "@types/d3-dsv": "^3.0.0", "bootstrap": "^5.2.1", "bootswatch": "^5.2.0", + "d3-dsv": "^3.0.1", "jquery": "3.6.0", "paper": "0.12.15", "react": "^18.2.0", diff --git a/src/data/coords/process/coordsMeasurement.ts b/src/data/coords/process/coordsMeasurement.ts new file mode 100644 index 0000000..8e323f5 --- /dev/null +++ b/src/data/coords/process/coordsMeasurement.ts @@ -0,0 +1,45 @@ +import {PathCoords} from "../pathCoords"; +import {Measurement} from "../../measurement/measurement"; +import {ToEllipseFitter} from "../transform/toEllipseFitter"; +import {ToConvexHull} from "../transform/toConvexHull"; +import {VectorCoords} from "../vectorCoords"; + +/** + * Transforme des coordonnées en Measures + */ +export class CoordsMeasurement { + + /** + * Effectue des mesures sur le coordonnées + */ + public measure(coords : PathCoords, scaleCoords : VectorCoords, scaleUnitCount: number, label: string) : Measurement { + let path = coords.toRemovedPath(); + path.closePath(); + + let linearScale = scaleCoords.distance() / scaleUnitCount; // pixels/cm + let areaScale = Math.pow(linearScale, 2); + let fittingEllipse = new ToEllipseFitter().transform(coords); + let convexHull = new ToConvexHull().transform(coords); + + let area = Math.abs(path.area) / areaScale; + let convexArea = Math.abs(convexHull.toRemovedPath().area) / areaScale; + let perimeter = path.length / linearScale; + let major = fittingEllipse.getMajorAxis() / linearScale; + let minor = fittingEllipse.getMinorAxis() / linearScale; + let circularity = 4 * Math.PI * area / Math.pow(perimeter, 2); + let ar = major / minor; + let round = (4 * area) / (Math.PI * major * major); + let solid = area / convexArea; + + return { + label: label, + area: area, + perimeter: perimeter, + circularity: circularity, + ar: ar, + round: round, solid: solid + } + } + + +} \ No newline at end of file diff --git a/src/data/coords/process/pointMerger.ts b/src/data/coords/process/pointMerger.ts new file mode 100644 index 0000000..d748578 --- /dev/null +++ b/src/data/coords/process/pointMerger.ts @@ -0,0 +1,67 @@ +/** + * Merge des point alignés horizontalement ou verticalement (4-connected) + */ +class PointMerger { + + private startPoint: paper.Point | null; + private endPoint: paper.Point | null; + + next(point : paper.Point | null) : paper.Point[] { + if(point == null) { // Null lorsque l'on a passé le dernier point => lus de point à merger, on retourne ce qu'il reste + if(this.endPoint != null) { + return [this.startPoint, this.endPoint]; + } else if(this.startPoint != null) { + return [this.startPoint]; + } else { + return []; + } + } else { + if (this.startPoint == null) { // On est sur le premier point + this.startPoint = point; + return []; + } else { + if(this.endPoint == null) { // On a déjà un point de départ + if(point.y == this.startPoint.y && point.x == this.startPoint.x) { + return [] + } else if(point.y == this.startPoint.y + || point.x == this.startPoint.x) { + this.endPoint = point; + return []; + } else { + let result = [this.startPoint]; + this.startPoint = point; + return result + } + } else { + if(point.y == this.endPoint.y && point.x == this.endPoint.x) { + return []; + + } else if(point.y == this.endPoint.y && Math.sign(this.endPoint.x - this.startPoint.x) == Math.sign(this.endPoint.x - this.startPoint.x)) { + // Dans l'alignement horizontal + this.endPoint = point; + return []; + + } else if(point.x == this.endPoint.x && Math.sign(this.endPoint.y - this.startPoint.y) == Math.sign(this.endPoint.y - this.startPoint.y)) { + // Dans l'alignement vertical + this.endPoint = point; + return []; + + } else { + if(point.y == this.endPoint.y || point.x == this.endPoint.x) { + let result = [this.startPoint]; + this.startPoint = this.endPoint; + this.endPoint = point; + return result; + + } else { + let result = [this.startPoint, this.endPoint]; + this.startPoint = point; + this.endPoint = null; + return result; + } + } + } + } + } + } +} diff --git a/src/data/dataExporter.ts b/src/data/dataExporter.ts index 732e6e7..ac63b69 100644 --- a/src/data/dataExporter.ts +++ b/src/data/dataExporter.ts @@ -1,160 +1,68 @@ -/** - * Utilitaire d'export des données - */ -import {LabData} from "../lab"; -import {ToEllipseFitter} from "./coords/transform/toEllipseFitter"; -import {Coords} from "./coords/coords"; -import {MathUtils} from "../utils/mathUtils"; -import {ToConvexHull} from "./coords/transform/toConvexHull"; -import {PathCoords} from "./coords/pathCoords"; - -const ROUNDING_DECIMALS = 3; - -/** - * Merge des point alignés horizontalement ou verticalement - */ -class PointMerger { - - private startPoint: paper.Point | null; - private endPoint: paper.Point | null; - - next(point : paper.Point | null) : paper.Point[] { - if(point == null) { // Null lorsque l'on a passé le dernier point => lus de point à merger, on retourne ce qu'il reste - if(this.endPoint != null) { - return [this.startPoint, this.endPoint]; - } else if(this.startPoint != null) { - return [this.startPoint]; - } else { - return []; - } - } else { - if (this.startPoint == null) { // On est sur le premier point - this.startPoint = point; - return []; - } else { - if(this.endPoint == null) { // On a déjà un point de départ - if(point.y == this.startPoint.y && point.x == this.startPoint.x) { - return [] - } else if(point.y == this.startPoint.y - || point.x == this.startPoint.x) { - this.endPoint = point; - return []; - } else { - let result = [this.startPoint]; - this.startPoint = point; - return result - } - } else { - if(point.y == this.endPoint.y && point.x == this.endPoint.x) { - return []; - - } else if(point.y == this.endPoint.y && Math.sign(this.endPoint.x - this.startPoint.x) == Math.sign(this.endPoint.x - this.startPoint.x)) { - // Dans l'alignement horizontal - this.endPoint = point; - return []; - - } else if(point.x == this.endPoint.x && Math.sign(this.endPoint.y - this.startPoint.y) == Math.sign(this.endPoint.y - this.startPoint.y)) { - // Dans l'alignement vertical - this.endPoint = point; - return []; - - } else { - if(point.y == this.endPoint.y || point.x == this.endPoint.x) { - let result = [this.startPoint]; - this.startPoint = this.endPoint; - this.endPoint = point; - return result; - - } else { - let result = [this.startPoint, this.endPoint]; - this.startPoint = point; - this.endPoint = null; - return result; - } - } - } - } - } - } -} - - -export class DataExporter { - - /** - * Transforme un Path en CSV - */ - public exportPathPointsAsXYCsv(coords : Coords, close : boolean) : string { - const path = coords.toRemovedPath(); - let data = ""; - let pointMerger: PointMerger = new PointMerger(); - for (let i = 0; i < path.length; i++) { - let point = path.getPointAt(i).round(); - pointMerger.next(point).forEach( - (p) => data += this.toCsv(p) - ); - } - pointMerger.next(null).forEach( - (p) => data += this.toCsv(p) - ); - return data; - } - - /** - * Transforme un Path en CSV par segments - */ - public exportPathSegmentsAsXYCsv(coords : Coords, close : boolean) : string { - const path = coords.toRemovedPath(); - let data = ""; - let pointMerger: PointMerger = new PointMerger(); - for (let i = 0; i < path.segments.length; i++) { - let segment = path.segments[i]; - data += this.toCsv(segment.point.round()); - } - return data; - } - - /** - * Transforme un Path en CSV - */ - public exportPathDescriptorsAsCsv(labData : LabData, coords : PathCoords) : string { - let path = coords.toRemovedPath(); - path.closePath(); - - let linearScale = labData.rulerCoords.distance() / labData.rulerTickCount; // pixels/cm - let areaScale = Math.pow(linearScale, 2); - let fittingEllipse = new ToEllipseFitter().transform(coords); - let convexHull = new ToConvexHull().transform(coords); - - let line = 1; - let label = labData.filename; - let area = Math.abs(path.area) / areaScale; - let convexArea = Math.abs(convexHull.toRemovedPath().area) / areaScale; - let perimeter = path.length / linearScale; - let major = fittingEllipse.getMajorAxis() / linearScale; - let minor = fittingEllipse.getMinorAxis() / linearScale; - let circularity = 4 * Math.PI * area / Math.pow(perimeter, 2); - let ar = major / minor; - let round = (4 * area) / (Math.PI * major * major); - let solid = area / convexArea; - - let headers : string[] = [ " ", "Label", "Area", "Perim.", "Circ.","AR","Round","Solidity"]; - let data = [ line, - label, - MathUtils.round(area, ROUNDING_DECIMALS), - MathUtils.round(perimeter, ROUNDING_DECIMALS), - MathUtils.round(circularity, ROUNDING_DECIMALS), - MathUtils.round(ar, ROUNDING_DECIMALS), - MathUtils.round(round, ROUNDING_DECIMALS), - MathUtils.round(solid, ROUNDING_DECIMALS), - ] - - return headers.join(",") + "\n" + data.join(","); - } - - - private toCsv(point : paper.Point) : string { - return point.x + "\t" + point.y + "\n"; - } - +/** + * Utilitaire d'export des données + */ +import {LabData} from "../lab"; +import {Coords} from "./coords/coords"; +import {MeasurementExport} from "./measurement/process/measurementExport"; +import {CoordsMeasurement} from "./coords/process/coordsMeasurement"; + +export class DataExporter { + + /** + * Pour effectuer les mesures + */ + private coordsMeasure = new CoordsMeasurement(); + + /** + * Pour l'export des données de mesures + */ + private measureExport: MeasurementExport = new MeasurementExport(); + + /** + * Transforme un Path en CSV + */ + public exportPathPointsAsXYCsv(coords : Coords, close : boolean) : string { + const path = coords.toRemovedPath(); + let data = ""; + let pointMerger = new PointMerger(); + for (let i = 0; i < path.length; i++) { + let point = path.getPointAt(i).round(); + pointMerger.next(point).forEach( + (p) => data += this.toCsv(p) + ); + } + pointMerger.next(null).forEach( + (p) => data += this.toCsv(p) + ); + return data; + } + + /** + * Transforme un Path en CSV par segments + */ + public exportPathSegmentsAsXYCsv(coords : Coords, close : boolean) : string { + const path = coords.toRemovedPath(); + let data = ""; + let pointMerger: PointMerger = new PointMerger(); + for (let i = 0; i < path.segments.length; i++) { + let segment = path.segments[i]; + data += this.toCsv(segment.point.round()); + } + return data; + } + + /** + * Transforme un Path en CSV + */ + public exportPathDescriptorsAsCsv(labData : LabData) : string { + let measurement = this.coordsMeasure.measure(labData.blobMaskCoords, labData.rulerCoords, labData.rulerTickCount, labData.filename); + return this.measureExport.exportMeasurements(labData.workInfo,[measurement]).csv; + } + + + private toCsv(point : paper.Point) : string { + return point.x + "\t" + point.y + "\n"; + } + + } \ No newline at end of file diff --git a/src/data/dataImporter.ts b/src/data/dataImporter.ts index a1e475f..b152147 100644 --- a/src/data/dataImporter.ts +++ b/src/data/dataImporter.ts @@ -1,25 +1,47 @@ -import {Coords} from "./coords/coords"; -import {PathCoords} from "./coords/pathCoords"; -import {StringUtils} from "../utils/stringUtils"; -import * as paper from "paper"; - -/** - * Import de données, sert plutôt ôu rle debug - */ -export class DataImporter { - - /** - * Charge un PathCoords depuis des coordonnées text - */ - public import(text: string): PathCoords { - let pathCoords = new PathCoords(); - let lines = StringUtils.splitLines(text); - lines.filter(line => line.trim().length > 0).forEach( - (line: string) => { - let [x, y] = line.split("\t"); - pathCoords.points.push(new paper.Point(Number(x), Number(y))); - } - ); - return pathCoords; - } -} +import {PathCoords} from "./coords/pathCoords"; +import {StringUtils} from "../utils/stringUtils"; +import * as paper from "paper"; +import {ExperienceEnum, GroupeEnum, WorkInfo} from "./work/workInfo"; +import {Measurement} from "./measurement/measurement"; +import {csvParse} from "d3-dsv"; + + + +/** + * Le contenu d'un fichier CSV de mesure (pour une photo) + */ +export interface CsvResultFileData { + filename: string, + workInfo: WorkInfo, + measures: Measurement[] +} + + +/** + * Import de données, sert plutôt pour le debug + */ +export class DataImporter { + + /** + * Fichier de résultats + */ + public readCsvResultFileData(filename: string, csv: string) : CsvResultFileData { + console.log(csvParse(csv)); + return null; + } + + /** + * Charge un PathCoords depuis des coordonnées text + */ + public readPathCoords(text: string): PathCoords { + let pathCoords = new PathCoords(); + let lines = StringUtils.splitLines(text); + lines.filter(line => line.trim().length > 0).forEach( + (line: string) => { + let [x, y] = line.split("\t"); + pathCoords.points.push(new paper.Point(Number(x), Number(y))); + } + ); + return pathCoords; + } +} diff --git a/src/data/measurement/measurement.ts b/src/data/measurement/measurement.ts new file mode 100644 index 0000000..7980351 --- /dev/null +++ b/src/data/measurement/measurement.ts @@ -0,0 +1,12 @@ +/** + * Contient les mesures métriques + */ +export interface Measurement { + label: string, // le nom du fichier + area: number, + perimeter: number, + circularity: number, + ar: number, + round: number, + solid: number +} \ No newline at end of file diff --git a/src/data/measurement/measurementWorks.ts b/src/data/measurement/measurementWorks.ts new file mode 100644 index 0000000..13fcd7e --- /dev/null +++ b/src/data/measurement/measurementWorks.ts @@ -0,0 +1,14 @@ +import {WorkInfo} from "../work/workInfo"; +import {Measurement} from "./measurement"; + +/** + * Regroupe des mesures par sessions de travail + */ +export interface MeasurementWorks { + + [work: string]: { + work: WorkInfo, + files: { [filename: string] : Measurement[] } + } + +} \ No newline at end of file diff --git a/src/data/measurement/process/measurementExport.ts b/src/data/measurement/process/measurementExport.ts new file mode 100644 index 0000000..78a3d60 --- /dev/null +++ b/src/data/measurement/process/measurementExport.ts @@ -0,0 +1,44 @@ +import {Measurement} from "../measurement"; +import {MathUtils} from "../../../utils/mathUtils"; +import {WorkInfo} from "../../work/workInfo"; +import {csvFormatRows} from "d3-dsv"; +import {WorkInfoFormatter} from "../../work/process/workInfoFormatter"; + +const ROUNDING_DECIMALS = 3; + +/** + * Export de mesures + */ +export class MeasurementExport { + + private workInfoFormatter = new WorkInfoFormatter(); + + + /** + * Export les mesures au format CSV + */ + public exportMeasurements(work: WorkInfo, measurements: Measurement[]) : { filename: string, csv: string } { + return { + filename: "Results_" + this.workInfoFormatter.format(work) + ".csv", + csv: csvFormatRows([[" ", "Label", "Area", "Perim.", "Circ.","AR","Round","Solidity"]] + .concat(measurements.map((measurement, i) => + [ (i + 1).toString(), + measurement.label, + MathUtils.round(measurement.area, ROUNDING_DECIMALS).toString(), + MathUtils.round(measurement.perimeter, ROUNDING_DECIMALS).toString(), + MathUtils.round(measurement.circularity, ROUNDING_DECIMALS).toString(), + MathUtils.round(measurement.ar, ROUNDING_DECIMALS).toString(), + MathUtils.round(measurement.round, ROUNDING_DECIMALS).toString(), + MathUtils.round(measurement.solid, ROUNDING_DECIMALS).toString(), + ] + )))}; + } + /** + * Export les mesures au format CSV + */ + public exportDryMeasures(work: WorkInfo) : { filename: string, csv: string } { + return this.exportMeasurements(work, []); + } + + +} \ No newline at end of file diff --git a/src/data/measurement/process/measurementImport.ts b/src/data/measurement/process/measurementImport.ts new file mode 100644 index 0000000..2d318d5 --- /dev/null +++ b/src/data/measurement/process/measurementImport.ts @@ -0,0 +1,56 @@ +/** + * Import de mesures + */ +import {Measurement} from "../measurement"; +import {WorkInfo} from "../../work/workInfo"; +import {WorkInfoParser} from "../../work/process/workInfoParser"; +import {csvParseRows} from "d3-dsv"; + +const MEASURE_FILENAME_REGEX = /^Results_(?<work>[a-zA-Z0-9]+).csv$/i; + +/** + * EN charge de l'import de mesures (lecture de fichiers CSV) + */ +export class MeasurementImport { + + /** + * Poru parser la session de travail + */ + private workInfoParser = new WorkInfoParser(); + + /** + * Lit des mesures depuis des données csv + * @param String + */ + public readMeasures(filename: string, csv: string) : { work: WorkInfo, measurements: Measurement[] } { + let match = filename.match(MEASURE_FILENAME_REGEX); + let work = null; + if(match != null) { + work = this.workInfoParser.parse(match.groups.work); + } + if(work == null) { + throw new Error("Le nom du fichier " + filename + " ne respecte pas la nomenclature (par ex.: Results_ExpJ2ConB3.csv)"); + } + + let measurements : Measurement[] = csvParseRows(csv, (d, i) : Measurement => { + if(i == 0) { + if(d.length != 8 || d[0] != " " || d[1] != "Label" || d[2] != "Area" || d[3] != "Perim." || d[4] != "Circ." || d[5] != "AR" || d[6] != "Round" || d[7] != "Solidity" ) { + throw new Error("Fichier " + filename + " : la première ligne du fichier ne contient pas les en-têtes attendus (\" ,Label,Area,Perim.,Circ.,AR,Round,Solidity\")") + } + } else { + return { + label: d[1], // le nom du fichier + area: +d[2], + perimeter: +d[3], + circularity: +d[4], + ar: +d[5], + round: +d[6], + solid: +d[7] + }; + } + }); + return { work: work, measurements: measurements }; + } + + +} \ No newline at end of file diff --git a/src/data/measurement/process/measurementMerge.ts b/src/data/measurement/process/measurementMerge.ts new file mode 100644 index 0000000..77a040d --- /dev/null +++ b/src/data/measurement/process/measurementMerge.ts @@ -0,0 +1,45 @@ +/** + * Merge des mesures + */ +import {MeasurementWorks} from "../measurementWorks"; +import {WorkInfo} from "../../work/workInfo"; +import {Measurement} from "../measurement"; +import {ObjectUtils} from "../../../utils/objectUtils"; +import {MeasurementImport} from "./measurementImport"; +import {WorkInfoFormatter} from "../../work/process/workInfoFormatter"; + +/** + * En charge du merge des mesures + */ +export class MeasurementMerge { + + /** + * Pour importer les données CSV + */ + private measurementImport = new MeasurementImport(); + + /** + * Pour encoder le WorkInfo + */ + private workInfoFormatter = new WorkInfoFormatter(); + + /** + * Ajoute un fichier de mesures dans + */ + public mergeInto(measurementWorks: MeasurementWorks, filename: string, work: WorkInfo, measurements: Measurement[]) : MeasurementWorks { + // La session de travail (ensemble de blobs) + let groupWork = ObjectUtils.deepClone(work); + groupWork.blob = null; + + measurementWorks = ObjectUtils.deepClone(measurementWorks); + + let workKey = this.workInfoFormatter.format(groupWork); + if (measurementWorks[workKey] == null) { + measurementWorks[workKey] = { work: groupWork, files: {}}; + } + measurementWorks[workKey].files[filename] = measurements; + return measurementWorks; + } + + +} \ No newline at end of file diff --git a/src/data/work/process/workInfoFormatter.ts b/src/data/work/process/workInfoFormatter.ts new file mode 100644 index 0000000..8c41520 --- /dev/null +++ b/src/data/work/process/workInfoFormatter.ts @@ -0,0 +1,22 @@ +/** + * Import et export des infos de travail en cours + */ +import {WorkInfo} from "../workInfo"; + +/** + * Formattage des infos du travail en cours + */ +export class WorkInfoFormatter { + + /** + * Transforme le work info en code + */ + public format(workInfo : WorkInfo) : string { + return workInfo.groupe + + "J" + workInfo.jour + + workInfo.experience + + (workInfo.blob != null ? "B" + workInfo.blob : ""); + } + + +} \ No newline at end of file diff --git a/src/data/work/process/workInfoParser.ts b/src/data/work/process/workInfoParser.ts new file mode 100644 index 0000000..76e9b5f --- /dev/null +++ b/src/data/work/process/workInfoParser.ts @@ -0,0 +1,28 @@ +import {ExperienceEnum, GroupeEnum, WorkInfo} from "../workInfo"; + + +const WORK_REGEXP = /^(?<groupe>Con|Exp)J(?<jour>[0-9]+)(?<experience>Cr|Ex)(B(?<blob>[0-9]+))?$/i; + +/** + * Parsing de code de travail en cours + */ +export class WorkInfoParser { + + /** + * Valide le bom de fichier + */ + public parse(name : string) : WorkInfo | null { + let match = name.match(WORK_REGEXP); + if(match == null) { + return null; + } else { + return { + groupe: match.groups.groupe.toLowerCase() == 'Con'.toLowerCase() ? GroupeEnum.Controle : GroupeEnum.Experimental, + jour: parseInt(match.groups.jour), + experience: match.groups.experience.toLowerCase() == 'Cr'.toLowerCase() ? ExperienceEnum.Croissance : ExperienceEnum.Exploration, + blob: match.groups.blob != null ? parseInt(match.groups.blob) : null, + } + } + } + +} \ No newline at end of file diff --git a/src/data/work/workInfo.ts b/src/data/work/workInfo.ts new file mode 100644 index 0000000..88d6aeb --- /dev/null +++ b/src/data/work/workInfo.ts @@ -0,0 +1,25 @@ +/** + * Le boîte de blob + */ +export enum GroupeEnum { + Experimental = 'Exp', + Controle = 'Con' +} + +/** + * La phase du blob + */ +export enum ExperienceEnum { + Croissance = 'Cr', + Exploration = 'Ex' +} + +/** + * Informations sur la photo + */ +export interface WorkInfo { + groupe : GroupeEnum, + jour : number, + experience : ExperienceEnum, + blob: number; +} \ No newline at end of file diff --git a/src/lab.tsx b/src/lab.tsx index 654753b..97d1758 100644 --- a/src/lab.tsx +++ b/src/lab.tsx @@ -1,348 +1,372 @@ -import * as React from 'react'; -import * as paper from "paper"; -import {StepManager} from "./ui/steps/stepManager"; -import {LoadPictureStep} from "./ui/steps/loadPictureStep"; -import {RulerStep} from "./ui/steps/rulerStep"; -import {Badge, Button, ButtonGroup, Col, Container, Form, Navbar, Row} from "react-bootstrap"; -import {Ruler} from "./instruments/ruler"; -import {PlacePetriDishStep} from "./ui/steps/placePetriDishStep"; -import {PetriDish} from "./instruments/petriDish"; -import {DrawBlobMaskStep} from "./ui/steps/drawBlobMaskStep"; -import {BlobMask} from "./instruments/blobMask"; -import {VectorCoords} from "./data/coords/vectorCoords"; -import {PathCoords} from "./data/coords/pathCoords"; -import {DownloadStep} from "./ui/steps/downloadStep"; -import {PaperUtils} from "./utils/paperUtils"; -import {EllipseCoords} from "./data/coords/ellipseCoords"; -import {Welcome} from "./ui/welcome"; - -/** - * Debug mode (ou pas) - */ -export const DEBUG_MODE = false; - -/** - * La taille par défaut de la règle - */ -export const DEFAULT_RULER_TICK_COUNT = 10; - -/** - * La taille minimum de la règle - */ -export const MIN_RULER_TICK_COUNT = 8; - -/** - * La taille maximum de la règle - */ -export const MAX_RULER_TICK_COUNT = 15; - - -export interface LabData { - pictureSize : paper.Size, - - filename : string, - - rulerTickCount : number, - - rulerCoords : VectorCoords, - - petriDishCoords : EllipseCoords, - - blobMaskCoords : PathCoords -} - - -/** - * Le lab - */ -export class Lab extends React.Component<{}> { - - /** - * Récolte des données - */ - public data : LabData | null; - - /** - * Le canvas sur lequel est dessiné la photo - */ - private canvas : HTMLCanvasElement | null = null; - - /** - * Le canvas sur lequel est dessiné la photo - */ - private welcome = React.createRef<Welcome>(); - - /** - * La photo du blob - */ - public raster : null | paper.Raster = null; - - /** - * La règle - */ - public ruler: Ruler; - - /** - * La boîte de petri - */ - public petriDish: PetriDish; - - /** - * Le contour du blob - */ - public blobMask: BlobMask; - - public constructor(props : {}) { - super(props); - } - - /** - * Post-init lorsque le lab est affiché - */ - public componentDidMount() { - if(this.canvas == null) { - throw new Error("Canvas should have been initiated"); - } - - paper.setup(this.canvas); - new paper.Tool(); - paper.tool.activate(); - - // Ajout du zoom avec la molette - this.canvas.addEventListener('wheel', (event) => { - let target = paper.view.viewToProject(new paper.Point(event.offsetX, event.offsetY)); - if (event.deltaY > 0) { - this.zoomOut(target); - } else { - this.zoomIn(target); - } - }); - - // Ajout des déplacements - paper.tool.onKeyDown = (event : paper.KeyEvent) => { - if(event.key == "control") { - PaperUtils.changeCursor("move"); - } - } - paper.tool.onKeyUp = (event : paper.KeyEvent) => { - if(event.key == "control") { - PaperUtils.changeCursor(null); - } - } - paper.tool.onMouseDrag = function(event) { - if(event.modifiers.control) { - let delta = event.point.subtract(event.downPoint); - paper.view.center = paper.view.center.subtract(delta); - event.preventDefault(); - } - } - - // Prise en compte du redimensionnement navigateur (ou agrandissement/retrécissement de la vue) - paper.view.onResize = (event) => { - if(this.raster != null) { - paper.view.center = this.raster.position; - } - } - } - - /** - * Lance une nouvelle session de travail - */ - public new(image : HTMLImageElement, filename : string) : boolean { - console.info("Nouvelle session de travail") - if(this.raster != null) { - if(window.confirm("Écraser le travail en cours ?")) { - this.reset(); - } else { - return false; - } - } - - // Masque le composant d'accueil - this.welcome.current.setState({visible: false }); - - // Init du Raster de l'image - this.raster = new paper.Raster(); - this.raster.image = image; - this.raster.bounds.point = new paper.Point(0, 0); - this.raster.smoothing = 'off'; - - // Init des données - let width = image.naturalWidth; - let height = image.naturalHeight; - this.data = { - pictureSize: new paper.Size(width, height), - - filename: filename, - - rulerTickCount : DEFAULT_RULER_TICK_COUNT, - - rulerCoords: new VectorCoords(new paper.Point(width * 0.25, height / 2), new paper.Point(width * 0.75, height / 2)), - - petriDishCoords: new EllipseCoords(new paper.Point(width / 2, height / 2), width * 0.75 / 2, width * 0.75 / 2, 0), - - blobMaskCoords: new PathCoords(), - }; - - // Le plus en dessous en premier - this.blobMask = new BlobMask(this, this.data.blobMaskCoords); - this.petriDish = new PetriDish(this, this.data.petriDishCoords); - this.ruler = new Ruler(this, this.data.rulerCoords); - - // Zoom global - this.zoomFit(); - - // Petit refresh - paper.view.update(); - - return true; - } - - /** - * Remet à zéro l'espace de travail - */ - private reset() : void { - if(this.raster != null) { - this.raster.remove(); - } - this.raster = null; - - // Vidage des instruments - this.ruler.clear(); - this.petriDish.clear(); - this.blobMask.clear(); - - } - - /** - * Zoom au plus près de la photo - */ - public zoomFit() : void { - if(this.raster != null && this.canvas != null && this.data.pictureSize != null) { - this.zoomOn(new paper.Rectangle(0, 0, this.data.pictureSize.width, this.data.pictureSize.height)) - } - } - - /** - * Zoom sur une zone - */ - public zoomOn(rectangle : paper.Rectangle, marginPercent : number = 0) { - paper.view.center = rectangle.center; - let xZoomFactor = Math.min(1, this.canvas.width / rectangle.width); - let yZoomFactor = Math.min(1, this.canvas.height / rectangle.height); - paper.view.zoom = Math.min(xZoomFactor, yZoomFactor) * (1 - marginPercent) / paper.view.pixelRatio; - paper.view.update(); - this.onZoomChanged(); - } - - /** - * Plus de zoom - */ - public zoomIn(target? : paper.Point) : void { - this.zoom(1.10, target); - } - - // Zooms par delta - - /** - * Moins de zoom - */ - public zoomOut(target? : paper.Point) : void { - this.zoom(0.90, target); - } - - /** - * Pas de zoom 1:1 - */ - public zoomNone() : void { - paper.view.zoom = 1; - this.onZoomChanged(); - } - - /** - * Centralise le zoom - */ - private zoom(zoomFactor : number, target? : paper.Point) { - let oldZoom = paper.view.zoom; - let newZoom = oldZoom * zoomFactor; - - if(target != undefined) { - // let viewPosition = paper.view.viewToProject(target); - let viewPosition = target; - let mpos = viewPosition; - let ctr = paper.view.center; - - let pc = mpos.subtract(ctr); - let offset = mpos.subtract(pc.multiply(0.95 / zoomFactor)).subtract(ctr); - - paper.view.center = paper.view.center.add(offset); - } - - // On borne les zooms pour ne pas que ça parte partout - // Zoom minimum = zoom fit - let minZoom = 0; - if(this.data != null) { - let xZoomFactor = Math.min(1, this.canvas.width / this.data.pictureSize.width) - let yZoomFactor = Math.min(1, this.canvas.height / this.data.pictureSize.height); - minZoom = Math.min(xZoomFactor, yZoomFactor) / paper.view.pixelRatio; - } - let maxZoom = 10; - paper.view.zoom = Math.min(maxZoom, Math.max(newZoom, minZoom)); - this.onZoomChanged(); - } - - /** - * Appelé lorsque le zoom a changé - */ - private onZoomChanged() { - this.ruler?.refresh(); - this.petriDish?.refresh(); - this.blobMask?.refresh(); - } - - render(): React.ReactNode { - return <Container fluid={true} className={"vh-100 d-flex flex-column"}> - <Navbar bg="light" expand="lg" className={"p-0"}> - <Container fluid={true}> - <Row className={"col-md-12"}> - <div className="d-flex d-flex justify-content-between"> - <Navbar.Brand className={"p-0"}><i className={"fa-solid fa-flask me-2"}></i>Blob Analysis Lab <sup><Badge pill bg="secondary" text="primary">demo</Badge></sup></Navbar.Brand> - <Form className={"inline-form"}> - <Form.Group controlId="zoomGroup"> - <Form.Label>Zoom :</Form.Label> - <ButtonGroup aria-label="Zoom" className={"ms-2"}> - <Button onClick={() => this.zoomIn()} variant={"primary"} size={"sm"}><i className="fa-solid fa-magnifying-glass-plus"></i></Button> - <Button onClick={() => this.zoomOut()} variant={"primary"} size={"sm"}><i className="fa-solid fa-magnifying-glass-minus"></i></Button> - <Button onClick={() => this.zoomFit()} variant={"primary"} size={"sm"}><i className="fa-regular fa-image"></i></Button> - <Button onClick={() => this.zoomNone()} variant={"primary"} size={"sm"}>1:1</Button> - </ButtonGroup> - <Form.Label className={"ms-3"}>[CTRL] + <i className="fa-solid fa-computer-mouse"></i> = <i className="fa-solid fa-arrows-up-down-left-right"></i></Form.Label> - </Form.Group> - </Form> - <div> - <Button href={"docs/index.html"} target="_blank" variant={"primary"} size={"sm"}>Tutoriel<i className="ms-2 fa-solid fa-book"></i></Button> - </div> - </div> - </Row> - </Container> - </Navbar> - <Row className="flex-grow-1"> - <div className="col position-relative"> - <Welcome ref={this.welcome}/> - <canvas ref={(canvas : HTMLCanvasElement)=> this.canvas = canvas} data-paper-resize="false" className="h-100 w-100 d-block" onContextMenu={() => false}></canvas> - </div> - <Col md={4} className={"border-2"} > - <div className="mb-3"> - <StepManager> - <LoadPictureStep lab={this} code="loadPicture" title="Charger une photo"/> - <RulerStep lab={this} code="placeRuler" title="Positionner la règle"/> - <PlacePetriDishStep lab={this} code="placePetriDish" title="Positionner la boîte de petri"/> - <DrawBlobMaskStep lab={this} code="drawBlobMask" title="Détourer le blob"/> - <DownloadStep lab={this} code="download" title="Télécharger les résultats"/> - </StepManager> - </div> - </Col> - </Row> - </Container> - } +import * as React from 'react'; +import * as paper from "paper"; +import {StepManager} from "./ui/steps/stepManager"; +import {LoadPictureStep} from "./ui/steps/loadPictureStep"; +import {RulerStep} from "./ui/steps/rulerStep"; +import {Badge, Button, ButtonGroup, Col, Container, Form, Navbar, Row} from "react-bootstrap"; +import {Ruler} from "./instruments/ruler"; +import {PlacePetriDishStep} from "./ui/steps/placePetriDishStep"; +import {PetriDish} from "./instruments/petriDish"; +import {DrawBlobMaskStep} from "./ui/steps/drawBlobMaskStep"; +import {BlobMask} from "./instruments/blobMask"; +import {VectorCoords} from "./data/coords/vectorCoords"; +import {PathCoords} from "./data/coords/pathCoords"; +import {DownloadStep} from "./ui/steps/downloadStep"; +import {PaperUtils} from "./utils/paperUtils"; +import {EllipseCoords} from "./data/coords/ellipseCoords"; +import {Welcome} from "./ui/welcome"; +import {DataImporter} from "./data/dataImporter"; +import {WorkInfo} from "./data/work/workInfo"; +import {IoUtils} from "./utils/ioUtils"; +import {WorkInfoParser} from "./data/work/process/workInfoParser"; + +/** + * Debug mode (ou pas) + */ +export const DEBUG_MODE = false; + +/** + * La taille par défaut de la règle + */ +export const DEFAULT_RULER_TICK_COUNT = 10; + +/** + * La taille minimum de la règle + */ +export const MIN_RULER_TICK_COUNT = 8; + +/** + * La taille maximum de la règle + */ +export const MAX_RULER_TICK_COUNT = 15; + + +export interface LabData { + + pictureSize : paper.Size, + + filename : string, + + workInfo : WorkInfo, + + rulerTickCount : number, + + rulerCoords : VectorCoords, + + petriDishCoords : EllipseCoords, + + blobMaskCoords : PathCoords +} + + +/** + * Le lab + */ +export class Lab extends React.Component<{}> { + + /** + * Récolte des données + */ + public data : LabData | null; + + /** + * Le canvas sur lequel est dessiné la photo + */ + private canvas : HTMLCanvasElement | null = null; + + /** + * Le canvas sur lequel est dessiné la photo + */ + private welcome = React.createRef<Welcome>(); + + /** + * La photo du blob + */ + public raster : null | paper.Raster = null; + + /** + * La règle + */ + public ruler: Ruler; + + /** + * La boîte de petri + */ + public petriDish: PetriDish; + + /** + * Le contour du blob + */ + public blobMask: BlobMask; + + /** + * Outil d'import de données + */ + public dataImporter = new DataImporter(); + + /** + * Parsing du work in progress + */ + public workInfoParser = new WorkInfoParser(); + + public constructor(props : {}) { + super(props); + } + + /** + * Post-init lorsque le lab est affiché + */ + public componentDidMount() { + if(this.canvas == null) { + throw new Error("Canvas should have been initiated"); + } + + paper.setup(this.canvas); + new paper.Tool(); + paper.tool.activate(); + + // Ajout du zoom avec la molette + this.canvas.addEventListener('wheel', (event) => { + let target = paper.view.viewToProject(new paper.Point(event.offsetX, event.offsetY)); + if (event.deltaY > 0) { + this.zoomOut(target); + } else { + this.zoomIn(target); + } + }); + + // Ajout des déplacements + paper.tool.onKeyDown = (event : paper.KeyEvent) => { + if(event.key == "control") { + PaperUtils.changeCursor("move"); + } + } + paper.tool.onKeyUp = (event : paper.KeyEvent) => { + if(event.key == "control") { + PaperUtils.changeCursor(null); + } + } + paper.tool.onMouseDrag = function(event) { + if(event.modifiers.control) { + let delta = event.point.subtract(event.downPoint); + paper.view.center = paper.view.center.subtract(delta); + event.preventDefault(); + } + } + + // Prise en compte du redimensionnement navigateur (ou agrandissement/retrécissement de la vue) + paper.view.onResize = (event) => { + if(this.raster != null) { + paper.view.center = this.raster.position; + } + } + } + + /** + * Lance une nouvelle session de travail + */ + public new(image : HTMLImageElement, filename : string) : boolean { + console.info("Nouvelle session de travail") + let workInfo = this.workInfoParser.parse(IoUtils.basename(filename)); + if(workInfo == null) { + window.alert("Le nom du fichier ne respecte pas nomenclature") + return false; + } + if(this.raster != null) { + if(window.confirm("Écraser le travail en cours ?")) { + this.reset(); + } else { + return false; + } + } + + // Masque le composant d'accueil + this.welcome.current.setState({visible: false }); + + // Init du Raster de l'image + this.raster = new paper.Raster(); + this.raster.image = image; + this.raster.bounds.point = new paper.Point(0, 0); + this.raster.smoothing = 'off'; + + // Init des données + let width = image.naturalWidth; + let height = image.naturalHeight; + this.data = { + pictureSize: new paper.Size(width, height), + + filename: filename, + + workInfo: workInfo, + + rulerTickCount : DEFAULT_RULER_TICK_COUNT, + + rulerCoords: new VectorCoords(new paper.Point(width * 0.25, height / 2), new paper.Point(width * 0.75, height / 2)), + + petriDishCoords: new EllipseCoords(new paper.Point(width / 2, height / 2), width * 0.75 / 2, width * 0.75 / 2, 0), + + blobMaskCoords: new PathCoords(), + }; + + // Le plus en dessous en premier + this.blobMask = new BlobMask(this, this.data.blobMaskCoords); + this.petriDish = new PetriDish(this, this.data.petriDishCoords); + this.ruler = new Ruler(this, this.data.rulerCoords); + + // Zoom global + this.zoomFit(); + + // Petit refresh + paper.view.update(); + + return true; + } + + /** + * Remet à zéro l'espace de travail + */ + private reset() : void { + if(this.raster != null) { + this.raster.remove(); + } + this.raster = null; + + // Vidage des instruments + this.ruler.clear(); + this.petriDish.clear(); + this.blobMask.clear(); + + } + + /** + * Zoom au plus près de la photo + */ + public zoomFit() : void { + if(this.raster != null && this.canvas != null && this.data.pictureSize != null) { + this.zoomOn(new paper.Rectangle(0, 0, this.data.pictureSize.width, this.data.pictureSize.height)) + } + } + + /** + * Zoom sur une zone + */ + public zoomOn(rectangle : paper.Rectangle, marginPercent : number = 0) { + paper.view.center = rectangle.center; + let xZoomFactor = Math.min(1, this.canvas.width / rectangle.width); + let yZoomFactor = Math.min(1, this.canvas.height / rectangle.height); + paper.view.zoom = Math.min(xZoomFactor, yZoomFactor) * (1 - marginPercent) / paper.view.pixelRatio; + paper.view.update(); + this.onZoomChanged(); + } + + /** + * Plus de zoom + */ + public zoomIn(target? : paper.Point) : void { + this.zoom(1.10, target); + } + + // Zooms par delta + + /** + * Moins de zoom + */ + public zoomOut(target? : paper.Point) : void { + this.zoom(0.90, target); + } + + /** + * Pas de zoom 1:1 + */ + public zoomNone() : void { + paper.view.zoom = 1; + this.onZoomChanged(); + } + + /** + * Centralise le zoom + */ + private zoom(zoomFactor : number, target? : paper.Point) { + let oldZoom = paper.view.zoom; + let newZoom = oldZoom * zoomFactor; + + if(target != undefined) { + // let viewPosition = paper.view.viewToProject(target); + let viewPosition = target; + let mpos = viewPosition; + let ctr = paper.view.center; + + let pc = mpos.subtract(ctr); + let offset = mpos.subtract(pc.multiply(0.95 / zoomFactor)).subtract(ctr); + + paper.view.center = paper.view.center.add(offset); + } + + // On borne les zooms pour ne pas que ça parte partout + // Zoom minimum = zoom fit + let minZoom = 0; + if(this.data != null) { + let xZoomFactor = Math.min(1, this.canvas.width / this.data.pictureSize.width) + let yZoomFactor = Math.min(1, this.canvas.height / this.data.pictureSize.height); + minZoom = Math.min(xZoomFactor, yZoomFactor) / paper.view.pixelRatio; + } + let maxZoom = 10; + paper.view.zoom = Math.min(maxZoom, Math.max(newZoom, minZoom)); + this.onZoomChanged(); + } + + /** + * Appelé lorsque le zoom a changé + */ + private onZoomChanged() { + this.ruler?.refresh(); + this.petriDish?.refresh(); + this.blobMask?.refresh(); + } + + render(): React.ReactNode { + return <Container fluid={true} className={"vh-100 d-flex flex-column"}> + <Navbar bg="light" expand="lg" className={"p-0"}> + <Container fluid={true}> + <Row className={"col-md-12"}> + <div className="d-flex d-flex justify-content-between"> + <Navbar.Brand className={"p-0"}><i className={"fa-solid fa-flask me-2"}></i>Blob Analysis Lab <sup><Badge pill bg="secondary" text="primary">demo</Badge></sup></Navbar.Brand> + <Form className={"inline-form"}> + <Form.Group controlId="zoomGroup"> + <Form.Label>Zoom :</Form.Label> + <ButtonGroup aria-label="Zoom" className={"ms-2"}> + <Button onClick={() => this.zoomIn()} variant={"primary"} size={"sm"}><i className="fa-solid fa-magnifying-glass-plus"></i></Button> + <Button onClick={() => this.zoomOut()} variant={"primary"} size={"sm"}><i className="fa-solid fa-magnifying-glass-minus"></i></Button> + <Button onClick={() => this.zoomFit()} variant={"primary"} size={"sm"}><i className="fa-regular fa-image"></i></Button> + <Button onClick={() => this.zoomNone()} variant={"primary"} size={"sm"}>1:1</Button> + </ButtonGroup> + <Form.Label className={"ms-3"}>[CTRL] + <i className="fa-solid fa-computer-mouse"></i> = <i className="fa-solid fa-arrows-up-down-left-right"></i></Form.Label> + </Form.Group> + </Form> + <div> + <Button href={"docs/index.html"} target="_blank" variant={"primary"} size={"sm"}>Tutoriel<i className="ms-2 fa-solid fa-book"></i></Button> + </div> + </div> + </Row> + </Container> + </Navbar> + <Row className="flex-grow-1"> + <div className="col position-relative"> + <Welcome ref={this.welcome}/> + <canvas ref={(canvas : HTMLCanvasElement)=> this.canvas = canvas} data-paper-resize="false" className="h-100 w-100 d-block" onContextMenu={() => false}></canvas> + </div> + <Col md={4} className={"border-2"} > + <div className="mb-3"> + <StepManager> + <LoadPictureStep lab={this} code="loadPicture" title="Charger une photo"/> + <RulerStep lab={this} code="placeRuler" title="Positionner la règle"/> + <PlacePetriDishStep lab={this} code="placePetriDish" title="Positionner la boîte de petri"/> + <DrawBlobMaskStep lab={this} code="drawBlobMask" title="Détourer le blob"/> + <DownloadStep lab={this} code="download" title="Télécharger les résultats"/> + </StepManager> + </div> + </Col> + </Row> + </Container> + } } \ No newline at end of file diff --git a/src/ui/merger.tsx b/src/ui/merger.tsx new file mode 100644 index 0000000..4733e81 --- /dev/null +++ b/src/ui/merger.tsx @@ -0,0 +1,148 @@ +import * as React from "react"; +import {ChangeEvent} from "react"; +import {Alert, Button, Col, InputGroup, ListGroup, Modal, Row} from "react-bootstrap"; +import {IoUtils} from "../utils/ioUtils"; +import {MeasurementImport} from "../data/measurement/process/measurementImport"; +import {ExperienceEnum, GroupeEnum} from "../data/work/workInfo"; +import {DownloadButton} from "./steps/downloadStep"; +import {MeasurementWorks} from "../data/measurement/measurementWorks"; +import {MeasurementMerge} from "../data/measurement/process/measurementMerge"; +import {MeasurementExport} from "../data/measurement/process/measurementExport"; +import {Measurement} from "../data/measurement/measurement"; + +/** + * L'état de l'affichage de l'outil de merge + */ +export interface MergerState { + visible : boolean, + measurementWorks: MeasurementWorks +} + +/** + * Outil de merge des fichiers de mesures + */ +export class Merger extends React.Component<{}, MergerState> { + + /** + * Pour importer des données + */ + private measurementImport = new MeasurementImport(); + + /** + * Pour exporter des données + */ + private measurementExport = new MeasurementExport(); + + /** + * Pour merger les données + */ + private measurementMerge = new MeasurementMerge(); + + public constructor(props: {}) { + super(props); + this.state = {visible: false, measurementWorks: {} } + } + + /** + * Affiche l'outil de merge + */ + public show() { + this.setState({visible: true}); + } + + /** + * Masque l'outil de merge + */ + public hide() { + this.setState({visible: false}); + } + + /** + * + * @private + */ + private addFiles(event : ChangeEvent<HTMLInputElement>) { + if(event.target.files != null) { + for (let file of event.target.files) { + IoUtils.readTextFile(file, text => { + let filename = file.name; + try { + let {work, measurements} = this.measurementImport.readMeasures(filename, text); + let measurementWorks = this.measurementMerge.mergeInto(this.state.measurementWorks, filename, work, measurements); + this.setState({measurementWorks: measurementWorks}); + } catch (error) { + alert(error.message); + } + }); + } + } + return true; + } + + /** + * Téléchargement de la description du blob + */ + private download(workCode: string) : void { + let measurements: Measurement[] = Object.keys(this.state.measurementWorks[workCode].files) + .flatMap(filename => this.state.measurementWorks[workCode].files[filename]); + + let { filename, csv } = this.measurementExport.exportMeasurements(this.state.measurementWorks[workCode].work, measurements); + IoUtils.downloadData(filename, "text/plain;charset=UTF-8", csv); + } + + + public render() { + let that = this; + return <Modal + show={this.state.visible} + backdrop="static" + keyboard={false} + size={"lg"} + onHide={this.hide.bind(this)} + scrollable={true} + > + <Modal.Header closeButton={true} closeVariant={"white"}> + <Modal.Title as={"h6"}>Fusionner les CSV</Modal.Title> + </Modal.Header> + <Modal.Body> + <Alert className={"p-2"} variant={"success"}><b>A la fin de l'analyse d'une séquence de photos </b>, regroupez ici les fichiers .csv générés par photo (par ex.: <em>Results_ExpJ1CrB10.csv</em>) pour générer le fichier attendu dans l'espace blob (par ex.: <em>Results_ExpJ1Cr.csv</em>).</Alert> + <Row> + <Col> + <b>Sélectionner les fichiers en vrac à regrouper :</b> + <div className="mb-3 mt-1"> + <input className="form-control" type="file" accept={".csv"} multiple={true} onChange={(e) => this.addFiles(e)}></input> + </div> + </Col> + </Row> + <Row> + <Col> + <b>Fichiers fusionnés :</b> + <ListGroup> + {Object.keys(this.state.measurementWorks).map((workCode) => { + return <ListGroup.Item key={workCode}> + <div className={"mb-2"}> + <span className={"ms-0"}><span className={"small text-dark"}>Groupe : </span><b>{this.state.measurementWorks[workCode].work.groupe == GroupeEnum.Experimental ? "Expérimental" : "Contrôle"}</b></span> + <span className={"ms-2"}><span className={"small text-dark"}>Jour : </span><b>{this.state.measurementWorks[workCode].work.jour}</b></span> + <span className={"ms-2"}><span className={"small text-dark"}>Expérience : </span><b>{this.state.measurementWorks[workCode].work.experience == ExperienceEnum.Exploration ? "Exploration" : "Croissance"}</b></span> + </div> + <div className={"mb-2"}> + { Object.keys(this.state.measurementWorks[workCode].files).map(value =><span key={value} className={"me-1 p-1 rounded border bg-light font-monospace"}>{value}</span>)} + </div> + <div className={"col-5"}> + <InputGroup size={"sm"}> + <DownloadButton downloading={false} disabled={false} onClick={() => {this.download(workCode)}}/> + <InputGroup.Text className={"col"}>{ that.measurementExport.exportDryMeasures(this.state.measurementWorks[workCode].work).filename }</InputGroup.Text> + </InputGroup> + </div> + </ListGroup.Item> + })} + </ListGroup> + </Col> + </Row> + </Modal.Body> + <Modal.Footer> + <Button variant="secondary" onClick={this.hide.bind(this)}>Fermer</Button> + </Modal.Footer> + </Modal> + } +} \ No newline at end of file diff --git a/src/ui/steps/downloadStep.tsx b/src/ui/steps/downloadStep.tsx index 8effb92..804b733 100644 --- a/src/ui/steps/downloadStep.tsx +++ b/src/ui/steps/downloadStep.tsx @@ -1,175 +1,206 @@ -import {Step, StepProps, StepState} from "./step"; -import * as React from "react"; -import {Alert, Button, InputGroup} from "react-bootstrap"; -import {IoUtils} from "../../utils/ioUtils"; -import {DataExporter} from "../../data/dataExporter"; -import * as paper from "paper"; -import {ImageDataWrapper, Rgba} from "../../render/ImageDataWrapper"; - -export interface DownloadButtonProps { - downloading: boolean, - onClick : () => void, - disabled: boolean, -} - -export class DownloadButton extends React.Component<DownloadButtonProps, any> { - - constructor(props : DownloadButtonProps) { - super(props); - } - - render() : React.ReactNode { - let faIcon = this.props.downloading ? "fa-solid fas fa-cog fa-spin" : "fa-solid fa-download"; - let key = this.props.downloading ? "downloading" : "notDownloading"; - return <Button key={key} onClick={this.props.onClick} disabled={this.props.disabled || this.props.downloading} variant={"primary"} size={"sm"}> - <i className={faIcon}></i> - </Button> - } - -} - -export interface DownloadStepState extends StepState { - petriDishDataFilename: string | null, - blobMaskDataFilename: string | null, - blobMaskFilename: string | null, - resultsFilename: string | null, - downloading: boolean -} - - - -/** - * Etape de téléchargement des fichiers - */ -export class DownloadStep extends Step<DownloadStepState> { - - /** - * Outil d'export de données - */ - private dataExporter: DataExporter = new DataExporter(); - - public constructor(props: StepProps) { - super(props, { active: false, activable: false, petriDishDataFilename : null, blobMaskDataFilename: null, blobMaskFilename: null, resultsFilename: null, downloading: false }); - } - - canBeActivated(): boolean { - return this.props.lab.data != null - && this.props.lab.ruler.hasBeenStarted() - && this.props.lab.petriDish.hasBeenStarted() - && this.props.lab.blobMask.hasBeenStarted() - && this.props.lab.data.blobMaskCoords.isClosed(); - } - - onActivation(): void { - this.setState({ - petriDishDataFilename: IoUtils.basename(this.props.lab.data.filename) + "_Coord_Boite.txt", - blobMaskDataFilename: IoUtils.basename(this.props.lab.data.filename) + "_Coord_Blob.txt", - blobMaskFilename: IoUtils.basename(this.props.lab.data.filename) + "_Mask.png", - resultsFilename: "Results_" + IoUtils.basename(this.props.lab.data.filename) + ".csv", - }); - } - - onDeactivation(): void { - } - - /** - * Téléchargement des données de la boîte de Petri - */ - private downloadPetriDishData() : void { - let data = this.dataExporter.exportPathPointsAsXYCsv(this.props.lab.data.petriDishCoords, true); - IoUtils.downloadData(this.state.petriDishDataFilename, "text/plain;charset=UTF-8", data); - } - - /** - * Téléchargement des données du mask - */ - private downloadBlobMaskData() : void { - let data = this.dataExporter.exportPathSegmentsAsXYCsv(this.props.lab.data.blobMaskCoords, true); - IoUtils.downloadData(this.state.blobMaskDataFilename, "text/plain;charset=UTF-8", data); - } - - /** - * Téléchargement des données du mask - */ - private downloadBlobMask() : void { - let path = this.props.lab.data.blobMaskCoords.toRemovedPath(); - path.closed = true; - path.fillColor = new paper.Color("black"); - path.strokeColor = null; - path.scale(1 / paper.view.pixelRatio, path.bounds.point); - - let raster = path.rasterize({ insert: false}); - raster.smoothing = "off"; - - let newCanvas = document.createElement('canvas'); - let w = this.props.lab.data.pictureSize.width; - newCanvas.width = w; - let h = this.props.lab.data.pictureSize.height; - newCanvas.height = h; - - var newContext = newCanvas.getContext('2d'); - newContext.fillStyle = "white"; - newContext.fillRect(0, 0, newCanvas.width, newCanvas.height); - newContext.drawImage(raster.canvas, path.bounds.x - 0.5, path.bounds.y - 0.5); - - // Re-aliasing - const imageDataWrapper = new ImageDataWrapper(newContext.getImageData(0, 0, w, h)); - - // Supprime les nuances de gris en se basant sur la valeur rouge (on est sur d'avoir du gris) - imageDataWrapper.apply((rgba: Rgba) => { - let l = rgba.r >= 128 ? 255 : 0; - // let l = rgba.r == 255 ? 255 : 0; - return {r: l, g: l, b: l, a: 255}; - }).andStore(newContext); - - IoUtils.downloadDataUrl(this.state.blobMaskFilename, newCanvas.toDataURL("image/png")); - - newCanvas.remove(); - } - - /** - * Téléchargement de la description du blob - */ - private downloadResults() : void { - this.downloading( () => { - let data = this.dataExporter.exportPathDescriptorsAsCsv(this.props.lab.data, this.props.lab.data.blobMaskCoords); - IoUtils.downloadData(this.state.resultsFilename, "text/plain;charset=UTF-8", data); - }); - } - - /** - * Execute une tâche en indiquant un chargement en cours - */ - private downloading(task : () => void) { - this.setState({downloading : true}, () => { - setTimeout(() => { - task(); - this.setState({downloading: false}); - },500); - }); - } - - render() : React.ReactNode { - return <div> - <Alert show={!this.state.activable} variant="warning" className={"p-1"}>Veuillez terminer les étapes précédentes.</Alert> - <p>Téléchargez les fichiers d'analyse de la photo.</p> - <InputGroup className="mb-1"> - <DownloadButton key="downloadPetriDishDataButtonKey" downloading={false} onClick={this.downloadPetriDishData.bind(this)} disabled={!this.state.active}/> - <InputGroup.Text className={"col"}>{ this.state.petriDishDataFilename }</InputGroup.Text> - </InputGroup> - <InputGroup className="mb-1"> - <DownloadButton key="downloadBlobMaskDataButtonKey" downloading={false} onClick={this.downloadBlobMaskData.bind(this)} disabled={!this.state.active}/> - <InputGroup.Text className={"col"}>{ this.state.blobMaskDataFilename }</InputGroup.Text> - </InputGroup> - <InputGroup className="mb-1"> - <DownloadButton key="downloadBlobMaskButtonKey" downloading={false} onClick={this.downloadBlobMask.bind(this)} disabled={!this.state.active}/> - <InputGroup.Text className={"col"}>{ this.state.blobMaskFilename }</InputGroup.Text> - </InputGroup> - <InputGroup className="mb-1"> - <DownloadButton key="downloadResultsButtonKey" downloading={this.state.downloading} onClick={this.downloadResults.bind(this)} disabled={!this.state.active}></DownloadButton> - <InputGroup.Text className ={"col"}>{ this.state.resultsFilename }</InputGroup.Text> - </InputGroup> - </div> - } - -} +import {Step, StepProps, StepState} from "./step"; +import * as React from "react"; +import {Alert, Anchor, Button, Col, InputGroup, Row} from "react-bootstrap"; +import {IoUtils} from "../../utils/ioUtils"; +import {DataExporter} from "../../data/dataExporter"; +import * as paper from "paper"; +import {ImageDataWrapper, Rgba} from "../../render/ImageDataWrapper"; +import {Merger} from "../merger"; +import {WorkInfoFormatter} from "../../data/work/process/workInfoFormatter"; +import {MeasurementExport} from "../../data/measurement/process/measurementExport"; + +export interface DownloadButtonProps { + downloading: boolean, + onClick : () => void, + disabled: boolean, +} + +export class DownloadButton extends React.Component<DownloadButtonProps, any> { + + constructor(props : DownloadButtonProps) { + super(props); + } + + render() : React.ReactNode { + let faIcon = this.props.downloading ? "fa-solid fas fa-cog fa-spin" : "fa-solid fa-download"; + let key = this.props.downloading ? "downloading" : "notDownloading"; + return <Button key={key} onClick={this.props.onClick} disabled={this.props.disabled || this.props.downloading} variant={"primary"} size={"sm"}> + <i className={faIcon}></i> + </Button> + } + +} + +export interface DownloadStepState extends StepState { + petriDishDataFilename: string | null, + blobMaskDataFilename: string | null, + blobMaskFilename: string | null, + resultsFilename: string | null, + downloading: boolean +} + + + +/** + * Etape de téléchargement des fichiers + */ +export class DownloadStep extends Step<DownloadStepState> { + + /** + * Accès au dialog d'outil de merge + * @private + */ + private mergerRef = React.createRef<Merger>(); + + /** + * Outil d'export de données + */ + private dataExporter = new DataExporter(); + + /** + * Outil d'export de données + */ + private measureExport = new MeasurementExport(); + + public constructor(props: StepProps) { + super(props, { active: false, activable: false, petriDishDataFilename : null, blobMaskDataFilename: null, blobMaskFilename: null, resultsFilename: null, downloading: false }); + } + + canBeActivated(): boolean { + return this.props.lab.data != null + && this.props.lab.ruler.hasBeenStarted() + && this.props.lab.petriDish.hasBeenStarted() + && this.props.lab.blobMask.hasBeenStarted() + && this.props.lab.data.blobMaskCoords.isClosed(); + } + + onActivation(): void { + this.setState({ + petriDishDataFilename: IoUtils.basename(this.props.lab.data.filename) + "_Coord_Boite.txt", + blobMaskDataFilename: IoUtils.basename(this.props.lab.data.filename) + "_Coord_Blob.txt", + blobMaskFilename: IoUtils.basename(this.props.lab.data.filename) + "_Mask.png", + resultsFilename: this.measureExport.exportDryMeasures(this.props.lab.data.workInfo).filename, // dry run juste pour le nom + }); + } + + onDeactivation(): void { + } + + /** + * Téléchargement des données de la boîte de Petri + */ + private downloadPetriDishData() : void { + let data = this.dataExporter.exportPathPointsAsXYCsv(this.props.lab.data.petriDishCoords, true); + IoUtils.downloadData(this.state.petriDishDataFilename, "text/plain;charset=UTF-8", data); + } + + /** + * Téléchargement des données du mask + */ + private downloadBlobMaskData() : void { + let data = this.dataExporter.exportPathSegmentsAsXYCsv(this.props.lab.data.blobMaskCoords, true); + IoUtils.downloadData(this.state.blobMaskDataFilename, "text/plain;charset=UTF-8", data); + } + + /** + * Téléchargement des données du mask + */ + private downloadBlobMask() : void { + let path = this.props.lab.data.blobMaskCoords.toRemovedPath(); + path.closed = true; + path.fillColor = new paper.Color("black"); + path.strokeColor = null; + path.scale(1 / paper.view.pixelRatio, path.bounds.point); + + let raster = path.rasterize({ insert: false}); + raster.smoothing = "off"; + + let newCanvas = document.createElement('canvas'); + let w = this.props.lab.data.pictureSize.width; + newCanvas.width = w; + let h = this.props.lab.data.pictureSize.height; + newCanvas.height = h; + + var newContext = newCanvas.getContext('2d'); + newContext.fillStyle = "white"; + newContext.fillRect(0, 0, newCanvas.width, newCanvas.height); + newContext.drawImage(raster.canvas, path.bounds.x - 0.5, path.bounds.y - 0.5); + + // Re-aliasing + const imageDataWrapper = new ImageDataWrapper(newContext.getImageData(0, 0, w, h)); + + // Supprime les nuances de gris en se basant sur la valeur rouge (on est sur d'avoir du gris) + imageDataWrapper.apply((rgba: Rgba) => { + let l = rgba.r >= 128 ? 255 : 0; + // let l = rgba.r == 255 ? 255 : 0; + return {r: l, g: l, b: l, a: 255}; + }).andStore(newContext); + + IoUtils.downloadDataUrl(this.state.blobMaskFilename, newCanvas.toDataURL("image/png")); + + newCanvas.remove(); + } + + /** + * Téléchargement de la description du blob + */ + private downloadResults() : void { + this.downloading( () => { + let data = this.dataExporter.exportPathDescriptorsAsCsv(this.props.lab.data); + IoUtils.downloadData(this.state.resultsFilename, "text/plain;charset=UTF-8", data); + }); + } + + /** + * Ouvre l'outil de merge des fichiers CSV + * @private + */ + private openMerger() { + this.mergerRef.current.show(); + } + + /** + * Execute une tâche en indiquant un chargement en cours + */ + private downloading(task : () => void) { + this.setState({downloading : true}, () => { + setTimeout(() => { + task(); + this.setState({downloading: false}); + },500); + }); + } + + + + render() : React.ReactNode { + return <div> + <Alert show={!this.state.activable} variant="warning" className={"p-1"}>Veuillez terminer les étapes précédentes.</Alert> + <p>Téléchargez les fichiers d'analyse de la photo.</p> + <InputGroup className="mb-1"> + <DownloadButton key="downloadPetriDishDataButtonKey" downloading={false} onClick={this.downloadPetriDishData.bind(this)} disabled={!this.state.active}/> + <InputGroup.Text className={"col"}>{ this.state.petriDishDataFilename }</InputGroup.Text> + </InputGroup> + <InputGroup className="mb-1"> + <DownloadButton key="downloadBlobMaskDataButtonKey" downloading={false} onClick={this.downloadBlobMaskData.bind(this)} disabled={!this.state.active}/> + <InputGroup.Text className={"col"}>{ this.state.blobMaskDataFilename }</InputGroup.Text> + </InputGroup> + <InputGroup className="mb-1"> + <DownloadButton key="downloadBlobMaskButtonKey" downloading={false} onClick={this.downloadBlobMask.bind(this)} disabled={!this.state.active}/> + <InputGroup.Text className={"col"}>{ this.state.blobMaskFilename }</InputGroup.Text> + </InputGroup> + <InputGroup className="mb-1"> + <DownloadButton key="downloadResultsButtonKey" downloading={this.state.downloading} onClick={this.downloadResults.bind(this)} disabled={!this.state.active}></DownloadButton> + <InputGroup.Text className ={"col"}>{ this.state.resultsFilename }</InputGroup.Text> + </InputGroup> + <Row className="mb-1"> + <Col> + <Button key="mergerButtonKey" onClick={this.openMerger.bind(this)}><i className="fa-solid fa-object-group me-2"></i>Etape 5' : fusionner les CSV</Button> + <a className={"ms-1"} href={"http://localhost:8081/docs/index.html#/"} target={"_blank"}>en savoir plus</a> + </Col> + </Row> + <Merger ref={this.mergerRef}></Merger> + </div> + } + +} diff --git a/src/ui/steps/drawBlobMaskStep.tsx b/src/ui/steps/drawBlobMaskStep.tsx index b8d654f..64e514f 100644 --- a/src/ui/steps/drawBlobMaskStep.tsx +++ b/src/ui/steps/drawBlobMaskStep.tsx @@ -1,79 +1,79 @@ -import {Step, StepProps, StepState} from "./step"; -import * as React from "react"; -import * as paper from "paper"; -import {Alert, Button} from "react-bootstrap"; -import {IoUtils} from "../../utils/ioUtils"; -import {DEBUG_MODE} from "../../lab"; -import {StringUtils} from "../../utils/stringUtils"; -import {DataImporter} from "../../data/dataImporter"; - - -interface DrawBlobMaskStepState extends StepState { - - closed: boolean; - -} - -/** - * Étape de placement de la boîte de petri - */ -export class DrawBlobMaskStep extends Step<DrawBlobMaskStepState> { - - public constructor(props : StepProps) { - super(props, { active: false, activable : false, closed : false }); - } - - canBeActivated(): boolean { - return this.props.lab.data != null; - } - - onActivation(): void { - this.props.lab.blobMask.activate(); - this.setState({closed: this.props.lab.blobMask.isClosed() }); - this.props.lab.blobMask.onClose = () => { - this.setState({closed: true }); - }; - this.props.lab.blobMask.onOpen = () => { - this.setState({closed: false }); - }; - this.props.lab.zoomOn( this.props.lab.data.petriDishCoords.bounds(), 0.05); - } - - onDeactivation(): void { - this.props.lab.blobMask.deactivate(); - } - - loadData(): void { - let dataImporter = new DataImporter(); - IoUtils.openTextFile( - (text : string) => { - this.props.lab.data.blobMaskCoords = dataImporter.import(text); - this.props.lab.blobMask.refresh(); - }); - } - - render() : React.ReactNode { - return <div> - <div> - <Alert show={!this.state.activable} variant="warning" className={"p-1"}><i className="ms-1 me-1 fa-solid fa-triangle-exclamation"></i>Veuillez charger une photo.</Alert> - <p>Entourez le blob <span className={"fw-bold"}>jusqu'à rejoindre le point de départ</span>.</p> - <Alert variant={"light"} className={"p-2"}><i className="ms-1 me-1 fa-solid fa-circle-info"></i>Un faux mouvement ? <br/> - Revenir en arrière : <Button className={"me-2"} size={"sm"} disabled={!this.state.active} onClick={() => this.props.lab.blobMask.undo()}><i className="fa-solid fa-delete-left"></i></Button> - Tout effacer : <Button className={"me-2"} size={"sm"} disabled={!this.state.active} onClick={() => this.props.lab.blobMask.undoAll()}><i className="fa-solid fa-trash-can"></i></Button> - </Alert> - <Button className={"col-3"} variant={"success"} disabled={!this.state.active || !this.state.closed} onClick={this.terminate.bind(this)}> - <span hidden={!this.state.closed}><i className="fa-solid fa-hands-clapping fa-beat-fade me-2"></i></span>Fini ! - </Button> - {DEBUG_MODE ? - <Button className={"ms-2 col-5"} variant={"danger"} disabled={!this.state.active} - onClick={this.loadData.bind(this)}> - <i className="fa-solid fa-bug"></i> Charger XY - </Button> - : <></> - } - </div> - </div> - } - -} - +import {Step, StepProps, StepState} from "./step"; +import * as React from "react"; +import * as paper from "paper"; +import {Alert, Button} from "react-bootstrap"; +import {IoUtils} from "../../utils/ioUtils"; +import {DEBUG_MODE} from "../../lab"; +import {StringUtils} from "../../utils/stringUtils"; +import {DataImporter} from "../../data/dataImporter"; + + +interface DrawBlobMaskStepState extends StepState { + + closed: boolean; + +} + +/** + * Étape de placement de la boîte de petri + */ +export class DrawBlobMaskStep extends Step<DrawBlobMaskStepState> { + + public constructor(props : StepProps) { + super(props, { active: false, activable : false, closed : false }); + } + + canBeActivated(): boolean { + return this.props.lab.data != null; + } + + onActivation(): void { + this.props.lab.blobMask.activate(); + this.setState({closed: this.props.lab.blobMask.isClosed() }); + this.props.lab.blobMask.onClose = () => { + this.setState({closed: true }); + }; + this.props.lab.blobMask.onOpen = () => { + this.setState({closed: false }); + }; + this.props.lab.zoomOn( this.props.lab.data.petriDishCoords.bounds(), 0.05); + } + + onDeactivation(): void { + this.props.lab.blobMask.deactivate(); + } + + loadData(): void { + let dataImporter = new DataImporter(); + IoUtils.openTextFile( + (text : string) => { + this.props.lab.data.blobMaskCoords = dataImporter.readPathCoords(text); + this.props.lab.blobMask.refresh(); + }); + } + + render() : React.ReactNode { + return <div> + <div> + <Alert show={!this.state.activable} variant="warning" className={"p-1"}><i className="ms-1 me-1 fa-solid fa-triangle-exclamation"></i>Veuillez charger une photo.</Alert> + <p>Entourez le blob <span className={"fw-bold"}>jusqu'à rejoindre le point de départ</span>.</p> + <Alert variant={"light"} className={"p-2"}><i className="ms-1 me-1 fa-solid fa-circle-info"></i>Un faux mouvement ? <br/> + Revenir en arrière : <Button className={"me-2"} size={"sm"} disabled={!this.state.active} onClick={() => this.props.lab.blobMask.undo()}><i className="fa-solid fa-delete-left"></i></Button> + Tout effacer : <Button className={"me-2"} size={"sm"} disabled={!this.state.active} onClick={() => this.props.lab.blobMask.undoAll()}><i className="fa-solid fa-trash-can"></i></Button> + </Alert> + <Button className={"col-3"} variant={"success"} disabled={!this.state.active || !this.state.closed} onClick={this.terminate.bind(this)}> + <span hidden={!this.state.closed}><i className="fa-solid fa-hands-clapping fa-beat-fade me-2"></i></span>Fini ! + </Button> + {DEBUG_MODE ? + <Button className={"ms-2 col-5"} variant={"danger"} disabled={!this.state.active} + onClick={this.loadData.bind(this)}> + <i className="fa-solid fa-bug"></i> Charger XY + </Button> + : <></> + } + </div> + </div> + } + +} + diff --git a/src/ui/steps/loadPictureStep.tsx b/src/ui/steps/loadPictureStep.tsx index f614a4a..ff7d9ff 100644 --- a/src/ui/steps/loadPictureStep.tsx +++ b/src/ui/steps/loadPictureStep.tsx @@ -1,49 +1,49 @@ -import {Step, StepProps, StepState} from "./step"; -import * as React from "react"; -import {ChangeEvent} from "react"; - -/** - * Etape de chargement du fichier - */ -export class LoadPictureStep extends Step<StepState> { - - public constructor(props : StepProps) { - super(props, { active: true, activable : false }); - } - - private fileChanged(event : ChangeEvent<HTMLInputElement>) : boolean { - if(event.target.files != null) { - const img = new Image(); - const file = event.target.files[0]; - img.src = URL.createObjectURL(file); - let filename = file.name; - let that = this; - img.onload = function () { - if(that.props.lab.new(img, filename)) { - that.terminate(); - } - } - } - return true; - } - - canBeActivated(): boolean { - return true; - } - - onActivation(): void { - } - - onDeactivation(): void { - } - - render() : React.ReactNode { - return <div> - <div className="mb-3"> - <input className="form-control" type="file" disabled={!this.state.active} aria-disabled={!this.state.active} onChange={(e) => this.fileChanged(e)}></input> - </div> - </div> - } - - +import {Step, StepProps, StepState} from "./step"; +import * as React from "react"; +import {ChangeEvent} from "react"; + +/** + * Etape de chargement du fichier + */ +export class LoadPictureStep extends Step<StepState> { + + public constructor(props : StepProps) { + super(props, { active: true, activable : false }); + } + + private fileChanged(event : ChangeEvent<HTMLInputElement>) : boolean { + if(event.target.files != null) { + const img = new Image(); + const file = event.target.files[0]; + img.src = URL.createObjectURL(file); + let filename = file.name; + let that = this; + img.onload = function () { + if(that.props.lab.new(img, filename)) { + that.terminate(); + } + } + } + return true; + } + + canBeActivated(): boolean { + return true; + } + + onActivation(): void { + } + + onDeactivation(): void { + } + + render() : React.ReactNode { + return <div> + <div className="mb-3"> + <input className="form-control" type="file" accept={"image/*"} disabled={!this.state.active} aria-disabled={!this.state.active} onChange={(e) => this.fileChanged(e)}></input> + </div> + </div> + } + + } \ No newline at end of file diff --git a/src/utils/ioUtils.ts b/src/utils/ioUtils.ts index a955a0a..e944ad4 100644 --- a/src/utils/ioUtils.ts +++ b/src/utils/ioUtils.ts @@ -1,55 +1,61 @@ -/** - * Une classe utilitaire pour les entrées/sorties - */ -export class IoUtils { - - /** - * Ouvre un chargement - */ - public static openTextFile(onTextLoad : (text: string) => void) : void { - let input : HTMLInputElement = document.createElement('input'); - input.type = 'file'; - input.accept = '.txt'; - input.onchange = (e: InputEvent) => { - // getting a hold of the file reference - var file = (e.target as HTMLInputElement).files[0]; - - // setting up the reader - let reader = new FileReader(); - reader.readAsText(file,'UTF-8'); - // here we tell the reader what to do when it's done reading... - reader.onload = readerEvent => { - onTextLoad(readerEvent.target.result as string); - } - - } - input.click(); - } - - /** - * Donne le nom de fichier sans extension - */ - public static basename(filename : string) : string { - return filename.replace(/\.[^/.]+$/, ""); - } - - /** - * Déclenche un téléchargement - */ - public static downloadData(filename : string, mimeType : string, data : string) { - this.downloadDataUrl(filename, "data:" + mimeType + "," + encodeURIComponent(data)); - } - - /** - * Déclenche un téléchargement - */ - public static downloadDataUrl(filename : string, dataUrl : string) { - let anchor = document.createElement("a"); - anchor.href = dataUrl; - anchor.download = filename; - anchor.style.display = 'none'; - document.body.appendChild(anchor); - anchor.click(); - document.body.removeChild(anchor); - } +/** + * Une classe utilitaire pour les entrées/sorties + */ +export class IoUtils { + + /** + * Ouvre un chargement + */ + public static openTextFile(onTextLoad : (text: string) => void) : void { + let input : HTMLInputElement = document.createElement('input'); + input.type = 'file'; + input.accept = '.txt'; + input.onchange = (e: InputEvent) => { + // getting a hold of the file reference + var file = (e.target as HTMLInputElement).files[0]; + + // setting up the reader + this.readTextFile(file, onTextLoad) + + } + input.click(); + } + + /** + * Lit le texte dans un fichier + */ + public static readTextFile(file: Blob, onTextLoad : (text: string) => void) : void { + let reader = new FileReader(); + reader.readAsText(file,'UTF-8'); + // here we tell the reader what to do when it's done reading... + reader.onload = readerEvent => { + onTextLoad(readerEvent.target.result as string); + } + } + /** + * Donne le nom de fichier sans extension + */ + public static basename(filename : string) : string { + return filename.replace(/\.[^/.]+$/, ""); + } + + /** + * Déclenche un téléchargement + */ + public static downloadData(filename : string, mimeType : string, data : string) { + this.downloadDataUrl(filename, "data:" + mimeType + "," + encodeURIComponent(data)); + } + + /** + * Déclenche un téléchargement + */ + public static downloadDataUrl(filename : string, dataUrl : string) { + let anchor = document.createElement("a"); + anchor.href = dataUrl; + anchor.download = filename; + anchor.style.display = 'none'; + document.body.appendChild(anchor); + anchor.click(); + document.body.removeChild(anchor); + } } \ No newline at end of file diff --git a/src/utils/objectUtils.ts b/src/utils/objectUtils.ts new file mode 100644 index 0000000..1560063 --- /dev/null +++ b/src/utils/objectUtils.ts @@ -0,0 +1,13 @@ +/** + * Utilitaire autour des objets + */ +export class ObjectUtils { + + /** + * Deep clonin + */ + public static deepClone<T>(obj: T) : T{ + return JSON.parse(JSON.stringify(obj)) as T; + } + +} \ No newline at end of file diff --git a/tests/data/dataExporter.test.ts b/tests/data/dataExporter.test.ts index 6df1b56..0330679 100644 --- a/tests/data/dataExporter.test.ts +++ b/tests/data/dataExporter.test.ts @@ -1,29 +1,31 @@ -import {DataExporter} from "../../src/data/dataExporter"; -import {Fixtures} from "../fixtures/fixtures"; -import expectedResultsCsv from "../fixtures/Results_ExpJ1CrB9.csv"; - -describe('Testing DataExporter...', () => { - - /** - * Class under test - */ - let dataExporter = new DataExporter(); - - it('CSV metrics are correct', () => { - let labData = Fixtures.labData(); - let descriptorsCsv = dataExporter.exportPathDescriptorsAsCsv(labData, labData.blobMaskCoords); - expect(descriptorsCsv).toEqual(expectedResultsCsv); - }); - - it('Tick count may vary along with the ruler length', () => { - let labData = Fixtures.labData(); - - labData.rulerTickCount = 8; - labData.rulerCoords.end = labData.rulerCoords.start.add( - labData.rulerCoords.end.subtract(labData.rulerCoords.start).multiply(8).divide(10) - ) - - let descriptorsCsv = dataExporter.exportPathDescriptorsAsCsv(labData, labData.blobMaskCoords); - expect(descriptorsCsv).toEqual(expectedResultsCsv); - }); +import {DataExporter} from "../../src/data/dataExporter"; +import {Fixtures} from "../fixtures/fixtures"; +import expectedResultsCsv from "../fixtures/Results_ExpJ1CrB9.csv"; + +describe('Testing DataExporter...', () => { + + /** + * Class under test + */ + let dataExporter = new DataExporter(); + + it('CSV metrics are correct', () => { + let labData = Fixtures.labData(); + let descriptorsCsv = dataExporter.exportPathDescriptorsAsCsv(labData); + expect(descriptorsCsv).toEqual(expectedResultsCsv); + }); + + it('Tick count may vary along with the ruler length', () => { + let labData = Fixtures.labData(); + + labData.rulerTickCount = 8; + labData.rulerCoords.end = labData.rulerCoords.start.add( + labData.rulerCoords.end.subtract(labData.rulerCoords.start).multiply(8).divide(10) + ) + + let descriptorsCsv = dataExporter.exportPathDescriptorsAsCsv(labData); + expect(descriptorsCsv).toEqual(expectedResultsCsv); + }); + + }); \ No newline at end of file diff --git a/tests/data/measurement/process/measurementImport.test.ts b/tests/data/measurement/process/measurementImport.test.ts new file mode 100644 index 0000000..60d1eb0 --- /dev/null +++ b/tests/data/measurement/process/measurementImport.test.ts @@ -0,0 +1,72 @@ +import {WorkInfoFormatter} from "../../../../src/data/work/process/workInfoFormatter"; +import {ExperienceEnum, GroupeEnum} from "../../../../src/data/work/workInfo"; +import {ObjectUtils} from "../../../../src/utils/objectUtils"; +import {MeasurementImport} from "../../../../src/data/measurement/process/measurementImport"; +import resultsExpJ1CrB9Csv from "../../../fixtures/Results_ExpJ1CrB9.csv"; +import resultsConJ11ExCsv from "../../../fixtures/Results_ConJ11Ex.csv"; + +describe('Testing Measurement import...', () => { + + /** + * Class under test + */ + let measurementImport = new MeasurementImport(); + + it('Mono blob is well imported ', () => { + let data = measurementImport.readMeasures("Results_ExpJ1CrB9.csv", resultsExpJ1CrB9Csv); + expect(data.work.groupe).toEqual(GroupeEnum.Experimental); + expect(data.work.jour).toEqual(1); + expect(data.work.experience).toEqual(ExperienceEnum.Croissance); + expect(data.work.blob).toEqual(9); + + expect(data.measurements).toHaveSize(1); + expect(data.measurements[0]).toEqual({ + label: "ExpJ1CrB9.jpg" , + area: 33.4, + perimeter: 33.93, + circularity: 0.365, + ar: 1.625, + round: 0.615, + solid: 0.871 + }); + }); + + it('Multi blob is well imported ', () => { + let data = measurementImport.readMeasures("Results_ConJ11Ex.csv", resultsConJ11ExCsv); + expect(data.work.groupe).toEqual(GroupeEnum.Controle); + expect(data.work.jour).toEqual(11); + expect(data.work.experience).toEqual(ExperienceEnum.Exploration); + expect(data.work.blob).toBeNull(); + + expect(data.measurements).toHaveSize(3); + expect(data.measurements[0]).toEqual({ + label: "ConJ11ExB1.jpg" , + area: 11.22, + perimeter: 54.93, + circularity: 1.212, + ar: 0.4, + round: 0.4, + solid: 0.271 + }); + expect(data.measurements[1]).toEqual({ + label: "ConJ11ExB2.jpg" , + area: 33.4, + perimeter: 33.93, + circularity: 0.365, + ar: 1.625, + round: 0.615, + solid: 0.871 + }); + expect(data.measurements[2]).toEqual({ + label: "ConJ11ExB9.jpg" , + area: 15.9, + perimeter: 55.87, + circularity: 0.6, + ar: 1.98, + round: 0.1, + solid: 0.45 + }); + + }); + +}); \ No newline at end of file diff --git a/tests/data/measurement/process/measurementMerge.test.ts b/tests/data/measurement/process/measurementMerge.test.ts new file mode 100644 index 0000000..0db5ecc --- /dev/null +++ b/tests/data/measurement/process/measurementMerge.test.ts @@ -0,0 +1,88 @@ +import {ExperienceEnum, GroupeEnum} from "../../../../src/data/work/workInfo"; +import {MeasurementImport} from "../../../../src/data/measurement/process/measurementImport"; +import resultsExpJ1CrB9Csv from "../../../fixtures/Results_ExpJ1CrB9.csv"; +import resultsConJ11ExB1Csv from "../../../fixtures/Results_ConJ11ExB1.csv"; +import resultsConJ11ExB2Csv from "../../../fixtures/Results_ConJ11ExB2.csv"; +import resultsConJ11ExB9Csv from "../../../fixtures/Results_ConJ11ExB9.csv"; +import {MeasurementMerge} from "../../../../src/data/measurement/process/measurementMerge"; +import {MeasurementWorks} from "../../../../src/data/measurement/measurementWorks"; + +describe('Testing Measurement merge...', () => { + + /** + * Class under test + */ + let measurementMerge = new MeasurementMerge(); + + /** + * Pour d'abord importer les données + */ + let measurementImport = new MeasurementImport(); + + it('Merge works well', () => { + let measurementWorks: MeasurementWorks = {}; + { + let {work, measurements} = measurementImport.readMeasures("Results_ConJ11ExB9.csv", resultsConJ11ExB9Csv); + measurementWorks = measurementMerge.mergeInto(measurementWorks, "Results_ConJ11ExB9.csv", work, measurements); + } + { + let {work, measurements} = measurementImport.readMeasures("Results_ConJ11ExB1.csv", resultsConJ11ExB1Csv); + measurementWorks = measurementMerge.mergeInto(measurementWorks, "Results_ConJ11ExB1.csv", work, measurements); + } + { + let {work, measurements} = measurementImport.readMeasures("Results_ExpJ1CrB9.csv", resultsExpJ1CrB9Csv); + measurementWorks = measurementMerge.mergeInto(measurementWorks, "Results_ExpJ1CrB9.csv", work, measurements); + } + { + let {work, measurements} = measurementImport.readMeasures("Results_ConJ11ExB2.csv", resultsConJ11ExB2Csv); + measurementWorks = measurementMerge.mergeInto(measurementWorks, "Results_ConJ11ExB2.csv", work, measurements); + } + expect(measurementWorks).toHaveSize(2); + expect(measurementWorks["ExpJ1Cr"].work).toEqual({groupe: GroupeEnum.Experimental, jour: 1, experience: ExperienceEnum.Croissance, blob: null}); + expect(measurementWorks["ExpJ1Cr"].files).toHaveSize(1); + expect(measurementWorks["ExpJ1Cr"].files["Results_ExpJ1CrB9.csv"]).toHaveSize(1); + expect(measurementWorks["ExpJ1Cr"].files["Results_ExpJ1CrB9.csv"][0]).toEqual({ + label: "ExpJ1CrB9.jpg" , + area: 33.4, + perimeter: 33.93, + circularity: 0.365, + ar: 1.625, + round: 0.615, + solid: 0.871 + }); + expect(measurementWorks["ConJ11Ex"].work).toEqual({groupe: GroupeEnum.Controle, jour: 11, experience: ExperienceEnum.Exploration, blob: null}); + expect(measurementWorks["ConJ11Ex"].files).toHaveSize(3); + expect(measurementWorks["ConJ11Ex"].files["Results_ConJ11ExB1.csv"]).toHaveSize(1); + expect(measurementWorks["ConJ11Ex"].files["Results_ConJ11ExB1.csv"][0]).toEqual({ + label: "ConJ11ExB1.jpg" , + area: 11.22, + perimeter: 54.93, + circularity: 1.212, + ar: 0.4, + round: 0.4, + solid: 0.271 + }); + expect(measurementWorks["ConJ11Ex"].files["Results_ConJ11ExB2.csv"]).toHaveSize(1); + expect(measurementWorks["ConJ11Ex"].files["Results_ConJ11ExB2.csv"][0]).toEqual({ + label: "ConJ11ExB2.jpg" , + area: 33.4, + perimeter: 33.93, + circularity: 0.365, + ar: 1.625, + round: 0.615, + solid: 0.871 + }); + expect(measurementWorks["ConJ11Ex"].files["Results_ConJ11ExB9.csv"]).toHaveSize(1); + expect(measurementWorks["ConJ11Ex"].files["Results_ConJ11ExB9.csv"][0]).toEqual({ + label: "ConJ11ExB9.jpg" , + area: 15.9, + perimeter: 55.87, + circularity: 0.6, + ar: 1.98, + round: 0.1, + solid: 0.45 + }); + }); + + +}); \ No newline at end of file diff --git a/tests/data/work/process/workInfoFormatter.test.ts b/tests/data/work/process/workInfoFormatter.test.ts new file mode 100644 index 0000000..a375111 --- /dev/null +++ b/tests/data/work/process/workInfoFormatter.test.ts @@ -0,0 +1,22 @@ +import {ExperienceEnum, GroupeEnum} from "../../../../src/data/work/workInfo"; +import {WorkInfoParser} from "../../../../src/data/work/process/workInfoParser"; +import {WorkInfoFormatter} from "../../../../src/data/work/process/workInfoFormatter"; +import {ObjectUtils} from "../../../../src/utils/objectUtils"; + +describe('Testing WorkInfoFormatter...', () => { + + /** + * Class under test + */ + let workInfoFormatter = new WorkInfoFormatter(); + + it('Work session formatting is correct', () => { + let workInfo1 = {groupe: GroupeEnum.Controle, jour: 5, experience: ExperienceEnum.Croissance, blob: 22}; + expect(workInfoFormatter.format(workInfo1)).toEqual("ConJ5CrB22"); + + let workInfo2 = ObjectUtils.deepClone(workInfo1); + workInfo2.blob = null; + expect(workInfoFormatter.format(workInfo2)).toEqual("ConJ5Cr"); + }); + +}); \ No newline at end of file diff --git a/tests/data/work/process/workInfoParser.test.ts b/tests/data/work/process/workInfoParser.test.ts new file mode 100644 index 0000000..98c572e --- /dev/null +++ b/tests/data/work/process/workInfoParser.test.ts @@ -0,0 +1,41 @@ +import {ExperienceEnum, GroupeEnum} from "../../../../src/data/work/workInfo"; +import {WorkInfoParser} from "../../../../src/data/work/process/workInfoParser"; + +describe('Testing WorkInfoParser...', () => { + + /** + * Class under test + */ + let workInfoParser = new WorkInfoParser(); + + it('Parsing works well', () => { + let workInfo1 = workInfoParser.parse("ConJ1ExB2"); + expect(workInfo1.groupe).toEqual(GroupeEnum.Controle); + expect(workInfo1.jour).toEqual(1); + expect(workInfo1.experience).toEqual(ExperienceEnum.Exploration); + expect(workInfo1.blob).toEqual(2); + + let workInfo2 = workInfoParser.parse("ExpJ25CrB99"); + expect(workInfo2.groupe).toEqual(GroupeEnum.Experimental); + expect(workInfo2.jour).toEqual(25); + expect(workInfo2.experience).toEqual(ExperienceEnum.Croissance); + expect(workInfo2.blob).toEqual(99); + + let workInfo3 = workInfoParser.parse("conj2crb3"); + expect(workInfo3.groupe).toEqual(GroupeEnum.Controle); + expect(workInfo3.jour).toEqual(2); + expect(workInfo3.experience).toEqual(ExperienceEnum.Croissance); + expect(workInfo3.blob).toEqual(3); + + let workInfo4 = workInfoParser.parse("ExpJ25Cr"); + expect(workInfo4.groupe).toEqual(GroupeEnum.Experimental); + expect(workInfo4.jour).toEqual(25); + expect(workInfo4.experience).toEqual(ExperienceEnum.Croissance); + expect(workInfo4.blob).toBeNull(); + + expect(workInfoParser.parse("ConJ1ExB2.jpg")).toBeNull(); + expect(workInfoParser.parse("ConJExB")).toBeNull(); + expect(workInfoParser.parse("J1ExB2")).toBeNull(); + expect(workInfoParser.parse("DumJ25CrB99")).toBeNull(); + }); +}); \ No newline at end of file diff --git a/tests/fixtures/Results_ConJ11Ex.csv b/tests/fixtures/Results_ConJ11Ex.csv new file mode 100644 index 0000000..33ba868 --- /dev/null +++ b/tests/fixtures/Results_ConJ11Ex.csv @@ -0,0 +1,4 @@ + ,Label,Area,Perim.,Circ.,AR,Round,Solidity +1,ConJ11ExB1.jpg,11.22,54.93,1.212,0.4,0.4,0.271 +2,ConJ11ExB2.jpg,33.4,33.93,0.365,1.625,0.615,0.871 +3,ConJ11ExB9.jpg,15.9,55.87,0.6,1.98,0.1,0.45 diff --git a/tests/fixtures/Results_ConJ11ExB1.csv b/tests/fixtures/Results_ConJ11ExB1.csv new file mode 100644 index 0000000..c89804d --- /dev/null +++ b/tests/fixtures/Results_ConJ11ExB1.csv @@ -0,0 +1,2 @@ + ,Label,Area,Perim.,Circ.,AR,Round,Solidity +1,ConJ11ExB1.jpg,11.22,54.93,1.212,0.4,0.4,0.271 \ No newline at end of file diff --git a/tests/fixtures/Results_ConJ11ExB2.csv b/tests/fixtures/Results_ConJ11ExB2.csv new file mode 100644 index 0000000..31b385d --- /dev/null +++ b/tests/fixtures/Results_ConJ11ExB2.csv @@ -0,0 +1,2 @@ + ,Label,Area,Perim.,Circ.,AR,Round,Solidity +1,ConJ11ExB2.jpg,33.4,33.93,0.365,1.625,0.615,0.871 \ No newline at end of file diff --git a/tests/fixtures/Results_ConJ11ExB9.csv b/tests/fixtures/Results_ConJ11ExB9.csv new file mode 100644 index 0000000..6f75c18 --- /dev/null +++ b/tests/fixtures/Results_ConJ11ExB9.csv @@ -0,0 +1,2 @@ + ,Label,Area,Perim.,Circ.,AR,Round,Solidity +1,ConJ11ExB9.jpg,15.9,55.87,0.6,1.98,0.1,0.45 \ No newline at end of file diff --git a/tests/fixtures/Results_ExpJ1Cr.csv b/tests/fixtures/Results_ExpJ1Cr.csv new file mode 100644 index 0000000..6d2caa0 --- /dev/null +++ b/tests/fixtures/Results_ExpJ1Cr.csv @@ -0,0 +1,2 @@ + ,Label,Area,Perim.,Circ.,AR,Round,Solidity +1,ExpJ1CrB9.jpg,33.4,33.93,0.365,1.625,0.615,0.871 \ No newline at end of file diff --git a/tests/fixtures/fixtures.ts b/tests/fixtures/fixtures.ts index 4c85fd4..9b201a2 100644 --- a/tests/fixtures/fixtures.ts +++ b/tests/fixtures/fixtures.ts @@ -1,37 +1,45 @@ -/** - * Une classe utilitaire pour données mockées - */ -import expJ1CrB9CoordBlobTxt from './ExpJ1CrB9_Coord_Blob.txt'; -import {DataImporter} from "../../src/data/dataImporter"; -import {LabData} from "../../src/lab"; -import {VectorCoords} from "../../src/data/coords/vectorCoords"; -import {EllipseCoords} from "../../src/data/coords/ellipseCoords"; - -/** - * Charge des données de tes - */ -export class Fixtures { - - /** - * Pour charger les données brutes - */ - private static dataImporter = new DataImporter(); - - /** - * Contenu de ExpJ1CrB9_Coord_Blob.txt - */ - public static labData() : LabData { - return { - filename: "ExpJ1CrB9.jpg", - pictureSize: new paper.Size(2250, 4000), - rulerCoords: new VectorCoords( new paper.Point(542,438), new paper.Point(1929, 398)), - rulerTickCount : 10, - petriDishCoords: new EllipseCoords(new paper.Point(1172, 1305), 631, 625), - blobMaskCoords : this.dataImporter.import(expJ1CrB9CoordBlobTxt), - } - } - - - - +/** + * Une classe utilitaire pour données mockées + */ +import expJ1CrB9CoordBlobTxt from './ExpJ1CrB9_Coord_Blob.txt'; +import {DataImporter} from "../../src/data/dataImporter"; +import {LabData} from "../../src/lab"; +import {VectorCoords} from "../../src/data/coords/vectorCoords"; +import {EllipseCoords} from "../../src/data/coords/ellipseCoords"; +import {WorkInfoFormatter} from "../../src/data/work/process/workInfoFormatter"; +import {WorkInfoParser} from "../../src/data/work/process/workInfoParser"; + +/** + * Charge des données de tes + */ +export class Fixtures { + + /** + * Pour charger les données brutes + */ + private static dataImporter = new DataImporter(); + + /** + * Pour écrire les + */ + private static workInfoParser = new WorkInfoParser(); + + /** + * Contenu de ExpJ1CrB9_Coord_Blob.txt + */ + public static labData() : LabData { + return { + filename: "ExpJ1CrB9.jpg", + pictureSize: new paper.Size(2250, 4000), + workInfo: this.workInfoParser.parse("ExpJ1CrB9"), + rulerCoords: new VectorCoords( new paper.Point(542,438), new paper.Point(1929, 398)), + rulerTickCount : 10, + petriDishCoords: new EllipseCoords(new paper.Point(1172, 1305), 631, 625), + blobMaskCoords : this.dataImporter.readPathCoords(expJ1CrB9CoordBlobTxt), + } + } + + + + } \ No newline at end of file -- GitLab