1

I've written some code that enables me to take data from DICOM files and separate the data into the individual FID signals.

from pylab import *
import dicom
import numpy as np
import scipy as sp

plan=dicom.read_file("1.3.46.670589.11.38085.5.22.3.1.4792.2013050818105496124")
all_points = array(plan.SpectroscopyData)
cmplx_data = all_points[0::2] -1j*all_points[1::2]
frames = int(plan.NumberOfFrames)
fid_pts = len(cmplx_data)/frames
del_t = plan.AcquisitionDuration / (frames * fid_pts)

fid_list = []
for fidN in arange(frames):
    offset = fidN * fid_pts 
    current_fid = cmplx_data[offset:offset+fid_pts]
    fid_list.append(current_fid)

I'd now like to quantify some of this data so, after applying a Fourier transform and shift I've tried to use Scipy's quad function and encountered the following error:

spec = fftshift(fft(fid_list[0])))
sp.integrate.quad(spec, 660.0, 700.0)



error                                     Traceback (most recent call last)
/home/dominicc/Experiments/In Vitro/Glu, Cr/Phantom 1: 10mM Cr, 5mM Glu/WIP_SV_PRESS_ME_128TEs_5ms_spacing_1828/<ipython-input-107-17cb50e45927> in <module>()
----> 1 sp.integrate.quad(fid, 660.0, 700.0)

/usr/lib/python2.7/dist-packages/scipy/integrate/quadpack.pyc in quad(func, a, b, args, full_output, epsabs, epsrel, limit, points, weight, wvar, wopts, maxp1, limlst)
243     if type(args) != type(()): args = (args,)
244     if (weight is None):
--> 245         retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points)
246     else:
247         retval = _quad_weight(func,a,b,args,full_output,epsabs,epsrel,limlst,limit,maxp1,weight,wvar,wopts)

/usr/lib/python2.7/dist-packages/scipy/integrate/quadpack.pyc in _quad(func, a, b, args, full_output, epsabs, epsrel, limit, points)
307     if points is None:
308         if infbounds == 0:
--> 309             return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
310         else:
311             return _quadpack._qagie(func,bound,infbounds,args,full_output,epsabs,epsrel,limit)

error: First argument must be a callable function.

Could somebody please suggest a way to make this object callable? I'm still not particularly clear after reading What is a "callable" in Python?. After reading that I tried

def fid():
    spec = fftshift(fft(fid_list[0])) 
    return spec

Which returned the same error.

Any help would be greatly appreciated, thanks.

Community
  • 1
  • 1
docar
  • 81
  • 2
  • 8
  • Shouldn't it be a function that takes an argument? How else can it be integrated? – Lev Levitsky May 09 '13 at 13:42
  • This question makes no sense. You cannot use `scipy.integrate.quad` to integrate an array. It integrates a *function* which takes an argument (like `sin(x)` for example). Use something like `scipy.integrate.simps` for integrating an array of function values. – talonmies May 09 '13 at 13:44

1 Answers1

4

Since you are integrating a function defined only on a grid (i.e., an array of numbers), you need to use one of the routines from "Integration, given fixed samples".

In fact, the first argument of quad() must be a function, something you can call (a "callable"). For instance, you can do:

>>> from scipy.integrate import quad
>>> def f(x):
...     return x**2
... 
>>> quad(f, 0, 1)
(0.33333333333333337, 3.700743415417189e-15)

This can be done instead by sampling f():

>>> from scipy.integrate import simps
>>> x_grid = numpy.linspace(0, 1, 101)  # 101 numbers between 0 and 1
>>> simps(x_grid**2, dx=x_grid[1]-x_grid[0])  # x_grid**2 is an *array*.  dx=0.01 between x_grid values
0.33333333333333337

Your situation is like in this second example: you integrate a sampled function, so it is natural to use one or cumtrapz(), simps() or romb().

Eric O Lebigot
  • 81,422
  • 40
  • 198
  • 249