From 51f9d97feae4f66313ae473f211329bfcd51e1d9 Mon Sep 17 00:00:00 2001 From: Anna Ilina Date: Tue, 24 Oct 2017 14:00:39 -0400 Subject: [PATCH] ENH: Added option to set scaling factor for image intensity for 3ddose file reader https://github.com/SlicerRt/SlicerRT/issues/73 --- ...tkSlicerDosxyzNrc3dDoseFileReaderLogic.cxx | 29 ++++++------------- .../vtkSlicerDosxyzNrc3dDoseFileReaderLogic.h | 2 +- ...rDosxyzNrc3dDoseFileReaderOptionsWidget.ui | 19 ++++++++++-- ...DosxyzNrc3dDoseFileReaderOptionsWidget.cxx | 21 ++++++++++---- ...qSlicerDosxyzNrc3dDoseFileReaderPlugin.cxx | 4 +-- 5 files changed, 44 insertions(+), 31 deletions(-) diff --git a/DosxyzNrc3dDoseFileReader/Logic/vtkSlicerDosxyzNrc3dDoseFileReaderLogic.cxx b/DosxyzNrc3dDoseFileReader/Logic/vtkSlicerDosxyzNrc3dDoseFileReaderLogic.cxx index 3534ee064..2329f22d5 100644 --- a/DosxyzNrc3dDoseFileReader/Logic/vtkSlicerDosxyzNrc3dDoseFileReaderLogic.cxx +++ b/DosxyzNrc3dDoseFileReader/Logic/vtkSlicerDosxyzNrc3dDoseFileReaderLogic.cxx @@ -58,50 +58,41 @@ vtkSlicerDosxyzNrc3dDoseFileReaderLogic::~vtkSlicerDosxyzNrc3dDoseFileReaderLogi { } - - +//---------------------------------------------------------------------------- bool vtkSlicerDosxyzNrc3dDoseFileReaderLogic::AreEqualWithTolerance(double a, double b) { return fabs(a - b) < MAX_TOLERANCE_SPACING; } - - //---------------------------------------------------------------------------- void vtkSlicerDosxyzNrc3dDoseFileReaderLogic::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); } -// - //---------------------------------------------------------------------------- -void vtkSlicerDosxyzNrc3dDoseFileReaderLogic::LoadDosxyzNrc3dDoseFile(char* filename) +void vtkSlicerDosxyzNrc3dDoseFileReaderLogic::LoadDosxyzNrc3dDoseFile(char* filename, float intensityScalingFactor/*=1.0*/) { - ifstream readFileStream(filename); //todo test that this doesn't crash when filename is null - - if (!readFileStream){ - vtkErrorMacro("LoadDosxyzNrc3dDoseFile: The specified file could not be opened."); - return; + if (!readFileStream) + { + vtkErrorMacro("LoadDosxyzNrc3dDoseFile: The specified file could not be opened."); + return; } int size[3] = { 0, 0, 0 }; double spacing[3] = { 0, 0, 0 }; double origin[3] = { 0, 0, 0 }; - std::string title = ""; // read in block 1 (number of voxels in x, y, z directions) readFileStream >> size[0] >> size[1] >> size[2]; int numTotalVoxels = size[0] * size[1] * size[2]; - if (size[0] <= 0 || size[1] <= 0 || size[2] <= 0) { vtkErrorMacro("LoadDosxyzNrc3dDoseFile: Number of voxels in X, Y, or Z direction must be greater than zero." << "numVoxelsX " << size[0] << ", numVoxelsY " << size[1] << ", numVoxelsZ " << size[2]); return; } - std::vector voxelBoundariesX(size[0] + 1); std::vector voxelBoundariesY(size[1] + 1); @@ -135,7 +126,6 @@ void vtkSlicerDosxyzNrc3dDoseFileReaderLogic::LoadDosxyzNrc3dDoseFile(char* file counter += 1; } - // read in block 3 (voxel boundaries, cm, in y direction) counter = 0; while (!readFileStream.eof() && counter < size[1] + 1) @@ -183,6 +173,8 @@ void vtkSlicerDosxyzNrc3dDoseFileReaderLogic::LoadDosxyzNrc3dDoseFile(char* file floatDosxyzNrc3dDoseVolumeData->SetExtent(0, size[0] - 1, 0, size[1] - 1, 0, size[2] - 1); floatDosxyzNrc3dDoseVolumeData->AllocateScalars(VTK_FLOAT, 1); + //todo: When loading .3ddose file from python, it is intensityScalarFactor set to 0 + float* floatPtr = (float*)floatDosxyzNrc3dDoseVolumeData->GetScalarPointer(); float currentValue = 0.0; for (long z = 0; z < size[2]; z++) @@ -196,13 +188,13 @@ void vtkSlicerDosxyzNrc3dDoseFileReaderLogic::LoadDosxyzNrc3dDoseFile(char* file vtkErrorMacro("LoadDosxyzNrc3dDoseFile: The end of file was reached earlier than specified."); } readFileStream >> currentValue; + currentValue = currentValue * intensityScalingFactor; (*floatPtr) = currentValue; ++floatPtr; } } } - // create volume node for dose values vtkSmartPointer dosxyzNrc3dDoseVolumeNode = vtkSmartPointer::New(); dosxyzNrc3dDoseVolumeNode->SetScene(this->GetMRMLScene()); @@ -230,12 +222,9 @@ void vtkSlicerDosxyzNrc3dDoseFileReaderLogic::LoadDosxyzNrc3dDoseFile(char* file dosxyzNrc3dDoseVolumeDisplayNode->SetAndObserveColorNodeID("vtkMRMLColorTableNodeGrey"); dosxyzNrc3dDoseVolumeNode->SetAndObserveDisplayNodeID(dosxyzNrc3dDoseVolumeDisplayNode->GetID()); - //todo: read in block 6 (error values array; relative errors) //todo: read error values in another volume node //todo: do I also need voxelCenters? readFileStream.close(); } - - diff --git a/DosxyzNrc3dDoseFileReader/Logic/vtkSlicerDosxyzNrc3dDoseFileReaderLogic.h b/DosxyzNrc3dDoseFileReader/Logic/vtkSlicerDosxyzNrc3dDoseFileReaderLogic.h index 729f1f67c..2bd667ab1 100644 --- a/DosxyzNrc3dDoseFileReader/Logic/vtkSlicerDosxyzNrc3dDoseFileReaderLogic.h +++ b/DosxyzNrc3dDoseFileReader/Logic/vtkSlicerDosxyzNrc3dDoseFileReaderLogic.h @@ -48,7 +48,7 @@ class VTK_SLICER_DOSXYZNRC3DDOSEFILEREADER_LOGIC_EXPORT vtkSlicerDosxyzNrc3dDose /// Load DosxyzNrc3dDose volume from file /// \param filename Path and filename of the DosxyzNrc3dDose file - void LoadDosxyzNrc3dDoseFile(char* filename); + void LoadDosxyzNrc3dDoseFile(char* filename, float intensityScalingFactor=1.0); /// Determine if two numbers are equal within a small tolerance (0.001) static bool AreEqualWithTolerance(double a, double b); diff --git a/DosxyzNrc3dDoseFileReader/Resources/UI/qSlicerDosxyzNrc3dDoseFileReaderOptionsWidget.ui b/DosxyzNrc3dDoseFileReader/Resources/UI/qSlicerDosxyzNrc3dDoseFileReaderOptionsWidget.ui index 3713c4030..89896306c 100644 --- a/DosxyzNrc3dDoseFileReader/Resources/UI/qSlicerDosxyzNrc3dDoseFileReaderOptionsWidget.ui +++ b/DosxyzNrc3dDoseFileReader/Resources/UI/qSlicerDosxyzNrc3dDoseFileReaderOptionsWidget.ui @@ -11,16 +11,29 @@ - Volume Options + DosxyzNrc3dDoseFileReader Options 0 - + + + Scaling factor applied on the dose values + + + Scaling factor: + + + + + + + + - Use Image Intensity Scale and Image Intensity Offset + 1.0 diff --git a/DosxyzNrc3dDoseFileReader/qSlicerDosxyzNrc3dDoseFileReaderOptionsWidget.cxx b/DosxyzNrc3dDoseFileReader/qSlicerDosxyzNrc3dDoseFileReaderOptionsWidget.cxx index 626809435..d92317362 100644 --- a/DosxyzNrc3dDoseFileReader/qSlicerDosxyzNrc3dDoseFileReaderOptionsWidget.cxx +++ b/DosxyzNrc3dDoseFileReader/qSlicerDosxyzNrc3dDoseFileReaderOptionsWidget.cxx @@ -20,6 +20,7 @@ /// Qt includes #include +#include // CTK includes #include @@ -48,11 +49,13 @@ qSlicerDosxyzNrc3dDoseFileReaderOptionsWidget::qSlicerDosxyzNrc3dDoseFileReaderO ctkFlowLayout::replaceLayout(this); - connect(d->UseImageIntensityScaleAndOffsetCheckBox, SIGNAL(toggled(bool)), - this, SLOT(updateProperties())); + connect(d->ScalingFactorLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateProperties())); + + // Image instensity scaling factor is 1.0 by default + float defaultScalingFactorValue = 1.0; + QString defaultScalingFactorString = QString::number(defaultScalingFactorValue); + d->ScalingFactorLineEdit->setText(defaultScalingFactorString); - // Image intensity scale and offset turned off by default - d->UseImageIntensityScaleAndOffsetCheckBox->setChecked(false); } //----------------------------------------------------------------------------- @@ -65,5 +68,13 @@ void qSlicerDosxyzNrc3dDoseFileReaderOptionsWidget::updateProperties() { Q_D(qSlicerDosxyzNrc3dDoseFileReaderOptionsWidget); - d->Properties["imageIntensityScaleAndOffset"] = d->UseImageIntensityScaleAndOffsetCheckBox->isChecked(); + bool ok = false; + float scalingFactor = d->ScalingFactorLineEdit->text().toFloat(&ok); + if (ok == false) + { + qCritical() << Q_FUNC_INFO << ": Unable to parse scaling factor parameter " << d->ScalingFactorLineEdit->text() << ". Using default value 1.0"; + scalingFactor = 1.0; + } + + d->Properties["scalingFactor"] = scalingFactor; } diff --git a/DosxyzNrc3dDoseFileReader/qSlicerDosxyzNrc3dDoseFileReaderPlugin.cxx b/DosxyzNrc3dDoseFileReader/qSlicerDosxyzNrc3dDoseFileReaderPlugin.cxx index ae886d441..7276dea3c 100644 --- a/DosxyzNrc3dDoseFileReader/qSlicerDosxyzNrc3dDoseFileReaderPlugin.cxx +++ b/DosxyzNrc3dDoseFileReader/qSlicerDosxyzNrc3dDoseFileReaderPlugin.cxx @@ -103,8 +103,8 @@ bool qSlicerDosxyzNrc3dDoseFileReaderPlugin::load(const IOProperties& properties QString fileName = properties["fileName"].toString(); Q_ASSERT(d->Logic); - bool useImageIntensityScaleAndOffsetFromFile = properties["imageIntensityScaleAndOffset"].toBool(); - d->Logic->LoadDosxyzNrc3dDoseFile(fileName.toLatin1().data()); + float intensityScalingFactor = properties["scalingFactor"].toFloat(); + d->Logic->LoadDosxyzNrc3dDoseFile(fileName.toLatin1().data(), intensityScalingFactor); this->setLoadedNodes(QStringList());