Giter Site home page Giter Site logo

pet-rd-tools's Introduction

pet-rd-tools

Build Status Codacy Badge DOI

Command line tools for PET-MR (pre)-processing.

Tools for validating and extracting raw PET data, and associated files, for the purposes of image reconstruction via STIR and SIRF. Currently these tools are mainly for the Siemens mMR system and GE Signa PET/MR, although other GE PET/CT scanners should work as well.

Requirements for building


Running the applications

nm_validate

The purpose of nm_validate is to confirm if a raw data file (or file pair) contains all the expected data.

WARNING: This currently only performs additional checks on Siemens mMR data. For GE data, there are no checks on the content of the RDF.

Usage:

nm_validate -i <DICOM file>

Example output for a valid list mode file:

I1205 17:15:37.418709 3333379008 NMValidate.cpp:99] Started: Tue Dec  5 17:15:37 2017
I1205 17:15:37.419257 3333379008 NMValidate.cpp:100] Running 'nm_validate' version: 0.1.0
I1205 17:15:39.136943 3333379008 Common.hpp:89] Manufacturer: SIEMENS 
I1205 17:15:39.136970 3333379008 Common.hpp:97] Model name: Biograph_mMR
I1205 17:15:39.136979 3333379008 Common.hpp:105] Image type: ORIGINAL\PRIMARY\PET_LISTMODE 
I1205 17:15:41.942068 3333379008 MMR.hpp:399] Expected number of LM words: 74308087
I1205 17:15:41.942098 3333379008 MMR.hpp:406] 297232348 bytes in LM field
I1205 17:15:41.942103 3333379008 MMR.hpp:410] 297232348 / 4 = 74308087 words
I1205 17:15:41.942114 3333379008 NMValidate.cpp:134] File appears to be VALID
I1205 17:15:41.942119 3333379008 NMValidate.cpp:139] Time taken: 4 seconds
I1205 17:15:41.942123 3333379008 NMValidate.cpp:140] Ended: Tue Dec  5 17:15:41 2017

nm_validate will check list mode, sinogram and normalisation (norm) files. The size of the anticipated raw data is checked, but not the actual contents. Due to compression of the sinogram data, only the existence of files are tested.

nm_extract

Raw PET data from the mMR scanner can be in one of two forms: a single DICOM file or a pair of files (one DICOM header and a raw binary file). nm_extract reads the DICOM data and extracts the Interfile header and the raw data for either of the two forms. Once extracted, the Interfile header can be used for image reconstruction with STIR.

GE PET scanners also store the raw data in a single DICOM file. nm_extract reads this file and extracts the GE RDF (Raw Data Format) file. This can then be used in STIR.

Usage:

nm_extract -i <DICOM file> [-o <OUTPUTDIR> -p <PREFIX> --noupdate ]

where <DICOM file> is the input file for extraction, <OUTPUTDIR> is the target output directory and <PREFIX> is the desired filename prefix for the output files. If the <OUTPUTDIR> does not exist, nm_validate will attempt to create it. If <OUTPUTDIR> is not specified, the output will be written to the same directory as the input.

For Siemens data, --noupdate will extract the raw Interfile without modification (mainly for debugging). For GE data, this option is ignored.

Output extensions

Siemens data:

  • List mode files will be extracted with .l extensions for the list mode data and .l.hdr for the associated Interfile header.
  • Sinograms files will have the extension .s for the sinogram data and .s.hdr for the associated Interfile header.
  • Normalisation files will be extracted with .n and .n.hdr extensions.

GE data:

  • List mode files will be extracted with .BLF extension.
  • Sinogram files will have .sino.rdf extension.
  • Norm and geometric norm files will have .norm.rdf and .geo.rdf extensions.

nm_mrac2mu

nm_mrac2mu extracts the patient mu-map from mMR MRAC DICOM data, scales to linear attenuation coefficients (LACs) and reslices into a full-size matrix (344 x 344 x 127) for PET reconstruction. The mu-map is oriented in LPS.

Usage:

nm_mrac2mu -i <DICOMDIR> -o <OUTPUT file> [--orient <ORIENTATION> --head]

where <DICOMDIR> is the path to the MRAC DICOM folder and <OUTPUT file> is the destination file. <ORIENTATION> is the desired coordinate orientation (default 'RAI'). The switch --head will generate a mu-map in 344x344x127 matrix and is currently hard-coded for the mMR brain MRAC.

Output extensions

  • The output file type is determined by the extension of the destination file. To produce a compressed NiFTi file, specify the extension .nii.gz e.g. myoutput.nii.gz.
  • If the extension .hv is given, an Interfile header is generated in addition to the volume.

nm_signa2mu

nm_signa2mu extracts the patient mu-map from the GE Signa mMR DICOM data, scales to linear attenuation coefficients (LACs) and writes to an output file.

Usage:

nm_signa2mu -i <DICOMDIR> -o <OUTPUT file> [--orient <ORIENTATION>]

where <DICOMDIR> is the path to the MRAC DICOM folder and <OUTPUT file> is the destination file. <ORIENTATION> is the desired coordinate orientation (default 'RAI').

Output extensions

  • The output file type is determined by the extension of the destination file. To produce a compressed NiFTi file, specify the extension .nii.gz e.g. myoutput.nii.gz.
  • If the extension .hv is given, an Interfile header is generated in addition to the volume.

pet-rd-tools's People

Contributors

ashgillman avatar bathomas avatar codacy-badger avatar kristhielemans avatar rijobro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

pet-rd-tools's Issues

nm_extract error creating listmode header

For certain files, nm_extract works fine, but for some others I've had a problem (although we're not sure if it's pet-rd-tools or something else (e.g., gdcm).

In nmtools/MMR.hpp, the DICOM tag (0x029, 0x1010) is initially used. If the returned string does not contain SV10, (0x029, 0x1110) is used instead.

However, for some images, the following line (in Common.hpp):

inStream << std::fixed << element.GetValue();

returns the length of the string instead of the string itself. This then causes problems.

For these images, we can manually change the code to look straight for (0x029, 0x1110), skipping out (0x029, 0x1010) altogether.

Sorry if this message is a bit cryptic, I can probably explain it better in person. @KrisThielemans helped with the debugging.

Installation problems

I've some problems, when I run make in the pet-rd-tools-master (see error_file.txt). Can anyone help me with some infos about the installation? I've installed all requirements.
error_file.txt

How to compile?

A very basic question, is there any instruction to compile this software?

add tests

our current Travis tests just check if everything builds. There are no run-time tests.

For this, we need to grab data from somewhere (which includes DCM).

Hard-coded reslice parameters

Hi,

It seems that not all MRAC acqusitions are made in the same resolution and size, and so some parameters in MRAC.hpp may not generalise.

I see resliceDefaultParams are defined as a JSON array, perhaps this could be specified as input?

sx, sy and sz aren't used from the params, rather calculated. Maybe they should only be calculated if not supplied in the params?

The xy padding of 100 and z cropping of (11,10) also seem to be tied to a specific acquisition, however I'm not sure of the best way to calculate appropriate values. Perhaps these operations are not actually required?

Cheers,
Ash

--head Resampled image is misaligned with NAC.

Hi,

I have run a STIR non-attenuation corrected reconstruction on my data, and compared the output with nm_mrac2mu's umap output. It is misaligned in the y direction. Any suggestions/speculations as to what might be causing this?

Cheers,
Ash

NB: If you click the images they will open in a new tab and you can cycle.
Look between the UTE and the NAC, since they are a similar scale the silly colorbar won't make the image move.

410141_umap hv
410141_ute2 hv
nac_sirf_s21i30_30 hv

Findglog.cmake

When building, I get the error:

/Users/rich/Documents/Code/petmr_rd_tools/Source/src/NMExtract.cpp:25:10: fatal error: 'glog/logging.h' file not found

I have set the glog_DIR variable, and with a bit of debugging in the Findglog.cmake, I can see that if (glog_FOUND) at line 182 is True. This means that the following code is executed:

# glog wraps the include directories into the exported glog::glog target.
set(GLOG_INCLUDE_DIR "")
set(GLOG_LIBRARY glog::glog)

At line 322, there is set(GLOG_LIBRARIES ${GLOG_LIBRARY}).

So, GLOG_INCLUDE_DIRS is blank and GLOG_LIBRARY/GLOG_LIBRARIES contain the useful stuff. However, neither of these variables are used outside of the Findglog.cmake.

nm_mrac2mu --head resampling

As the metioned in the documentation, the output resampled images will be in size 344x344x127, if the --head flag is enabled.

However, in our case, the output attenuation map is in 244x244x108?

Of course, we can do resampling the attenuation map in the SIRF recon pipeline, to match the output size(344x344x127). But just a bit confused about whether the resampling was designing to be done in pet-rd-tool or in SIRF?

WIthout the resampling, this will cause the error when estimating the scatters, in SIRF. (see error message below):

/opt/SIRF-SuperBuild/INSTALL/python/sirf/STIR.py in process(self)
2745 self.output = AcquisitionData()
2746 self.output.handle = pystir.cSTIR_runScatterEstimator(self.handle)
-> 2747 check_status(self.output.handle)
2748 print('ScatterEstimator:: estimation finished.')
2749

/opt/SIRF-SuperBuild/INSTALL/python/sirf/Utilities.py in check_status(handle, stack)
408 repr(line) + ' of ' + file + '; ' +
409 'the reconstruction engine output may provide more information'
--> 410 raise error(errorMsg)
411
412

error: ??? "'\nERROR: ScatterSimulation: limitation in #planes and voxel-size for the attenuation image.\nThis would cause a shift of -19.2969mm w.r.t. the activity image.\n(see https://github.com/UCL/STIR/issues/495.\\n' exception caught at line 439 of /opt/SIRF-SuperBuild/sources/SIRF/src/xSTIR/cSTIR/cstir.cpp; the reconstruction engine output may provide more information"

any hints would be helpful. thanks

GE Signa - Loading coil files

  • Parse MRAC to determine which coils were plugged in.
  • Load required coil files and scale to LAC, accounting for bed position.

--head option isn't guaranteed to resample to 344x344

In fact, out MRAC acquisitions aren't the same size in x and y directions, so nm_mrac2mu actually produces different sizes in x and y, which is not compatible with certain aspects of STIR.

Sorry for repeating, I think I have mentioned this in a previous issue, but I am creating a new one to make a PR against :)

Ash

nm_mrac2mu high LAC values gets wrong conversion

When performing a conversion with nm_mrac2mu an inpainted high-density region in the umap does not get correctly translated.
An inpainted region with value 5000 (1e4/cm) get converted to 0.0904 (1/cm) after using nm_mrac2mu (v2.0.1).

Steps to reproduce the error:
Use a siemens biograph mMR 4-class umap as a basis. Paint in a high-density region and rewrite the dicom files like the original umap dicom series, but with the now modified pixel arrays. Convert the dicom folder to interfile using nm_mrac2mu.

Suggested solution:
Change conversion to allow for larger values or throw a warning if max value in input umap exceeds the maximum supported value of the conversion tool.

Optional: Why high LAC values can be useful?
I use a umap with an inpainted high-density region painted into a region that I can recognize both in the reconstructed PET and the umap itself to verify the alignment of the umap and PET data during image reconstruction.

nm_extract core dump on "header-only" GE Dicoms

GE stores the DICO headers only on the scanner (presumably without the binary blob). Running nm_extract gives a core dump currently after writing header to.... Instead, it should exit with an error

GE Signa - coil/hardware files

  • Create an application that will reslice GE Signa coil/hardware files into the appropriate location for reconstruction.
  1. Read MRAC and manifest.
  2. Load suitable coil files and scale to LAC, accounting for bed position.
  3. Rescale MRAC to LAC.
  4. Keep coil files and MRAC separate.
  5. Output Interfile

No output path and relative input path

Using nm_extract -i file.dcm gives the following error:

I0201 16:10:04.987962 94860736 NMExtract.cpp:139] Output path "" does not exist!
I0201 16:10:04.987970 94860736 NMExtract.cpp:142] Creating output path ""
I0201 16:10:04.988512 94860736 NMExtract.cpp:146] Unable to create output directory!

The error goes away with nm_extract -i /abs/path/file.dcm or nm_extract -i file.dcm -o ..

nm_extract listmode file extracting error message

I try to extract a listMode file from mMR .dcm with nm_extract and got this error:

I1022 16:10:39.149196 14604 NMExtract.cpp:105] Started: Thu Oct 22 16:10:39 2020
I1022 16:10:39.149358 14604 NMExtract.cpp:106] Running 'nm_extract' version: 2.0.0
I1022 16:10:39.149489 14604 Common.hpp:190] Manufacturer: SIEMENS 
I1022 16:10:39.149497 14604 Common.hpp:198] Model name: Biograph_mMR
I1022 16:10:39.149500 14604 MMR.hpp:135] Image type: ORIGINAL\PRIMARY\PET_LISTMODE 
double free or corruption (top)
Cancelled (memory snapshot written)

I translated the last line by my own, because I use Linux in German.

Check size of decompressed sinograms

nm_validate deliberately does not check the size of a sinogram due to compression. Should check if sinogram is compressed, and if not, check the size.

GE Signa - Output DICOM MRAC

Write a new DICOM set that represents the fused image. Need to change study UID, series UID + number, Instance UID

Segmentation fault when running nm_validate and nm_extract

I get the following error messages when attempting to convert raw PET from a .dcm and .bf pair to the required interfile format for SIRF. I don't have any idea what is causing the issue.

nm_validate -i

I20200804 15:52:31.933540 34091 NMValidate.cpp:101] Started: Tue Aug 4 15:52:31 2020
I20200804 15:52:31.933631 34091 NMValidate.cpp:102] Running 'nm_validate' version: 2.0.0
I20200804 15:52:31.934140 34091 Common.hpp:190] Manufacturer: SIEMENS
I20200804 15:52:31.934155 34091 Common.hpp:198] Model name: Biograph_mMR
I20200804 15:52:31.934165 34091 MMR.hpp:135] Image type: ORIGINAL\PRIMARY\PET_LISTMODE
Segmentation fault

nm_extract -i

I20200804 15:54:50.730965 34102 NMExtract.cpp:105] Started: Tue Aug 4 15:54:50 2020
I20200804 15:54:50.731042 34102 NMExtract.cpp:106] Running 'nm_extract' version: 2.0.0
I20200804 15:54:50.731570 34102 Common.hpp:190] Manufacturer: SIEMENS
I20200804 15:54:50.731580 34102 Common.hpp:198] Model name: Biograph_mMR
I20200804 15:54:50.731588 34102 MMR.hpp:135] Image type: ORIGINAL\PRIMARY\PET_LISTMODE
I20200804 15:54:50.732039 34102 NMExtract.cpp:151] No output directory specified. Placing output in same directory as input.
I20200804 15:54:50.732087 34102 NMExtract.cpp:182] Writing raw data to:
Segmentation fault

Resampling in wrong direction?

Hi,

I have used the nm_mrac utility to convert a u-map acquisition to interfile, and then ran STIR's calculate_attenuation_coefficients with the input sinogram as the template. I attach here a screenshot of projection views of the sinogram and of the ACFs.

screenshot from 2018-01-23 16-22-23

As you can see, it appears the y-axis has been inverted (it is a little hard to tell w.r.t. x-axis also). Is this likely to be an issue with the resampling in nm_mrac do you think?

Cheers,
Ash

empty global scanner calibration factor in norm file

Hi,

After using nm_extract to convert normalization file (Simenes raw data, a dicom header and a binary .bf file), the value of 'GLOBAL SCANNER CALIBRATION FACTOR' in the xxxx.n.hdr file is empty.

Just wondering what could cause this value to be empty?

---- part of the normalization header file ----

%GLOBAL SCANNER CALIBRATION FACTOR:=
%scanner quantification factor (Bq*s/ECAT counts):=1.94365e+007
%calibration date (yyyy:mm:dd):=2016:08:10
%calibration time (hh:mm:ss GMT+00:00):=22:55:32
%cross calibration factor:=1.014

Thanks

MRAC Interfile output should depend on patient orientation

Interfile is normally a "gantry-based" coordinate system (although it isn't really well defined in the very old Interfile standard, but that's how STIR interprets it.) ITK uses a patient-based coordinate system. That means that the reorientation should depend on patient orientation, but it currently doesn't.
We currently default to RAI

itk::SpatialOrientation::ValidCoordinateOrientationFlags _outputOrientation
= itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RAI;

A somewhat related problem is that this choice is inconsistent with STIR's implementation by @ashgillman, which uses RAS for HFS. Indeed, @ashgillman noted in #18 that he has to use RAS for his (presumably HFS) data. @bathomas replied he choose RAI to fit e7tools "Interfile-like" images. This might imply that Siemens uses different coordinate axis (i.e. axially oriented in the other direction) for its Interfile than STIR. I have no idea what e7tools does for different patient orientations.

This is all a bit of a mess of course.

I'm reluctant to duplicate @ashgillman careful STIR code on patient orientation here, especially if the Interfile output isn't suitable for STIR anyway. My current inclination is to "abandon" the MRAC code here, and move/copy relevant bits into STIR. (essentially we need the rescaling and resampling).

nm_extract listmode file extracting warning message with mMR .bf file

when running nm_extract on a mMR dcm file for a list file that has the .bf, it writes a warning like

expected number of LM words: <large number>
10240 bytes in LM fields
10240 / 4 = 2560 words
Expect no. of LM words does not equal no. read!
Looking for BF file...
...
.bf file size in bytes: .< largenumber*4>

Everything seems fine but the warning is confusing. I think it'd be better to say something like

Expected no. of LM words does not equal to the size of the LM fields. I'm going to look for a BF file

possibly also write that the .bf file size is correct.

nm_extract seems to require --output

when running without --output flag, nm_extract says something like "I will use the current directory" but then errors with cannot create output directory ""

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.