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
3 changes: 2 additions & 1 deletion go_server/src/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ func copyOutput(r io.Reader, response *string) {

// ReadFile reads a file and returns its content as a string
func ReadFile(filename string) string {
absPath, _ := filepath.Abs(filename)
cleanPath := strings.Trim(filename, "\" \t\n\r")
absPath, _ := filepath.Abs(cleanPath)
log.Println("Reading file: " + absPath)
data, err := os.ReadFile(absPath)
if err != nil {
Expand Down
10 changes: 6 additions & 4 deletions pythonCode/med_libs/MEDml/nodes/ModelHandler.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import ast
import copy
import json
from typing import Union
Expand Down Expand Up @@ -131,6 +132,7 @@ def __calculate_all_metrics(self, y_true, y_pred, y_pred_proba=None):
metrics['MCC'] = round(matthews_corrcoef(y_true, y_pred), 3)

except Exception as e:
raise ValueError(f"Error calculating metrics: {e}")
print(f"Error calculating metrics: {e}")
# Set default values for all metrics
default_metrics = ["AUC", "Sensitivity", "Specificity", "PPV", "NPV", "Accuracy", "F1", "MCC"]
Expand All @@ -145,7 +147,7 @@ def __calculate_overall_metrics(self, fold_metrics):
log_metrics = {}

if not fold_metrics:
return overall_metrics
return overall_metrics, log_metrics

# Get all metric names from first fold
first_fold_metrics = list(fold_metrics.values())[0]
Expand Down Expand Up @@ -401,7 +403,7 @@ def __custom_train_and_evaluate(
if self.optimize_threshold:
if len(pycaret_exp.get_config('y').unique()) == 2 and not self.ensembleEnabled:
self.CodeHandler.add_line("code", f"# Optimizing model threshold based on {self.threshold_optimization_metric}", indent=0)
self.CodeHandler.add_line("code", f"best_model = pycaret_exp.optimize_threshold(best_model, metric='{self.threshold_optimization_metric}')", indent=0)
self.CodeHandler.add_line("code", f"best_model = pycaret_exp.optimize_threshold(best_model, optimize='{self.threshold_optimization_metric}')", indent=0)

# Finalize the model
if finalize:
Expand Down Expand Up @@ -552,7 +554,7 @@ def __handle_splitted_data(self, experiment: dict, settings: dict, **kwargs) ->
)
self.CodeHandler.add_line(
"code",
f"trained_models = [pycaret_exp.optimize_threshold(trained_models[0], metric='{self.threshold_optimization_metric}')]"
f"trained_models = [pycaret_exp.optimize_threshold(trained_models[0], optimize='{self.threshold_optimization_metric}')]"
)

if finalize:
Expand Down Expand Up @@ -756,7 +758,7 @@ def _execute(self, experiment: dict = None, **kwargs) -> json:

else:
trained_models = [experiment['pycaret_exp'].optimize_threshold(trained_models[0], optimize=self.threshold_optimization_metric)]
self.CodeHandler.add_line("code", f"trained_models = [pycaret_exp.optimize_threshold(trained_models[0], metric='{self.threshold_optimization_metric}')]")
self.CodeHandler.add_line("code", f"trained_models = [pycaret_exp.optimize_threshold(trained_models[0], optimize='{self.threshold_optimization_metric}')]")

if finalize:
trained_models = [experiment['pycaret_exp'].finalize_model(model) for model in trained_models]
Expand Down
11 changes: 6 additions & 5 deletions pythonCode/med_libs/MEDml/nodes/ModelIO.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,14 @@ def _execute(self, experiment: dict = None, **kwargs) -> json:
if dir(fitted_model).__contains__('feature_names_in_'):
model_features = fitted_model.__getattribute__('feature_names_in_')
elif dir(fitted_model).__contains__('feature_name_') and model_features is None:
model_features = fitted_model.__getattribute__('feature_name_')
model_features = fitted_model.__getattribute__('feature_names_in_')
elif dir(fitted_model).__contains__('classifier_') and dir(fitted_model.classifier_).__contains__('feature_names_in_'):
model_features = fitted_model.classifier_.feature_names_in_
else:
model_features= fitted_model.__getattr__('feature_names_in_')

raise ValueError(f"Could not find model features. Model attributes : {dir(fitted_model)}, model type: {type(fitted_model)}")
if model_features is None:
raise ValueError(f"Could not find model features. Model attributes : {dir(fitted_model)}, model type: {type(fitted_model)}, model features: {model_features}")
raise ValueError(f"Could not find model features. Model attributes : {dir(fitted_model)}, model type: {type(fitted_model)}")

model_features = list(model_features)

# Model's name
Expand Down
2 changes: 1 addition & 1 deletion pythonCode/med_libs/MEDml/nodes/Split.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ def _execute(self, experiment: dict = None, **kwargs) -> json:
splitter = StratifiedKFold(n_splits=cv_folds, shuffle=True, random_state=random_state)
self.CodeHandler.add_line("code", f"splitter = StratifiedKFold(n_splits={cv_folds}, shuffle=True, random_state={random_state})")
fold_iter = splitter.split(np.zeros(n_samples), y)
self.CodeHandler.add_line("code", f"fold_iter = splitter.split(np.zeros({n_samples}), y)")
self.CodeHandler.add_line("code", f"fold_iter = splitter.split(np.zeros(len(dataset)), y)")
else:
splitter = KFold(n_splits=cv_folds, shuffle=True, random_state=random_state)
self.CodeHandler.add_line("code", f"splitter = KFold(n_splits={cv_folds}, shuffle=True, random_state={random_state})")
Expand Down
Binary file not shown.
16 changes: 15 additions & 1 deletion pythonCode/modules/superset/SupersetEnvManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,21 @@ def _get_build_env(self):
"""

env = os.environ.copy()
if sys.platform != "win32":
if sys.platform == "darwin":
# Force the compiler to use the system SDK and headers
cc = shutil.which("clang") or shutil.which("gcc")
cxx = shutil.which("clang++") or shutil.which("g++")
if cc:
env["CC"] = cc
if cxx:
env["CXX"] = cxx

# Critical for 'cryptography' and 'python-geohash' compilation
env["LDFLAGS"] = "-L/usr/local/opt/openssl/lib -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib"
env["CPPFLAGS"] = "-I/usr/local/opt/openssl/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include"
# Prevents error: 'implicit declaration of function' during geohash build
env["CFLAGS"] = "-Wno-error=implicit-function-declaration"
elif sys.platform != "win32":
cc = shutil.which("gcc") or shutil.which("cc")
cxx = shutil.which("g++") or shutil.which("c++")
if cc:
Expand Down
1 change: 0 additions & 1 deletion pythonEnv/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,6 @@ safetensors==0.4.0
schemdraw==0.15
scikit-base==0.5.2
scikit-image==0.19.3
scikit-learn==1.2.0
scikit-plot==0.3.7
scipy==1.10.1
seaborn==0.12.2
Expand Down
2 changes: 1 addition & 1 deletion renderer/components/learning/nodesTypes/splitNode.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ const SplitNode = ({ id, data }) => {
key={id}
id={id}
data={data}
color="#EAD196"
color="#cea037"
setupParam={data.setupParam}
nodeLink="/documentation/split"
defaultSettings={
Expand Down
28 changes: 7 additions & 21 deletions renderer/components/learning/nodesTypes/trainModelNode.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ const TrainModelNode = ({ id, data }) => {
const [modalShowTuning, setModalShowTuning] = useState(false)
const { updateNode } = useContext(FlowFunctionsContext)
const [IntegrateTuning, setIntegrateTuning] = useState(data.internal.isTuningEnabled ?? false)
const [optimizeThresh, setOptimizeThresh] = useState(data.internal.isOptimizeThreshold ?? false)
const [ensembleEnabled, setEnsembleEnabled] = useState(data.internal.settings.isEnsembleEnabled ?? false)
const [calibrateEnabled, setCalibrateEnabled] = useState(data.internal.settings.isCalibrateEnabled ?? false)
const [optimizeThresh, setOptimizeThresh] = useState(data.internal.optimizeThreshold ?? false)
const [ensembleEnabled, setEnsembleEnabled] = useState(data.internal.ensembleEnabled ?? false)
const [calibrateEnabled, setCalibrateEnabled] = useState(data.internal.calibrateEnabled ?? false)

// Check if isTuningEnabled exists in data.internal, if not initialize it
// Check if default settings exists in data.internal, if not initialize it
useEffect(() => {
let hasUpdates = false

Expand All @@ -58,8 +58,9 @@ const TrainModelNode = ({ id, data }) => {
const defaults = {
isTuningEnabled: false,
useTuningGrid: false,
isEnsembleEnabled: false,
isCalibrateEnabled: false,
ensembleEnabled: false,
calibrateEnabled: false,
optimizeThreshold: false,
settingsEnsembling: {},
settingsCalibration: {}
}
Expand Down Expand Up @@ -185,21 +186,6 @@ const TrainModelNode = ({ id, data }) => {
})
}

/**
*
* @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.value)
data.internal.isTuningEnabled = e.value
updateNode({
id: id,
updatedData: data.internal
})
}

return (
<>
{/* build on top of the Node component */}
Expand Down
42 changes: 34 additions & 8 deletions renderer/components/learning/results/utilities/parameters.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,45 @@ import { Column } from "primereact/column"
const Parameters = ({ params, tableProps, columnNames }) => {
const [data, setData] = useState([])
const [selectedRows, setSelectedRows] = useState([])

const isEmptyOrNull = (value) => {
// Check specifically for null or undefined
if (value == null) { // Using loose equality (==) checks for both null and undefined
return true
}

// Check if the value is an object (but not null, which typeof also calls "object")
if (typeof value === 'object') {
// A robust check for an empty object: ensure its constructor is Object and it has no own properties
return Object.keys(value).length === 0 && value.constructor === Object
}

// Other non-object, non-null values (like strings, numbers, booleans)
// are not considered "empty objects" or "null" by this definition.
return false
}

useEffect(() => {
if (params) {
let dataList = []
Object.keys(params).forEach((key) => {
let value = params[key]
// For array values
if (Array.isArray(value)) {
value = JSON.stringify(value)
// skip null or undefined values
if (isEmptyOrNull(params[key])) {
dataList.push({
param: key,
Value: "null"
})
} else {
let value = params[key]
// For array values
if (Array.isArray(value)) {
value = JSON.stringify(value)
}
dataList.push({
param: key,
Value: value != null ? value : "null"
})
}
dataList.push({
param: key,
Value: value != null ? value : "null"
})
})
setData(dataList)
}
Expand Down
17 changes: 4 additions & 13 deletions renderer/components/mainPages/application.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,8 @@ const ApplicationPage = ({ pageId }) => {
* @param {Array} columnsArray An array of the columns of the dataset
*/
const checkWarnings = (columnsArray) => {
let datasetColsString = JSON.stringify(columnsArray)
let modelColsString = JSON.stringify(modelFeatures)
if (datasetColsString !== modelColsString && modelFeatures && columnsArray) {
if (!modelFeatures.every((col) => columnsArray.includes(col)) && modelFeatures && columnsArray) {
const missingCols = modelFeatures.filter(col => !columnsArray.includes(col))
setDatasetHasWarning({
state: true,
tooltip: (
Expand All @@ -371,17 +370,9 @@ const ApplicationPage = ({ pageId }) => {
<div style={{ maxHeight: "400px", overflowY: "auto", overflowX: "hidden" }}>
<Row>
<Col>
<p>Needed columns:</p>
<p>Missing columns:</p>
<ul>
{modelFeatures.sort().map((col) => {
return <li key={col}>{col}</li>
})}
</ul>
</Col>
<Col>
<p>Received columns:</p>
<ul>
{columnsArray.sort().map((col) => {
{missingCols.map((col) => {
return <li key={col}>{col}</li>
})}
</ul>
Expand Down
2 changes: 1 addition & 1 deletion renderer/components/mainPages/superset/SupersetFrame.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ const SupersetDashboard = () => {
})
} else if (system === "darwin") {
// macOS
exec(`pkill -f superset`, (err, stdout, stderr) => {
exec(`/usr/bin/pkill -f superset`, (err, stdout, stderr) => {
if (err) {
console.error(err)
toast.error("Error killing Superset", {autoClose: 5000})
Expand Down
1 change: 0 additions & 1 deletion renderer/styles/flow/reactFlow.css
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@
}

.draggable-side-node.p-card {
background: #f3f3f3;
color: #495057;
box-shadow:
2px 2px 3px -1px rgb(0 0 0 / 20%),
Expand Down
3 changes: 1 addition & 2 deletions renderer/styles/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
--button-bg: #0d6efd;
--button-text: #ffffff;
--button-hover: #0b5ed7;
--card-bg: #ffffff;
--card-bg: #f8f9fa;
--card-border: #dee2e6;
--input-bg: #ffffff;
--input-border: #ced4da;
Expand Down Expand Up @@ -105,7 +105,6 @@ label {

.card-header,
.p-card-header {
background-color: var(--card-bg) !important;
border-bottom-color: var(--border-color) !important;
color: var(--text-primary) !important;
}
Expand Down
Loading