# HG changeset patch # User Benjamin Golinvaux # Date 1573219535 -3600 # Node ID 7681f39437487cef1c48cc3b82f3b759fdb5d102 # Parent 45df56448b2ac681ee865593395d8d398b0cc5fb Changed handling of DoseGridScaling: before this commit, rescaleSlope was set to the DoseGridScaling value if rescale* tags weren't present AND in the case of a dose. This caused issues in dose files where all three tags (DoseGridScaling, RescaleSlope and RescaleIntercept) were present, which previously led to the DoseGridScaling tag to be ignored. Now, the rescale* tags are *ignored* in dose files and DoseGridScaling is always taken into account. diff -r 45df56448b2a -r 7681f3943748 Framework/Toolbox/DicomInstanceParameters.cpp --- a/Framework/Toolbox/DicomInstanceParameters.cpp Tue Nov 05 18:26:59 2019 +0100 +++ b/Framework/Toolbox/DicomInstanceParameters.cpp Fri Nov 08 14:25:35 2019 +0100 @@ -115,33 +115,50 @@ if (!dicom.LookupStringValue(doseUnits_, DICOM_TAG_DOSE_UNITS, false)) { - LOG(WARNING) << "Tag DoseUnits (0x3004, 0x0002) is missing in " << sopInstanceUid_; + LOG(ERROR) << "Tag DoseUnits (0x3004, 0x0002) is missing in " << sopInstanceUid_; doseUnits_ = ""; } - } isColor_ = (imageInformation_.GetPhotometricInterpretation() != Orthanc::PhotometricInterpretation_Monochrome1 && imageInformation_.GetPhotometricInterpretation() != Orthanc::PhotometricInterpretation_Monochrome2); - double doseGridScaling; - if (dicom.ParseDouble(rescaleIntercept_, Orthanc::DICOM_TAG_RESCALE_INTERCEPT) && dicom.ParseDouble(rescaleSlope_, Orthanc::DICOM_TAG_RESCALE_SLOPE)) { - hasRescale_ = true; - } - else if (dicom.ParseDouble(doseGridScaling, Orthanc::DICOM_TAG_DOSE_GRID_SCALING)) - { - hasRescale_ = true; - rescaleIntercept_ = 0; - rescaleSlope_ = doseGridScaling; + if (sopClassUid_ == SopClassUid_RTDose) + { + LOG(INFO) << "DOSE HAS Rescale*: rescaleIntercept_ = " << rescaleIntercept_ << " rescaleSlope_ = " << rescaleSlope_; + // WE SHOULD NOT TAKE THE RESCALE VALUE INTO ACCOUNT IN THE CASE OF DOSES + hasRescale_ = false; + } + else + { + hasRescale_ = true; + } + } else { hasRescale_ = false; } + if (dicom.ParseDouble(doseGridScaling_, Orthanc::DICOM_TAG_DOSE_GRID_SCALING)) + { + if (sopClassUid_ == SopClassUid_RTDose) + { + LOG(INFO) << "DOSE HAS DoseGridScaling: doseGridScaling_ = " << doseGridScaling_; + } + } + else + { + doseGridScaling_ = 1.0; + if (sopClassUid_ == SopClassUid_RTDose) + { + LOG(ERROR) << "Tag DoseGridScaling (0x3004, 0x000e) is missing in " << sopInstanceUid_ << " doseGridScaling_ will be set to 1.0"; + } + } + Vector c, w; if (LinearAlgebra::ParseVector(c, dicom, Orthanc::DICOM_TAG_WINDOW_CENTER) && LinearAlgebra::ParseVector(w, dicom, Orthanc::DICOM_TAG_WINDOW_WIDTH) && @@ -155,6 +172,8 @@ else { hasDefaultWindowing_ = false; + defaultWindowingCenter_ = 0; + defaultWindowingWidth_ = 0; } if (sopClassUid_ == SopClassUid_RTDose) @@ -245,16 +264,25 @@ } - void DicomInstanceParameters::Data::ApplyRescale(Orthanc::ImageAccessor& image, + void DicomInstanceParameters::Data::ApplyRescaleAndDoseScaling(Orthanc::ImageAccessor& image, bool useDouble) const { if (image.GetFormat() != Orthanc::PixelFormat_Float32) { throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); } - + + double factor = doseGridScaling_; + double offset = 0.0; + if (hasRescale_) { + factor *= rescaleSlope_; + offset = rescaleIntercept_; + } + + if ( (factor != 1.0) || (offset != 0.0) ) + { const unsigned int width = image.GetWidth(); const unsigned int height = image.GetHeight(); @@ -268,7 +296,7 @@ for (unsigned int x = 0; x < width; x++, p++) { double value = static_cast(*p); - *p = static_cast(value * rescaleSlope_ + rescaleIntercept_); + *p = static_cast(value * factor + offset); } } else @@ -276,7 +304,7 @@ // Fast, approximate implementation using float for (unsigned int x = 0; x < width; x++, p++) { - *p = (*p) * static_cast(rescaleSlope_) + static_cast(rescaleIntercept_); + *p = (*p) * static_cast(factor) + static_cast(offset); } } } @@ -348,8 +376,8 @@ Orthanc::ImageProcessing::Convert(*converted, pixelData); // Correct rescale slope/intercept if need be - //data_.ApplyRescale(*converted, (pixelData.GetFormat() == Orthanc::PixelFormat_Grayscale32)); - data_.ApplyRescale(*converted, false); + //data_.ApplyRescaleAndDoseScaling(*converted, (pixelData.GetFormat() == Orthanc::PixelFormat_Grayscale32)); + data_.ApplyRescaleAndDoseScaling(*converted, false); return converted.release(); } diff -r 45df56448b2a -r 7681f3943748 Framework/Toolbox/DicomInstanceParameters.h --- a/Framework/Toolbox/DicomInstanceParameters.h Tue Nov 05 18:26:59 2019 +0100 +++ b/Framework/Toolbox/DicomInstanceParameters.h Fri Nov 08 14:25:35 2019 +0100 @@ -60,6 +60,7 @@ bool hasIndexInSeries_; unsigned int indexInSeries_; std::string doseUnits_; + double doseGridScaling_; void ComputeDoseOffsets(const Orthanc::DicomMap& dicom); @@ -70,8 +71,8 @@ bool IsPlaneWithinSlice(unsigned int frame, const CoordinateSystem3D& plane) const; - void ApplyRescale(Orthanc::ImageAccessor& image, - bool useDouble) const; + void ApplyRescaleAndDoseScaling( + Orthanc::ImageAccessor& image, bool useDouble) const; }; @@ -205,5 +206,10 @@ { return data_.doseUnits_; } + + double GetDoseGridScaling() const + { + return data_.doseGridScaling_; + } }; }