Skip to content

Commit

Permalink
merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaudbore committed Nov 26, 2024
2 parents 6249ad2 + 4fbef98 commit 04699ce
Show file tree
Hide file tree
Showing 20 changed files with 113 additions and 99 deletions.
10 changes: 5 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,24 @@ RUN git clone -b $MRTRIX3_GIT_COMMITISH --depth 1 https://github.com/MRtrix3/mrt
&& rm -rf tmp

# Download minified ART ACPCdetect (V2.0).
FROM base-builder as acpcdetect-installer
FROM base-builder AS acpcdetect-installer
WORKDIR /opt/art
RUN curl -fsSL https://osf.io/73h5s/download \
| tar xz --strip-components 1

# Download minified ANTs (2.3.4-2).
FROM base-builder as ants-installer
FROM base-builder AS ants-installer
WORKDIR /opt/ants
RUN curl -fsSL https://osf.io/yswa4/download \
| tar xz --strip-components 1

# Download FreeSurfer files.
FROM base-builder as freesurfer-installer
FROM base-builder AS freesurfer-installer
WORKDIR /opt/freesurfer
RUN curl -fsSLO https://raw.githubusercontent.com/freesurfer/freesurfer/v7.1.1/distribution/FreeSurferColorLUT.txt

# Download minified FSL (6.0.7.7)
FROM base-builder as fsl-installer
FROM base-builder AS fsl-installer
WORKDIR /opt/fsl
RUN curl -fsSL https://osf.io/ph9ex/download \
| tar xz --strip-components 1
Expand Down Expand Up @@ -108,4 +108,4 @@ RUN strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so

RUN ln -s /usr/bin/python3 /usr/bin/python

CMD ["/bin/bash"]
CMD ["/bin/bash"]
8 changes: 4 additions & 4 deletions Singularity
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ Include: apt
export FSLDIR FSLOUTPUTTYPE FSLMULTIFILEQUIT FSLTCLSH FSLWISH

# All
LD_LIBRARY_PATH="/.singularity.d/libs:/usr/lib:/opt/fsl/lib:$LD_LIBRARY_PATH"
PATH="/opt/mrtrix3/bin:/opt/ants/bin:/opt/art/bin:/opt/fsl/bin:$PATH"
LD_LIBRARY_PATH="/.singularity.d/libs:/usr/lib:$LD_LIBRARY_PATH"
PATH="/opt/mrtrix3/bin:/opt/ants/bin:/opt/art/bin:/opt/fsl/share/fsl/bin:$PATH"
export LD_LIBRARY_PATH PATH

%post
Expand All @@ -51,8 +51,8 @@ Include: apt
mkdir -p /opt/ants && curl -fsSL https://osf.io/yswa4/download | tar xz -C /opt/ants --strip-components 1
# Download FreeSurfer lookup table file (v7.1.1).
mkdir -p /opt/freesurfer && curl -fsSL -o /opt/freesurfer/FreeSurferColorLUT.txt https://raw.githubusercontent.com/freesurfer/freesurfer/v7.1.1/distribution/FreeSurferColorLUT.txt
# Download minified FSL (6.0.4-2).
mkdir -p /opt/fsl && curl -fsSL https://osf.io/dtep4/download | tar xz -C /opt/fsl --strip-components 1
# Download minified FSL (6.0.7.7).
mkdir -p /opt/fsl && curl -fsSL https://osf.io/ph9ex/download | tar xz -C /opt/fsl --strip-components 1

# Use Python3 for anything requesting Python, since Python2 is not installed
ln -s /usr/bin/python3 /usr/bin/python
Expand Down
2 changes: 1 addition & 1 deletion cmd/5ttcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ void run ()
}
}

const std::string vox_option_suggestion = get_options ("masks").size() ? (" (suggest checking " + std::string(argument.size() > 1 ? "outputs from" : "output of") + " -masks option)") : " (suggest re-running using the -masks option to see voxels where tissue fractions do not sum to 1.0)";
const std::string vox_option_suggestion = get_options ("voxels").size() ? (" (suggest checking " + std::string(argument.size() > 1 ? "outputs from" : "output of") + " -voxels option)") : " (suggest re-running using the -voxels option to see voxels where tissue fractions do not sum to 1.0)";

if (major_error_count) {
if (argument.size() > 1)
Expand Down
30 changes: 27 additions & 3 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ OPTIONS
-conda prevent stripping anaconda/miniconda from the PATH (only use if
you intend building with the conda toolchain - not recommended)
-fsl prevent stripping FSL from the PATH (only use if you intend
building with the FSL toolchain - not recommended)
ENVIRONMENT VARIABLES
Expand Down Expand Up @@ -194,6 +197,7 @@ R_module = False
openmp = False
dev = False
conda = False
fsl = False

optimlevel = 3

Expand Down Expand Up @@ -227,6 +231,8 @@ for arg in sys.argv[1:]:
openmp = True
elif '-conda'.startswith (arg):
conda = True
elif '-fsl'.startswith (arg):
fsl = True
else:
sys.stdout.write (usage_string)
sys.exit (1)
Expand Down Expand Up @@ -292,15 +298,30 @@ if conda:
else:
path = []
for entry in os.environ['PATH'].split(os.pathsep):
if 'conda' in entry:
if 'conda' in entry.lower():
report ('WARNING: anaconda/miniconda detected in PATH ("' + entry + '") - removed to avoid conflicts\n')
issue_conda_warning = True
else:
path += [ entry ]
path = os.pathsep.join(path)
os.environ['PATH'] = path

log ('PATH set to: ' + path)
# if not using FSL, remove any mention of FSL from PATH:
issue_fsl_warning = False
if fsl:
path = os.environ['PATH']
else:
path = []
for entry in os.environ['PATH'].split(os.pathsep):
if 'fsl' in entry.lower():
report ('WARNING: FSL detected in PATH ("' + entry + '") - removed to avoid conflicts\n')
issue_fsl_warning = True
else:
path += [ entry ]
path = os.pathsep.join(path)
os.environ['PATH'] = path

log ('\nPATH set to: ' + path)



Expand Down Expand Up @@ -741,7 +762,10 @@ if 'LINKLIB_ARGS' in os.environ.keys():


if issue_conda_warning:
report ('\nNOTE: if you intend to build with anaconda/miniconda (not recommended), pass the -conda flag to ./configure\n\n')
report ('NOTE: if you intend to build with anaconda/miniconda (not recommended), pass the -conda flag to ./configure\n')
if issue_fsl_warning:
report ('NOTE: if you intend to build with the FSL toolchain (not recommended), pass the -fsl flag to ./configure\n')
report ('\n')



Expand Down
24 changes: 21 additions & 3 deletions core/file/png.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace MR


Reader::Reader (const std::string& filename) :
infile (fopen (filename.c_str(), "rb")),
png_ptr (NULL),
info_ptr (NULL),
width (0),
Expand All @@ -46,7 +47,6 @@ namespace MR
color_type (0),
channels (0)
{
FILE* infile = fopen (filename.c_str(), "rb");
unsigned char sig[8];
if (fread (sig, 1, 8, infile) < 8)
throw Exception ("error reading from PNG file \"" + filename + "\"");
Expand Down Expand Up @@ -130,6 +130,10 @@ namespace MR
png_ptr = NULL;
info_ptr = NULL;
}
if (infile) {
fclose(infile);
infile = NULL;
}
}


Expand Down Expand Up @@ -183,6 +187,7 @@ namespace MR
bit_depth (0),
filename (filename),
data_type (H.datatype()),
multiplier (1.0),
outfile (NULL)
{
if (Path::exists (filename) && !App::overwrite_files)
Expand All @@ -196,6 +201,8 @@ namespace MR
throw Exception ("Unable to set jump buffer for PNG structure for image \"" + filename + "\"");
}
outfile = fopen (filename.c_str(), "wb");
if (!outfile)
throw Exception ("Unable to open PNG file for writing for image \"" + filename + "\": " + strerror (errno));
png_init_io (png_ptr, outfile);
png_set_compression_level (png_ptr, Z_DEFAULT_COMPRESSION);
switch (H.ndim()) {
Expand Down Expand Up @@ -231,17 +238,23 @@ namespace MR
png_destroy_write_struct (&png_ptr, &info_ptr);
throw Exception ("Undefined data type in image \"" + H.name() + "\" for PNG writer");
case DataType::Bit:
bit_depth = 1;
assert (false);
break;
case DataType::UInt8:
bit_depth = 8;
break;
case DataType::Float32:
bit_depth = 8;
multiplier = std::numeric_limits<uint8_t>::max(); break;
break;
case DataType::UInt16:
case DataType::UInt32:
case DataType::UInt64:
bit_depth = 16;
break;
case DataType::Float64:
bit_depth = 16;
multiplier = std::numeric_limits<uint16_t>::max(); break;
break;
}
// Detect cases where one axis has a size of 1, and hence represents the image plane
Expand Down Expand Up @@ -302,6 +315,10 @@ namespace MR
png_ptr = NULL;
info_ptr = NULL;
}
if (outfile) {
fclose(outfile);
outfile = NULL;
}
}


Expand All @@ -323,10 +340,11 @@ namespace MR
row_pointers[row] = to_write + row * row_bytes;
png_write_image (png_ptr, row_pointers);
png_write_end (png_ptr, info_ptr);
delete [] row_pointers;
};


if (bit_depth == 1 || data_type == DataType::UInt8 || data_type == DataType::UInt16BE) {
if (data_type == DataType::UInt8 || data_type == DataType::UInt16BE) {
finish (data);
} else {
uint8_t scratch[row_bytes * height];
Expand Down
14 changes: 4 additions & 10 deletions core/file/png.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ namespace MR
void load (uint8_t*);

private:
FILE* infile;
png_structp png_ptr;
png_infop info_ptr;
png_uint_32 width, height;
Expand Down Expand Up @@ -83,6 +84,7 @@ namespace MR
int color_type, bit_depth;
std::string filename;
DataType data_type;
default_type multiplier;
FILE* outfile;

static void error_handler (png_struct_def*, const char*);
Expand All @@ -100,16 +102,8 @@ namespace MR
std::function<default_type(const void*,size_t,default_type,default_type)> fetch_func;
std::function<void(default_type,void*,size_t,default_type,default_type)> store_func;
__set_fetch_store_functions<default_type> (fetch_func, store_func, data_type);
default_type multiplier = 1.0;
switch (data_type() & DataType::Type) {
case DataType::Float32: multiplier = std::numeric_limits<uint8_t>::max(); break;
case DataType::Float64: multiplier = std::numeric_limits<uint16_t>::max(); break;
}
for (size_t i = 0; i != num_elements; ++i) {
Raw::store_BE<T> (std::min (default_type(std::numeric_limits<T>::max()), std::max (0.0, std::round(multiplier * fetch_func (in_ptr, 0, 0.0, 1.0)))), out_ptr);
in_ptr += data_type.bytes();
out_ptr += sizeof(T);
}
for (size_t i = 0; i != num_elements; ++i)
Raw::store_BE<T> (std::min (default_type(std::numeric_limits<T>::max()), std::max (0.0, std::round(multiplier * fetch_func (in_ptr, i, 0.0, 1.0)))), out_ptr, i);
};


Expand Down
30 changes: 14 additions & 16 deletions core/formats/png.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,16 @@ namespace MR
}

H.size(0) = png.get_width();
H.stride(0) = -3;
H.stride(0) = -2;

H.size(1) = png.get_height();
H.stride(1) = -4;
H.stride(1) = -3;

H.size(2) = 1;
H.stride(2) = 1;
H.stride(2) = 4;

if (H.ndim() == 4)
H.stride(3) = 2;
H.stride(3) = 1;

H.spacing (0) = H.spacing (1) = H.spacing (2) = 1.0;
H.transform().setIdentity();
Expand Down Expand Up @@ -132,14 +132,14 @@ namespace MR
if (H.ndim() == 4 && H.size(3) > 4)
throw Exception ("A 4D image written to PNG must have between one and four volumes (requested: " + str(H.size(3)) + ")");

// TODO After looping over axes via square-bracket notation,
// After looping over axes via square-bracket notation,
// there needs to be at least two axes with size greater than one
size_t unity_axes = 0;
size_t nonunity_axes = 0;
for (size_t axis = 0; axis != H.ndim(); ++axis) {
if (H.size (axis) == 1)
++unity_axes;
if (H.size (axis) > 1)
++nonunity_axes;
}
if (unity_axes - (H.ndim() - num_axes) < 2)
if (nonunity_axes - (H.ndim() - num_axes) < 2)
throw Exception ("Too few (non-unity) image axes to support PNG export");

// For 4D images, can support:
Expand All @@ -149,7 +149,7 @@ namespace MR
// - 4 volumes (save as RGBA)
// This needs to be compatible with NameParser used in Header::create():
// "num_axes" subtracts from H.ndim() however many instances of [] there are
size_t width_axis = 0, axis_to_zero = 3;
size_t axis_to_zero = 3;
if (H.ndim() - num_axes > 1)
throw Exception ("Cannot nominate more than one axis using square-bracket notation for PNG format");
switch (num_axes) {
Expand All @@ -170,7 +170,6 @@ namespace MR
axis_to_zero = 1;
} else if (H.size(0) == 1) {
axis_to_zero = 0;
width_axis = 1;
} else {
// If image is 3D, and all three axes have size greater than one, and we
// haven't used the square-bracket notation, we can't export genuine 3D data
Expand All @@ -192,8 +191,6 @@ namespace MR
}
if (axis < 0)
throw Exception ("Cannot export 4D image to PNG format if all three spatial axes have size greater than 1 and square-bracket notation is not used");
if (!axis_to_zero)
width_axis = 1;
break;
default:
throw Exception ("Cannot generate PNG file(s) from image with more than 4 axes");
Expand All @@ -209,7 +206,7 @@ namespace MR
H.stride(1) = -3;
H.spacing(1) = 1.0;
if (H.ndim() > 2) {
H.stride(2) = 4;
H.stride(2) = -4;
H.spacing(2) = 1.0;
}
if (H.ndim() > 3) {
Expand All @@ -223,9 +220,10 @@ namespace MR

H.transform().setIdentity();

if (H.datatype() == DataType::Bit && H.size (width_axis) % 8) {
WARN ("Cannot write bitwise PNG image with width not a factor of 8; will instead write with 8-bit depth");
if (H.datatype() == DataType::Bit) {
WARN ("Cannot write bitwise PNG images; will instead write with 8-bit depth");
H.datatype() = DataType::UInt8;
H.intensity_scale() = 1.0 / 255.0;
}

return true;
Expand Down
5 changes: 3 additions & 2 deletions core/header.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -785,12 +785,13 @@ namespace MR
Header result (headers[0]);

if (axis_to_concat >= result.ndim()) {
Stride::symbolise (result);
result.ndim() = axis_to_concat + 1;
result.size(axis_to_concat) = 1;
result.stride(axis_to_concat) = axis_to_concat+1;
Stride::actualise (result);
}

result.stride (axis_to_concat) = result.ndim()+1;

for (size_t axis = 0; axis != result.ndim(); ++axis) {
if (axis != axis_to_concat && result.size (axis) <= 1) {
for (const auto& H : headers) {
Expand Down
Loading

0 comments on commit 04699ce

Please sign in to comment.