Add All Folders
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
# Galaxy Project
|
||||
|
||||
This folder contains prototypes and files related to the **Galaxy Workflow Engine**.
|
||||
|
||||
The goal of this section is to define and run simple workflows to demonstrate Galaxy's capabilities in managing and reproducing scientific processes.
|
||||
|
||||
## Quick Start
|
||||
To run a sample workflow:
|
||||
1. Prepare a workflow file (e.g. `workflow.xml`).
|
||||
2. Run Galaxy and load the workflow.
|
||||
|
||||
## Folder Structure
|
||||
- `workflow.xml`: A prototype of a simple workflow
|
||||
- Other tools and supporting files will be added in the future
|
||||
|
||||
## Description
|
||||
Galaxy is a powerful platform for performing scientific and data analytics. In this project, we use it to create reproducible and auditable workflows.
|
||||
@@ -0,0 +1,48 @@
|
||||
version: "3.9"
|
||||
|
||||
services:
|
||||
galaxy:
|
||||
image: quay.io/bgruening/galaxy:24.2
|
||||
container_name: galaxy_radiuma
|
||||
ports:
|
||||
- "8080:80" # رابط وب Galaxy
|
||||
environment:
|
||||
- GALAXY_CONFIG_BRAND=Radiuma Galaxy
|
||||
- GALAXY_CONFIG_ADMIN_USERS=admin@radiuma.org
|
||||
- GALAXY_CONFIG_REQUIREMENTS_FILE=/galaxy/config/requirements.txt
|
||||
- GALAXY_CONFIG_BOOTSTRAP_ADMIN_API_KEY=radiuma_admin_key # ✅ جایگزین master_api_key
|
||||
- GALAXY_CONFIG_ENABLE_FTP_UPLOAD_DIR=True
|
||||
- GALAXY_CONFIG_FTP_UPLOAD_DIR=/ftp_uploads # ✅ مسیر داخلی FTP
|
||||
- GALAXY_CONFIG_TOOL_CONFIG_FILE=/galaxy/config/tool_conf.xml
|
||||
- GALAXY_CONFIG_LOG_LEVEL=DEBUG
|
||||
- GALAXY_CONFIG_WATCH_TOOLS=False
|
||||
- GALAXY_CONFIG_DATABASE_CONNECTION=postgresql://galaxy:galaxy@postgres:5432/galaxy
|
||||
volumes:
|
||||
- galaxy_data:/galaxy/database
|
||||
- ./galaxy/tools:/galaxy/tools
|
||||
- ./requirements.txt:/galaxy/config/requirements.txt
|
||||
- ./galaxy/config/tool_conf.xml:/galaxy/config/tool_conf.xml
|
||||
- ./ftp:/ftp_uploads # ✅ mount صحیح برای FTP
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
|
||||
postgres:
|
||||
image: postgres:15
|
||||
container_name: galaxy_postgres
|
||||
environment:
|
||||
POSTGRES_USER: galaxy
|
||||
POSTGRES_PASSWORD: galaxy
|
||||
POSTGRES_DB: galaxy
|
||||
volumes:
|
||||
- ./galaxy_db:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "pg_isready", "-U", "galaxy", "-h", "postgres"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
volumes:
|
||||
galaxy_data:
|
||||
@@ -0,0 +1,5 @@
|
||||
<section id="radiuma" name="Radiuma Tools">
|
||||
<tool file="radiuma/radiomics.xml"/>
|
||||
<tool file="radiuma/preprocessing.xml"/>
|
||||
<tool file="radiuma/classification.xml"/>
|
||||
</section>
|
||||
@@ -0,0 +1,24 @@
|
||||
<tool id="pysera_radiomics" name="PySERA Radiomics Extraction" version="2.1.2">
|
||||
<description>Standardized radiomics feature extraction using PySERA</description>
|
||||
|
||||
<command><![CDATA[
|
||||
python3 -m pysera \
|
||||
--image-input "$image_input" \
|
||||
--mask-input "$mask_input" \
|
||||
--output "$output"
|
||||
]]></command>
|
||||
|
||||
<inputs>
|
||||
<param name="image_input" type="data" label="Medical Image (NIfTI/DICOM)" />
|
||||
<param name="mask_input" type="data" label="Segmentation Mask" />
|
||||
</inputs>
|
||||
|
||||
<outputs>
|
||||
<data name="output" format="csv" label="Extracted Radiomics Features" />
|
||||
</outputs>
|
||||
|
||||
<help><![CDATA[
|
||||
This tool uses PySERA (Python Standardized Extraction for Radiomics Analysis)
|
||||
for IBSI-compliant radiomics feature extraction.
|
||||
]]></help>
|
||||
</tool>
|
||||
@@ -0,0 +1,6 @@
|
||||
<param name="algorithm" type="select" label="Classifier">
|
||||
<option value="LogisticRegression">Logistic Regression</option>
|
||||
<option value="KNeighborsClassifier">KNN</option>
|
||||
<option value="AdaBoostClassifier">AdaBoost</option>
|
||||
<option value="BaggingClassifier">Bagging</option>
|
||||
</param>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
from sklearn.utils import resample, shuffle
|
||||
|
||||
class preprocessing:
|
||||
|
||||
def __init__(self,X):
|
||||
self.X = X
|
||||
|
||||
|
||||
|
||||
# def SelectAlg(self):
|
||||
# import json
|
||||
# f = open('data.json')
|
||||
# JSONdata = json.load(f)
|
||||
# f.close()
|
||||
# algn = self.AlgName
|
||||
# if self.AlgName == "resample":
|
||||
|
||||
# self.Vs_resample(
|
||||
# JSONdata[algn][0],
|
||||
# JSONdata[algn][1]
|
||||
# )
|
||||
# elif self.AlgName == "shuffle":
|
||||
# self.Vs_shuffle(
|
||||
# JSONdata[algn][0],
|
||||
# JSONdata[algn][1]
|
||||
# )
|
||||
# else:
|
||||
# print("Algorithm name is wrong")
|
||||
|
||||
|
||||
|
||||
def Vs_resampling(self,str=False,rep=False):
|
||||
|
||||
if str:
|
||||
x2 = resample(self.X , replace=rep)
|
||||
else:
|
||||
x2 = resample(self.X , replace=rep)
|
||||
|
||||
return x2
|
||||
|
||||
|
||||
|
||||
def Vs_shuffling(self):
|
||||
|
||||
x2 = shuffle(self.X)
|
||||
|
||||
return x2
|
||||
@@ -0,0 +1,13 @@
|
||||
<tool id="radiuma_preprocessing" name="Preprocessing" version="1.0.0">
|
||||
<command>python3 $__tool_directory__/preprocessing.py --input $input --method $method --output $output</command>
|
||||
<inputs>
|
||||
<param name="input" type="data" format="csv" label="Input Features"/>
|
||||
<param name="method" type="select" label="Method">
|
||||
<option value="resample">Resample</option>
|
||||
<option value="shuffle">Shuffle</option>
|
||||
</param>
|
||||
</inputs>
|
||||
<outputs>
|
||||
<data name="output" format="csv" label="Processed Features"/>
|
||||
</outputs>
|
||||
</tool>
|
||||
@@ -0,0 +1,556 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, messagebox
|
||||
from tkinter.filedialog import askopenfilename, askdirectory
|
||||
from PIL import Image, ImageTk
|
||||
from prompt_toolkit.data_structures import Point
|
||||
|
||||
|
||||
def radiomics_feature_generator_view(self, oid):
|
||||
def _validate(P, mi, ma):
|
||||
if P == "":
|
||||
P = mi
|
||||
if P.count(".") > 1:
|
||||
return False
|
||||
P = P.replace(".", "")
|
||||
return P.isdigit() and float(P) >= float(mi) and float(P) <= float(ma)
|
||||
|
||||
def _validate_c(P, mi, ma):
|
||||
if P == "":
|
||||
P = mi
|
||||
items = P.split(",")
|
||||
for i in items:
|
||||
if i.count(".") > 1:
|
||||
return False
|
||||
j = i.replace(".", "")
|
||||
if j == '':
|
||||
j = '0'
|
||||
i = '0.'
|
||||
if not (j.isdigit() and float(i) >= float(mi) and float(i) <= float(ma)) and i != "":
|
||||
return False
|
||||
return True
|
||||
|
||||
def _validate_int(P, mi, ma):
|
||||
if P == "":
|
||||
P = mi
|
||||
try:
|
||||
if P == '-':
|
||||
P = '-1'
|
||||
return int(P) >= int(mi) and int(P) <= int(ma)
|
||||
except:
|
||||
return False
|
||||
|
||||
self.arr_img = ImageTk.PhotoImage(Image.open("images/arrow-icon.png").resize((20, 20)))
|
||||
main = self.newWindow
|
||||
main.none = False
|
||||
main.attributes('-toolwindow', True)
|
||||
main.title('Radiomic Feature Generator')
|
||||
main.resizable(False, False)
|
||||
|
||||
self.rbg = "#FFFFFF"
|
||||
root = tk.Frame(main, bg=self.rbg)
|
||||
# menu = tk.Frame(main, bg=self.bg)
|
||||
root.grid(row=0, column=1)
|
||||
|
||||
# first row
|
||||
# ttk.Separator(root, orient='horizontal').grid(column=0, row=0, columnspan=7, sticky="ew", padx=5, pady=5)
|
||||
frame = tk.Frame(root, highlightthickness=2, highlightcolor="#D1CFE2", bg=self.rbg)
|
||||
frame.grid(column=0, row=0, columnspan=6, sticky="news", padx=16, pady=(10, 5), ipady=2, ipadx=2)
|
||||
tk.Label(frame, text="Source", bg=self.rbg, fg="#1C1C28").grid(column=0, row=0, sticky=tk.W, padx=5, pady=5)
|
||||
|
||||
self.ra_file_folder = tk.StringVar(value=0)
|
||||
self.ra_file_folder.set(self.ras_file_folder[oid].get())
|
||||
|
||||
def select_radio(clean=True):
|
||||
if self.ra_file_folder.get() == "0":
|
||||
if clean:
|
||||
if self.comp_conn[oid] == -1:
|
||||
self.ra_file_slc_lbl.set("Select a file...")
|
||||
self.ra_file_slc2_lbl.set("Select a file...")
|
||||
elif self.comp_conn[oid] == 0 or self.comp_conn[oid] == 2:
|
||||
self.ra_file_slc_lbl.set("Set by connection link")
|
||||
self.ra_file_slc2_lbl.set("Select a file...")
|
||||
else:
|
||||
self.ra_file_slc_lbl.set("Select a file...")
|
||||
self.ra_file_slc2_lbl.set("Set by connection link")
|
||||
self.file_select = ""
|
||||
self.file_slc_btn.config(image=self.slc_file_photo)
|
||||
self.file_slc2_btn.config(image=self.slc_file_photo)
|
||||
else:
|
||||
if clean:
|
||||
if self.comp_conn[oid] == -1:
|
||||
self.ra_file_slc_lbl.set("Select a folder...")
|
||||
self.ra_file_slc2_lbl.set("Select a folder...")
|
||||
elif self.comp_conn[oid] == 0 or self.comp_conn[oid] == 2:
|
||||
self.ra_file_slc_lbl.set("Set by connection link")
|
||||
self.ra_file_slc2_lbl.set("Select a folder...")
|
||||
else:
|
||||
self.ra_file_slc_lbl.set("Select a folder...")
|
||||
self.ra_file_slc2_lbl.set("Set by connection link")
|
||||
self.file_select = ""
|
||||
self.file_slc_btn.config(image=self.slc_folder_photo)
|
||||
self.file_slc2_btn.config(image=self.slc_folder_photo)
|
||||
|
||||
tk.Radiobutton(frame, bg=self.rbg, text="Single file", variable=self.ra_file_folder, value=0,
|
||||
command=select_radio).grid(column=1, row=0, padx=(0, 0))
|
||||
tk.Radiobutton(frame, bg=self.rbg, text="Folder", variable=self.ra_file_folder, value=1, command=select_radio).grid(
|
||||
column=1, row=0, padx=(150, 0))
|
||||
tk.Label(frame, text="Original image", bg=self.rbg).grid(column=0, row=2, sticky=tk.W, padx=(5, 26), pady=5)
|
||||
self.ra_file_slc_lbl = tk.StringVar(value="Select a file...")
|
||||
if self.comp_conn[oid] == 0 or self.comp_conn[oid] == 2:
|
||||
self.ra_file_slc_lbl.set("Set by connection link")
|
||||
else:
|
||||
t = self.ras_file_slc_lbl[oid].get()
|
||||
if t.startswith("Set"):
|
||||
if self.ras_file_folder[oid].get() == "0":
|
||||
t = "Select a file..."
|
||||
else:
|
||||
t = "Select a folder..."
|
||||
self.ra_file_slc_lbl.set(t)
|
||||
ttk.Entry(frame, textvariable=self.ra_file_slc_lbl, state="disabled").grid(column=0, row=2, sticky="we",
|
||||
padx=(100, 0), pady=5, ipady=10)
|
||||
|
||||
def select_file():
|
||||
self.newWindow.attributes('-topmost', True)
|
||||
if self.ra_file_folder.get() == "0":
|
||||
self.file_select = askopenfilename(parent=root)
|
||||
else:
|
||||
self.file_select = askdirectory(parent=root)
|
||||
self.newWindow.attributes('-topmost', False)
|
||||
self.ra_file_slc_lbl.set(self.file_select)
|
||||
|
||||
self.slc_file_photo = tk.PhotoImage(file="images/file.png")
|
||||
self.slc_folder_photo = tk.PhotoImage(file="images/folder.png")
|
||||
self.file_slc_btn = tk.Button(frame, image=self.slc_file_photo, command=select_file, bg="#9CADCE", borderwidth=0,
|
||||
height=40, width=40, state='disabled' if (
|
||||
self.comp_conn[oid] == 0 or self.comp_conn[oid] == 2) else 'normal')
|
||||
self.file_slc_btn.grid(column=0, row=2, sticky="w", padx=(220, 0))
|
||||
|
||||
tk.Label(frame, text="Region of interest (ROI)", bg=self.rbg).grid(column=1, row=2, sticky="e", padx=5, pady=5)
|
||||
self.ra_file_slc2_lbl = tk.StringVar(value="Select a file...")
|
||||
if self.comp_conn[oid] == 1 or self.comp_conn[oid] == 2:
|
||||
self.ra_file_slc2_lbl.set("Set by connection link")
|
||||
else:
|
||||
t = self.ras_file_slc2_lbl[oid].get()
|
||||
if t.startswith("Set"):
|
||||
if self.ras_file_folder[oid].get() == "0":
|
||||
t = "Select a file..."
|
||||
else:
|
||||
t = "Select a folder..."
|
||||
self.ra_file_slc2_lbl.set(t)
|
||||
ttk.Entry(frame, textvariable=self.ra_file_slc2_lbl, state="disabled").grid(column=2, row=2, sticky="we",
|
||||
padx=(5, 0), pady=5, columnspan=2,
|
||||
ipady=10, ipadx=4)
|
||||
|
||||
def select_file2():
|
||||
self.newWindow.attributes('-topmost', True)
|
||||
if self.ra_file_folder.get() == "0":
|
||||
self.file_select2 = askopenfilename(parent=root)
|
||||
else:
|
||||
self.file_select2 = askdirectory(parent=root)
|
||||
self.newWindow.attributes('-topmost', False)
|
||||
self.ra_file_slc2_lbl.set(self.file_select2)
|
||||
|
||||
self.file_slc2_btn = tk.Button(frame, image=self.slc_file_photo, command=select_file2, bg="#9CADCE", borderwidth=0,
|
||||
height=40, width=40, state='disabled' if (
|
||||
self.comp_conn[oid] == 1 or self.comp_conn[oid] == 2) else 'normal')
|
||||
self.file_slc2_btn.grid(column=7, row=2, sticky="w")
|
||||
select_radio(False)
|
||||
|
||||
# ttk.Separator(root, orient='horizontal').grid(column=0, row=4, columnspan=7, sticky="ew", padx=5, pady=5)
|
||||
frame = tk.Frame(root, highlightthickness=2, highlightcolor="#D1CFE2", bg=self.rbg)
|
||||
frame.grid(column=0, row=4, columnspan=6, sticky="news", padx=16, pady=5, ipady=2, ipadx=2)
|
||||
tk.Label(frame, text="Destination", bg=self.rbg, fg="#1C1C28").grid(column=0, row=4, sticky=tk.W, padx=5, pady=5)
|
||||
self.ra_file_dest_lbl = tk.StringVar(value="Select a folder...")
|
||||
self.ra_file_dest_lbl.set(self.ras_file_dest_lbl[oid].get())
|
||||
ttk.Entry(frame, textvariable=self.ra_file_dest_lbl, state="disabled").grid(column=1, row=4, sticky="we",
|
||||
padx=(5, 0), pady=5, columnspan=2,
|
||||
ipady=10, ipadx=4)
|
||||
|
||||
def select_dest_folder():
|
||||
self.newWindow.attributes('-topmost', True)
|
||||
self.dest_select = askdirectory(parent=root)
|
||||
self.newWindow.attributes('-topmost', False)
|
||||
self.ra_file_dest_lbl.set(self.dest_select)
|
||||
|
||||
tk.Button(frame, image=self.slc_folder_photo, command=select_dest_folder, bg="#9CADCE", borderwidth=0, height=40,
|
||||
width=40, ).grid(column=3, row=4, sticky="w")
|
||||
|
||||
# second tab
|
||||
# ttk.Separator(root, orient='horizontal').grid(column=0, row=6, columnspan=7, sticky="ew", padx=5, pady=5)
|
||||
frame = tk.Frame(root, highlightthickness=2, highlightcolor="#D1CFE2", bg=self.rbg)
|
||||
frame.grid(column=0, row=6, columnspan=6, sticky="news", padx=16, pady=5, ipady=2, ipadx=2)
|
||||
tk.Label(frame, text="Parameters", bg=self.rbg, fg="#1C1C28").grid(column=0, row=6, sticky=tk.W, padx=5, pady=5)
|
||||
tk.Label(frame, bg=self.rbg,
|
||||
text="Image modality type").grid(column=0,
|
||||
row=7,
|
||||
padx=3,
|
||||
pady=3, sticky="w")
|
||||
self.ra_rfg_imt_value = tk.StringVar(value="CT")
|
||||
self.ra_rfg_imt_value.set(self.ras_rfg_imt_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_imt_value, "CT", "PET", "SPECT", "MR")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=1, row=7, padx=3, pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg,
|
||||
text="Intensity outlier re-segmentatin flag").grid(column=2, row=7, padx=(20, 3), pady=3, sticky="w")
|
||||
self.ra_rfg_iorf_value = tk.StringVar(value="0")
|
||||
self.ra_rfg_iorf_value.set(self.ras_rfg_iorf_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_iorf_value, "0", "1")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=3,
|
||||
row=7,
|
||||
padx=3,
|
||||
pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg,
|
||||
text="Discretization type").grid(column=0,
|
||||
row=8,
|
||||
padx=3,
|
||||
pady=3, sticky="w")
|
||||
self.ra_rfg_dit_value = tk.StringVar(value="FBN")
|
||||
self.ra_rfg_dit_value.set(self.ras_rfg_dit_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_dit_value, "FBN", "FBS")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=1,
|
||||
row=8,
|
||||
padx=3,
|
||||
pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg,
|
||||
text="Image quantization flag").grid(column=2, row=8, padx=(20, 3), pady=3, sticky="w")
|
||||
self.ra_rfg_iqf_value = tk.StringVar(value="0")
|
||||
self.ra_rfg_iqf_value.set(self.ras_rfg_iqf_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_iqf_value, "0", "1")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=3,
|
||||
row=8,
|
||||
padx=3,
|
||||
pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg,
|
||||
text="Bin size/width").grid(column=0, row=9, padx=3, pady=3, sticky="w")
|
||||
self.ra_rgd_nhb_value = tk.StringVar(value="8")
|
||||
self.ra_rgd_nhb_value.set(self.ras_rgd_nhb_value[oid].get())
|
||||
ttk.Entry(frame, textvariable=self.ra_rgd_nhb_value, validate="all", justify="center",
|
||||
validatecommand=(frame.register(_validate_c), "%P", 0, 128)).grid(column=1, row=9, padx=3, pady=3,
|
||||
sticky="we")
|
||||
|
||||
tk.Label(frame, bg=self.rbg, text="Re-segmentation interval range").grid(column=2, row=9, padx=(20, 2), pady=3,
|
||||
sticky="w")
|
||||
|
||||
tk.Label(frame, bg=self.rbg, text="[").grid(column=3, row=9, padx=(0, 0), pady=3, sticky="w")
|
||||
self.ra_rgd_rir1_value = tk.StringVar(value=-3000)
|
||||
self.ra_rgd_rir1_value.set(self.ras_rgd_rir1_value[oid].get())
|
||||
ttk.Spinbox(frame, from_=-3000, to=0, textvariable=self.ra_rgd_rir1_value, validate="key", width=6,
|
||||
validatecommand=(frame.register(_validate_int), "%P", -3000, 0), justify="center").grid(column=3, row=9,
|
||||
padx=(0, 80),
|
||||
pady=3,
|
||||
sticky="e")
|
||||
tk.Label(frame, bg=self.rbg, text=",").grid(column=3, row=9, padx=(70, 0), pady=3, sticky="w")
|
||||
self.ra_rgd_rir2_value = tk.StringVar(value=3000)
|
||||
self.ra_rgd_rir2_value.set(self.ras_rgd_rir2_value[oid].get())
|
||||
ttk.Spinbox(frame, from_=0, to=3000, textvariable=self.ra_rgd_rir2_value, validate="key", width=6,
|
||||
validatecommand=(frame.register(_validate_int), "%P", 0, 3000), justify="center").grid(column=3, row=9,
|
||||
padx=(80, 0),
|
||||
pady=3,
|
||||
sticky="w")
|
||||
tk.Label(frame, bg=self.rbg, text="]").grid(column=3, row=9, padx=(140, 0), pady=0, sticky="w")
|
||||
|
||||
tk.Label(frame, bg=self.rbg, text="Resampling (scaling) flag").grid(column=0, row=10, padx=3, pady=3, sticky="w")
|
||||
self.ra_rfg_rf_value = tk.StringVar(value="1")
|
||||
self.ra_rfg_rf_value.set(self.ras_rfg_rf_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_rf_value, "0", "1")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=1, row=10, padx=3, pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg, text="ROI partial volume threshold").grid(column=2, row=10, padx=(20, 3), pady=3,
|
||||
sticky="w")
|
||||
self.ra_rgd_roi_value = tk.StringVar(value=0.5)
|
||||
self.ra_rgd_roi_value.set(self.ras_rgd_roi_value[oid].get())
|
||||
ttk.Spinbox(frame, from_=0, to=1, increment=0.1, textvariable=self.ra_rgd_roi_value, validate="key",
|
||||
validatecommand=(frame.register(_validate), "%P", 0, 1), justify="center").grid(column=3, row=10,
|
||||
padx=3, pady=3,
|
||||
sticky="we")
|
||||
tk.Label(frame, bg=self.rbg, text="Image resampling interpolation type").grid(column=0, row=11, padx=3, pady=3,
|
||||
sticky="w")
|
||||
self.ra_rfg_irit_value = tk.StringVar(value="Nearest")
|
||||
self.ra_rfg_irit_value.set(self.ras_rfg_irit_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_irit_value, "Nearest", "Linear", "Cubic")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=1, row=11, padx=3, pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg, text="Quantization type").grid(column=2, row=11, padx=(20, 3), pady=3, sticky="w")
|
||||
self.ra_rfg_qt_value = tk.StringVar(value="Uniform")
|
||||
self.ra_rfg_qt_value.set(self.ras_rfg_qt_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_qt_value, "Uniform")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=3, row=11, padx=3, pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg, text="ROI resampling interpolation type").grid(column=0, row=12, padx=3, pady=3,
|
||||
sticky="w")
|
||||
self.ra_rfg_roit_value = tk.StringVar(value="Nearest")
|
||||
self.ra_rfg_roit_value.set(self.ras_rfg_roit_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_roit_value, "Nearest", "Linear", "Cubic")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=1, row=12, padx=3, pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg, text="Intensity volume histogram (IVH) type").grid(column=2, row=12, padx=(20, 3),
|
||||
pady=3, sticky="w")
|
||||
self.ra_rfg_ivht_value = tk.StringVar(value="1")
|
||||
self.ra_rfg_ivht_value.set(self.ras_rfg_ivht_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_ivht_value, "0", "1", "2", "3")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=3, row=12, padx=3, pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg, text="3D isotropic voxel size flag (mm)").grid(column=0, row=13, padx=3, pady=3,
|
||||
sticky="w")
|
||||
self.ra_rgd_3ivs_value = tk.StringVar(value=6.00)
|
||||
self.ra_rgd_3ivs_value.set(self.ras_rgd_3ivs_value[oid].get())
|
||||
ttk.Spinbox(frame, from_=0, to=50, increment=1, textvariable=self.ra_rgd_3ivs_value, validate="key",
|
||||
validatecommand=(frame.register(_validate), "%P", 0, 50), justify="center").grid(column=1, row=13,
|
||||
padx=3, pady=3,
|
||||
sticky="we")
|
||||
tk.Label(frame, bg=self.rbg, text="IVH discretization type").grid(column=2, row=13, padx=(20, 3), pady=3,
|
||||
sticky="w")
|
||||
self.ra_rfg_idt_value = tk.StringVar(value="0")
|
||||
self.ra_rfg_idt_value.set(self.ras_rfg_idt_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_idt_value, "0", "1")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=3, row=13, padx=3, pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg, text="2D isotropic voxel size flag (mm)").grid(column=0,
|
||||
row=14,
|
||||
padx=3,
|
||||
pady=3, sticky="w")
|
||||
self.ra_rgd_2ivs_value = tk.StringVar(value=1.00)
|
||||
self.ra_rgd_2ivs_value.set(self.ras_rgd_2ivs_value[oid].get())
|
||||
ttk.Spinbox(frame, from_=0, to=50, increment=1, textvariable=self.ra_rgd_2ivs_value, validate="key",
|
||||
validatecommand=(frame.register(_validate), "%P", 0, 50), justify="center").grid(column=1,
|
||||
row=14,
|
||||
padx=3,
|
||||
pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg,
|
||||
text="IVH discretization binning option (number/width)").grid(column=2, row=14, padx=(20, 3), pady=3,
|
||||
sticky="w")
|
||||
self.ra_rgd_ivho_value = tk.StringVar(value=200.00)
|
||||
self.ra_rgd_ivho_value.set(self.ras_rgd_ivho_value[oid].get())
|
||||
ttk.Spinbox(frame, from_=0, to=1000, increment=1, textvariable=self.ra_rgd_ivho_value, validate="key",
|
||||
validatecommand=(frame.register(_validate), "%P", 0, 1000), justify="center").grid(column=3,
|
||||
row=14,
|
||||
padx=3,
|
||||
pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg,
|
||||
text="Isotropic 2D voxels flag").grid(column=0,
|
||||
row=15,
|
||||
padx=3,
|
||||
pady=3, sticky="w")
|
||||
self.ra_rfg_i2vf_value = tk.StringVar(value="0")
|
||||
self.ra_rfg_i2vf_value.set(self.ras_rfg_i2vf_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_i2vf_value, "0", "1")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=1,
|
||||
row=15,
|
||||
padx=3,
|
||||
pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg,
|
||||
text="Max number of ROIs per image").grid(column=2, row=15, padx=(20, 3), pady=3, sticky="w")
|
||||
self.ra_rgd_mri_value = tk.StringVar(value="4")
|
||||
self.ra_rgd_mri_value.set(self.ras_rgd_mri_value[oid].get())
|
||||
ttk.Spinbox(frame, from_=0, to=1000000, textvariable=self.ra_rgd_mri_value, validate="key",
|
||||
validatecommand=(frame.register(_validate_int), "%P", 0, 1000000), justify="center").grid(column=3,
|
||||
row=15,
|
||||
padx=3,
|
||||
pady=3,
|
||||
sticky="we")
|
||||
tk.Label(frame, bg=self.rbg,
|
||||
text="Round voxel intensity values flag").grid(column=0,
|
||||
row=16,
|
||||
padx=3,
|
||||
pady=3, sticky="w")
|
||||
self.ra_rfg_rviv_value = tk.StringVar(value="0")
|
||||
self.ra_rfg_rviv_value.set(self.ras_rfg_rviv_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_rviv_value, "0", "1")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=1,
|
||||
row=16,
|
||||
padx=3,
|
||||
pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg,
|
||||
text="Combine multiple ROIs to one flag").grid(column=2, row=16, padx=(20, 3), pady=3, sticky="w")
|
||||
self.ra_rfg_cmrf_value = tk.StringVar(value="0")
|
||||
self.ra_rfg_cmrf_value.set(self.ras_rfg_cmrf_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_cmrf_value, "0", "1")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=3,
|
||||
row=16,
|
||||
padx=3,
|
||||
pady=3, sticky="we")
|
||||
tk.Label(frame, bg=self.rbg,
|
||||
text="Range re-segmentation flag").grid(column=0,
|
||||
row=17,
|
||||
padx=3,
|
||||
pady=3, sticky="w")
|
||||
self.ra_rfg_rrf_value = tk.StringVar(value="0")
|
||||
self.ra_rfg_rrf_value.set(self.ras_rfg_rrf_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_rrf_value, "0", "1")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=1,
|
||||
row=17,
|
||||
padx=3,
|
||||
pady=3, sticky="we")
|
||||
tk.Label(frame, text="Type of output data", bg=self.rbg).grid(column=2, row=17, padx=(20, 3), pady=3, sticky="w")
|
||||
self.ra_rfg_tod_value = tk.StringVar(value="2")
|
||||
self.ra_rfg_tod_value.set(self.ras_rfg_tod_value[oid].get())
|
||||
w = tk.OptionMenu(frame, self.ra_rfg_tod_value, "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12")
|
||||
w.config(indicatoron=False, compound='right', image=self.arr_img)
|
||||
w.config(highlightthickness=0, highlightbackground="black")
|
||||
w.grid(column=3,
|
||||
row=17,
|
||||
padx=3,
|
||||
pady=3, sticky="we")
|
||||
|
||||
# last row
|
||||
# self.close_photo = tk.PhotoImage(file="images/close.png")
|
||||
# self.close_photo = self.close_photo.zoom(5)
|
||||
# self.close_photo = self.close_photo.subsample(3)
|
||||
|
||||
def destroy():
|
||||
self.set_radiomix_params(oid)
|
||||
root.quit()
|
||||
root.destroy()
|
||||
main.none = True
|
||||
|
||||
def close():
|
||||
main.quit()
|
||||
main.destroy()
|
||||
# root.quit()
|
||||
# root.destroy()
|
||||
|
||||
main.protocol("WM_DELETE_WINDOW", close)
|
||||
# root.protocol("WM_DELETE_WINDOW", destroy)
|
||||
# ttk.Button(root, image=self.close_photo, command=destroy).grid(column=3, row=18, sticky="e", padx=40)
|
||||
tk.Button(root, image=self.close_photo, bg=self.rbg, command=destroy, borderwidth=0).grid(column=1, row=18,
|
||||
columnspan=5, padx=124,
|
||||
sticky="e", pady=(0, 5))
|
||||
|
||||
# self.ok_photo = tk.PhotoImage(file="images/OK 25.png")
|
||||
|
||||
# self.ok_photo = self.ok_photo.zoom(3)
|
||||
# self.ok_photo = self.ok_photo.subsample(2)
|
||||
def okf():
|
||||
for it in self.ra_rgd_nhb_value.get().split(","):
|
||||
if float(it) < 0 or float(it) > 128:
|
||||
messagebox.showerror(title="Parameter range",
|
||||
message="please select 'Bin size/width' paramter in [0, 128] range.")
|
||||
return
|
||||
if float(self.ra_rgd_rir1_value.get()) < -3000 or float(self.ra_rgd_rir1_value.get()) > 0:
|
||||
messagebox.showerror(title="Parameter range",
|
||||
message="please select 'Re-segmentation interval range' paramter in [-3000, 3000] range.")
|
||||
elif float(self.ra_rgd_rir2_value.get()) < 0 or float(self.ra_rgd_rir2_value.get()) > 3000:
|
||||
messagebox.showerror(title="Parameter range",
|
||||
message="please select 'Re-segmentation interval range' paramter in [-3000, 3000] range.")
|
||||
elif float(self.ra_rgd_roi_value.get()) < 0 or float(self.ra_rgd_roi_value.get()) > 1:
|
||||
messagebox.showerror(title="Parameter range",
|
||||
message="please select 'ROI partial volume threshold' paramter in [0, 1] range.")
|
||||
elif float(self.ra_rgd_3ivs_value.get()) < 0 or float(self.ra_rgd_3ivs_value.get()) > 50:
|
||||
messagebox.showerror(title="Parameter range",
|
||||
message="please select '3D isotropic voxel size flag(mm)' paramter in [0, 50] range.")
|
||||
elif float(self.ra_rgd_2ivs_value.get()) < 0 or float(self.ra_rgd_2ivs_value.get()) > 50:
|
||||
messagebox.showerror(title="Parameter range",
|
||||
message="please select '2D isotropic voxel size flag(mm)' paramter in [0, 50] range.")
|
||||
elif float(self.ra_rgd_ivho_value.get()) < 0 or float(self.ra_rgd_ivho_value.get()) > 1000:
|
||||
messagebox.showerror(title="Parameter range",
|
||||
message="please select 'IVH discretization binning option (number/width)' paramter in [0, 1000] range.")
|
||||
elif float(self.ra_rgd_mri_value.get()) < 0 or float(self.ra_rgd_mri_value.get()) > 1000:
|
||||
messagebox.showerror(title="Parameter range",
|
||||
message="please select 'Max no. of ROIs per image' paramter in [0, 1000] range.")
|
||||
else:
|
||||
change = False
|
||||
change = self.check_entry(self.ras_rfg_tod_value[oid], self.ra_rfg_tod_value, change)
|
||||
change = self.check_entry(self.ras_rfg_rrf_value[oid], self.ra_rfg_rrf_value, change)
|
||||
change = self.check_entry(self.ras_rfg_cmrf_value[oid], self.ra_rfg_cmrf_value, change)
|
||||
change = self.check_entry(self.ras_rfg_rviv_value[oid], self.ra_rfg_rviv_value, change)
|
||||
change = self.check_entry(self.ras_rgd_mri_value[oid], self.ra_rgd_mri_value, change)
|
||||
change = self.check_entry(self.ras_rfg_i2vf_value[oid], self.ra_rfg_i2vf_value, change)
|
||||
change = self.check_entry(self.ras_rgd_ivho_value[oid], self.ra_rgd_ivho_value, change)
|
||||
change = self.check_entry(self.ras_rgd_2ivs_value[oid], self.ra_rgd_2ivs_value, change)
|
||||
change = self.check_entry(self.ras_rfg_idt_value[oid], self.ra_rfg_idt_value, change)
|
||||
change = self.check_entry(self.ras_rgd_3ivs_value[oid], self.ra_rgd_3ivs_value, change)
|
||||
change = self.check_entry(self.ras_rfg_ivht_value[oid], self.ra_rfg_ivht_value, change)
|
||||
change = self.check_entry(self.ras_rfg_roit_value[oid], self.ra_rfg_roit_value, change)
|
||||
change = self.check_entry(self.ras_rfg_qt_value[oid], self.ra_rfg_qt_value, change)
|
||||
change = self.check_entry(self.ras_rfg_irit_value[oid], self.ra_rfg_irit_value, change)
|
||||
change = self.check_entry(self.ras_rgd_roi_value[oid], self.ra_rgd_roi_value, change)
|
||||
change = self.check_entry(self.ras_rfg_rf_value[oid], self.ra_rfg_rf_value, change)
|
||||
change = self.check_entry(self.ras_rgd_rir2_value[oid], self.ra_rgd_rir2_value, change)
|
||||
change = self.check_entry(self.ras_rgd_rir1_value[oid], self.ra_rgd_rir1_value, change)
|
||||
change = self.check_entry(self.ras_rgd_nhb_value[oid], self.ra_rgd_nhb_value, change)
|
||||
change = self.check_entry(self.ras_rfg_iqf_value[oid], self.ra_rfg_iqf_value, change)
|
||||
change = self.check_entry(self.ras_rfg_dit_value[oid], self.ra_rfg_dit_value, change)
|
||||
change = self.check_entry(self.ras_rfg_iorf_value[oid], self.ra_rfg_iorf_value, change)
|
||||
change = self.check_entry(self.ras_rfg_imt_value[oid], self.ra_rfg_imt_value, change)
|
||||
change = self.check_entry(self.ras_file_dest_lbl[oid], self.ra_file_dest_lbl, change)
|
||||
change = self.check_entry(self.ras_file_slc2_lbl[oid], self.ra_file_slc2_lbl, change)
|
||||
change = self.check_entry(self.ras_file_slc_lbl[oid], self.ra_file_slc_lbl, change)
|
||||
change = self.check_entry(self.ras_file_folder[oid], self.ra_file_folder, change)
|
||||
if change:
|
||||
self.set_object_state(oid, 'normal', 'hidden', 'hidden', 'hidden')
|
||||
self.check_connection_remove(oid)
|
||||
root.quit()
|
||||
root.destroy()
|
||||
|
||||
# ttk.Button(root, image=self.ok_photo, command=okf).grid(column=3, row=18, sticky="e")
|
||||
tk.Button(root, image=self.ok_img, bg=self.rbg, command=okf, borderwidth=0).grid(column=5, row=18, sticky="e",
|
||||
padx=(0, 16), pady=(0, 5))
|
||||
root.mainloop()
|
||||
if main.none:
|
||||
return None
|
||||
if not (self.ra_file_slc_lbl.get().startswith("Select ") or self.ra_file_slc2_lbl.get().startswith(
|
||||
"Select ") or self.ra_file_dest_lbl.get().startswith("Select ")):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class RoundedButton(tk.Canvas):
|
||||
def __init__(self, parent, width, height, corner_radius, padding, color, bg, command=None, text=""):
|
||||
tk.Canvas.__init__(self, parent, borderwidth=0,
|
||||
relief="flat", highlightthickness=0, bg=bg)
|
||||
self.command = command
|
||||
|
||||
rad = 2 * corner_radius
|
||||
|
||||
def shape():
|
||||
self.create_polygon((padding, height - corner_radius - padding, padding, corner_radius + padding,
|
||||
padding + corner_radius, padding, width - padding - corner_radius, padding,
|
||||
width - padding, corner_radius + padding, width - padding,
|
||||
height - corner_radius - padding, width - padding - corner_radius, height - padding,
|
||||
padding + corner_radius, height - padding), fill=color, outline=color)
|
||||
self.create_arc((padding, padding + rad, padding + rad, padding), start=90, extent=90, fill=color,
|
||||
outline=color)
|
||||
self.create_arc((width - padding - rad, padding, width - padding, padding + rad), start=0, extent=90,
|
||||
fill=color, outline=color)
|
||||
self.create_arc((width - padding, height - rad - padding, width - padding - rad, height - padding),
|
||||
start=270, extent=90, fill=color, outline=color)
|
||||
self.create_arc((padding, height - padding - rad, padding + rad, height - padding), start=180, extent=90,
|
||||
fill=color, outline=color)
|
||||
self.create_text(width / 2, height / 2, text=text)
|
||||
|
||||
id = shape()
|
||||
(x0, y0, x1, y1) = self.bbox("all")
|
||||
width = (x1 - x0)
|
||||
height = (y1 - y0)
|
||||
self.configure(width=width, height=height)
|
||||
self.bind("<ButtonPress-1>", self._on_press)
|
||||
self.bind("<ButtonRelease-1>", self._on_release)
|
||||
|
||||
def _on_press(self, event):
|
||||
self.configure(relief="sunken")
|
||||
|
||||
def _on_release(self, event):
|
||||
self.configure(relief="raised")
|
||||
if self.command is not None:
|
||||
self.command()
|
||||
@@ -0,0 +1,25 @@
|
||||
<tool id="radiuma_radiomics" name="Radiomics Feature Extractor" version="1.0.0">
|
||||
<description>Extract IBSI-compliant radiomics features using PySERA</description>
|
||||
<command>
|
||||
python3 $__tool_directory__/run_radiomics.py
|
||||
--image $image
|
||||
--mask $mask
|
||||
--output $output.extra_files_path
|
||||
--categories "$categories"
|
||||
--dimensions "$dimensions"
|
||||
--apply_preprocessing "$apply_preprocessing"
|
||||
</command>
|
||||
<inputs>
|
||||
<param name="image" type="data" format="nii" label="Input Image"/>
|
||||
<param name="mask" type="data" format="nii" label="Segmentation Mask"/>
|
||||
<param name="categories" type="text" value="glcm, glrlm" label="Feature Categories"/>
|
||||
<param name="dimensions" type="text" value="1st, 2_5d, 3d" label="Spatial Dimensions"/>
|
||||
<param name="apply_preprocessing" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Apply Preprocessing"/>
|
||||
</inputs>
|
||||
<outputs>
|
||||
<data name="output" format="csv" label="Extracted Radiomics Features" from_work_dir="radiomics_features.csv"/>
|
||||
</outputs>
|
||||
<help>
|
||||
This tool extracts handcrafted radiomics features from medical images using the PySERA library.
|
||||
</help>
|
||||
</tool>
|
||||
@@ -0,0 +1,21 @@
|
||||
from pysera.classifier import Classifier
|
||||
import argparse
|
||||
import pandas as pd
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--x_train", required=True)
|
||||
parser.add_argument("--y_train", required=True)
|
||||
parser.add_argument("--x_val", required=True)
|
||||
parser.add_argument("--y_val", required=True)
|
||||
parser.add_argument("--algorithm", choices=["LogisticRegression", "KNeighborsClassifier"], required=True)
|
||||
parser.add_argument("--output", required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
X_train = pd.read_csv(args.x_train)
|
||||
y_train = pd.read_csv(args.y_train)
|
||||
X_val = pd.read_csv(args.x_val)
|
||||
y_val = pd.read_csv(args.y_val)
|
||||
|
||||
clf = Classifier(X_train, y_train, X_val, y_val)
|
||||
result = clf.run(algorithm=args.algorithm)
|
||||
pd.DataFrame(result).to_csv(args.output, index=False)
|
||||
@@ -0,0 +1,19 @@
|
||||
from pysera.preprocessing import Preprocessor
|
||||
import argparse
|
||||
import pandas as pd
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--input", required=True)
|
||||
parser.add_argument("--method", choices=["resample", "shuffle"], required=True)
|
||||
parser.add_argument("--output", required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
df = pd.read_csv(args.input)
|
||||
prep = Preprocessor(df)
|
||||
|
||||
if args.method == "resample":
|
||||
result = prep.resample()
|
||||
elif args.method == "shuffle":
|
||||
result = prep.shuffle()
|
||||
|
||||
result.to_csv(args.output, index=False)
|
||||
@@ -0,0 +1,34 @@
|
||||
# run_radiomics.py
|
||||
|
||||
import pysera
|
||||
import argparse
|
||||
import os
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--image", required=True)
|
||||
parser.add_argument("--mask", required=True)
|
||||
parser.add_argument("--output", required=True)
|
||||
parser.add_argument("--categories", default="glcm, glrlm")
|
||||
parser.add_argument("--dimensions", default="1st, 2_5d, 3d")
|
||||
parser.add_argument("--apply_preprocessing", default="True")
|
||||
args = parser.parse_args()
|
||||
|
||||
# اطمینان از وجود مسیر خروجی
|
||||
os.makedirs(args.output, exist_ok=True)
|
||||
|
||||
# اجرای PySERA
|
||||
result = pysera.process_batch(
|
||||
image_input=args.image,
|
||||
mask_input=args.mask,
|
||||
output_path=args.output,
|
||||
categories=args.categories,
|
||||
dimensions=args.dimensions,
|
||||
apply_preprocessing=args.apply_preprocessing == "True"
|
||||
)
|
||||
|
||||
# ذخیره خروجی ویژگیها به CSV
|
||||
if result["success"]:
|
||||
features = result["features_extracted"]
|
||||
features.to_csv(os.path.join(args.output, "radiomics_features.csv"), index=False)
|
||||
else:
|
||||
print("Error:", result.get("error", "Unknown error"))
|
||||
@@ -0,0 +1,3 @@
|
||||
from .classifiers import Classifiers
|
||||
from .preprocessor import Preprocessor
|
||||
from .radiomics_extractor import RadiomicsExtractor
|
||||
@@ -0,0 +1,12 @@
|
||||
import pandas as pd
|
||||
from sklearn.utils import resample, shuffle
|
||||
|
||||
class Preprocessor:
|
||||
def __init__(self, df: pd.DataFrame):
|
||||
self.df = df
|
||||
|
||||
def resample(self, replace=False):
|
||||
return resample(self.df, replace=replace)
|
||||
|
||||
def shuffle(self):
|
||||
return shuffle(self.df)
|
||||
@@ -0,0 +1,90 @@
|
||||
astroid==4.0.1
|
||||
certifi==2025.10.5
|
||||
charset-normalizer==3.4.4
|
||||
cleo==2.1.0
|
||||
colorama==0.4.6
|
||||
connected-components-3d==3.26.0
|
||||
contourpy==1.3.3
|
||||
crashtest==0.4.1
|
||||
cycler==0.12.1
|
||||
dataclasses==0.6
|
||||
dcmrtstruct2nii==5
|
||||
dill==0.4.0
|
||||
distlib==0.4.0
|
||||
docx==0.2.4
|
||||
et_xmlfile==2.0.0
|
||||
filelock==3.20.0
|
||||
fonttools==4.60.1
|
||||
fpdf==1.7.2
|
||||
fsspec==2025.9.0
|
||||
idna==3.11
|
||||
imageio==2.37.0
|
||||
importlib_resources==6.5.2
|
||||
iniconfig==2.3.0
|
||||
isort==7.0.0
|
||||
itk==5.4.4.post1
|
||||
itk-core==5.4.4.post1
|
||||
itk-filtering==5.4.4.post1
|
||||
itk-io==5.4.4.post1
|
||||
itk-numerics==5.4.4.post1
|
||||
itk-registration==5.4.4.post1
|
||||
itk-segmentation==5.4.4.post1
|
||||
Jinja2==3.1.6
|
||||
joblib==1.5.2
|
||||
kiwisolver==1.4.9
|
||||
kmodes==0.12.2
|
||||
lazy_loader==0.4
|
||||
lxml==6.0.2
|
||||
MarkupSafe==3.0.3
|
||||
matplotlib==3.10.7
|
||||
mccabe==0.7.0
|
||||
mpmath==1.3.0
|
||||
networkx==3.5
|
||||
nibabel==5.3.2
|
||||
numpy==2.2.6
|
||||
opencv-python==4.12.0.88
|
||||
openpyxl==3.1.5
|
||||
packaging==25.0
|
||||
pandas==2.3.3
|
||||
pillow==12.0.0
|
||||
platformdirs==4.5.0
|
||||
pluggy==1.6.0
|
||||
psutil==7.1.2
|
||||
psycopg2-binary==2.9.11
|
||||
pyaml==25.7.0
|
||||
pydicom==3.0.1
|
||||
Pygments==2.19.2
|
||||
pylint==4.0.1
|
||||
pynrrd==1.1.3
|
||||
pyparsing==3.2.5
|
||||
pysera==2.1.2
|
||||
pytest==8.4.2
|
||||
python-dateutil==2.9.0.post0
|
||||
python-docx==1.2.0
|
||||
pytz==2025.2
|
||||
PyWavelets==1.9.0
|
||||
PyYAML==6.0.3
|
||||
RapidFuzz==3.14.1
|
||||
ReliefF==0.1.2
|
||||
reportlab==4.4.4
|
||||
requests==2.32.5
|
||||
rt-utils==1.2.7
|
||||
scikit-image==0.25.2
|
||||
scikit-learn==1.7.2
|
||||
scikit-optimize==0.10.2
|
||||
scipy==1.16.3
|
||||
six==1.17.0
|
||||
sklearn-relief==1.0.0b2
|
||||
sympy==1.14.0
|
||||
termcolor==3.2.0
|
||||
threadpoolctl==3.6.0
|
||||
tifffile==2025.10.16
|
||||
tomlkit==0.13.3
|
||||
torch==2.8.0
|
||||
torchaudio==2.8.0
|
||||
torchvision==0.23.0
|
||||
typing_extensions==4.15.0
|
||||
tzdata==2025.2
|
||||
uml-class-diagram-generator==0.1
|
||||
urllib3==2.5.0
|
||||
virtualenv==20.35.3
|
||||
Reference in New Issue
Block a user