diff --git a/Plugins/org.mitk.gui.qt.photoacousticsimulation/src/internal/PASimulator.cpp b/Plugins/org.mitk.gui.qt.photoacousticsimulation/src/internal/PASimulator.cpp index b9e5b04b93..a4742d0c97 100644 --- a/Plugins/org.mitk.gui.qt.photoacousticsimulation/src/internal/PASimulator.cpp +++ b/Plugins/org.mitk.gui.qt.photoacousticsimulation/src/internal/PASimulator.cpp @@ -1,303 +1,310 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include // Qmitk #include "PASimulator.h" // Qt #include #include #include // mitk #include #include #include #ifdef __linux__ #include #include #else #include #endif #include #include const std::string PASimulator::VIEW_ID = "org.mitk.views.pasimulator"; void PASimulator::SetFocus() { m_Controls.pushButtonShowRandomTissue->setFocus(); } void PASimulator::CreateQtPartControl( QWidget *parent ) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi( parent ); connect(m_Controls.pushButtonShowRandomTissue, SIGNAL(clicked()), this, SLOT(DoImageProcessing()) ); - connect(m_Controls.checkBoxGauss, SIGNAL(stateChanged(int)), this, SLOT(GaussBoxClicked())); + connect(m_Controls.checkBoxGauss, SIGNAL(stateChanged(int)), this, SLOT(ClickedGaussBox())); connect(m_Controls.pushButtonOpenPath, SIGNAL(clicked()), this, SLOT(OpenFolder()) ); connect(m_Controls.pushButtonOpenBinary, SIGNAL(clicked()), this, SLOT(OpenBinary()) ); connect(m_Controls.checkBoxGenerateBatch, SIGNAL(clicked()), this, SLOT(UpdateVisibilityOfBatchCreation()) ); connect(m_Controls.pushButtonAjustWavelength, SIGNAL(clicked()), this, SLOT(UpdateParametersAccordingToWavelength()) ); + connect(m_Controls.checkBoxRngSeed, SIGNAL(clicked()), this, SLOT(ClickedCheckboxFixedSeed()) ); m_Controls.spinboxSigma->setEnabled(false); m_Controls.labelSigma->setEnabled(false); m_Controls.label_NrrdFilePath->setText((std::string(getenv("HOME"))+"/").c_str()); m_PhotoacousticPropertyCalculator = mitk::PhotoacousticPropertyCalculator::New(); UpdateVisibilityOfBatchCreation(); + ClickedCheckboxFixedSeed(); + ClickedGaussBox(); +} + +void PASimulator::ClickedCheckboxFixedSeed() +{ + m_Controls.spinBoxRngSeed->setEnabled(m_Controls.checkBoxRngSeed->isChecked()); } void PASimulator::UpdateParametersAccordingToWavelength() { int wavelength = m_Controls.spinboxWavelength->value(); double bloodOxygenation = m_Controls.spinboxBloodOxygenSaturation->value()/100; mitk::PhotoacousticPropertyCalculator::Properties result = m_PhotoacousticPropertyCalculator->CalculatePropertyForSpecificWavelength( mitk::PhotoacousticPropertyCalculator::TissueType::BLOOD, wavelength, bloodOxygenation); m_Controls.spinboxMaxAbsorption->setValue(result.mua); m_Controls.spinboxMinAbsorption->setValue(result.mua); m_Controls.spinboxBloodVesselScattering->setValue(result.mus); m_Controls.spinboxBloodVesselAnisotropy->setValue(result.g); result = m_PhotoacousticPropertyCalculator->CalculatePropertyForSpecificWavelength( mitk::PhotoacousticPropertyCalculator::TissueType::EPIDERMIS, wavelength, bloodOxygenation); m_Controls.spinboxSkinAbsorption->setValue(result.mua); m_Controls.spinboxSkinScattering->setValue(result.mus); m_Controls.spinboxSkinAnisotropy->setValue(result.g); result = m_PhotoacousticPropertyCalculator->CalculatePropertyForSpecificWavelength( mitk::PhotoacousticPropertyCalculator::TissueType::FAT, wavelength, bloodOxygenation); m_Controls.spinboxFatAbsorption->setValue(result.mua); m_Controls.spinboxFatScattering->setValue(result.mus); m_Controls.spinboxFatAnisotropy->setValue(result.g); result = m_PhotoacousticPropertyCalculator->CalculatePropertyForSpecificWavelength( mitk::PhotoacousticPropertyCalculator::TissueType::STANDARD_TISSUE, wavelength, bloodOxygenation); m_Controls.spinboxBackgroundAbsorption->setValue(result.mua); m_Controls.spinboxBackgroundScattering->setValue(result.mus); m_Controls.spinboxBackgroundAnisotropy->setValue(result.g); } void PASimulator::UpdateVisibilityOfBatchCreation() { m_Controls.widgetBatchFile->setVisible(m_Controls.checkBoxGenerateBatch->isChecked()); } void PASimulator::DoImageProcessing() { if(m_Controls.checkBoxGenerateBatch->isChecked()) { if(m_Controls.labelBinarypath->text().isNull() || m_Controls.labelBinarypath->text().isEmpty()) { QMessageBox::warning(nullptr, QString("Warning"), QString("You need to specify the binary first!")); return; } } int numberOfVolumes = m_Controls.spinboxNumberVolumes->value(); if(numberOfVolumes<1) { QMessageBox::warning(nullptr, QString("Warning"), QString("You need to create at least one volume!")); return; } // Getting values from UI double maxAbsorption = m_Controls.spinboxMaxAbsorption->value(); double minAbsorption = m_Controls.spinboxMinAbsorption->value(); double maxBending= m_Controls.spinboxMaxBending->value(); double minBending = m_Controls.spinboxMinBending->value(); double maxRadius = m_Controls.spinboxMaxDiameter->value(); double minRadius = m_Controls.spinboxMinDiameter->value(); int maxVessels = m_Controls.spinboxMaxVessels->value(); int minVessels = m_Controls.spinboxMinVessels->value(); int xDim = m_Controls.spinboxXDim->value(); int yDim = m_Controls.spinboxYDim->value(); int zDim = m_Controls.spinboxZDim->value(); int mcflag = m_Controls.spinboxMcFlag->value(); int launchflag = m_Controls.spinboxLaunchFlag->value(); int boundaryflag = m_Controls.spinboxboundaryFlag->value(); double launchPointX = m_Controls.spinboxLaunchpointX->value(); double launchPointY = m_Controls.spinboxLaunchpointY->value(); double launchPointZ = m_Controls.spinboxLaunchpointZ->value(); double focusPointX = m_Controls.spinboxFocuspointX->value(); double focusPointY = m_Controls.spinboxFocuspointY->value(); double focusPointZ = m_Controls.spinboxFocuspointZ->value(); double trajectoryVectorX = m_Controls.spinboxTrajectoryVectorX->value(); double trajectoryVectorY = m_Controls.spinboxTrajectoryVectorY->value(); double trajectoryVectorZ = m_Controls.spinboxTrajectoryVectorZ->value(); double radius = m_Controls.spinboxRadius->value(); double waist = m_Controls.spinboxWaist->value(); double sigma = m_Controls.spinboxSigma->value(); bool doGauss = m_Controls.checkBoxGauss->isChecked(); double basicAbsorption = m_Controls.spinboxBackgroundAbsorption->value(); double basicScattering = m_Controls.spinboxBackgroundScattering->value(); double basicAnisotropy = m_Controls.spinboxBackgroundAnisotropy->value(); double airThickness = m_Controls.spinboxAirThickness->value(); double fatPercentage = m_Controls.spinboxFatPercentage->value(); double fatAbsorption = m_Controls.spinboxFatAbsorption->value(); double fatScattering = m_Controls.spinboxFatScattering->value(); double fatAnisotropy = m_Controls.spinboxFatAnisotropy->value(); double skinThickness = m_Controls.spinboxSkinThickness->value(); double skinAbsorption = m_Controls.spinboxSkinAbsorption->value(); double skinScattering = m_Controls.spinboxSkinScattering->value(); double skinAnisotropy = m_Controls.spinboxSkinAnisotropy->value(); bool randomizePhysicalProperties = m_Controls.checkBoxRandomizeParameters->isChecked(); double randomPercentage = m_Controls.spinboxRandomizeSigma->value(); double spacing = m_Controls.spinboxSpacing->value(); int bifurcationFrequency = m_Controls.spinboxBifurcationFrequency->value(); double vesselScattering = m_Controls.spinboxBloodVesselScattering->value(); double vesselAnisotropy = m_Controls.spinboxBloodVesselAnisotropy->value(); bool useRngSeed = m_Controls.checkBoxRngSeed->isChecked(); long rngSeed = m_Controls.spinBoxRngSeed->value(); for(int volumeIndex = 0; volumeIndex < numberOfVolumes; volumeIndex++) { MITK_DEBUG << "Generating in silico data"; mitk::PhotoacousticVolume::Pointer volume = mitk::PhotoacousticTissueGenerator::GenerateInSilicoData(xDim, yDim, zDim, spacing, basicAbsorption, basicScattering, basicAnisotropy, airThickness, skinAbsorption, skinScattering, skinAnisotropy, skinThickness, fatAbsorption, fatScattering, fatAnisotropy, fatPercentage, randomizePhysicalProperties, randomPercentage, minVessels, maxVessels, minBending, maxBending, minAbsorption, maxAbsorption, minRadius, maxRadius, mcflag, launchflag, boundaryflag, launchPointX, launchPointY, launchPointZ, focusPointX, focusPointY, focusPointZ, trajectoryVectorX, trajectoryVectorY, trajectoryVectorZ, radius, waist, sigma, doGauss, bifurcationFrequency, vesselScattering, vesselAnisotropy, useRngSeed, rngSeed, &mitk::PhotoacousticVesselMeanderStrategy::CalculateRandomlyDivergingPosition); MITK_DEBUG << "Generating mitk::Image"; mitk::Image::Pointer tissueVolume = volume->ConvertToMitkImage(); if(m_Controls.checkBoxGenerateBatch->isChecked()) { std::string volumeNumber = ""; if(volumeIndex<10) { volumeNumber = "00" + std::to_string(volumeIndex); } else if(volumeIndex<100) { volumeNumber = "0" + std::to_string(volumeIndex); } else { volumeNumber = std::to_string(volumeIndex); } std::string outputFolderName = m_Controls.label_NrrdFilePath->text().toStdString() + m_Controls.lineEditTissueName->text().toStdString() + volumeNumber; std::string savePath = outputFolderName + ".nrrd"; mitk::IOUtil::Save(tissueVolume, savePath); std::string filename = "executescript"; std::string filenameAllSimulation = "simulate_all"; #ifdef __linux__ mkdir(outputFolderName.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); filename += ".sh"; filenameAllSimulation += ".sh"; #else mkdir(outputFolderName.c_str()); filename += ".bat"; filenameAllSimulation += ".bat"; #endif std::ofstream file(outputFolderName+"/"+filename); if(file.is_open()) { for(double d = -1.8; d <=1.9; d+=0.12) { file << m_Controls.labelBinarypath->text().toStdString() << " -i " << savePath << " -o " << outputFolderName << "/" << m_Controls.lineEditTissueName->text().toStdString() << "_yo" << round(d*100) / 100 << ".nrrd" << " -yo " << round(d*100) / 100 << " -n " << (m_Controls.spinboxNumberPhotons->value()*1000L) << "\n"; } file.close(); } std::ofstream fileAllSimulation(m_Controls.label_NrrdFilePath->text().toStdString()+"/"+filenameAllSimulation, std::ios_base::app); if(fileAllSimulation.is_open()) { for(double d = -1.8; d <=1.9; d+=0.12) { fileAllSimulation << m_Controls.labelBinarypath->text().toStdString() << " -i " << savePath << " -o " << outputFolderName << "/" << m_Controls.lineEditTissueName->text().toStdString() << "_yo" << round(d*100) / 100 << ".nrrd" << " -yo " << round(d*100) / 100 << " -n " << (m_Controls.spinboxNumberPhotons->value()*1000L) << "\n"; } fileAllSimulation.close(); } } mitk::DataNode::Pointer dataNode = mitk::DataNode::New(); dataNode->SetData(tissueVolume); dataNode->SetName(m_Controls.lineEditTissueName->text().toStdString()); this->GetDataStorage()->Add(dataNode); mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); } MITK_DEBUG << "Handing stuff to UI Thread now.."; } -void PASimulator::GaussBoxClicked() +void PASimulator::ClickedGaussBox() { if(m_Controls.checkBoxGauss->isChecked()) { m_Controls.spinboxSigma->setEnabled(true); - m_Controls.labelSigma->setEnabled(true);void OpenBinary(); + m_Controls.labelSigma->setEnabled(true); } else { m_Controls.spinboxSigma->setEnabled(false); m_Controls.labelSigma->setEnabled(false); } - } void PASimulator::OpenFolder() { m_Controls.label_NrrdFilePath->setText(QFileDialog::getExistingDirectory().append("/")); } void PASimulator::OpenBinary() { m_Controls.labelBinarypath->setText(QFileDialog::getOpenFileName()); } diff --git a/Plugins/org.mitk.gui.qt.photoacousticsimulation/src/internal/PASimulator.h b/Plugins/org.mitk.gui.qt.photoacousticsimulation/src/internal/PASimulator.h index 7c17f2f629..3d8056f9ed 100644 --- a/Plugins/org.mitk.gui.qt.photoacousticsimulation/src/internal/PASimulator.h +++ b/Plugins/org.mitk.gui.qt.photoacousticsimulation/src/internal/PASimulator.h @@ -1,75 +1,76 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef PASimulator_h #define PASimulator_h #include #include #include "ui_PASimulatorControls.h" #include "mitkPhotoacousticTissueGenerator.h" #include "mitkPhotoacousticVolume.h" #include "mitkPhotoacousticPropertyCalculator.h" /** \brief PASimulator \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. \sa QmitkAbstractView \ingroup ${plugin_target}_internal */ class PASimulator : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: static const std::string VIEW_ID; protected slots: /// \brief Called when the user clicks the GUI button void DoImageProcessing(); - void GaussBoxClicked(); + void ClickedGaussBox(); + void ClickedCheckboxFixedSeed(); void OpenFolder(); void OpenBinary(); void UpdateVisibilityOfBatchCreation(); void UpdateParametersAccordingToWavelength(); protected: virtual void CreateQtPartControl(QWidget *parent) override; virtual void SetFocus() override; Ui::PASimulatorControls m_Controls; mitk::PhotoacousticPropertyCalculator::Pointer m_PhotoacousticPropertyCalculator; private: }; #endif // PASimulator_h diff --git a/Plugins/org.mitk.gui.qt.photoacousticsimulation/src/internal/PASimulatorControls.ui b/Plugins/org.mitk.gui.qt.photoacousticsimulation/src/internal/PASimulatorControls.ui index 5fe666390c..1c7ac5080e 100644 --- a/Plugins/org.mitk.gui.qt.photoacousticsimulation/src/internal/PASimulatorControls.ui +++ b/Plugins/org.mitk.gui.qt.photoacousticsimulation/src/internal/PASimulatorControls.ui @@ -1,2296 +1,2296 @@ PASimulatorControls 0 0 430 655 0 0 QmitkTemplate - 4 + 0 Generator 10 10 391 581 0 0 0 0 0 0 75 true Volume parameters Size x: 1 9999 70 y: 9999 100 z: 9999 70 voxels Qt::Horizontal 40 20 50 false Spacing: 2 0.010000000000000 0.060000000000000 cm Qt::Horizontal 40 20 Randomize physical parameters: true Qt::Horizontal 40 20 sigma: 0 100.000000000000000 0.010000000000000 2.000000000000000 % Partial volume effects true Qt::Horizontal 40 20 sigma: 10.000000000000000 0.100000000000000 1.000000000000000 voxels Custom RNG Seed: true Qt::Horizontal 40 20 999999999 258936 Generate batch file output: false Tissue name: PhotoacousticTissue Number of volumes to generate: 1 9999999 1 Qt::Horizontal 40 20 Save generated tissue path: 0 0 50 0 50 16777215 open Path to MitkMcxyz binary: 0 0 50 0 50 16777215 open Number of Photons (x1000): 0 999999999 1 100000 Generate Tissue Qt::Vertical 20 40 Tissue 10 10 391 581 0 0 0 0 0 0 0 0 11 75 true Air Thickness 0.100000000000000 1.800000000000000 mm Qt::Horizontal 40 20 75 true Background tissue Absorption coefficient: 0.100000000000000 0.100000000000000 per cm Qt::Horizontal 40 20 Scattering coefficient: 1000.000000000000000 15.000000000000000 per cm Qt::Horizontal 40 20 Anisotropy facor: 1.000000000000000 0.010000000000000 0.900000000000000 Qt::Horizontal 40 20 75 true Skin Thickness 0.100000000000000 0.400000000000000 mm Qt::Horizontal 40 20 Absorption coefficient: 0.100000000000000 3.000000000000000 per cm Qt::Horizontal 40 20 Scattering coefficient: 1000.000000000000000 20.000000000000000 per cm Qt::Horizontal 40 20 Anisotropy facor: 1.000000000000000 0.010000000000000 0.900000000000000 Qt::Horizontal 40 20 75 true Fat Body fat percentage 0 0.100000000000000 10.000000000000000 % Qt::Horizontal 40 20 Absorption coefficient: 0.100000000000000 0.200000000000000 per cm Qt::Horizontal 40 20 Scattering coefficient: 1000.000000000000000 18.000000000000000 per cm Qt::Horizontal 40 20 Anisotropy facor: 1.000000000000000 0.010000000000000 0.900000000000000 Qt::Horizontal 40 20 Qt::Vertical 20 40 Vessels 10 10 391 581 0 0 0 0 75 true Vessel Parameters Count 1 1 to 7 Vessels Qt::Horizontal 40 20 Diameter 0.600000000000000 to 5.000000000000000 mm Qt::Horizontal 40 20 Absorbtion 2.000000000000000 to 10.000000000000000 per cm Qt::Horizontal 40 20 Curvedness 5.000000000000000 0.100000000000000 to 5.000000000000000 0.010000000000000 1.000000000000000 Curving Units Qt::Horizontal 40 20 Bifurcation frequency 0 1.000000000000000 100000.000000000000000 1.000000000000000 50.000000000000000 voxel until bifurcation Qt::Horizontal 40 20 Scattering coefficient 2 0.000000000000000 1000.000000000000000 1.000000000000000 15.000000000000000 per cm Qt::Horizontal 40 20 Anisotropy factor 2 0.000000000000000 1.000000000000000 0.100000000000000 0.900000000000000 Qt::Horizontal 40 20 Qt::Vertical 20 40 Monte Carlo 10 10 391 581 0 0 0 0 0 0 75 true Monte Carlo Parameters mcflag: 1 4 Qt::Horizontal 40 20 launchflag: 0 0 Qt::Horizontal 40 20 boundaryflag: 1 2 Qt::Horizontal 40 20 75 true Initial launch point: x 3 5.000000000000000 0.000000000000000 y 3 10.000000000000000 0.000000000000000 z 3 10.000000000000000 0.000000000000000 Qt::Horizontal 40 20 75 true Focus point: x 4 1000000.000000000000000 0.000000000000000 y 4 1000000.000000000000000 0.000000000000000 z 4 1000000.000000000000000 0.000000000000000 Qt::Horizontal 40 20 75 true Trajectory vector: x 4 1000000.000000000000000 0.000000000000000 y 4 1000000.000000000000000 0.342000000000000 z 4 1000000.000000000000000 0.939700000000000 Qt::Horizontal 40 20 radius: 4 1000.000000000000000 0.500000000000000 Qt::Horizontal 40 20 waist: 4 1000.000000000000000 0.010000000000000 Qt::Horizontal 40 20 Qt::Vertical 20 40 Wavelength 10 10 391 581 0 0 0 0 0 0 75 true Adjust physical properties by wavelength false 16777215 150 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This widget enables the adjustment of the physical properties of the tissue according to a selected wavelength of the light and the oxygen saturation of the blood.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The algorithm and measurements were provided by the publication <span style=" font-weight:600;">Optical properties of biological tissues: a review </span>by Steve L. Jacques.</p></body></html> Wavelength: 0 300.000000000000000 1000.000000000000000 650.000000000000000 Qt::Horizontal 40 20 Vessel oxygen saturation: 0 100.000000000000000 75.000000000000000 % Qt::Horizontal 40 20 Adjust tissue properties Qt::Vertical 20 40