Does anyone know any handy module to at least read in .mgh files from Python? Or should I simply try mri_convert them into .minc and use netcdf module within python?
Thanks in advance for the ideas!
How much detail do you need frmo the mgh file? I wrote a quick Python script which reads in at least the volume data but I think I just passed over most of the other stuff in there...
Yaroslav Halchenko wrote:
Does anyone know any handy module to at least read in .mgh files from Python? Or should I simply try mri_convert them into .minc and use netcdf module within python?
Thanks in advance for the ideas!
actually I need thickness data out of it. Is .mgh format documented somewhere?
On Thu, 24 Apr 2008, Pádraig Kitterick wrote:
How much detail do you need frmo the mgh file? I wrote a quick Python script which reads in at least the volume data but I think I just passed over most of the other stuff in there...
Yaroslav Halchenko wrote:
Does anyone know any handy module to at least read in .mgh files from Python? Or should I simply try mri_convert them into .minc and use netcdf module within python?
Thanks in advance for the ideas!
Here you go Yaroslav...
http://surfer.nmr.mgh.harvard.edu/fswiki/FsTutorial/MghFormat
Krish
On Apr 24, 2008, at 11:49 AM, Yaroslav Halchenko wrote:
actually I need thickness data out of it. Is .mgh format documented somewhere?
On Thu, 24 Apr 2008, Pádraig Kitterick wrote:
How much detail do you need frmo the mgh file? I wrote a quick Python script which reads in at least the volume data but I think I just passed over most of the other stuff in there...
Yaroslav Halchenko wrote:
Does anyone know any handy module to at least read in .mgh files from Python? Or should I simply try mri_convert them into .minc and use netcdf module within python?
Thanks in advance for the ideas!
-- Yaroslav Halchenko Research Assistant, Psychology Department, Rutgers-Newark Student Ph.D. @ CS Dept. NJIT Office: (973) 353-5440x263 | FWD: 82823 | Fax: (973) 353-1171 101 Warren Str, Smith Hall, Rm 4-105, Newark NJ 07102 WWW: http://www.linkedin.com/in/yarik _______________________________________________ Freesurfer mailing list Freesurfer@nmr.mgh.harvard.edu https://mail.nmr.mgh.harvard.edu/mailman/listinfo/freesurfer
Yaroslav,
The mgh format is pseudo-documented here:
https://surfer.nmr.mgh.harvard.edu/fswiki/FsTutorial/MghFormat
But the thickness data is not stored in mgh format, but rather in another proprietary format, with documentation here:
http://wideman-one.com/gw/brain/fs/surfacefileformats.htm
Your best option is to look at the matlab scripts in the $FREESURFER_HOME/matlab directory. In particular, read_curv.m, which I have attached to the email (along with worker routine fread3.m).
Krish Subramaniam, a new software engineer here at MGH, cc'd in this email, has just started a project where some of the major IO routines will be written in python, so maybe you can coordinate with him.
Nick
On Thu, 2008-04-24 at 11:49 -0400, Yaroslav Halchenko wrote:
actually I need thickness data out of it. Is .mgh format documented somewhere?
On Thu, 24 Apr 2008, Pádraig Kitterick wrote:
How much detail do you need frmo the mgh file? I wrote a quick Python script which reads in at least the volume data but I think I just passed over most of the other stuff in there...
Yaroslav Halchenko wrote:
Does anyone know any handy module to at least read in .mgh files from Python? Or should I simply try mri_convert them into .minc and use netcdf module within python?
Thanks in advance for the ideas!
MGH is just a generic volume-based format so I think thickness data will be stored in a 1xNumVerticesx1x1 volume. Here is a python function which reads in the volume data. It's basically a translation of the readmgh function from the Freesurfer matlab toolbox. You can modify it to return more parts of the file data if necessary...
--------------- import struct import numpy
def read_mgh(filename): fp = open(filename,'rb') intsize = struct.calcsize('>i') shortsize = struct.calcsize('>h') floatsize = struct.calcsize('>f') charsize = struct.calcsize('>b')
v = struct.unpack('>i',fp.read(intsize))[0] ndim1 = struct.unpack('>i',fp.read(intsize))[0] ndim2 = struct.unpack('>i',fp.read(intsize))[0] ndim3 = struct.unpack('>i',fp.read(intsize))[0] nframes = struct.unpack('>i',fp.read(intsize))[0] vtype = struct.unpack('>i',fp.read(intsize))[0] dof = struct.unpack('>i',fp.read(intsize))[0]
UNUSED_SPACE_SIZE = 256 USED_SPACE_SIZE = (3*4) + (4*3*4) # space for ras transform unused_space_size = UNUSED_SPACE_SIZE - 2
ras_good_flag = struct.unpack('>h',fp.read(shortsize))[0] if ras_good_flag: # We read these in but don't process them # as we just want to move to the volume data delta = struct.unpack('>fff',fp.read(floatsize*3)) Mdc = struct.unpack('>fffffffff',fp.read(floatsize*9)) Pxyz_c = struct.unpack('>fff',fp.read(floatsize*3))
unused_space_size = unused_space_size - USED_SPACE_SIZE
for i in range(unused_space_size): struct.unpack('>b',fp.read(charsize))[0]
nv = ndim1 * ndim2 * ndim3 * nframes vol = numpy.fromstring(fp.read(floatsize*nv),dtype=numpy.float32).byteswap()
nvert = max([ndim1,ndim2,ndim3]) vol = numpy.reshape(vol,(ndim1,ndim2,ndim3,nframes),order='F') vol = numpy.squeeze(vol) fp.close()
return vol
-------------- Padraig.
Yaroslav Halchenko wrote:
actually I need thickness data out of it. Is .mgh format documented somewhere?
On Thu, 24 Apr 2008, Pádraig Kitterick wrote:
How much detail do you need frmo the mgh file? I wrote a quick Python script which reads in at least the volume data but I think I just passed over most of the other stuff in there...
Yaroslav Halchenko wrote:
Does anyone know any handy module to at least read in .mgh files from Python? Or should I simply try mri_convert them into .minc and use netcdf module within python?
Thanks in advance for the ideas!
Pádraig is correct in stating that thickness data can be stored in an mgh file. But the default output of the freesurer recon-all stream does not store them in that format: it will output ?h.thickness files, which are the proprietary format.
However, those can be converted to .mgh like this:
mris_convert -c lh.thickness lh.inflated lh.thickness.mgh
or to ascii like this:
mris_convert -c lh.thickness lh.inflated lh.thickness.asc
But I doubt that helps too much, since I'm guessing you want to avoid having to use the freesurfer binaries and want to just read the files directly.
Nick
On Thu, 2008-04-24 at 17:09 +0100, Pádraig Kitterick wrote:
MGH is just a generic volume-based format so I think thickness data will be stored in a 1xNumVerticesx1x1 volume. Here is a python function which reads in the volume data. It's basically a translation of the readmgh function from the Freesurfer matlab toolbox. You can modify it to return more parts of the file data if necessary...
import struct import numpy
def read_mgh(filename): fp = open(filename,'rb') intsize = struct.calcsize('>i') shortsize = struct.calcsize('>h') floatsize = struct.calcsize('>f') charsize = struct.calcsize('>b')
v = struct.unpack('>i',fp.read(intsize))[0] ndim1 = struct.unpack('>i',fp.read(intsize))[0] ndim2 = struct.unpack('>i',fp.read(intsize))[0] ndim3 = struct.unpack('>i',fp.read(intsize))[0] nframes = struct.unpack('>i',fp.read(intsize))[0] vtype = struct.unpack('>i',fp.read(intsize))[0] dof = struct.unpack('>i',fp.read(intsize))[0] UNUSED_SPACE_SIZE = 256 USED_SPACE_SIZE = (3*4) + (4*3*4) # space for ras transform unused_space_size = UNUSED_SPACE_SIZE - 2 ras_good_flag = struct.unpack('>h',fp.read(shortsize))[0] if ras_good_flag: # We read these in but don't process them # as we just want to move to the volume data delta = struct.unpack('>fff',fp.read(floatsize*3)) Mdc = struct.unpack('>fffffffff',fp.read(floatsize*9)) Pxyz_c = struct.unpack('>fff',fp.read(floatsize*3)) unused_space_size = unused_space_size - USED_SPACE_SIZE for i in range(unused_space_size): struct.unpack('>b',fp.read(charsize))[0] nv = ndim1 * ndim2 * ndim3 * nframes vol =numpy.fromstring(fp.read(floatsize*nv),dtype=numpy.float32).byteswap()
nvert = max([ndim1,ndim2,ndim3]) vol = numpy.reshape(vol,(ndim1,ndim2,ndim3,nframes),order='F') vol = numpy.squeeze(vol) fp.close() return vol
Padraig.
Yaroslav Halchenko wrote:
actually I need thickness data out of it. Is .mgh format documented somewhere?
On Thu, 24 Apr 2008, Pádraig Kitterick wrote:
How much detail do you need frmo the mgh file? I wrote a quick Python script which reads in at least the volume data but I think I just passed over most of the other stuff in there...
Yaroslav Halchenko wrote:
Does anyone know any handy module to at least read in .mgh files from Python? Or should I simply try mri_convert them into .minc and use netcdf module within python?
Thanks in advance for the ideas!
Thank everyone for very informative comments!
I am a newbie in freesurfer myself, I just got a dataset for the analysis (data was preprocessed in freesurfer), and since I am moving myself toward doing any analysis in python, and the tools I use now are python libraries, I wanted to load the data in python.
What I got was
$> /bin/ls -R .: lh.exper_dossdintnoage.glmdir rh.exper.thickness.10.mgh lh.exper.thickness.10.mgh rh.exper_dossdintnoage.glmdir
./lh.exper_dossdintnoage.glmdir: ar1.mgh beta.mgh dossdintnoage eres.mgh fsgd.X.mat mri_glmfit.log rstd.mgh rvar.mgh Xg.dat y.fsgd
./lh.exper_dossdintnoage.glmdir/dossdintnoage: C.dat F.mgh gamma.mgh maxvox.dat sig.mgh
./rh.exper_dossdintnoage.glmdir: ar1.mgh beta.mgh dossdintnoage eres.mgh fsgd.X.mat mri_glmfit.log rstd.mgh rvar.mgh Xg.dat y.fsgd
./rh.exper_dossdintnoage.glmdir/dossdintnoage: C.dat F.mgh gamma.mgh maxvox.dat sig.mgh
Also there is a directory on top $> ls ../EXPERAVE/ 4 label/ 0 mri/ 0 scripts/ 4 stats/ 4 surf/ 0 tmp/ for the avg subject
If I understand it right, .glmdir are just the result of glm analysis which I am not interested in at the moment. I wanted to get thickness out, thus {l,r}h.exper.thickness.10.mgh seemed the one I needed ;) I'm not sure if they originally were in the proprietary format...
if I got it right mris_convert needs original mesh (lh.inflated) which was used for the lh.exper.thickness.10.mgh. I have a few for avg subject, but I am not sure which one (inflated or not) was used for generation of the thickness or is the thickness mesh independent somehow?
On Thu, 24 Apr 2008, Nick Schmansky wrote:
But I doubt that helps too much, since I'm guessing you want to avoid having to use the freesurfer binaries and want to just read the files directly.
well, I can leave with 1 time conversion ;) Having direct interface from python is a neat thing to have though. by ldd on mris_convert and its size (3MB) I guess freesurfer statically compiles in IO functionality in. It would be great if there just was a dynamic library which does IO. Then it could be quite easy to create python wrapper which would use it more or less directly...
Nick
Hi Yaroslav and Pádraig,
Please follow the link pasted below to get an alpha version of pymgh. It requires the latest Python and Numpy.
https://www.nmr.mgh.harvard.edu/facility/filedrop/showgroup/10224/1/2a5da2a1... (expires in 30 days )
Make sure PYTHONPATH has the directory which contains 'pymgh'. Found by typing,
import sys sys.path
As far as the usage goes, pymgh basically instantiates a "MGH" class ( which contains details about the header as well as the data ) when you call the load() method. There is a class save() method as well as a module save() method ( static function) The following examples will throw more light.
from pymgh import mgh m = mgh.MGH() m.load('test.mgz') # this loads information from test.mgz onto m. Both .mgh and .mgz work
m.header # see the header information
m.vol # the N-D numpy volume of the same datatype as mri_type
v = m.vol * 3 # some basic manipulation
m.save(filename = 'modtest.mgz', volume = v ) # save the new volume with same headers onto a different file
There is also a module method mgh.save() which requires all keyword arguments. More documentation on functions are found in their docstrings and I am afraid it's the only documentation available now. pymgh mostly follows the structure in the wiki page describing MGHformat. And the resulting Numpy volume has the exact shape as the MATLAB volume loaded by load_mgh.m
This package is fresh, so expect surprises. I request you to go to the tests/ directory and run the test_mgh_io.py before everything. It has a few basic sanity tests.
cd tests/ python test_mgh_io.py -v 2
Contact me ( krish @ nmr... ) if you want to report a bug / suggestions etc.
Thanks Krish
On Apr 24, 2008, at 1:23 PM, Yaroslav Halchenko wrote:
well, I can leave with 1 time conversion ;) Having direct interface from python is a neat thing to have though. by ldd on mris_convert and its size (3MB) I guess freesurfer statically compiles in IO functionality in. It would be great if there just was a dynamic library which does IO. Then it could be quite easy to create python wrapper which would use it more or less directly...
Hi Krish,
Thanks once again for providing that library. I came back to analyze the data and got some problems storing the results into MGH format. Before I try to figure out a fix (and send it back to you) I thought that may be you could share an uptodated snapshot of the library (may be the issue I am experiencing was already fixed).
Thank you in advance!
On Thu, 24 Apr 2008, Krish Subramaniam wrote:
Hi Yaroslav and Pádraig,
Please follow the link pasted below to get an alpha version of pymgh. It requires the latest Python and Numpy.
https://www.nmr.mgh.harvard.edu/facility/filedrop/showgroup/10224/1/2a5da2a1... (expires in 30 days )
Make sure PYTHONPATH has the directory which contains 'pymgh'. Found by typing,
freesurfer@nmr.mgh.harvard.edu