Skip to content

Commit

Permalink
Merge branch 'acr-mode-experimental' into temp-branch
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderGetka-cbica authored May 31, 2022
2 parents cce8818 + 7851888 commit aed3fa1
Show file tree
Hide file tree
Showing 19 changed files with 1,276 additions and 74 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ SET( ${PROJECT_NAME}_Variant "Full" ) # the particular variant of CaPTk (Full/Ne

SET( PROJECT_VERSION_MAJOR 1 )
SET( PROJECT_VERSION_MINOR 9 )
SET( PROJECT_VERSION_PATCH 0 )
SET( PROJECT_VERSION_PATCH 0.ACRExperimental )
SET( PROJECT_VERSION_TWEAK )

# check for the string "nonRelease" in the PROJECT_VERSION_PATCH variable
Expand Down
6 changes: 3 additions & 3 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ schedules:
displayName: Daily midnight build
branches:
include:
- master
- acr-mode-experimental

trigger:
batch: true
branches:
include: ['master']
include: ['acr-mode-experimental']

# 20200312: apparently this is now explicitly required for azure
pr:
branches:
include: ['master']
include: ['acr-mode-experimental']

jobs:
- job: 'WindowsBuild'
Expand Down
20 changes: 17 additions & 3 deletions src/CaPTk.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ int main(int argc, char** argv)
std::string cmd_inputs, cmd_mask, cmd_tumor, cmd_tissue;
float cmd_maskOpacity = 1;
bool comparisonMode = false;
bool loadOnStartupWithStudyBrowser = false;

// this is used to populate the available CWL files for the cli
auto cwlFolderPath =
Expand Down Expand Up @@ -86,6 +87,10 @@ int main(int argc, char** argv)
parser.addOptionalParameter("ts", "tissuePt", cbica::Parameter::FILE, ".txt", "Tissue Point file for the image(s) being loaded");
parser.addOptionalParameter("a", "advanced", cbica::Parameter::BOOLEAN, "none", "Advanced visualizer which does *not* consider", "origin information during loading");
parser.addOptionalParameter("c", "comparisonMode", cbica::Parameter::BOOLEAN, "true or false", "Enable/Disable comparison mode", "comparison mode during loading");

// ACR collaboration options, although possibly usable in other contexts
parser.addOptionalParameter("acr", "acrExperimentalMode", cbica::Parameter::BOOLEAN, "none", "Enable the ACR collaboration mode, with fewer features and a modified GUI");
parser.addOptionalParameter("bs", "browseStudy", cbica::Parameter::BOOLEAN, "none", "Open CaPTk with an experimental study-browser for previewing image information -- requires NIFTIs converted from DICOM and JSON data");

//parser.exampleUsage("-i C:/data/input1.nii.gz,C:/data/input2.nii.gz -m C:/data/inputMask.nii.gz -tu C:/data/init_seed.txt -ts C:/data/init_GLISTR.txt");
parser.addExampleUsage("-i C:/data/input1.nii.gz,C:/data/input2.nii.gz -m C:/data/inputMask.nii.gz -tu C:/data/init_seed.txt -ts C:/data/init_GLISTR.txt",
Expand Down Expand Up @@ -169,6 +174,10 @@ int main(int argc, char** argv)
{
parser.getParameterValue("c", comparisonMode);
}
if (parser.isPresent("bs"))
{
loadOnStartupWithStudyBrowser = true;
}

#if defined(__linux__)
//auto defaultFormat = QVTKOpenGLWidget::defaultFormat();
Expand Down Expand Up @@ -251,6 +260,10 @@ int main(int argc, char** argv)
{
window.EnableAdvancedVisualizer();
}
if (parser.isPresent("acr"))
{
window.EnableACRMode();
}

// get everything to QString
std::vector< QString > inputFiles_QString;
Expand Down Expand Up @@ -320,9 +333,10 @@ int main(int argc, char** argv)
#endif
}
else
window.loadFromCommandLine(inputFiles_QString, comparisonMode, inputMask.toStdString(),
cmd_maskOpacity, cmd_tumor, cmd_tissue/*, true*/); // at this point, inputFiles_QString will have at least 1 value

{
window.loadFromCommandLine(inputFiles_QString, comparisonMode, inputMask.toStdString(),
cmd_maskOpacity, cmd_tumor, cmd_tissue, loadOnStartupWithStudyBrowser /*, true*/); // at this point, inputFiles_QString will have at least 1 value
}


//window.setFixedSize(QSize(2735, 1538)); // useful when doing video recording from SP4 and maintain 16x9 ratio
Expand Down
9 changes: 9 additions & 0 deletions src/applications/FeatureExtraction/src/FeatureExtraction.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -1251,6 +1251,15 @@ void FeatureExtraction< TImage >::SetSelectedROIsAndLabels(std::string roi, std:
{
m_roiLabels = tempstr2;
}
if (m_roiLabels.size() < m_roi.size())
{
auto labelsInitialSize = m_roiLabels.size();
auto missingLabelsCount = m_roi.size() - m_roiLabels.size();
for (unsigned int i = 0; i < missingLabelsCount; i++)
{
m_roiLabels.push_back("Label" + std::to_string(m_roi[labelsInitialSize + i]));
}
}
}

if (m_debug)
Expand Down
14 changes: 13 additions & 1 deletion src/applications/GeodesicTraining/src/GeodesicTrainingCaPTkApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
//#include "ApplicationBase.h"
#include <QObject>

// Do this to make sure we can connect signals/slots across threads with std::strings
Q_DECLARE_METATYPE(std::string)

class GeodesicTrainingApplicationBase : public QObject
{
Q_OBJECT
Expand All @@ -30,7 +33,9 @@ public slots:
//void GeodesicTrainingFinished3D(typename itk::Image<int, 3>::Pointer result);
//void GeodesicTrainingFinished2D(typename itk::Image<int, 2>::Pointer result);
void GeodesicTrainingFinishedWithError(QString errorMessage);
void GeodesicTrainingFinishedWithError(); // For when no error message is published
void GeodesicTrainingProgressUpdate(int progress, std::string message, int max);
//void GeodesicTrainingProgressUpdate(int progress, QString message, int max);

protected:
std::thread m_Thread;
Expand All @@ -47,7 +52,10 @@ class GeodesicTrainingCaPTkApp :
typedef itk::Image<int, Dimensions> LabelsImageType;
typedef typename LabelsImageType::Pointer LabelsImagePointer;

explicit GeodesicTrainingCaPTkApp(QObject* parent = nullptr) : GeodesicTrainingApplicationBase(parent) {}
explicit GeodesicTrainingCaPTkApp(QObject* parent = nullptr) : GeodesicTrainingApplicationBase(parent)
{
qRegisterMetaType<std::string>(); // Needs to be done at runtime to allow these connections
}

virtual ~GeodesicTrainingCaPTkApp() {}

Expand All @@ -61,6 +69,8 @@ class GeodesicTrainingCaPTkApp :
/** Overriden from GeodesicTrainingSegmentation class */
void progressUpdate(std::string message, int progress) override
{
// use QString to avoid argument queuing issues across threads
// (see https://stackoverflow.com/a/17083775)
emit GeodesicTrainingProgressUpdate(progress, message, 100);
}

Expand All @@ -73,6 +83,8 @@ class GeodesicTrainingCaPTkApp :
this->SetLabels(labelsImage);
this->SetSaveAll(true);
this->SetProcessing(true, 6, true, false, false, 5000000); // Disable pixel limit, all else default.
emit GeodesicTrainingProgressUpdate(10, "Geodesic Training Segmentation in progress...", 100);

auto executeResult = this->Execute();

if (executeResult->ok) {
Expand Down
1 change: 1 addition & 0 deletions src/view/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ SET( GUI
CaPTkDockWidget
fBiasCorrectionDialog
fBraTSSegmentation
fStudyBrowserDialog
#fSegmentationPanel
#fHelpAppDialog
)
Expand Down
18 changes: 18 additions & 0 deletions src/view/gui/fDrawingPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ fDrawingPanel::fDrawingPanel(QWidget * parent) : QWidget(parent)
connect(HelpButton, SIGNAL(clicked()), this, SLOT(helpClicked()));
connect(changeButton, SIGNAL(clicked()), this, SLOT(ChangeLabelValuesClicked()));
connect(applyMaskButton, SIGNAL(clicked()), this, SLOT(OnApplyMaskButtonClicked()));
connect(runGeodesicTrainingSegmentationButton, SIGNAL(clicked()), this, SLOT(OnRunGTSButtonClicked()));
connect(finalizeSegmentationButton, SIGNAL(clicked()), this, SLOT(OnFinalizeSegmentationButtonClicked()));
}

void fDrawingPanel::helpClicked()
Expand Down Expand Up @@ -137,4 +139,20 @@ void fDrawingPanel::FillButtonFunctionality()
void fDrawingPanel::OnApplyMaskButtonClicked()
{
emit ApplyMask();
}

void fDrawingPanel::EnableACRMode()
{
applyMaskButton->hide();
algorithmGroup->setHidden(false);
}

void fDrawingPanel::OnRunGTSButtonClicked()
{
emit runGTSButtonClicked();
}

void fDrawingPanel::OnFinalizeSegmentationButtonClicked()
{
emit finalizeSegmentationButtonClicked();
}
6 changes: 6 additions & 0 deletions src/view/gui/fDrawingPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class fDrawingPanel : public QWidget, private Ui::fDrawingPanel
}

int getCurrentOpacity() { return m_currentOpacity; };
void EnableACRMode();

signals :
void clearMask(int label=-1);
Expand All @@ -76,8 +77,11 @@ signals :
void CurrentMaskOpacityChanged(int); // multiLabel related change
void helpClicked_Interaction(std::string);
void sig_ChangeLabelValuesClicked(const std::string, const std::string);
void runGTSButtonClicked();
void finalizeSegmentationButtonClicked();
void ApplyMask();


public slots :

//! Enable voxel based erase functionality
Expand Down Expand Up @@ -118,6 +122,8 @@ public slots :

//! Apply mask
void OnApplyMaskButtonClicked();
void OnRunGTSButtonClicked();
void OnFinalizeSegmentationButtonClicked();

private:
int m_currentOpacity; // set default to the tenth spinbox selection (1.0 mask opacity)
Expand Down
118 changes: 117 additions & 1 deletion src/view/gui/fFeaturePanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ void fFeaturePanel::computeFeature(int type)
}
}

((fMainWindow*)m_listener)->updateProgress(30, "Calculating and exporting features", images.size());
((fMainWindow*)m_listener)->updateProgress(30, "Calculating and exporting features", 100); // last param used to be images.size()???

if (images[0]->GetLargestPossibleRegion().GetSize()[2] == 1)
{
Expand Down Expand Up @@ -378,6 +378,7 @@ void fFeaturePanel::computeFeature(int type)
}

m_btnCompute->setEnabled(true);
emit computationFinished();
return;
}

Expand Down Expand Up @@ -439,4 +440,119 @@ void fFeaturePanel::onIBSI2Toggled(bool checked)
msgbox.setText(msg);
msgbox.exec();
}
}

void fFeaturePanel::EnableACRMode()
{
m_doACRCallbackOnFinish = true;
// force Image Selection to All Images, hide those options
radio1->setChecked(false);
radio1->hide();
radio2->setChecked(true);

// For speed, uncheck these by default for now so that demos are done quickly
// TBD: Once we address long-running feature extraction, this can be changed back.
m_GLCM->setChecked(false);
m_GLSZM->setChecked(false);
m_GLRLM->setChecked(false);
m_NGTDM->setChecked(false);
m_LBP->setChecked(false);
m_Histogram->setChecked(false);
m_Collage->setChecked(false);
m_Lattice->setChecked(false);


// Add/replace Compute+save button, hide output file selector
// TODO switch to a temp dir and store this location for deletion later
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
QString outputDirRoot = env.value("DART_CAPTK_OUTPUT_DIR_ROOT", "NULL");
cbica::createDirectory(cbica::normalizePath(outputDirRoot.toStdString() + "/temp/"));
QString tmpFeatureFilePath = outputDirRoot + "/temp/tmp_features.csv";
m_txtSaveFileName->setText(QString::fromStdString(cbica::normPath(tmpFeatureFilePath.toStdString()))); // will be deleted after each run
m_txtSaveFileName->hide();
m_btnBrowseSaveFile->hide();
saveGroup_file->hide();
instructionsGroup->setHidden(false);
//m_verticalConcat->hide(); // We may need to hide this if we want all output to be uniform
saveGroup->setTitle("Output");

// Ensure output uniformity in a consistent format for training module
m_verticalConcat->setChecked(false);
m_verticalConcat->setVisible(false);
m_btnCompute->setText("Compute + Save to DART");
}

std::string fFeaturePanel::GetCurrentOutputPath()
{
return m_txtSaveFileName->text().toStdString();
}

bool fFeaturePanel::GetSelectedROIValuesAndLabelsVectors(std::vector<int>& vals, std::vector<std::string>& labels)
{
vals.clear();
labels.clear();
auto roi = m_roi->text().toStdString();
auto roi_labels = m_roi_label->text().toStdString();
bool roivaluesfound = false;
bool roilabelsfound = false;

if (!roi.empty() && roi != "all")
{
auto tempstr = cbica::stringSplit(roi, "|");
auto tempstr2 = cbica::stringSplit(roi, ",");
if (tempstr2.size() > tempstr.size())
{
tempstr = tempstr2;
}
for (size_t i = 0; i < tempstr.size(); i++)
{
vals.push_back(std::stoi(tempstr[i]));
if (roi_labels.empty())
{
labels.push_back(tempstr[i]);
}
}

roivaluesfound = true;
}

if (!roi_labels.empty() && roi_labels != "all")
{
labels = cbica::stringSplit(roi_labels, "|");
auto tempstr2 = cbica::stringSplit(roi_labels, ",");
if (tempstr2.size() > labels.size())
{
labels = tempstr2;
}
if (labels.size() < vals.size())
{
auto labelsInitialSize = labels.size();
auto missingLabelsCount = vals.size() - labels.size();
for (unsigned int i = 0; i < missingLabelsCount; i++)
{
labels.push_back("Label" + std::to_string(vals[labelsInitialSize + i]));
}
}
roilabelsfound = true;
}

return (roivaluesfound && roilabelsfound);
}

void fFeaturePanel::SetROIValuesAndLabelStrings(std::string valuesString, std::string labelsString)
{
m_roi->setText(QString::fromStdString(valuesString));
m_roi_label->setText(QString::fromStdString(labelsString));
}

bool fFeaturePanel::IBSIFeaturesEnabled()
{
if (m_IBSI2->isChecked())
{
return true;
}
else
{
return false;
}
}
16 changes: 15 additions & 1 deletion src/view/gui/fFeaturePanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,25 @@ class fFeaturePanel : public QWidget, private Ui::fFeaturePanel
m_tempFolderLocation = input_tempFolder;
}

void EnableACRMode();

//! Get the currently selected output filepath.
std::string GetCurrentOutputPath();

//! Populate the 2 given vectors with the ROI values (intensity in mask image) and labels (corresponding region names)
// returns true if this actually works, false if nothing is selected or if "all" is typed in
bool GetSelectedROIValuesAndLabelsVectors(std::vector<int>& vals, std::vector<std::string>& labels);

// return true if IBSI features are toggled on. Useful for detecting when to pick up the artifacts.
bool IBSIFeaturesEnabled();

signals:
void m_btnComputeClicked();
void helpClicked_FeaUsage(std::string);
void computationFinished();

public slots :
void SetROIValuesAndLabelStrings(std::string valuesString, std::string labelsString);
void browseOutputFileName();
void ComputeFunctionality();
void CancelFunctionality();
Expand Down Expand Up @@ -115,7 +128,8 @@ class fFeaturePanel : public QWidget, private Ui::fFeaturePanel
m_FeatureMaps.push_back(featureMap);
}
}

// Flag for whether to run the ACR callback script (only works in an ACR containerized environment)
bool m_doACRCallbackOnFinish;
};


Expand Down
Loading

0 comments on commit aed3fa1

Please sign in to comment.