Exemple #1
0
    def drawsurf1(self,steplist=None):
	'drawsurf1(self,steplist=None) - draw spectrum surface cell by stepwise'
	self.clearcanvas()
	self.createAxis()
	# use color table if ctable is set
	if self.ctable:
	    p = reshape(self.CT[self.ct],(256,3))
	    spec=[]
	    for i in range(256):
		pp = p[i]
		st = '#%02x%02x%02x' % (int(pp[0]),int(pp[1]),int(pp[2]))
		spec.append(st)	
	    self.ctc = spec
	da = self.data
	dv = self.vmax-self.vmin
	if dv != 0.:
		data = divide(subtract(da,self.vmin),dv/self.maxY)
		da1 = divide(subtract(da,self.vmin),dv/255)
	else:
		data = da
		da1 = divide(da,self.vmin/255)

	rows= len(data)
	steps= len(data[0])
	lasthv = self.maxY*self.yfac
        xadj   = float(self.xincr)/4.0
	if xadj < 2: xadj=2	
	if steplist == None:
		steplist = range(steps-1)
#	for cidx in range(steps-1):
	for cidx in steplist:
	    for row in range(rows-1):
                rootx  = self.xorg + cidx*self.xincr - row*self.hoff/self.rows
                rooty  = self.yorg + row*self.voff/self.rows
		datum = [data[rows-1-row][cidx+1],data[rows-1-row][cidx],data[rows-1-row-1][cidx],data[rows-1-row-1][cidx+1]]
	        lside = multiply(datum,self.yfac)
		if self.ctable:
		     if not(self.average):
			ind = int(da1[rows-1-row,cidx])
		     else:
			ind = int((da1[rows-1-row,cidx]+da1[rows-1-row-1,cidx]+ da1[rows-1-row,cidx+1]+da1[rows-1-row-1,cidx+1])/4)
		     color = self.ctc[ind]
		else:
		     color = self.spectrum[cidx]
		self.canvas.create_polygon(
			rootx+self.xincr,rooty-lside[0],
			rootx,rooty-lside[1],
			rootx-self.hroff,rooty-lside[2]+self.vroff,
			rootx+self.xincr-self.hroff,rooty-lside[3]+self.vroff,
                        fill=color, outline=color,
                        width=xadj)

	    self.root.update()
Exemple #2
0
    def drawsurf(self,type=None):
	'drawsurf(self,type=None) - draw spectrum surface with/without skirt'
	da = self.data
	dv = self.vmax-self.vmin
	if dv != 0.:
		data = divide(subtract(da,self.vmin),dv/self.maxY)
	else:
		data = da
	rows= len(data)
	steps= len(data[0])
	lasthv = self.maxY*self.yfac
	
	for row in range(rows):
            rootx  = self.xorg - row*self.hoff/self.rows
            rooty  = self.yorg + row*self.voff/self.rows
	    rowdata = data[rows-1-row]
	    for cidx in range(steps):
		datum = rowdata[cidx]
		lside = datum*self.yfac
		color = self.spectrum[cidx]
		if type == None:
                    self.canvas.create_polygon(rootx, rooty-lside, 
                        fill=color, outline=color,
                        width=self.xincr)
		else:
                    self.canvas.create_polygon(rootx, rooty-lside, 
			rootx+self.hroff, rooty-lside-self.vroff,
			rootx+self.hroff, rooty-self.vroff,
			rootx,rooty-lside,
                        fill=color, outline=color,
                        width=self.xincr)
		rootx = rootx + self.xincr
	    self.root.update()
Exemple #3
0
    def drawrows(self,list=None):
	'drawrows(self,list=None) - draw all or list of rows in 3D coordinates'
	self.clearcanvas()
	self.createAxis()
	da = self.data
	dv = self.vmax-self.vmin
	if dv != 0.0:
		data = divide(subtract(da,self.vmin),dv/self.maxY)
	else:
		data = da
	rows= len(data)
	steps= len(data[0])
	lasthv = self.maxY*self.yfac
	
	if list == None: list = range(rows)
	for row in list:
	  if row < rows and row >=0 :
#            rootx  = self.xorg - row*self.hoff/self.rows
#            rooty  = self.yorg + row*self.voff/self.rows
#	     rowdata1 = data[rows-1-row]
            rootx  = self.xorg - (rows-1-row)*self.hoff/self.rows
            rooty  = self.yorg + (rows-1-row)*self.voff/self.rows
	    rowdata1 = data[row]
	    for cidx in range(steps-1):
		datum = [rowdata1[cidx],rowdata1[cidx+1]]
		lside = multiply(datum,self.yfac)
		self.canvas.create_line( rootx,rooty-lside[0],
			rootx+self.xincr,rooty-lside[1],
			capstyle=ROUND,
			width=self.linewidth,fill='darkblue')
		rootx = rootx + self.xincr

	    self.root.update()
Exemple #4
0
def corrcoef(*args):
    """
    
    corrcoef(X) where X is a matrix returns a matrix of correlation
    coefficients for each row of X.
    
    corrcoef(x,y) where x and y are vectors returns the matrix or
    correlation coefficients for x and y.

    Numeric arrays can be real or complex

    The correlation matrix is defined from the covariance matrix C as

    r(i,j) = C[i,j] / (C[i,i]*C[j,j])
    """

    if len(args) == 2:
        X = transpose(array([args[0]] + [args[1]]))
    elif len(args == 1):
        X = args[0]
    else:
        raise RuntimeError, 'Only expecting 1 or 2 arguments'

    C = cov(X)
    d = resize(diagonal(C), (2, 1))
    r = divide(C, sqrt(matrixmultiply(d, transpose(d))))[0, 1]
    try:
        return r.real
    except AttributeError:
        return r
Exemple #5
0
    def draw(self):
	'draw(self) - draw 3D spectrum plot and 2D image plot of input data array'
	da = self.data
	dv = self.vmax-self.vmin
        for i in range(self.rows):
	    if dv == 0: 
	       data = self.steps* [1.]
	    else:
	       data = divide(subtract(da[self.maxY-1-i],self.vmin),dv/self.maxY)
            self.plotData(i, data)
            self.root.update()
	self.drawImage()
Exemple #6
0
 def draw(self):
     'draw(self) - draw 3D spectrum plot and 2D image plot of input data array'
     da = self.data
     dv = self.vmax - self.vmin
     for i in range(self.rows):
         if dv == 0:
             data = self.steps * [1.]
         else:
             data = divide(subtract(da[self.maxY - 1 - i], self.vmin),
                           dv / self.maxY)
         self.plotData(i, data)
         self.root.update()
     self.drawImage()
Exemple #7
0
    def drawstepSline(self, list=None):
        'drawstepSline(self,list=None) - draw selected step slices in spectrum color'
        self.clearcanvas()
        self.createAxis()
        da = self.data
        dv = self.vmax - self.vmin
        if dv != 0.0:
            data = divide(subtract(da, self.vmin), dv / self.maxY)
        else:
            data = da
        rows = len(data)
        steps = len(data[0])
        lasthv = self.maxY * self.yfac

        if list == None: list = range(steps)
        else:
            ll = []
            for i in range(len(list)):
                if list[i] < steps:
                    ll.append(list[i])
            list = ll
        np = len(list)
        for row in range(rows - 1):
            rootx = self.xorg - row * self.hoff / self.rows
            rooty = self.yorg + row * self.voff / self.rows
            rowdata1 = data[rows - 1 - row]
            rowdata2 = data[rows - 1 - row - 1]
            for i in range(np):
                cidx = list[i]
                if cidx >= 0 and cidx < steps:
                    datum = [rowdata2[cidx], rowdata1[cidx]]
                    lside = multiply(datum, self.yfac)
                    color = self.spectrum[cidx]
                    self.canvas.create_polygon(rootx - self.hroff,
                                               rooty - lside[0] + self.vroff,
                                               rootx,
                                               rooty - lside[1],
                                               rootx,
                                               rooty,
                                               rootx - self.hroff,
                                               rooty + self.vroff,
                                               outline=color,
                                               width=self.linewidth,
                                               fill=color)
                    if np < steps:
                        if i < (np - 1):
                            rootx = rootx + self.xincr * (list[i + 1] - cidx)
                    else:
                        rootx = rootx + self.xincr

            self.root.update()
Exemple #8
0
    def drawstepSline(self,list=None):
	'drawstepSline(self,list=None) - draw selected step slices in spectrum color'
	self.clearcanvas()
	self.createAxis()
	da = self.data
	dv = self.vmax-self.vmin
	if dv != 0.0:
		data = divide(subtract(da,self.vmin),dv/self.maxY)
	else:
		data = da
	rows= len(data)
	steps= len(data[0])
	lasthv = self.maxY*self.yfac
	
	if list == None: list=range(steps)
	else:
		ll = []
		for i in range(len(list)):
			if list[i] < steps:
				ll.append(list[i])	
		list = ll
    	np = len(list)
	for row in range(rows-1):
            rootx  = self.xorg - row*self.hoff/self.rows
            rooty  = self.yorg + row*self.voff/self.rows
	    rowdata1 = data[rows-1-row]
	    rowdata2 = data[rows-1-row-1]
	    for i in range(np):
	      cidx = list[i]
	      if cidx >=0 and cidx < steps:
		datum = [rowdata2[cidx],rowdata1[cidx]]
		lside = multiply(datum,self.yfac)
		color = self.spectrum[cidx]
		self.canvas.create_polygon(
			rootx-self.hroff,rooty-lside[0]+self.vroff,
			rootx,rooty-lside[1],
			rootx,rooty,
			rootx-self.hroff,rooty+self.vroff,
			outline=color,width=self.linewidth,
			fill=color)
		if np < steps:
		    if i < (np-1):
		        rootx = rootx + self.xincr*(list[i+1]-cidx)
		else:
		    rootx = rootx + self.xincr

	    self.root.update()
Exemple #9
0
    def drawsteps(self, list=None):
        'drawsteps(self,list=None) - draw all or selected step list in 3D coordinates'
        self.clearcanvas()
        self.createAxis()
        da = self.data
        dv = self.vmax - self.vmin
        if dv != 0.0:
            data = divide(subtract(da, self.vmin), dv / self.maxY)
        else:
            data = da
        rows = len(data)
        steps = len(data[0])
        lasthv = self.maxY * self.yfac

        if list == None: list = range(steps)
        else:
            ll = []
            for i in range(len(list)):
                if list[i] < steps:
                    ll.append(list[i])
            list = ll
        np = len(list)
        for row in range(rows - 1):
            rootx = self.xorg - row * self.hoff / self.rows
            rooty = self.yorg + row * self.voff / self.rows
            rowdata1 = data[rows - 1 - row]
            rowdata2 = data[rows - 1 - row - 1]
            for i in range(np):
                cidx = list[i]
                if cidx >= 0 and cidx < steps:
                    datum = [rowdata1[cidx], rowdata2[cidx]]
                    lside = multiply(datum, self.yfac)
                    self.canvas.create_line(
                        rootx,
                        rooty - lside[0],
                        rootx - self.hroff,
                        rooty - lside[1] + self.vroff,
                        #			capstyle=ROUND,
                        width=self.linewidth,
                        fill='darkblue')
                    if np < steps:
                        if i < (np - 1):
                            rootx = rootx + self.xincr * (list[i + 1] - cidx)
                    else:
                        rootx = rootx + self.xincr

            self.root.update()
Exemple #10
0
    def drawsteps(self,list=None):
	'drawsteps(self,list=None) - draw all or selected step list in 3D coordinates'
	self.clearcanvas()
	self.createAxis()
	da = self.data
	dv = self.vmax-self.vmin
	if dv != 0.0:
		data = divide(subtract(da,self.vmin),dv/self.maxY)
	else:
		data = da
	rows= len(data)
	steps= len(data[0])
	lasthv = self.maxY*self.yfac
	
	if list == None: list=range(steps)
	else:
		ll = []
		for i in range(len(list)):
			if list[i] < steps:
				ll.append(list[i])	
		list = ll
    	np = len(list)
	for row in range(rows-1):
            rootx  = self.xorg - row*self.hoff/self.rows
            rooty  = self.yorg + row*self.voff/self.rows
	    rowdata1 = data[rows-1-row]
	    rowdata2 = data[rows-1-row-1]
	    for i in range(np):
	      cidx = list[i]
	      if cidx >=0 and cidx < steps:
		datum = [rowdata1[cidx],rowdata2[cidx]]
		lside = multiply(datum,self.yfac)
		self.canvas.create_line(
			rootx,rooty-lside[0],
			rootx-self.hroff,rooty-lside[1]+self.vroff,
#			capstyle=ROUND,
			width=self.linewidth,fill='darkblue')
		if np < steps:
		    if i < (np-1):
		        rootx = rootx + self.xincr*(list[i+1]-cidx)
		else:
		    rootx = rootx + self.xincr

	    self.root.update()
Exemple #11
0
    def drawmesh(self):
        'drawmesh(self) - draw surface elements as mesh elements'
        self.clearcanvas()
        self.createAxis()
        da = self.data
        dv = self.vmax - self.vmin
        if dv != 0.:
            data = divide(subtract(da, self.vmin), dv / self.maxY)
        else:
            data = da
        rows = len(data)
        steps = len(data[0])
        lasthv = self.maxY * self.yfac

        for row in range(rows - 1):
            rootx = self.xorg - row * self.hoff / self.rows
            rooty = self.yorg + row * self.voff / self.rows
            rowdata1 = data[rows - 1 - row]
            rowdata2 = data[rows - 1 - row - 1]
            for cidx in range(steps - 1):
                datum = [
                    rowdata2[cidx], rowdata1[cidx], rowdata1[cidx + 1],
                    rowdata2[cidx + 1]
                ]
                lside = multiply(datum, self.yfac)
                self.canvas.create_line(rootx - self.hroff,
                                        rooty - lside[0] + self.vroff,
                                        rootx,
                                        rooty - lside[1],
                                        rootx + self.xincr,
                                        rooty - lside[2],
                                        rootx + self.xincr - self.hroff,
                                        rooty - lside[3] + self.vroff,
                                        fill='darkblue')
                if (row + 1) == (rows - 1):
                    self.canvas.create_line(rootx + self.xincr - self.hroff,
                                            rooty - lside[3] + self.vroff,
                                            rootx - self.hroff,
                                            rooty - lside[0] + self.vroff,
                                            fill='darkblue')
                rootx = rootx + self.xincr

            self.root.update()
Exemple #12
0
def cohere(x,
           y,
           NFFT=256,
           Fs=2,
           detrend=detrend_none,
           window=window_hamming,
           noverlap=0):
    """
    cohere the coherence between x and y.  Coherence is the normalized
    cross spectral density

    Cxy = |Pxy|^2/(Pxx*Pyy)

    The return value is (Cxy, f), where f are the frequencies of the
    coherence vector.  See the docs for psd and csd for information
    about the function arguments NFFT, detrend, windowm noverlap, as
    well as the methods used to compute Pxy, Pxx and Pyy.

    """

    Pxx, f = psd(x,
                 NFFT=NFFT,
                 Fs=Fs,
                 detrend=detrend,
                 window=window,
                 noverlap=noverlap)
    Pyy, f = psd(y,
                 NFFT=NFFT,
                 Fs=Fs,
                 detrend=detrend,
                 window=window,
                 noverlap=noverlap)
    Pxy, f = csd(x,
                 y,
                 NFFT=NFFT,
                 Fs=Fs,
                 detrend=detrend,
                 window=window,
                 noverlap=noverlap)

    Cxy = divide(absolute(Pxy)**2, Pxx * Pyy)
    return Cxy, f
Exemple #13
0
    def drawsurf(self, type=None):
        'drawsurf(self,type=None) - draw spectrum surface with/without skirt'
        da = self.data
        dv = self.vmax - self.vmin
        if dv != 0.:
            data = divide(subtract(da, self.vmin), dv / self.maxY)
        else:
            data = da
        rows = len(data)
        steps = len(data[0])
        lasthv = self.maxY * self.yfac

        for row in range(rows):
            rootx = self.xorg - row * self.hoff / self.rows
            rooty = self.yorg + row * self.voff / self.rows
            rowdata = data[rows - 1 - row]
            for cidx in range(steps):
                datum = rowdata[cidx]
                lside = datum * self.yfac
                color = self.spectrum[cidx]
                if type == None:
                    self.canvas.create_polygon(rootx,
                                               rooty - lside,
                                               fill=color,
                                               outline=color,
                                               width=self.xincr)
                else:
                    self.canvas.create_polygon(rootx,
                                               rooty - lside,
                                               rootx + self.hroff,
                                               rooty - lside - self.vroff,
                                               rootx + self.hroff,
                                               rooty - self.vroff,
                                               rootx,
                                               rooty - lside,
                                               fill=color,
                                               outline=color,
                                               width=self.xincr)
                rootx = rootx + self.xincr
            self.root.update()
Exemple #14
0
    def drawmesh(self):
	'drawmesh(self) - draw surface elements as mesh elements'
	self.clearcanvas()
	self.createAxis()
	da = self.data
	dv = self.vmax-self.vmin
	if dv != 0.:
	    data = divide(subtract(da,self.vmin),dv/self.maxY)
	else:
	    data = da
	rows= len(data)
	steps= len(data[0])
	lasthv = self.maxY*self.yfac
	
	for row in range(rows-1):
            rootx  = self.xorg - row*self.hoff/self.rows
            rooty  = self.yorg + row*self.voff/self.rows
	    rowdata1 = data[rows-1-row]
	    rowdata2 = data[rows-1-row-1]
	    for cidx in range(steps-1):
		datum = [rowdata2[cidx],rowdata1[cidx],rowdata1[cidx+1],rowdata2[cidx+1]]
		lside = multiply(datum,self.yfac)
		self.canvas.create_line(
			rootx-self.hroff,rooty-lside[0]+self.vroff,
			rootx,rooty-lside[1],
			rootx+self.xincr,rooty-lside[2],
			rootx+self.xincr-self.hroff,rooty-lside[3]+self.vroff,
			fill='darkblue')
		if (row+1) == (rows-1):
			self.canvas.create_line(
			rootx+self.xincr-self.hroff,rooty-lside[3]+self.vroff,
			rootx-self.hroff,rooty-lside[0]+self.vroff,
			fill='darkblue')
		rootx = rootx + self.xincr

	    self.root.update()
Exemple #15
0
    def drawrows(self, list=None):
        'drawrows(self,list=None) - draw all or list of rows in 3D coordinates'
        self.clearcanvas()
        self.createAxis()
        da = self.data
        dv = self.vmax - self.vmin
        if dv != 0.0:
            data = divide(subtract(da, self.vmin), dv / self.maxY)
        else:
            data = da
        rows = len(data)
        steps = len(data[0])
        lasthv = self.maxY * self.yfac

        if list == None: list = range(rows)
        for row in list:
            if row < rows and row >= 0:
                #            rootx  = self.xorg - row*self.hoff/self.rows
                #            rooty  = self.yorg + row*self.voff/self.rows
                #	     rowdata1 = data[rows-1-row]
                rootx = self.xorg - (rows - 1 - row) * self.hoff / self.rows
                rooty = self.yorg + (rows - 1 - row) * self.voff / self.rows
                rowdata1 = data[row]
                for cidx in range(steps - 1):
                    datum = [rowdata1[cidx], rowdata1[cidx + 1]]
                    lside = multiply(datum, self.yfac)
                    self.canvas.create_line(rootx,
                                            rooty - lside[0],
                                            rootx + self.xincr,
                                            rooty - lside[1],
                                            capstyle=ROUND,
                                            width=self.linewidth,
                                            fill='darkblue')
                    rootx = rootx + self.xincr

                self.root.update()
Exemple #16
0
    def drawsurf1(self, steplist=None):
        'drawsurf1(self,steplist=None) - draw spectrum surface cell by stepwise'
        self.clearcanvas()
        self.createAxis()
        # use color table if ctable is set
        if self.ctable:
            p = reshape(self.CT[self.ct], (256, 3))
            spec = []
            for i in range(256):
                pp = p[i]
                st = '#%02x%02x%02x' % (int(pp[0]), int(pp[1]), int(pp[2]))
                spec.append(st)
            self.ctc = spec
        da = self.data
        dv = self.vmax - self.vmin
        if dv != 0.:
            data = divide(subtract(da, self.vmin), dv / self.maxY)
            da1 = divide(subtract(da, self.vmin), dv / 255)
        else:
            data = da
            da1 = divide(da, self.vmin / 255)

        rows = len(data)
        steps = len(data[0])
        lasthv = self.maxY * self.yfac
        xadj = float(self.xincr) / 4.0
        if xadj < 2: xadj = 2
        if steplist == None:
            steplist = range(steps - 1)
#	for cidx in range(steps-1):
        for cidx in steplist:
            for row in range(rows - 1):
                rootx = self.xorg + cidx * self.xincr - row * self.hoff / self.rows
                rooty = self.yorg + row * self.voff / self.rows
                datum = [
                    data[rows - 1 - row][cidx + 1], data[rows - 1 - row][cidx],
                    data[rows - 1 - row - 1][cidx],
                    data[rows - 1 - row - 1][cidx + 1]
                ]
                lside = multiply(datum, self.yfac)
                if self.ctable:
                    if not (self.average):
                        ind = int(da1[rows - 1 - row, cidx])
                    else:
                        ind = int((da1[rows - 1 - row, cidx] +
                                   da1[rows - 1 - row - 1, cidx] +
                                   da1[rows - 1 - row, cidx + 1] +
                                   da1[rows - 1 - row - 1, cidx + 1]) / 4)
                    color = self.ctc[ind]
                else:
                    color = self.spectrum[cidx]
                self.canvas.create_polygon(rootx + self.xincr,
                                           rooty - lside[0],
                                           rootx,
                                           rooty - lside[1],
                                           rootx - self.hroff,
                                           rooty - lside[2] + self.vroff,
                                           rootx + self.xincr - self.hroff,
                                           rooty - lside[3] + self.vroff,
                                           fill=color,
                                           outline=color,
                                           width=xadj)

            self.root.update()
Exemple #17
0
def psd(x,
        NFFT=256,
        Fs=2,
        detrend=detrend_none,
        window=window_hamming,
        noverlap=0):
    """
    The power spectral density by Welches average periodogram method.
    The vector x is divided into NFFT length segments.  Each segment
    is detrended by function detrend and windowed by function window.
    noperlap gives the length of the overlap between segments.  The
    absolute(fft(segment))**2 of each segment are averaged to compute Pxx,
    with a scaling to correct for power loss due to windowing.  Fs is
    the sampling frequency.

    -- NFFT must be a power of 2
    -- detrend and window are functions, unlike in matlab where they are
       vectors.
    -- if length x < NFFT, it will be zero padded to NFFT
    

    Refs:
      Bendat & Piersol -- Random Data: Analysis and Measurement
        Procedures, John Wiley & Sons (1986)

    """

    if NFFT % 2:
        raise ValueError, 'NFFT must be a power of 2'

    # zero pad x up to NFFT if it is shorter than NFFT
    if len(x) < NFFT:
        n = len(x)
        x = resize(x, (NFFT, ))
        x[n:] = 0

    # for real x, ignore the negative frequencies


#    if x.typecode()==Complex: numFreqs = NFFT
    if any(numpy.iscomplex(x)): numFreqs = NFFT
    else: numFreqs = NFFT // 2 + 1

    #    windowVals = window(ones((NFFT,),x.typecode()))
    windowVals = window(numpy.ones(NFFT))
    step = NFFT - noverlap
    ind = range(0, len(x) - NFFT + 1, step)
    n = len(ind)
    #    Pxx = zeros((numFreqs,n), Float)
    Pxx = numpy.zeros([numFreqs, n])

    # do the ffts of the slices
    for i in range(n):
        thisX = x[ind[i]:ind[i] + NFFT]
        thisX = windowVals * detrend(thisX)
        fx = absolute(fft(thisX))**2
        #print("numFreqs={0:f}".format(numFreqs))
        #print("len of fx slice={0:d}".format(len(fx[:int(numFreqs)])))
        #print("len of destination in Pxx={0:d}")
        Pxx[:, i] = fx[:int(numFreqs)]

    # Scale the spectrum by the norm of the window to compensate for
    # windowing loss; see Bendat & Piersol Sec 11.5.2
    if n > 1: Pxx = mean(Pxx, 1)
    Pxx = divide(Pxx, norm(windowVals)**2)
    freqs = Fs / NFFT * arange(0, numFreqs)
    return Pxx, freqs
Exemple #18
0
def csd(x,
        y,
        NFFT=256,
        Fs=2,
        detrend=detrend_none,
        window=window_hamming,
        noverlap=0):
    """
    The cross spectral density Pxy by Welches average periodogram
    method.  The vectors x and y are divided into NFFT length
    segments.  Each segment is detrended by function detrend and
    windowed by function window.  noverlap gives the length of the
    overlap between segments.  The product of the direct FFTs of x and
    y are averaged over each segment to compute Pxy, with a scaling to
    correct for power loss due to windowing.  Fs is the sampling
    frequency.

    NFFT must be a power of 2

    Refs:
      Bendat & Piersol -- Random Data: Analysis and Measurement
        Procedures, John Wiley & Sons (1986)

    """

    if NFFT % 2:
        raise ValueError, 'NFFT must be a power of 2'

    # zero pad x and y up to NFFT if they are shorter than NFFT
    if len(x) < NFFT:
        n = len(x)
        x = resize(x, (NFFT, ))
        x[n:] = 0
    if len(y) < NFFT:
        n = len(y)
        y = resize(y, (NFFT, ))
        y[n:] = 0

    # for real x, ignore the negative frequencies


#    if x.typecode()==Complex: numFreqs = NFFT
    if any(numpy.iscomplex(x)): numFreqs = NFFT
    else: numFreqs = NFFT // 2 + 1

    #    windowVals = window(ones((NFFT,),x.typecode()))
    windowVals = window(numpy.ones(NFFT))
    step = NFFT - noverlap
    ind = range(0, len(x) - NFFT + 1, step)
    n = len(ind)
    #    Pxy = zeros((numFreqs,n), Complex)
    Pxy = numpy.zeros([numFreqs, n])

    # do the ffts of the slices
    for i in range(n):
        thisX = x[ind[i]:ind[i] + NFFT]
        thisX = windowVals * detrend(thisX)
        thisY = y[ind[i]:ind[i] + NFFT]
        thisY = windowVals * detrend(thisY)
        fx = fft(thisX)
        fy = fft(thisY)
        Pxy[:, i] = fy[:numFreqs] * conjugate(fx[:numFreqs])

    # Scale the spectrum by the norm of the window to compensate for
    # windowing loss; see Bendat & Piersol Sec 11.5.2
    if n > 1: Pxy = mean(Pxy, 1)
    Pxy = divide(Pxy, norm(windowVals)**2)
    freqs = Fs / NFFT * arange(0, numFreqs)
    return Pxy, freqs