diff --git a/NEWS b/NEWS index ad5e5d0..7c7b495 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,22 @@ +New in Version 0.1.19 +===================== +* added script: make_xfm_for_grid.pl which creates an xfm file for a provided deformation grid + (vector file) + +New in Version 0.1.18 +===================== +* 2to3 fixes +* fix `install_requires` in setup.py + +New in Version 0.1.17 +===================== +* fix bug in TFCE implementation +* fix linking on OS X + +New in Version 0.1.16 +===================== +* fix compilation against static HDF5 libs + New in Version 0.1.15 ===================== * fairly big overhaul of rotational_minctracc.py: it turns out that the centre of gravity (cog) diff --git a/m4/mni_REQUIRE_MNILIBS.m4 b/m4/mni_REQUIRE_MNILIBS.m4 index 925d33e..caef3b6 100644 --- a/m4/mni_REQUIRE_MNILIBS.m4 +++ b/m4/mni_REQUIRE_MNILIBS.m4 @@ -8,6 +8,7 @@ AC_DEFUN([mni_REQUIRE_MINC], mni_REQUIRE_LIB(netcdf,[#include ],[int i = ncopen("",0);]) if test "$with_minc2" = "yes"; then mni_REQUIRE_LIB(z,[#include ],[int f = compress2;]) + mni_REQUIRE_LIB(dl,[#include ],[int f = dlopen("",0)]) mni_REQUIRE_LIB(hdf5,[#include ],[int f = H5Fopen("",0,H5P_DEFAULT);]) mni_REQUIRE_LIB(minc2,[#include ],[int i = miicv_create();]) AC_DEFINE([MINC2], 1, [Define if should build with MINC 2.0]) diff --git a/m4/smr_WITH_BUILD_PATH.m4 b/m4/smr_WITH_BUILD_PATH.m4 index 1874aac..be425f2 100644 --- a/m4/smr_WITH_BUILD_PATH.m4 +++ b/m4/smr_WITH_BUILD_PATH.m4 @@ -22,7 +22,7 @@ AC_DEFUN([smr_WITH_BUILD_PATH], for d in `echo $withval | tr : ' '`; do test -d $d || AC_MSG_ERROR([build path $d not found.]) test -d $d/include && CPPFLAGS="$CPPFLAGS -I$d/include" - test -d $d/lib && LDFLAGS="$LDFLAGS -L$d/lib" + test -d $d/lib && LDFLAGS="$LDFLAGS -L$d/lib -Wl,-rpath,$d/lib" done ]) ]) diff --git a/perl/make_xfm_for_grid.pl b/perl/make_xfm_for_grid.pl new file mode 100755 index 0000000..d777d55 --- /dev/null +++ b/perl/make_xfm_for_grid.pl @@ -0,0 +1,47 @@ +#!/usr/bin/perl + +# generates an xfm file for a provided grid file + +use strict; +use warnings; + +use File::Spec; +use MNI::Startup; +use Getopt::Tabular; +use MNI::Spawn; +use MNI::FileUtilities qw(test_file check_output_dirs); + +my $usage = " + +$0 [options] deformation_grid.mnc output_xfm_for_grid.xfm\n"; + + +# handle arguments +my @left_over_args; +my @arg_table = + ( @DefaultArgs, + ); + +GetOptions(\@arg_table, \@ARGV, \@left_over_args) or die "\n"; + + +my $deformation_grid = shift @left_over_args or die $usage; +my $output_xfm = shift @left_over_args or die $usage; + +if(-f $output_xfm and not $Clobber) { + die "Error: output xfm file already exists and -clobber not specified: $output_xfm.\n"; +} + +if(not -f $deformation_grid){ + die "Error: deformation grid does not exist: $deformation_grid.\n"; +} + +# save the realpath to the grid, otherwise it won't necessarily work +my $deformation_grid_abs_path = File::Spec->rel2abs( $deformation_grid ); + +# write to the output +open(OUTPUT, "> $output_xfm"); +print OUTPUT "MNI Transform File\n"; +print OUTPUT "% created by $0 with grid $deformation_grid\n"; +print OUTPUT "Transform_Type = Grid_Transform;\n"; +print OUTPUT "Displacement_Volume = $deformation_grid_abs_path;\n"; diff --git a/python/TFCE b/python/TFCE index 58c82d8..90c1439 100755 --- a/python/TFCE +++ b/python/TFCE @@ -5,9 +5,10 @@ from pyminc.volumes.factory import * from scipy import ndimage, weave from numpy import * import operator +from functools import reduce -def tfce(invol, outvol, dh=0.1, E=0.5, H=2.0): +def tfce(invol, outvol, dh=0.1, E=0.5, H=2.0, negative = False): #infile = "1.mnc" #out = "1-tfce.mnc" @@ -26,16 +27,16 @@ def tfce(invol, outvol, dh=0.1, E=0.5, H=2.0): # connected components labelling l = ndimage.label(thresh) - print "L:", l[1] + print("L:", l[1]) # compute the size of each label - sizes = array(ndimage.sum(thresh, l[0], range(l[1]+1))) + sizes = array(ndimage.sum(thresh, l[0], list(range(l[1]+1)))) # modulate label size by voxel volume sizes = sizes * reduce(operator.mul, invol.separations) - print "sizes", sizes.shape + print("sizes", sizes.shape) # compute TFCE if l[1] > 0: - print "inside", h, l[1] + print("inside", h, l[1]) code = """ for (int x=0; x < nx; ++x) { for (int y=0; y < ny; ++y) { @@ -43,7 +44,11 @@ def tfce(invol, outvol, dh=0.1, E=0.5, H=2.0): if (labeled(x,y,z) > 0) { int e = labeled(x,y,z); //std::cout << data(x,y,z) << " " << h << " " << sizes(e) << std::endl; - data(x,y,z) = data(x,y,z) + (pow(h, H) * pow(sizes(e), E) * dh); + if(negative == 1){ + data(x,y,z) = data(x,y,z) - (pow(h, H) * pow(sizes(e), E) * dh); + } else { + data(x,y,z) = data(x,y,z) + (pow(h, H) * pow(sizes(e), E) * dh); + } //data(x,y,z) = n; }}}} """ @@ -52,11 +57,11 @@ def tfce(invol, outvol, dh=0.1, E=0.5, H=2.0): labeled = l[0] weave.inline(code, ['data', 'nx', 'ny', 'nz', 'labeled', 'h', - 'H', 'E', 'sizes', 'dh'], + 'H', 'E', 'sizes', 'dh', 'negative'], type_converters=weave.converters.blitz, compiler='gcc') - print h + print(h) #outvol.writeFile() #outvol.closeVolume() @@ -101,8 +106,8 @@ Smith and Nichols. Threshold-free cluster enhancement: addressing problems of sm tfce(invol, outvol, options.dh, options.E, options.H) if options.pos_and_neg == "both" or options.pos_and_neg == "neg": invol.data = invol.data * -1 - tfce(invol, outvol, options.dh, options.E, options.H) + tfce(invol, outvol, options.dh, options.E, options.H, negative = True) outvol.writeFile() outvol.closeVolume() - \ No newline at end of file + diff --git a/python/measure_xcorr b/python/measure_xcorr index 1fa845d..b9b8927 100755 --- a/python/measure_xcorr +++ b/python/measure_xcorr @@ -46,7 +46,7 @@ if __name__ == "__main__": result = compute_xcorr(sourcevol, targetvol, options.mask) - print result + print(result) diff --git a/python/rotational_minctracc.py b/python/rotational_minctracc.py index d1df504..2d75ec6 100755 --- a/python/rotational_minctracc.py +++ b/python/rotational_minctracc.py @@ -11,6 +11,7 @@ import shutil import subprocess import sys +import math def get_tempfile(suffix): @@ -115,6 +116,23 @@ def compute_xcorr(sourcefile, targetvol, maskvol): f3 = 0 if maskvol is not None: + # we've had issues with mask files that after + # running autocrop on them, only contain "nan" + # values. This seems to happen when the original + # mask has a valid image range indicated as: + # image: unsigned short 1 to 1 + # when that happens, all following calculations + # fail, so we should quit: + if math.isnan(maskvol.data.sum()): + # clean up... + shutil.rmtree("%s/rot_%s" % (os.environ["TMPDIR"], os.getpid())) + raise ValueError("\n\n* * * * * * * * * *\n" + "Error: the mask volume is corrupted. No values are found inside the mask.\n" + "probably you are using a mask with only the value 1 in it, but which at the same\n" + "time has a valid range of 1 to 1 . You can check this using mincinfo.\n" + "You need to generate a new mask. To produce a full field of view mask for file.mnc\n" + "run:\n\nminccalc -expression if(true){out = 1;} file.mnc file_mask.mnc\n" + "* * * * * * * * * *\n") f1 = sum(sourcevol.data[maskvol.data > 0.5] * \ targetvol.data[maskvol.data > 0.5]) f2 = sum(sourcevol.data[maskvol.data > 0.5] ** 2) diff --git a/python/volumes_from_labels_only b/python/volumes_from_labels_only index 2caa479..1df135d 100755 --- a/python/volumes_from_labels_only +++ b/python/volumes_from_labels_only @@ -23,7 +23,7 @@ if __name__ == "__main__": for l in labels: voxelsPerLabel = len(atlas.data[atlas.data == l]) - volumePerLabel = volumePerVoxel*voxelsPerLabel + volumePerLabel = volumePerVoxel*voxelsPerLabel output.write(str(int(l)) + ", " + str(volumePerLabel) + "\n") atlas.closeVolume() diff --git a/setup.py b/setup.py index 9c1f01a..1e459b6 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,8 @@ import sys setup(name="python-stuffs", - version='0.1.15', + version='0.1.19', + install_requires=['numpy', 'scipy', 'pyminc'], scripts=["python/TFCE", "python/smooth_vector", "python/measure_xcorr",