Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions pythonCode/med_libs/MEDml/nodes/ModelHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ def __init__(self, id_: int, global_config_json: json) -> None:
"""
super().__init__(id_, global_config_json)
if self.type == 'train_model':
self.isTuningEnabled = self.config_json['data']['internal']['isTuningEnabled']
if self.isTuningEnabled:
self.settingsTuning = self.config_json['data']['internal']['settingsTuning']
self.model_id = self.config_json['associated_id']
model_obj = self.global_config_json['nodes'][self.model_id]
self.config_json['data']['estimator'] = {
Expand Down Expand Up @@ -66,7 +69,14 @@ def _execute(self, experiment: dict = None, **kwargs) -> json:
"code",
f"trained_models = [pycaret_exp.create_model({self.CodeHandler.convert_dict_to_params(settings)})]"
)
if self.isTuningEnabled:
trained_models = [experiment['pycaret_exp'].tune_model(trained_models[0], **self.settingsTuning)]
self.CodeHandler.add_line(
"code",
f"trained_models = [pycaret_exp.tune_model(trained_models[0], {self.CodeHandler.convert_dict_to_params(self.settingsTuning)})]"
)
trained_models_copy = trained_models.copy()

self._info_for_next_node = {'models': trained_models}
for model in trained_models_copy:
model_copy = copy.deepcopy(model)
Expand Down
2 changes: 1 addition & 1 deletion pythonCode/submodules/MEDimage
Submodule MEDimage updated 57 files
+2 −2 .github/workflows/python-app.yml
+1 −1 .github/workflows/python-publish.yml
+0 −143 .gitignore
+1 −5 .readthedocs.yaml
+21 −674 LICENSE.md
+1 −1 MEDimage/__init__.py
+0 −840 MEDimage/biomarkers/BatchExtractorTexturalFilters.py
+0 −1 MEDimage/biomarkers/__init__.py
+120 −143 MEDimage/biomarkers/int_vol_hist.py
+0 −299 MEDimage/filters/TexturalFilter.py
+0 −1 MEDimage/filters/__init__.py
+0 −19 MEDimage/filters/apply_filter.py
+0 −1,738 MEDimage/filters/textural_filters_kernels.py
+1 −1 MEDimage/learning/DataCleaner.py
+29 −26 MEDimage/learning/DesignExperiment.py
+7 −8 MEDimage/learning/Normalization.py
+15 −6 MEDimage/learning/RadiomicsLearner.py
+649 −212 MEDimage/learning/Results.py
+0 −694 MEDimage/learning/Stats.py
+0 −1 MEDimage/learning/__init__.py
+3 −17 MEDimage/learning/ml_utils.py
+1 −1 MEDimage/processing/segmentation.py
+47 −34 MEDimage/wrangling/DataManager.py
+13 −20 README.md
+1 −1 docs/Installation.rst
+1 −3 docs/conf.py
+0 −1,439 docs/extraction_config.rst
+ docs/figures/ExperimentNameBreakdown.png
+ docs/figures/HeatmapDepicted.png
+ docs/figures/HistogramExample.png
+ docs/figures/LearningWorkflow.png
+ docs/figures/MEDimage-app-be.png
+ docs/figures/MEDimage-app-depicted.png
+ docs/figures/MEDimage-app-dm.png
+ docs/figures/TreeExample.png
+ docs/figures/pakcage-overview.png
+4 −24 docs/index.rst
+9 −52 docs/tutorials.rst
+27 −31 environment.yml
+4 −2 notebooks/tutorial/DataManager-Tutorial.ipynb
+28 −56,509 notebooks/tutorial/Learning-Tutorial.ipynb
+0 −470 notebooks/tutorial/learning/FEATURES/radiomics__T2F(gliomaTumorAuto)__intensity.csv
+0 −1 notebooks/tutorial/learning/FEATURES/radiomics__T2F(gliomaTumorAuto)__intensity.txt
+0 −470 notebooks/tutorial/learning/FEATURES/radiomics__T2F(gliomaTumorAuto)__morph.csv
+0 −1 notebooks/tutorial/learning/FEATURES/radiomics__T2F(gliomaTumorAuto)__morph.txt
+0 −470 notebooks/tutorial/learning/FEATURES/radiomics__T2F(gliomaTumorAuto)__texture.csv
+0 −1 notebooks/tutorial/learning/FEATURES/radiomics__T2F(gliomaTumorAuto)__texture.txt
+227 −0 notebooks/tutorial/learning/Glioma__LGG_IDH__outcomes.csv
+1 −5 notebooks/tutorial/learning/settings/ml_design.json
+18 −0 notebooks/tutorial/learning/settings/ml_fset_selection.json
+8 −0 notebooks/tutorial/learning/settings/ml_imbalance.json
+6 −3 notebooks/tutorial/learning/settings/ml_variables.json
+25 −33 pyproject.toml
+24 −30 requirements.txt
+8 −8 scripts/download_data.py
+3 −4 setup.py
+18 −87 tests/test_extraction.py
2 changes: 1 addition & 1 deletion pythonCode/submodules/MEDprofiles
16 changes: 10 additions & 6 deletions renderer/components/flow/node.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,16 @@ const NodeObject = ({ id, data, nodeSpecific, nodeBody, defaultSettings, onClick
/>
</div>
<hr className="solid" />
{/* here are the default settings of the node. if nothing is specified, nothing is displayed*/}
{defaultSettings}
{/* here are the node specific settings. if nothing is specified, nothing is displayed*/}
{nodeSpecific}
{/* note : quand on va implémenter codeeditor */}
{/* <CodeEditor data={data} /> */}
<div className="options-overlayPanel-settingsBody">
<Stack direction="vertical" gap={1}>
{/* here are the default settings of the node. if nothing is specified, nothing is displayed*/}
{defaultSettings}
{/* here are the node specific settings. if nothing is specified, nothing is displayed*/}
{nodeSpecific}
{/* note : quand on va implémenter codeeditor */}
{/* <CodeEditor data={data} /> */}
</Stack>
</div>
</Stack>
</OverlayPanel>
</>
Expand Down
1 change: 0 additions & 1 deletion renderer/components/layout/layoutManager.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ const LayoutManager = (props) => {
toast.error("Go server is not connected !")
}
)

}
})
}
Expand Down
42 changes: 39 additions & 3 deletions renderer/components/learning/modalSettingsChooser.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ import { FlowFunctionsContext } from "../flow/context/flowFunctionsContext"
* This component is used to display a ModalSettingsChooser modal.
* it handles the display of the modal and the available options
*/
const ModalSettingsChooser = ({ show, onHide, options, id, data }) => {
const ModalSettingsChooser = ({ show, onHide, options, id, data, optionsTuning = null }) => {
const [checkedUpdate, setCheckedUpdate] = useState(null)
const [checkedUpdateTuning, setCheckedUpdateTuning] = useState(null)
const { updateNode } = useContext(FlowFunctionsContext)

// update the node when a setting is checked or unchecked from the modal
Expand All @@ -38,17 +39,52 @@ const ModalSettingsChooser = ({ show, onHide, options, id, data }) => {
}
}, [checkedUpdate])

// update the node when a setting is checked or unchecked from the modal
useEffect(() => {
if (checkedUpdateTuning != null) {
if (checkedUpdateTuning.checked) {
!data.internal.checkedOptionsTuning.includes(checkedUpdateTuning.optionName) && data.internal.checkedOptionsTuning.push(checkedUpdateTuning.optionName)
} else {
data.internal.checkedOptionsTuning = data.internal.checkedOptionsTuning.filter((optionName) => optionName != checkedUpdateTuning.optionName)
delete data.internal.settingsTuning[checkedUpdateTuning.optionName]
}
updateNode({
id: id,
updatedData: data.internal
})
}
}, [checkedUpdateTuning])

return (
// Base modal component built from react-bootstrap
<Modal show={show} onHide={onHide} size="lg" aria-labelledby="contained-modal-title-vcenter" centered className="modal-settings-chooser">
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">{data.setupParam.title + " options"}</Modal.Title>
</Modal.Header>
{/* Display all the options available for the node */}
<Modal.Body >
<Modal.Body>
{Object.entries(options).map(([optionName, optionInfos], i) => {
return <CheckOption key={optionName + i} optionName={optionName} optionInfos={optionInfos} updateCheckState={setCheckedUpdate} defaultState={data.internal.checkedOptions.includes(optionName)} />
return (
<CheckOption key={optionName + i} optionName={optionName} optionInfos={optionInfos} updateCheckState={setCheckedUpdate} defaultState={data.internal.checkedOptions.includes(optionName)} />
)
})}
{/* Display all the options available for the tuning */}
{optionsTuning && (
<>
<h3>Tuning options</h3>
{Object.entries(optionsTuning).map(([optionName, optionInfos], i) => {
return (
<CheckOption
key={optionName + i}
optionName={optionName}
optionInfos={optionInfos}
updateCheckState={setCheckedUpdateTuning}
defaultState={data.internal.checkedOptionsTuning.includes(optionName)}
/>
)
})}
</>
)}
</Modal.Body>
<Modal.Footer>
<Button onClick={onHide}>Save</Button>
Expand Down
191 changes: 191 additions & 0 deletions renderer/components/learning/nodesTypes/trainModelNode.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
import React, { useState, useContext, useEffect } from "react"
import Node from "../../flow/node"
import Input from "../input"
import { Button } from "react-bootstrap"
import ModalSettingsChooser from "../modalSettingsChooser"
import * as Icon from "react-bootstrap-icons"
import { FlowFunctionsContext } from "../../flow/context/flowFunctionsContext"
import { Stack } from "react-bootstrap"
import { Checkbox } from "primereact/checkbox"

/**
*
* @param {string} id id of the node
* @param {object} data data of the node
* @param {string} type type of the node
* @returns {JSX.Element} A StandardNode node
*
* @description
* This component is used to display a StandardNode node.
* it handles the display of the node and the modal
*
*/
const TrainModelNode = ({ id, data }) => {
const [modalShow, setModalShow] = useState(false) // state of the modal
const { updateNode } = useContext(FlowFunctionsContext)
const [IntegrateTuning, setIntegrateTuning] = useState(data.internal.isTuningEnabled ?? false)
const [modalTuningBody, setModalTuningBody] = useState(null)

// Check if isTuningEnabled exists in data.internal, if not initialize it
useEffect(() => {
if (!("isTuningEnabled" in data.internal)) {
data.internal.isTuningEnabled = false
updateNode({
id: id,
updatedData: data.internal
})
}
console.log(data.internal)
}, [])

/**
*
* @param {Object} inputUpdate the object containing the name and the value of the input
* @description
* This function is used to update the settings of the node
*/
const onInputChange = (inputUpdate) => {
data.internal.settings[inputUpdate.name] = inputUpdate.value
updateNode({
id: id,
updatedData: data.internal
})
}

/**
*
* @param {Object} inputUpdate the object containing the name and the value of the input
* @description
* This function is used to update the settings of the node
*/
const onInputChangeTuning = (inputUpdate) => {
data.internal.settingsTuning[inputUpdate.name] = inputUpdate.value
updateNode({
id: id,
updatedData: data.internal
})
}

/**
*
* @param {Object} hasWarning an object containing the state of the warning and the tooltip
* @description
* This function is used to handle the warning of the node
*/
const handleWarning = (hasWarning) => {
data.internal.hasWarning = hasWarning
updateNode({
id: id,
updatedData: data.internal
})
}

/**
*
* @param {Object} e the event of the checkbox
* @description
* This function is used to handle the checkbox for enabling the tuning
*/
const handleIntegration = (e) => {
setIntegrateTuning(e.checked)
data.internal.isTuningEnabled = e.checked
updateNode({
id: id,
updatedData: data.internal
})
}

return (
<>
{/* build on top of the Node component */}
<Node
key={id}
id={id}
data={data}
setupParam={data.setupParam}
// no body for this node (particular to this node)
// default settings are the default settings of the node, so mandatory settings
defaultSettings={
<>
{"default" in data.setupParam.possibleSettings && (
<>
<Stack direction="vertical" gap={1}>
{Object.entries(data.setupParam.possibleSettings.default).map(([settingName, setting]) => {
return (
<Input
setHasWarning={handleWarning}
key={settingName}
name={settingName}
settingInfos={setting}
currentValue={data.internal.settings[settingName]}
onInputChange={onInputChange}
/>
)
})}
</Stack>
</>
)}
</>
}
// node specific is the body of the node, so optional settings
nodeSpecific={
<>
<div className="flex align-items-center">
<Checkbox inputId="integrateTuning" checked={IntegrateTuning} onChange={(e) => handleIntegration(e)} />
<label htmlFor="integrateTuning" className="ml-2" style={{ paddingLeft: "5px" }}>
Integrate Tuning
</label>
</div>
{/* the button to open the modal (the plus sign)*/}
<Button variant="light" className="width-100 btn-contour" onClick={() => setModalShow(true)}>
<Icon.Plus width="30px" height="30px" className="img-fluid" />
</Button>
{/* the modal component*/}
<ModalSettingsChooser
show={modalShow}
onHide={() => setModalShow(false)}
options={data.setupParam.possibleSettings.options}
data={data}
id={id}
optionsTuning={data.internal.isTuningEnabled ? data.setupParam.possibleSettingsTuning.options : null}
/>
{/* the inputs for the options */}
{data.internal.checkedOptions.map((optionName) => {
return (
<Input
key={optionName}
name={optionName}
settingInfos={data.setupParam.possibleSettings.options[optionName]}
currentValue={data.internal.settings[optionName]}
onInputChange={onInputChange}
/>
)
})}
{data.internal.isTuningEnabled && data.internal.checkedOptionsTuning && data.internal.checkedOptionsTuning.length > 0 && (
<>
<hr />
<div style={{ fontWeight: "bold", margin: "10px 0" }}>Tune Model Options</div>
{data.internal.checkedOptionsTuning.map((optionName) => {
console.log(data)
return (
<Input
key={optionName}
name={optionName}
settingInfos={data.setupParam.possibleSettingsTuning.options[optionName]}
currentValue={data.internal.settingsTuning[optionName]}
onInputChange={onInputChangeTuning}
/>
)
})}
</>
)}
</>
}
// Link to documentation
nodeLink={"https://medomics-udes.gitbook.io/medomicslab-docs/tutorials/development/learning-module"}
/>
</>
)
}

export default TrainModelNode
Loading