Evil-DICOM icon indicating copy to clipboard operation
Evil-DICOM copied to clipboard

Unable to read Primary Fluence Mode Sequence

Open Malorh opened this issue 3 years ago • 0 comments

I need to look up if a treatment beam is a flattening filter free beam. This information is stored in the "primary fluence mode sequence" (tag 3285,1000) (see ftp://medical.nema.org/medical/dicom/final/cp805_ft.pdf when this was added to DICOM in 2008). However, EvilDICOM (v. 2.0.6.5; the most recent version) has all the following variables empty (tested using the DICOMObject and DICOMSelector): PrimaryFluenceModeSequence_ FluenceModeID_ (and the variables without the underscore are unsurprisingly null, since they point to the first element in the lists).

Very notably, the DICOMObject can detect the tag (3285,1000) as unknown. It is registered under items in BeamSequence (300A,00B0).

I have tested this using DICOM RT plan files from two different institutions. Therefore, I think it less likely that I'm using a corrupt file. Third party software "DicomEdit" can detect the dicom tag and data like any other tag. It shows the following subitems (VR = value representation) with example values for my file

Tag VR Description Value
(3285,0010) LO Varian Medical Systems VISION 3285 Varian Medical Systems VISION 3285
(3285,1001) CS Fluence Mode NON_STANDARD
(3285,1002) SH Fluence Mode ID FFF

Note that the Fluence Mode ID only exists if the Fluence mode is NON_STANDARD (see the link above to the DICOM source) (though I don't know why it specifies (3002,0051) as the tag number for Fluence Mode).

Should other people come across the issue for their research before an update is released, know that you can parse the hex data to string and then scan the string to see if it contains the desired data (e.g. STANDARD, NON_STANDARD, FFF). Although this is obviously suboptimal, it is better than nothing. Example code:

DICOMObject dcm = DICOMObject.Read(file); // "file" is a string with value as the path to my file (RP*.dcm)
var primaryFluenceModeSequence = dcm.FindAll("32851000");
// @other people reading this on github; remember to here check if the sequence exist and handle accordingly. For my needs, this is "if (primaryFluenceModeSequence.Count == 0) return false;" here, though yours may differ, obviously.
int nFluenceBytes = primaryFluenceModeSequence[iBeam].DData_.Count;
byte[] fluenceBytes = new byte[nFluenceBytes];
for (int iByte = 0; iByte < nFluenceBytes; iByte++)
{
	fluenceBytes[iByte] = (byte)primaryFluenceModeSequence[iBeam].DData_[iByte];
}
string fluenceAsString = System.Text.Encoding.ASCII.GetString(fluenceBytes);
bool isFffBeam;
if (fluenceAsString.Contains("NON_STANDARD") && fluenceAsString.Contains("FFF")) isFffBeam = true;
else isFffBeam = false;

PS: Thanks a lot for EvilDICOM. It has saved me a lot of time!

Malorh avatar Jan 05 '21 10:01 Malorh