<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Research: Math, Computing and MRI &#187; Python</title>
	<atom:link href="http://mri.brechmos.org/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://mri.brechmos.org</link>
	<description>by Craig Jones</description>
	<lastBuildDate>Wed, 10 Aug 2011 16:53:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Python plots with no display</title>
		<link>http://mri.brechmos.org/2010/02/python-plots-with-no-display/</link>
		<comments>http://mri.brechmos.org/2010/02/python-plots-with-no-display/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 01:43:37 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://mri.brechmos.org/?p=577</guid>
		<description><![CDATA[I have been working on some offline processing of data and creating graphs on the fly which automatically get updated on a website. What has been problematic is to do this without a display (for example run from a cron &#8230; <a href="http://mri.brechmos.org/2010/02/python-plots-with-no-display/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I have been working on some offline processing of data and creating graphs on the fly which automatically get updated on a website.  What has been problematic is to do this without a display (for example run from a cron job).  I <a href="http://www.dalkescientific.com/writings/diary/archive/2005/04/23/matplotlib_without_gui.html">found a solution</a> which seems to work with the EPD package I am using on a linux box.</p>
<p>[cc lang="python"]<br />
from matplotlib.figure import Figure<br />
from matplotlib.backends.backend_agg import FigureCanvasAgg</p>
<p>fig = Figure(figsize=(4,4))<br />
fig.gca().plot(range(1,10))<br />
canvas=FigureCanvasAgg(fig)<br />
canvas.print_figure(&#8216;bob.png&#8217;, dpi=150)<br />
[/cc]</p>
<p>There are likely some other ways to do it, but this works for me.</p>
]]></content:encoded>
			<wfw:commentRss>http://mri.brechmos.org/2010/02/python-plots-with-no-display/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reading Raw Data in Python</title>
		<link>http://mri.brechmos.org/2010/02/reading-raw-data-in-python/</link>
		<comments>http://mri.brechmos.org/2010/02/reading-raw-data-in-python/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 02:25:50 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://mri.brechmos.org/?p=559</guid>
		<description><![CDATA[In a similar vein to reading raw data into Matlab, I created a similar type of function in Python: [cc lang="python"] def readraw(filename, shape, intype=&#8217;int16&#8242;, byteSwap=False): &#8220;&#8221;" readraw &#8211; To read in a raw file and reformat it to the &#8230; <a href="http://mri.brechmos.org/2010/02/reading-raw-data-in-python/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In a similar vein to <a href="http://mri.brechmos.org/2010/02/01/reading-raw-data-in-matlab/">reading raw data into Matlab</a>, I created a similar type of function in Python:</p>
<p>[cc lang="python"]<br />
def readraw(filename, shape, intype=&#8217;int16&#8242;, byteSwap=False):<br />
        &#8220;&#8221;" readraw &#8211; To read in a raw file and reformat it to the right shape &#8220;&#8221;"</p>
<p>        #  Read in the file<br />
        if filename.endswith(&#8216;gz&#8217;):<br />
                fp = gzip.open(filename, &#8216;rb&#8217;)<br />
        else:<br />
                fp = open(filename, &#8216;rb&#8217;)</p>
<p>        d = fromfile(file=fp, dtype=intype).reshape(shape)</p>
<p>        d.byteswap(byteSwap)</p>
<p>        return d<br />
[/cc]</p>
]]></content:encoded>
			<wfw:commentRss>http://mri.brechmos.org/2010/02/reading-raw-data-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Anisotropic Diffusion Image Filtering in MRI</title>
		<link>http://mri.brechmos.org/2010/01/anisotropic-diffusion-image-filtering-in-mri/</link>
		<comments>http://mri.brechmos.org/2010/01/anisotropic-diffusion-image-filtering-in-mri/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 03:25:51 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Matlab]]></category>
		<category><![CDATA[MRI]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://mri.brechmos.org/?p=432</guid>
		<description><![CDATA[Background Magnetic resonance imaging has the tradeoff of signal-to-noise vs time vs resolution.  You can only choose two. For some applications it may be better to get higher temporal and spatial resolution than signal-to-noise and then one may do some &#8230; <a href="http://mri.brechmos.org/2010/01/anisotropic-diffusion-image-filtering-in-mri/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>Background</h2>
<p>Magnetic resonance imaging has the tradeoff of signal-to-noise vs time vs resolution.  You can only choose two. For some applications it may be better to get higher temporal and spatial resolution than signal-to-noise and then one may do some spatial filtering.  Simple filtering would be applying a median filter or Gaussian smoothing over the image (or volume).  But there are better techniques.</p>
<h2>Smarter Filtering</h2>
<p>One option for a smarter filter is the anisotropic diffusion filter which was first introduced to MRI in 1992 ((G. Gerig et al., “Nonlinear anisotropic filtering of MRI data,” <span style="font-style: italic;">Medical Imaging, IEEE Transactions on</span> 11, no. 2 (1992): 221-232.<span class="Z3988" title="url_ver=Z39.88-2004&amp;ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Ajournal&amp;rft.genre=article&amp;rft.atitle=Nonlinear%20anisotropic%20filtering%20of%20MRI%20data&amp;rft.jtitle=Medical%20Imaging%2C%20IEEE%20Transactions%20on&amp;rft.stitle=Medical%20Imaging%2C%20IEEE%20Transactions%20on&amp;rft.volume=11&amp;rft.issue=2&amp;rft.aufirst=G.&amp;rft.aulast=Gerig&amp;rft.au=G.%20Gerig&amp;rft.au=O.%20Kubler&amp;rft.au=R.%20Kikinis&amp;rft.au=F.A.%20Jolesz&amp;rft.date=1992&amp;rft.pages=221-232&amp;rft.issn=0278-0062"> </span>)).  The basic idea is given a central voxel in a kernel and an estimation of noise the surrounding voxels are included in the smoothing based on the difference in signal to the central voxel relative to the estimation of noise.</p>
<p>I wrote a paper on this technique applied to multi-echo data ((Craig K Jones, Kenneth P Whittall, and Alex L MacKay, “Robust myelin water quantification: averaging vs. spatial filtering,” Magnetic Resonance in Medicine: Official Journal of the Society of Magnetic Resonance in Medicine / Society of Magnetic Resonance in Medicine 50, no. 1 (July 2003): 206-209)).</p>
<p>There is a fine line between filtering and over-filtering.  That is a whole separate discussion.</p>
<table>
<caption> The images below are a single slice of an MPRAGE image without filtering (left) and with anisotropic diffusion filtering (right).  The bottom set are just zoomed in versions of the top.  The filtered data might be slightly over filtered but was done to show the affect of the filter.<br />
</caption>
<tbody>
<tr>
<td><a rel="attachment wp-att-468" href="http://mri.brechmos.org/2010/01/19/anisotropic-diffusion-image-filtering-in-mri/mprage_noaniso-2/"><img class="alignnone size-medium wp-image-468" title="mprage_noaniso" src="http://mri.brechmos.org/wp-content/uploads/2010/01/19/anisotropic-diffusion-image-filtering-in-mri/mprage_noaniso1-450x450.png" alt="" width="350" /></a></td>
<td><a rel="attachment wp-att-466" href="http://mri.brechmos.org/2010/01/19/anisotropic-diffusion-image-filtering-in-mri/mprage_aniso-2/"><img class="alignnone size-medium wp-image-466" title="mprage_aniso" src="http://mri.brechmos.org/wp-content/uploads/2010/01/19/anisotropic-diffusion-image-filtering-in-mri/mprage_aniso1-449x450.png" alt="" width="350" /></a></td>
</tr>
<tr>
<td><a rel="attachment wp-att-469" href="http://mri.brechmos.org/2010/01/19/anisotropic-diffusion-image-filtering-in-mri/mprage_noaniso_zoomed-2/"><img class="alignnone size-medium wp-image-469" title="mprage_noaniso_zoomed" src="http://mri.brechmos.org/wp-content/uploads/2010/01/19/anisotropic-diffusion-image-filtering-in-mri/mprage_noaniso_zoomed1-277x450.png" alt="" width="277" height="450" /></a></td>
<td><a rel="attachment wp-att-467" href="http://mri.brechmos.org/2010/01/19/anisotropic-diffusion-image-filtering-in-mri/mprage_aniso_zoomed-2/"><img class="alignnone size-medium wp-image-467" title="mprage_aniso_zoomed" src="http://mri.brechmos.org/wp-content/uploads/2010/01/19/anisotropic-diffusion-image-filtering-in-mri/mprage_aniso_zoomed1-275x450.png" alt="" width="275" height="450" /></a></td>
</tr>
</tbody>
</table>
<h2>Code</h2>
<h3>Matlab</h3>
<p>The version below is for a 3D dataset:<br />
[cc lang="matlab"]</p>
<p>function [filt_vol] = aniso3d(orig_vol, kappa, niters)</p>
<p>if( nargin &lt; 3 )<br />
error(&#8216;aniso3d: Need more parameters&#8217;);<br />
end</p>
<p>filt_vol = orig_vol;</p>
<p>for iters = 1:niters</p>
<p>    dE = convn(filt_vol, [0 -1 1], &#8216;full&#8217;); dE=dE(:,2:ncols(dE)-1,:);<br />
    dW = convn(filt_vol, [-1 1 0], &#8216;full&#8217;); dW=dW(:,2:ncols(dW)-1,:);<br />
    dN = convn(filt_vol, [0; -1; 1], &#8216;full&#8217;); dN=dN(2:nrows(dN)-1,:,:);<br />
    dS = convn(filt_vol, [-1; 1; 0], &#8216;full&#8217;); dS=dS(2:nrows(dS)-1,:,:);<br />
    kernel = zeros(1,1,3); kernel(2) = -1; kernel(3) = 1;<br />
    dU = convn(filt_vol, kernel, &#8216;full&#8217;); dU=dU(:,:,2:size(dU,3)-1);<br />
    kernel = zeros(1,1,3); kernel(1) = -1; kernel(2) = 1;<br />
    dD = convn(filt_vol, kernel, &#8216;full&#8217;); dD=dD(:,:,2:size(dD,3)-1);</p>
<p>    filt_vol = filt_vol +  &#8230;<br />
        3/28 * ((double(exp(- (abs(dE) / kappa).^2 )) .* double(dE)) &#8211; (double(exp(- (abs(dW) / kappa).^2 )) .* double(dW))) + &#8230;<br />
        3/28 * ((double(exp(- (abs(dN) / kappa).^2 )) .* double(dN)) &#8211; (double(exp(- (abs(dS) / kappa).^2 )) .*  double(dS))) + &#8230;<br />
        1/28 * ((double(exp(- (abs(dU) / kappa).^2 )) .* double(dU)) &#8211; (double(exp(- (abs(dD) / kappa).^2 )) .* double(dD)));<br />
end<br />
[/cc]</p>
<p>For 4D data one can also smooth across the 4th dimension (whether it is time, diffusion etc).<br />
[cc lang="matlab"]<br />
function [filt_vol] = aniso3d_chan(orig_vol, kappa, niters)<br />
%<br />
%  aniso3d_chan &#8211; Run the anisotropic diffusion filter in 3D<br />
%                 and over the multiple channels.<br />
%</p>
<p>if( nargin &lt; 3 )<br />
error(&#8216;aniso3d: Need more parameters&#8217;);<br />
end</p>
<p>filt_vol = float(squeeze(orig_vol));</p>
<p>for iters = 1:niters<br />
    dE = convn(filt_vol, [0 -1 1], &#8216;full&#8217;); dE=dE(:,2:ncols(dE)-1,:,:);<br />
    cE = repmat(sqrt(sum(dE.^2, 4)), [1 1 1 size(dE,4)]);<br />
    filt_vol = filt_vol + 3/28 * ((exp(- (cE / kappa).^2 )) .* (dE));<br />
    clear cE;<br />
    clear dE;</p>
<p>    dW = convn(filt_vol, [-1 1 0], &#8216;full&#8217;); dW=dW(:,2:ncols(dW)-1,:,:);<br />
    cW = repmat(sqrt(sum(dW.^2, 4)), [1 1 1 size(dW,4)]);<br />
    filt_vol = filt_vol &#8211; 3/28 * ((exp(- (cW / kappa).^2 )) .* (dW));<br />
    clear dW;<br />
    clear cW;</p>
<p>    dN = convn(filt_vol, [0; -1; 1], &#8216;full&#8217;); dN=dN(2:nrows(dN)-1,:,:,:);<br />
    cN = repmat(sqrt(sum(dN.^2, 4)), [1 1 1 size(dN,4)]);<br />
    filt_vol = filt_vol + 3/28 * ((exp(- (cN / kappa).^2 )) .* (dN));<br />
    clear dN;<br />
    clear cN;</p>
<p>    dS = convn(filt_vol, [-1; 1; 0], &#8216;full&#8217;); dS=dS(2:nrows(dS)-1,:,:,:);<br />
    cS = repmat(sqrt(sum(dS.^2, 4)), [1 1 1 size(dS,4)]);<br />
    filt_vol = filt_vol &#8211; 3/28 * ((exp(- (cS / kappa).^2 )) .* (dS));<br />
    clear cS;<br />
    clear dS;</p>
<p>    kernel = zeros(1,1,3); kernel(2) = -1; kernel(3) = 1;<br />
    dU = convn(filt_vol, kernel, &#8216;full&#8217;); dU=dU(:,:,2:size(dU,3)-1,:);<br />
    cU = repmat(sqrt(sum(dU.^2, 4)), [1 1 1 size(dS,4)]);<br />
    filt_vol = filt_vol + 1/28 * ((exp(- (cU / kappa).^2 )) .* (dU));<br />
    clear dU;<br />
    clear cU;</p>
<p>    kernel = zeros(1,1,3); kernel(1) = -1; kernel(2) = 1;<br />
    dD = convn(filt_vol, kernel, &#8216;full&#8217;); dD=dD(:,:,2:size(dD,3)-1,:);<br />
    cD = repmat(sqrt(sum(dD.^2, 4)), [1 1 1 size(dS,4)]);<br />
    filt_vol = filt_vol &#8211; 1/28 * ((exp(- (cD / kappa).^2 )) .* (dD));<br />
    clear dD;<br />
    clear cD;<br />
end<br />
[/cc]</p>
<h3>Python</h3>
<p>The Python code is very similar to the Matlab code above.  It does 2D images or 3D volumes, but I have not coded the smoothing across the 4th dimension.  That will have to be done later.<br />
[cc lang="python"]<br />
def aniso(v, kappa=-1, N=1):</p>
<p>        if kappa == -1:<br />
                kappa = prctile(v, 40)</p>
<p>        vf = v.copy()</p>
<p>        for ii in range(N):<br />
                dE = -vf + roll(vf,-1,0)<br />
                dW = vf &#8211; roll(vf,1,0)</p>
<p>                dN = -vf + roll(vf,-1,1)<br />
                dS = vf &#8211; roll(vf,1,1)</p>
<p>                if len(v.shape) > 2:<br />
                        dU = -vf + roll(vf,-1,2)<br />
                        dD = vf &#8211; roll(vf,1,2)</p>
<p>                vf = vf + \<br />
                        3./28. * ((exp(- (abs(dE) / kappa)**2 ) * dE) &#8211; (exp(- (abs(dW) / kappa)**2 ) * dW)) + \<br />
                        3./28. * ((exp(- (abs(dN) / kappa)**2 ) * dN) &#8211; (exp(- (abs(dS) / kappa)**2 ) * dS))<br />
                if len(v.shape) > 2:<br />
                        vf += 1./28. * ((exp(- (abs(dU) / kappa)**2 ) * dU) &#8211; (exp(- (abs(dD) / kappa)**2 ) * dD)) </p>
<p>        return vf<br />
[/cc]</p>
]]></content:encoded>
			<wfw:commentRss>http://mri.brechmos.org/2010/01/anisotropic-diffusion-image-filtering-in-mri/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Noise in MRI (magnitude) data</title>
		<link>http://mri.brechmos.org/2010/01/noise-in-mri-magnitude-data/</link>
		<comments>http://mri.brechmos.org/2010/01/noise-in-mri-magnitude-data/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 04:53:00 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Matlab]]></category>
		<category><![CDATA[MRI]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://mri.brechmos.org/?p=355</guid>
		<description><![CDATA[Background Magnitude MRI data has Rician noise distribution by definition ((Hákon Gudbjartsson and Samuel Patz, “The Rician Distribution of Noisy MRI Data,” Magnetic resonance in medicine : official journal of the Society of Magnetic Resonance in Medicine / Society of &#8230; <a href="http://mri.brechmos.org/2010/01/noise-in-mri-magnitude-data/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>Background</h2>
<p>Magnitude MRI data has<a href="http://en.wikipedia.org/wiki/Rice_distribution"> Rician noise distribution</a> by definition ((Hákon Gudbjartsson and Samuel Patz, “The Rician Distribution of Noisy MRI Data,” Magnetic resonance in medicine : official journal of the Society of Magnetic Resonance in Medicine / Society of Magnetic Resonance in Medicine 34, no. 6 (December 1995): 910-914)).  It comes about because two channels each with Gaussian noise are squared and added together ((R M Henkelman, “Measurement of signal intensities in the presence of noise in MR images,” Medical Physics 12, no. 2 (April 1985): 232-233.)).  There is a <a href="/research/magnetic-resonance-imaging/noise-in-mri-magnitude-data">longer description here</a>.</p>
<h2>Modeling</h2>
<p>The Rician noise is created as $latex y_e(t_i) = \sqrt{ \left[y(t_i) + e_1 \right]^2 + e_2^2 }$, where $latex y$ is the true signal, and $latex e_1$ and $latex e_2$ are random numbers from a Gaussian distribution with zero mean and standard deviation $latex \sigma$.  The standard deviation, $latex \sigma$, for the Gaussian distribution is related to the signal to noise ratio and is typically on the order of 1% &#8211; 10% of the signal $latex y$.</p>
<h2>Code</h2>
<p>It is relatively easy to model this using Matlab or Python. For the code here I am modeling a T2 decay curve and then the noise.</p>
<h3>Matlab</h3>
<p>[cc lang="matlab"]</p>
<p>%  Setup the initial variables<br />
rho = 100;<br />
t2 = 80; % in ms<br />
te = 10:10:320;  % in ms</p>
<p>%  Create a T2 decay curve<br />
y = rho * exp(-te / t2 );</p>
<p>%  Define the noise to be 5% of the signal<br />
s = 5;</p>
<p>%  Create the two Gaussian random variable vectors<br />
e1 = s * randn(size(y));<br />
e2 = s * randn(size(y));</p>
<p>%  Now create the new, noisy decay curve.<br />
y_e = sqrt( (y+e1).^2 + (e2).^2 );</p>
<p>[/cc]</p>
<h3>Python</h3>
<p>The Python version is quite similar.</p>
<p>[cc lang="python"]</p>
<p>from __future__ import division</p>
<p>#  Setup the initial variables<br />
rho = 100<br />
t2 = 80 # in ms<br />
te = r_[10:330:10] # in ms</p>
<p>#  Create a T2 decay curve<br />
y = rho * exp( -te / t2 )</p>
<p>#  Define the noise to be 5% of the signal<br />
s = 5;</p>
<p>#  Create the two Gaussian random variable vectors<br />
e1 = normal(0, 5, y.shape)<br />
e2 = normal(0, 5, y.shape)</p>
<p>#  Now create the new, noisy decay curve.<br />
y_e = sqrt( (y+e1)**2 + (e2)**2 );</p>
<p>[/cc]</p>
<p>There are a couple of small gotcha&#8217;s that at least tripped me up as I am still relatively new to Python.</p>
<ol>
<li>The first is that <a href="http://www.python.org/dev/peps/pep-0238/">under Python 2.x all data is processed as integer</a> (not doubles, as the default is in Matlab).  Supposedly this is going to change in Python 3, but to get around it for now, the best thing to do is to add the [cci lang="python"]from __future__ import divison[/cci].</li>
<li>To define [cci lang="python"]te[/cci] I had to go to 330, rather than 320 as the generator is an open set on the higher end so it does not include the number.</li>
<li>There are several options for creating the random numbers.  There is a Python module called [cci lang="python"]random[/cci] that could be used.  Instead I used the Numpy [cci lang="python"]normal[/cci] instead as I can pass in the shape parameter.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://mri.brechmos.org/2010/01/noise-in-mri-magnitude-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Change font size of tick labels</title>
		<link>http://mri.brechmos.org/2010/01/change-font-size-of-tick-labels/</link>
		<comments>http://mri.brechmos.org/2010/01/change-font-size-of-tick-labels/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 19:23:59 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://mri.brechmos.org/?p=35</guid>
		<description><![CDATA[For making figures it is sometimes important (or quite important) to increase the font size of the x or y ticklabels. Here is one way I found to do it: [cc lang="python"] fig1 = figure() for t in gca().get_yticklabels(): t.set_fontsize(14) &#8230; <a href="http://mri.brechmos.org/2010/01/change-font-size-of-tick-labels/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For making figures it is sometimes important (or quite important) to increase the font size of the x or y ticklabels. Here is one way I found to do it:</p>
<p>[cc lang="python"]<br />
fig1 = figure()<br />
for t in gca().get_yticklabels():<br />
    t.set_fontsize(14)</p>
<p>fig1.canvas.draw()</p>
<p>[/cc]</p>
<p>For some reason there has to be a [cci lang="python"]fig1.canvas.draw()[/cci] at the end of this to refresh the figure.</p>
<p><a rel="attachment wp-att-279" href="http://mri.brechmos.org/2010/01/12/change-font-size-of-tick-labels/plot_small_ticklabels/"><img class="alignleft size-medium wp-image-279" title="plot_small_ticklabels" src="http://mri.brechmos.org/wp-content/uploads/2010/01/12/change-font-size-of-tick-labels/plot_small_ticklabels-450x337.png" alt="" width="450" height="337" /></a><a rel="attachment wp-att-280" href="http://mri.brechmos.org/2010/01/12/change-font-size-of-tick-labels/plot_larger_ticklabels/"><img class="size-medium wp-image-280 alignleft" title="plot_larger_ticklabels" src="http://mri.brechmos.org/wp-content/uploads/2010/01/12/change-font-size-of-tick-labels/plot_larger_ticklabels-450x337.png" alt="" width="450" height="337" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://mri.brechmos.org/2010/01/change-font-size-of-tick-labels/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finding coordinates in MRI data volumes</title>
		<link>http://mri.brechmos.org/2010/01/finding-coordinates-in-mri-data-volumes/</link>
		<comments>http://mri.brechmos.org/2010/01/finding-coordinates-in-mri-data-volumes/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 19:22:42 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://mri.brechmos.org/?p=32</guid>
		<description><![CDATA[I find myself wanting to run through a list of (x,y,z) coordinates of some data volume (here called “d”) to do some sort of processing on each voxel. What I have come up with is the following… First, find the &#8230; <a href="http://mri.brechmos.org/2010/01/finding-coordinates-in-mri-data-volumes/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-273" href="http://mri.brechmos.org/2010/01/12/finding-coordinates-in-mri-data-volumes/mprage-2/"><img class="alignright size-medium wp-image-273" title="mprage" src="http://mri.brechmos.org/wp-content/uploads/2010/01/12/finding-coordinates-in-mri-data-volumes/mprage1-398x450.png" alt="" width="287" height="324" /></a>I find myself wanting to run through a list of (x,y,z) coordinates of some data volume (here called “d”) to do some sort of processing on each voxel. What I have come up with is the following…</p>
<p>First, find the set of coordinates that match some criterion. For example, find all coordinates in “d” that are greater than the 70<sup>th</sup> percentile:<br />
[cc lang="python"]coords = array( nonzero( d &gt; prctile( d, 70 ) ) ).transpose()[/cc]<br />
Now that we have the list of coordinates, we can run through each coordinate and do some sort of processing on it:<br />
[cc lang="python"]<br />
for ii,coord in enumerate( coords ):<br />
    r = coord[0]<br />
    c = coord[1]</p>
<p># more stuff here<br />
[/cc]<br />
Obviously if you are using a 3 dimensional volume &#8220;d&#8221; then you would use:<br />
[cc lang="python"]<br />
    s = coord[0]<br />
    r = coord[2]<br />
    c = coord[2]<br />
[/cc]</p>
]]></content:encoded>
			<wfw:commentRss>http://mri.brechmos.org/2010/01/finding-coordinates-in-mri-data-volumes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Project Euler</title>
		<link>http://mri.brechmos.org/2010/01/project-euler/</link>
		<comments>http://mri.brechmos.org/2010/01/project-euler/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 02:16:55 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Math]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://mri.brechmos.org/?p=24</guid>
		<description><![CDATA[A very interesting Math type website is Project Euler. There are over 250 mathematical problems to solve in varying degrees of difficulty. The basic idea is to attempt to solve the problem using snippets of code such that the run &#8230; <a href="http://mri.brechmos.org/2010/01/project-euler/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://mri.brechmos.org/wp-content/uploads/2010/01/05/project-euler/project_euler1.jpg"><img class="alignright size-full wp-image-65" title="project_euler" src="http://mri.brechmos.org/wp-content/uploads/2010/01/05/project-euler/project_euler1.jpg" alt="" width="203" height="71" /></a>A very interesting Math type website is <a title="http://www.projecteuler.net" rel="nofollow" href="http://www.projecteuler.net/"> Project Euler</a>. There are over 250 mathematical problems to solve in varying degrees of difficulty. The basic idea is to attempt to solve the problem using snippets of code such that the run time is less than 1 minute.</p>
<p>I have used this website to learn Python and have had great fun figuring out different ways of solving the problems. I can&#8217;t say all mine have completed in less than a minute, but getting there.<a href="http://mri.brechmos.org/wp-content/uploads/2010/01/05/project-euler/project_euler.jpg"><img class="alignright size-full wp-image-25" title="project_euler" src="http://mri.brechmos.org/wp-content/uploads/2010/01/05/project-euler/project_euler.jpg" alt="" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://mri.brechmos.org/2010/01/project-euler/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python code for reading in Varian FDF files</title>
		<link>http://mri.brechmos.org/2010/01/python-code-for-reading-in-varian-fdf-files/</link>
		<comments>http://mri.brechmos.org/2010/01/python-code-for-reading-in-varian-fdf-files/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 02:58:35 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://mri.brechmos.org/?p=338</guid>
		<description><![CDATA[Below is a Python class that will read in a Varian FDF file, or a Varian &#8220;.img&#8221; directory (which contains the FDF files). I have used this in the past, but can&#8217;t make any claims about it. I offer it &#8230; <a href="http://mri.brechmos.org/2010/01/python-code-for-reading-in-varian-fdf-files/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Below is a Python class that will read in a Varian FDF file, or a Varian &#8220;.img&#8221; directory (which contains the FDF files).  I have used this in the past, but can&#8217;t make any claims about it.  I offer it up in hopes it is useful to someone.</p>
<p>[cc lang="python"]<br />
import os<br />
import re<br />
from numpy import *<br />
import struct</p>
<p>class Varian:</p>
<p>	def __init__(self):<br />
		pass</p>
<p>	def read( self, filename ):<br />
		if filename.endswith(&#8216;.fdf&#8217;):<br />
			data = self.readFDF( filename )<br />
		elif filename.endswith(&#8216;.img&#8217;):<br />
			data = self.readIMG( filename )<br />
		else:<br />
			print &#8220;Unknown filename %s &#8221; % (filename)</p>
<p>		return data</p>
<p>	def readFDF(self, filename ):</p>
<p>		fp = open( filename, &#8216;rb&#8217; )</p>
<p>		xsize = -1<br />
		ysize = -1<br />
		zsize = 1<br />
		bigendian = -1<br />
		done = False</p>
<p>		while not done :</p>
<p>			line = fp.readline()	</p>
<p>			if( len( line ) >= 1 and line[0] == chr(12) ):<br />
				break</p>
<p>			if( len( line ) >= 1 and line[0] != chr(12) ):</p>
<p>				if( line.find(&#8216;bigendian&#8217;) > 0 ):<br />
					endian = line.split(&#8216;=&#8217;)[-1].rstrip(&#8216;\n; &#8216;).strip(&#8216; &#8216;)</p>
<p>				if( line.find(&#8216;echos&#8217;) > 0 ):<br />
					nechoes = line.split(&#8216;=&#8217;)[-1].rstrip(&#8216;\n; &#8216;).strip(&#8216; &#8216;)</p>
<p>				if( line.find(&#8216;echo_no&#8217;) > 0 ):<br />
					echo_no = line.split(&#8216;=&#8217;)[-1].rstrip(&#8216;\n; &#8216;).strip(&#8216; &#8216;)</p>
<p>				if( line.find(&#8216;nslices&#8217;) > 0 ):<br />
					nslices = line.split(&#8216;=&#8217;)[-1].rstrip(&#8216;\n; &#8216;).strip(&#8216; &#8216;)</p>
<p>				if( line.find(&#8216;slice_no&#8217;) > 0 ):<br />
					sl = line.split(&#8216;=&#8217;)[-1].rstrip(&#8216;\n; &#8216;).strip(&#8216; &#8216;)</p>
<p>				if( line.find(&#8216;matrix&#8217;) > 0 ):<br />
					m = re.findall(&#8216;(\d+)&#8217;, line.rstrip())</p>
<p>					if len(m) == 2:<br />
						xsize, ysize = int(m[0]), int(m[1])<br />
					elif len(m) == 3:<br />
						xsize, ysize, zsize = int(m[0]), int(m[1]), int(m[2])</p>
<p>		fp.seek(-xsize*ysize*zsize*4,2)</p>
<p>		if bigendian == 1:<br />
			fmt = &#8220;>%df&#8221; % (xsize*ysize*zsize)<br />
		else:<br />
			fmt = &#8220;<%df&#8221; % (xsize*ysize*zsize)</p>
<p>		data = struct.unpack(fmt, fp.read(xsize*ysize*zsize*4))<br />
		data = array( data ).reshape( [xsize, ysize, zsize ] ).squeeze()</p>
<p>		fp.close()</p>
<p>		return data</p>
<p>	def readIMG(self, directory):</p>
<p>		# Get a list of all the FDF files in the directory<br />
		try:<br />
			files = os.listdir(directory)<br />
		except:<br />
			print &#8220;Could not find the directory %s&#8221; % directory<br />
			return</p>
<p>		files = [ file for file in files if file.endswith('.fdf') ]</p>
<p>		data = []<br />
		for file in files:<br />
			data.append( self.readFDF( directory+&#8217;/'+file ) )</p>
<p>		data = transpose( array( data ), (1,2,0) ) </p>
<p>		return data</p>
<p>[/cc]</p>
]]></content:encoded>
			<wfw:commentRss>http://mri.brechmos.org/2010/01/python-code-for-reading-in-varian-fdf-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python Dicom</title>
		<link>http://mri.brechmos.org/2010/01/python-dicom/</link>
		<comments>http://mri.brechmos.org/2010/01/python-dicom/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 02:52:02 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://mri.brechmos.org/?p=336</guid>
		<description><![CDATA[There is a great Python package pydicom that implements a nice interface in order to be able to access data within Dicom files. One application which I wrote up was a dicom directory summarizer which goes through a list of &#8230; <a href="http://mri.brechmos.org/2010/01/python-dicom/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There is a great Python package <a href="http://code.google.com/p/pydicom/">pydicom</a> that implements a nice interface in order to be able to access data within Dicom files.</p>
<p>One application which I wrote up was a dicom directory summarizer which goes through a list of dicom files and summarizes the types of MRI data in the directory.  I found myself getting frustrated trying to figure out which series of data was which given the huge number of dicom files (with really long names too!) in a directory. </p>
<p>The code below may be run within a Dicom directory and should run on Siemens Dicom data (IMA) files.  It has been a while that I have run it so I can&#8217;t guarantee that it will work, but it should be a good place to start.</p>
<p>[cc lang="python"]<br />
#! /usr/bin/python</p>
<p>import dicom<br />
import os<br />
import re</p>
<p>def blah(val):<br />
	return re.compile(&#8216;[\-\w]+\.MR\.[\-\w]+\.\d+\.1\..*&#8217;).match(val, 1)</p>
<p># Get a list of all the files<br />
files = []<br />
for entry in os.listdir(&#8216;.&#8217;):<br />
	if ~os.path.isdir(entry) &#038; entry.endswith(&#8216;IMA&#8217;):<br />
		files.append(entry)</p>
<p># Filter to find the first of each series<br />
firsts = filter( blah, files )</p>
<p>firsts.sort(key=lambda s: int( re.compile(&#8216;[\-\w]+\.MR\.[\-\w]+\.(\d+)\.1\..*&#8217;).search(s).group(1)) )</p>
<p>#  Read the first and output some interesting stuff<br />
d = dicom.ReadFile(firsts[1])<br />
print &#8221; Patient: &#8221; + d.PatientsName<br />
print &#8220;Acquired: &#8221; + d.StudyDate[0:4]+&#8221;-&#8221;+d.StudyDate[4:6]+&#8221;-&#8221;+d.StudyDate[6:8] \<br />
	+ &#8221; &#8221; + d.StudyTime[0:2] + &#8220;:&#8221; + d.StudyTime[2:4] + &#8220;:&#8221; + d.StudyTime[4:6]<br />
print &#8220;Comments: &#8221; + d.ImageComments</p>
<p>#  Run through the first file of each of the series<br />
for entry in firsts:<br />
	d = dicom.ReadFile(entry)</p>
<p>	num = re.compile(&#8216;[\-\w]+\.MR\.[\-\w]+\.(\d+)\.1\..*&#8217;).search(entry).group(1)</p>
<p>	out =  &#8220;\t&#8221; + str(num) + &#8220;) &#8221; +  d.SeriesDescription </p>
<p>	tt = &#8216;[_\-\w]+\.MR\.[_\-\w]+\.&#8217;+str(num)+&#8217;\..*&#8217;<br />
	count = 0<br />
	r = re.compile(tt)<br />
	for f in files:<br />
		if( r.match(f, 1) ):<br />
			#print &#8220;%s matches %d&#8221; % (f, ii)<br />
			count = count + 1</p>
<p>	if( not re.compile(&#8220;.*(FA|TRACEW|TENSOR|ADC|MoCoSeries)$&#8221;).match(d.SeriesDescription, 1 ) ):<br />
		out += &#8221; (vols=&#8221; + str(count)</p>
<p>		if( &#8216;RepetitionTime&#8217; in d ):<br />
			out += &#8220;, TR=&#8221; + str(d.RepetitionTime)</p>
<p>		if( &#8216;EchoTime&#8217; in d ):<br />
			out += &#8220;, TE=&#8221; + str(d.EchoTime)</p>
<p>		out += &#8220;)&#8221;</p>
<p>	print out</p>
<p>[/cc]</p>
]]></content:encoded>
			<wfw:commentRss>http://mri.brechmos.org/2010/01/python-dicom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Progressbar</title>
		<link>http://mri.brechmos.org/2009/09/progressbar-2/</link>
		<comments>http://mri.brechmos.org/2009/09/progressbar-2/#comments</comments>
		<pubDate>Sun, 13 Sep 2009 18:41:58 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://mri.brechmos.org/?p=111</guid>
		<description><![CDATA[Much of my MR research is quite computationally expensive so there are many times that I have been sitting wondering how many times through a certain loop I have been.  Enter progressbar.  It is a nice small package which allows &#8230; <a href="http://mri.brechmos.org/2009/09/progressbar-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Much of my MR research is quite computationally expensive so there are many times that I have been sitting wondering how many times through a certain loop I have been.  Enter <a href="http://pypi.python.org/pypi/progressbar/2.2">progressbar</a>.  It is a nice small package which allows me to see, quite nicely, where I am in my loop.</p>
<p>Here is an example of what I typically do:</p>
<p>[cc lang="python"]</p>
<p>from progressbar import ProgressBar, Percentage, Bar, ETA</p>
<p>coords = array( numpy.nonzero( _data[-1] &gt; thresh ) ).transpose()</p>
<p>pbar = ProgressBar(widgets=['Calc Offset Map ', Percentage(), Bar(), ETA()], maxval=coords.shape[0]).start()</p>
<p>for ii,coord in enumerate(coords):</p>
<p># some big calculation here<br />
pbar.update(ii)</p>
<p>pbar.finish()</p>
<p>[/cc]</p>
<p>This gives me a really nice, informative and pleasing text progressbar.</p>
]]></content:encoded>
			<wfw:commentRss>http://mri.brechmos.org/2009/09/progressbar-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

