rexcardan / Evil-DICOM

A C# DICOM Library
171 stars 98 forks source link

Floating Point Single - Private element #27

Closed phillipgsmith closed 9 years ago

phillipgsmith commented 9 years ago

I may not be doing something right but I have tried everything I can think of. I have a file that has a private element that is an array of floating point single (VR = FL)

If I do this, I get the expected number "count" of items but of course the type is incorrect. var valTest1 = dcm.FindAll("30091047");

I thought this should do the trick but the "count" of items is still what is expected but they are all null. var valTest2 = dcm.FindAll("30091047").Select(d => d as FloatingPointSingle).ToList();

I also tried this and both work as expected.

var valTest3 = dcm.FindAll(TagHelper.SCAN_SPOT_METERSETS_DELIVERED); var valTest4 = dcm.FindAll(TagHelper.SCAN_SPOT_METERSETS_DELIVERED).Select(d => d as FloatingPointSingle).ToList();

Any suggestions?

rexcardan commented 9 years ago

The difference is that if the tag is not in the tag dictionary, the library does not know how to interpret the data. It stores it as an Unknown VR type. What I should add is a method of the Unknown VR type that does something like :

var success = UnknownVR.TryAs<>(out fpsValue);

In the meantime, you can use the data parser to get the data. Unknown VR types just store the raw bytes of the data along with the tag, so you could use:

var vals= dcm.FindAll("30091047") .Select(d => d as Unknown) .Select(u=> new FloatingPointSingle(u.Tag, LittleEndianReader.ReadSinglePrecision(u.Data)); .ToList();

phillipgsmith commented 9 years ago

I tried what you suggested (several different ways actually...)

            var vals = dcm.FindAll("30091047")
                          .Select(d => d as Unknown)
                          .Select(u=> new FloatingPointSingle(u.Tag, LittleEndianReader.ReadSinglePrecision(u.Data))
                          .ToList());

It shows: u.Data shows - Argument type "System.Collections.Generic.List" is not assignable to parameter type byte[]

And also .ToList is not available. I thought that you may have meant _DData.

phillipgsmith commented 9 years ago

I wish I could specify a VR on the call to FindAll or somehow add my private elements which I assume I could do but I would have to rebuild the library.

rexcardan commented 9 years ago

I'm sorry. I should have tested my code before posting here. This works for me.

        var found = dcm.FindAll("30091047")
            .Select(f => f as Unknown)
            .Select(u=>new FloatingPointSingle(u.Tag, LittleEndianReader.ReadSinglePrecision(u.Data_.ToArray())))
            .ToList();

Here is the full test:

        var dcm = new DICOMObject();
        var fs = new FloatingPointSingle(new Tag("30091047"), 25.0f);
        dcm.Add(fs);
        dcm.Write("test.dcm", new EvilDICOM.Core.IO.Writing.DICOMWriteSettings() { TransferSyntax = EvilDICOM.Core.Enums.TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN });

        dcm = DICOMObject.Read("test.dcm");
        var found = dcm.FindAll("30091047")
            .Select(f => f as Unknown)
            .Select(u=>new FloatingPointSingle(u.Tag, LittleEndianReader.ReadSinglePrecision(u.Data_.ToArray())))
            .ToList();

        Assert.IsTrue(found.First() is FloatingPointSingle);
phillipgsmith commented 9 years ago

That did the trick. Thanks so much.