content: 
  from SimpleCV.base import *
  import scipy.signal as sps
  import scipy.optimize as spo
  import numpy as np
  import copy, operator
  
  
  class LineScan(list):
      """
      **SUMMARY**
  
      A line scan is a one dimensional signal pulled from the intensity
      of a series of a pixels in an image. LineScan allows you to do a series
      of operations just like on an image class object. You can also treat the
      line scan as a python list object. A linescan object is automatically
      generated by calling ImageClass.getLineScan on an image. You can also
      roll your own by declaring a LineScan object and passing the constructor
      a 1xN list of values.
  
      **EXAMPLE**
  
      >>>> import matplotlib.pyplot as plt
      >>>> img = Image('lenna')
      >>>> s = img.getLineScan(y=128)
      >>>> ss = s.smooth()
      >>>> plt.plot(s)
      >>>> plt.plot(ss)
      >>>> plt.show()
      """
      pointLoc = None
      image = None
  
      def __init__(self, args, **kwargs):
          if isinstance(args, np.ndarray):
              args = args.tolist()
          list.__init__(self,args)
          self.image = None
          self.pt1 = None
          self.pt2 = None
          self.row = None
          self.col = None
          self.channel = -1
          for key in kwargs:
              if key == 'pointLocs':
                  if kwargs[key] is not None:
                      self.pointLoc = kwargs[key]
              if key == 'image':
                  if kwargs[key] is not None:
                      self.img = kwargs[key]
              if key == 'pt1':
                  if kwargs[key] is not None:
                      self.pt1 = kwargs[key]
              if key == 'pt2':
                  if kwargs[key] is not None:
                      self.pt2 = kwargs[key]
              if key == "x":
                  if kwargs[key] is not None:
                      self.col = kwargs[key]
              if key == "y":
                  if kwargs[key] is not None:
                      self.row = kwargs[key]
              if key == "channel":
                  if kwargs[key] is not None:
                      self.channel = kwargs[key]
                      
          if(self.pointLoc is None):
              self.pointLoc = zip(range(0,len(self)),range(0,len(self)))
  
      def __getitem__(self,key):
          """
          **SUMMARY**
  
          Returns a LineScan when sliced. Previously used to
          return list. Now it is possible to use LineScanm member
          functions on sub-lists
  
          """
          if type(key) is types.SliceType: #Or can use 'try:' for speed
              return LineScan(list.__getitem__(self, key))
          else:
              return list.__getitem__(self,key)
  
      def __getslice__(self, i, j):
          """
          Deprecated since python 2.0, now using __getitem__
          """
          return self.__getitem__(slice(i,j))
  
      def __sub__(self,other):
          
          if len(self) == len(other):
              retVal = LineScan(map(operator.sub,self,other))
          else:
              print 'Size mismatch'
              return None
          retVal._update(self)
          return retVal
  
      def __add__(self,other):
          
          if len(self) == len(other):
              retVal = LineScan(map(operator.add,self,other))
          else:
              print 'Size mismatch'
              return None
          retVal._update(self)
          return retVal
  
      def __mul__(self,other):
  
          if len(self) == len(other):
              retVal = LineScan(map(operator.mul,self,other))
          else:
              print 'Size mismatch'
              return None
  
          retVal._update(self)
          return retVal
  
      def __div__(self,other):
  
          if len(self) == len(other):
              try:
                  retVal = LineScan(map(operator.div,self,other))
              except ZeroDivisionError:
                  print 'Second LineScan contains zeros'
                  return None
          else:
              print 'Size mismatch'
              return None
  
          retVal._update(self)
          return retVal
  
      def _update(self, linescan):
          """
          ** SUMMARY**
  
          Updates LineScan's Instance Objects.
  
          """
          self.image = linescan.image
          self.pt1 = linescan.pt1
          self.pt2 = linescan.pt2
          self.row = linescan.row
          self.col = linescan.col
          self.channel = linescan.channel
          self.pointLoc = linescan.pointLoc
  
  
      def smooth(self,degree=3):
          """
          **SUMMARY**
  
          Perform a Gasusian simple smoothing operation on the signal.
  
          **PARAMETERS**
  
          * *degree* - The degree of the fitting function. Higher degree means more smoothing.
  
          **RETURNS**
  
          A smoothed LineScan object.
  
          **EXAMPLE**
  
          >>>> import matplotlib.pyplot as plt
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(y=128)
          >>>> plt.plot(sl)
          >>>> plt.plot(sl.smooth(7))
          >>>> plt.show()
  
          **NOTES**
          Cribbed from http://www.swharden.com/blog/2008-11-17-linear-data-smoothing-in-python/
          """
          window=degree*2-1
          weight=np.array([1.0]*window)
          weightGauss=[]
          for i in range(window):
              i=i-degree+1
              frac=i/float(window)
              gauss=1/(np.exp((4*(frac))**2))
              weightGauss.append(gauss)
          weight=np.array(weightGauss)*weight
          smoothed=[0.0]*(len(self)-window)
          for i in range(len(smoothed)):
              smoothed[i]=sum(np.array(self[i:i+window])*weight)/sum(weight)
          # recenter the signal so it sits nicely on top of the old
          front = self[0:(degree-1)]
          front += smoothed
          front += self[-1*degree:]
          retVal = LineScan(front,image=self.image,pointLoc=self.pointLoc,pt1=self.pt1,pt2=self.pt2)
          retVal._update(self)
          return retVal
  
      def normalize(self):
          """
          **SUMMARY**
  
          Normalize the signal so the maximum value is scaled to one.
  
          **RETURNS**
  
          A normalized scanline object.
  
          **EXAMPLE**
  
          >>>> import matplotlib.pyplot as plt
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(y=128)
          >>>> plt.plot(sl)
          >>>> plt.plot(sl.normalize())
          >>>> plt.show()
  
          """
          temp = np.array(self, dtype='float32')
          temp = temp / np.max(temp)
          retVal = LineScan(list(temp[:]),image=self.image,pointLoc=self.pointLoc,pt1=self.pt1,pt2=self.pt2)
          retVal._update(self)
          return retVal
  
      def scale(self,value_range=(0,1)):
          """
          **SUMMARY**
  
          Scale the signal so the maximum and minimum values are
          all scaled to the values in value_range. This is handy
          if you want to compare the shape of two signals that
          are scaled to different ranges.
  
          **PARAMETERS**
  
          * *value_range* - A tuple that provides the lower and upper bounds
                            for the output signal.
  
          **RETURNS**
  
          A scaled LineScan object.
  
          **EXAMPLE**
  
          >>>> import matplotlib.pyplot as plt
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(y=128)
          >>>> plt.plot(sl)
          >>>> plt.plot(sl.scale(value_range(0,255)))
          >>>> plt.show()
      
          **SEE ALSO**
  
          """
          temp = np.array(self, dtype='float32')
          vmax = np.max(temp)
          vmin = np.min(temp)
          a = np.min(value_range)
          b = np.max(value_range)
          temp = (((b-a)/(vmax-vmin))*(temp-vmin))+a
          retVal = LineScan(list(temp[:]),image=self.image,pointLoc=self.pointLoc,pt1=self.pt1,pt2=self.pt2)
          retVal._update(self)
          return retVal
  
      def minima(self):
          """
          **SUMMARY**
  
          The function the global minima in the line scan.
  
          **RETURNS**
  
          Returns a list of tuples of the format:
          (LineScanIndex,MinimaValue,(image_position_x,image_position_y))
  
          **EXAMPLE**
  
          >>>> import matplotlib.pyplot as plt
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(y=128)
          >>>> minima = sl.smooth().minima()
          >>>> plt.plot(sl)
          >>>> for m in minima:
          >>>>    plt.plot(m[0],m[1],'ro')
          >>>> plt.show()
  
          """
          # all of these functions should return
          # value, index, pixel coordinate
          # [(index,value,(pix_x,pix_y))...]
          minvalue = np.min(self)
          idxs = np.where(np.array(self)==minvalue)[0]
          minvalue = np.ones((1,len(idxs)))*minvalue # make zipable
          minvalue = minvalue[0]
          pts = np.array(self.pointLoc)
          pts = pts[idxs]
          pts = [(p[0],p[1]) for p in pts] # un numpy this
          return zip(idxs,minvalue,pts)
  
      def maxima(self):
          """
          **SUMMARY**
  
          The function finds the global maxima in the line scan.
  
          **RETURNS**
  
          Returns a list of tuples of the format:
          (LineScanIndex,MaximaValue,(image_position_x,image_position_y))
  
          **EXAMPLE**
  
          >>>> import matplotlib.pyplot as plt
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(y=128)
          >>>> maxima = sl.smooth().maxima()
          >>>> plt.plot(sl)
          >>>> for m in maxima:
          >>>>    plt.plot(m[0],m[1],'ro')
          >>>> plt.show()
  
          """
  
          # all of these functions should return
          # value, index, pixel coordinate
          # [(index,value,(pix_x,pix_y))...]
          maxvalue = np.max(self)
          idxs = np.where(np.array(self)==maxvalue)[0]
          maxvalue = np.ones((1,len(idxs)))*maxvalue # make zipable
          maxvalue = maxvalue[0]
          pts = np.array(self.pointLoc)
          pts = pts[idxs]
          pts = [(p[0],p[1]) for p in pts] # un numpy
          return zip(idxs,maxvalue,pts)
  
      def derivative(self):
          """
          **SUMMARY**
  
          This function finds the discrete derivative of the signal.
          The discrete derivative is simply the difference between each
          succesive samples. A good use of this function is edge detection
  
          **RETURNS**
  
          Returns the discrete derivative function as a LineScan object.
  
          **EXAMPLE**
  
          >>>> import matplotlib.pyplot as plt
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(y=128)
          >>>> plt.plot(sl)
          >>>> plt.plot(sl.derivative())
          >>>> plt.show()
  
          """
          temp = np.array(self,dtype='float32')
          d = [0]
          d += list(temp[1:]-temp[0:-1])
          retVal = LineScan(d,image=self.image,pointLoc=self.pointLoc,pt1=self.pt1,pt2=self.pt2)
          #retVal.image = self.image
          #retVal.pointLoc = self.pointLoc
          return retVal
  
      def localMaxima(self):
          """
          **SUMMARY**
  
          The function finds local maxima in the line scan. Local maxima
          are defined as points that are greater than their neighbors to
          the left and to the right.
  
          **RETURNS**
  
          Returns a list of tuples of the format:
          (LineScanIndex,MaximaValue,(image_position_x,image_position_y))
  
          **EXAMPLE**
  
          >>>> import matplotlib.pyplot as plt
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(y=128)
          >>>> maxima = sl.smooth().maxima()
          >>>> plt.plot(sl)
          >>>> for m in maxima:
          >>>>    plt.plot(m[0],m[1],'ro')
          >>>> plt.show()
  
          """
          temp = np.array(self)
          idx = np.r_[True, temp[1:] > temp[:-1]] & np.r_[temp[:-1] > temp[1:], True]
          idx = np.where(idx==True)[0]
          values = temp[idx]
          pts = np.array(self.pointLoc)
          pts = pts[idx]
          pts = [(p[0],p[1]) for p in pts] # un numpy
          return zip(idx,values,pts)
  
  
      def localMinima(self):
          """""
          **SUMMARY**
  
          The function the local minima in the line scan. Local minima
          are defined as points that are less than their neighbors to
          the left and to the right.
  
          **RETURNS**
  
          Returns a list of tuples of the format:
          (LineScanIndex,MinimaValue,(image_position_x,image_position_y))
  
          **EXAMPLE**
  
          >>>> import matplotlib.pyplot as plt
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(y=128)
          >>>> minima = sl.smooth().minima()
          >>>> plt.plot(sl)
          >>>> for m in minima:
          >>>>    plt.plot(m[0],m[1],'ro')
          >>>> plt.show()
  
          """
          temp = np.array(self)
          idx = np.r_[True, temp[1:] < temp[:-1]] & np.r_[temp[:-1] < temp[1:], True]
          idx = np.where(idx==True)[0]
          values = temp[idx]
          pts = np.array(self.pointLoc)
          pts = pts[idx]
          pts = [(p[0],p[1]) for p in pts] # un numpy
          return zip(idx,values,pts)
  
      def resample(self,n=100):
          """
          **SUMMARY**
  
          Resample the signal to fit into n samples. This method is
          handy if you would like to resize multiple signals so that
          they fit together nice. Note that using n < len(LineScan)
          can cause data loss.
  
          **PARAMETERS**
  
          * *n* - The number of samples to resample to.
  
          **RETURNS**
  
          A LineScan object of length n.
  
          **EXAMPLE**
  
          >>>> import matplotlib.pyplot as plt
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(y=128)
          >>>> plt.plot(sl)
          >>>> plt.plot(sl.resample(100))
          >>>> plt.show()
  
          """
          signal = sps.resample(self,n)
          pts = np.array(self.pointLoc)
          # we assume the pixel points are linear
          # so we can totally do this better manually
          x = linspace(pts[0,0],pts[-1,0],n)
          y = linspace(pts[0,1],pts[-1,1],n)
          pts = zip(x,y)
          retVal = LineScan(list(signal),image=self.image,pointLoc=self.pointLoc,pt1=self.pt1,pt2=self.pt2)
          retVal._update(self)
          return retVal
  
  
      # this needs to be moved out to a cookbook or something
      #def linear(xdata,m,b):
      #    return m*xdata+b
  
      # need to add polyfit too
      #http://docs.scipy.org/doc/numpy/reference/generated/numpy.polyfit.html
      def fitToModel(self,f,p0=None):
          """
          **SUMMARY**
  
          Fit the data to the provided model. This can be any arbitrary
          2D signal. Return the data of the model scaled to the data.
  
  
          **PARAMETERS**
  
          * *f* - a function of the form f(x_values, p0,p1, ... pn) where
                  p is parameter for the model.
  
          * *p0* - a list of the initial guess for the model parameters.
  
          **RETURNS**
  
          A LineScan object where the fitted model data replaces the
          actual data.
  
  
          **EXAMPLE**
  
          >>>> def aLine(x,m,b):
          >>>>     return m*x+b
          >>>> import matplotlib.pyplot as plt
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(y=128)
          >>>> fit = sl.fitToModel(aLine)
          >>>> plt.plot(sl)
          >>>> plt.plot(fit)
          >>>> plt.show()
  
          """
          yvals = np.array(self,dtype='float32')
          xvals = range(0,len(yvals),1)
          popt,pcov = spo.curve_fit(f,xvals,yvals,p0=p0)
          yvals = f(xvals,*popt)
          retVal = LineScan(list(yvals),image=self.image,pointLoc=self.pointLoc,pt1=self.pt1,pt2=self.pt2)
          retVal._update(self)
          return retVal
  
  
      def getModelParameters(self,f,p0=None):
          """
          **SUMMARY**
  
          Fit a model to the data and then return
  
          **PARAMETERS**
  
          * *f* - a function of the form f(x_values, p0,p1, ... pn) where
                  p is parameter for the model.
  
          * *p0* - a list of the initial guess for the model parameters.
  
          **RETURNS**
  
          The model parameters as a list. For example if you use a line
          model y=mx+b the function returns the m and b values that fit
          the data.
  
          **EXAMPLE**
  
          >>>> def aLine(x,m,b):
          >>>>     return m*x+b
          >>>> import matplotlib.pyplot as plt
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(y=128)
          >>>> p = sl.getModelParameters(aLine)
          >>>> print p
  
          """
          yvals = np.array(self,dtype='float32')
          xvals = range(0,len(yvals),1)
          popt,pcov = spo.curve_fit(f,xvals,yvals,p0=p0)
          return popt
  
      def convolve(self,kernel):
          """
          **SUMMARY**
  
          Convolve the line scan with a one dimenisional kernel stored as
          a list. This allows you to create an arbitrary filter for the signal.
  
          **PARAMETERS**
  
          * *kernel* - An Nx1 list or np.array that defines the kernel.
  
          **RETURNS**
  
          A LineScan feature with the kernel applied. We crop off
          the fiddly bits at the end and the begining of the kernel
          so everything lines up nicely.
  
          **EXAMPLE**
  
          >>>> import matplotlib.pyplot as plt
          >>>> smooth_kernel = [0.1,0.2,0.4,0.2,0.1]
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(y=128)
          >>>> out = sl.convolve(smooth_kernel)
          >>>> plt.plot(sl)
          >>>> plt.plot(out)
          >>>> plt.show()
  
          **SEE ALSO**
  
          """
          out = np.convolve(self,np.array(kernel,dtype='float32'),'same')
          retVal = LineScan(out,image=self.image,pointLoc=self.pointLoc,pt1=self.pt1,pt2=self.pt2,channel=self.channel)
          return retVal
  
      def fft(self):
          """
          **SUMMARY**
  
          Perform a Fast Fourier Transform on the line scan and return
          the FFT output and the frequency of each value.
  
  
          **RETURNS**
  
          The FFT as a numpy array of irrational numbers and a one dimensional
          list of frequency values.
  
          **EXAMPLE**
  
          >>>> import matplotlib.pyplot as plt
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(y=128)
          >>>> fft,freq = sl.fft()
          >>>> plt.plot(freq,fft.real,freq,fft.imag)
          >>>> plt.show()
  
          """
          signal = np.array(self,dtype='float32')
          fft = np.fft.fft(signal)
          freq = np.fft.fftfreq(len(signal))
          return (fft,freq)
  
  
      def ifft(self,fft):
          """
          **SUMMARY**
  
          Perform an inverse fast Fourier transform on the provided
          irrationally valued signal and return the results as a
          LineScan.
  
  
          **PARAMETERS**
  
          * *fft* - A one dimensional numpy array of irrational values
                    upon which we will perform the IFFT.
  
          **RETURNS**
  
          A LineScan object of the reconstructed signal.
  
          **EXAMPLE**
  
          >>>> img = Image('lenna')
          >>>> sl = img.getLineScan(pt1=(0,0),pt2=(300,200))
          >>>> fft,frq = sl.fft()
          >>>> fft[30:] = 0 # low pass filter
          >>>> sl2 = sl.ifft(fft)
          >>>> import matplotlib.pyplot as plt
          >>>> plt.plot(sl)
          >>>> plt.plot(sl2)
          """
          signal = np.fft.ifft(fft)
          retVal = LineScan(signal.real)
          retVal.image = self.image
          retVal.pointLoc = self.pointLoc
          return retVal
  
      def createEmptyLUT(self,defaultVal=-1):
          """
          **SUMMARY**
  
          Create an empty look up table (LUT).
  
          If default value is what the lut is intially filled with
          if defaultVal == 0
              the array is all zeros.
          if defaultVal > 0
              the array is set to default value. Clipped to 255.
          if defaultVal < 0
              the array is set to the range [0,255]
          if defaultVal is a tuple of two values:
              we set stretch the range of 0 to 255 to match
              the range provided.
  
  
          **PARAMETERS**
  
          * *defaultVal* - See above.
  
          **RETURNS**
  
          A LUT.
  
          **EXAMPLE**
  
          >>>> ls = img.getLineScan(x=10)
          >>>> lut = ls.createEmptyLUT()
          >>>> ls2 = ls.applyLUT(lut)
          >>>> plt.plot(ls)
          >>>> plt.plot(ls2)
          >>>> plt.show()
  
          """
          lut = None
          if( isinstance(defaultVal,list) or
              isinstance(defaultVal,tuple)):
              start = np.clip(defaultVal[0],0,255)
              stop = np.clip(defaultVal[1],0,255)
              lut = np.around(np.linspace(start,stop,256),0)
              lut = np.array(lut,dtype='uint8')
              lut = lut.tolist()
          elif( defaultVal == 0 ):
              lut = np.zeros([1,256]).tolist()[0]
          elif( defaultVal > 0 ):
              defaultVal = np.clip(defaultVal,1,255)
              lut = np.ones([1,256])*defaultVal
              lut = np.array(lut,dtype='uint8')
              lut = lut.tolist()[0]
          elif( defaultVal < 0 ):
              lut = np.linspace(0,256,256)
              lut = np.array(lut,dtype='uint8')
              lut = lut.tolist()
          return lut
  
      def fillLUT(self,lut,idxs,value=255):
          """
          **SUMMARY**
  
          Fill up an existing LUT (look up table) at the indexes specified
          by idxs with the value specified by value. This is useful for picking
          out specific values.
  
          **PARAMETERS**
  
          * *lut* - An existing LUT (just a list of 255 values).
          * *idxs* -  The indexes of the LUT to fill with the value.
                      This can also be a sample swatch of an image.
          * *value* - the value to set the LUT[idx] to
  
  
          **RETURNS**
  
          An updated LUT.
  
          **EXAMPLE**
  
          >>>> ls = img.getLineScan(x=10)
          >>>> lut = ls.createEmptyLUT()
          >>>> swatch = img.crop(0,0,10,10)
          >>>> ls.fillLUT(lut,swatch,255)
          >>>> ls2 = ls.applyLUT(lut)
          >>>> plt.plot(ls)
          >>>> plt.plot(ls2)
          >>>> plt.show()
  
          """
          # for the love of god keep this small
          # for some reason isInstance is being persnickety
          if(idxs.__class__.__name__  == 'Image' ):
              npg = idxs.getGrayNumpy()
              npg = npg.reshape([npg.shape[0]*npg.shape[1]])
              idxs = npg.tolist()
          value = np.clip(value,0,255)
          for idx in idxs:
              if(idx >= 0 and idx < len(lut)):
                  lut[idx]=value
          return lut
  
      def threshold(self,threshold=128,invert=False):
          """
          **SUMMARY**
  
          Do a 1D threshold operation. Values about the threshold
          will be set to 255, values below the threshold will be
          set to 0. If invert is true we do the opposite.
  
          **PARAMETERS**
  
          * *threshold* - The cutoff value for our threshold.
          * *invert* - if invert is false values above the threshold
                       are set to 255, if invert is True the are set to 0.
  
          **RETURNS**
  
          The thresholded linescan operation.
  
          **EXAMPLE**
  
          >>>> ls = img.getLineScan(x=10)
          >>>> ls2 = ls.threshold()
          >>>> plt.plot(ls)
          >>>> plt.plot(ls2)
          >>>> plt.show()
  
          """
          out = []
          high = 255
          low = 0
          if( invert ):
              high = 0
              low = 255
          for pt in self:
              if( pt < threshold ):
                  out.append(low)
              else:
                  out.append(high)
          retVal = LineScan(out,image=self.image,pointLoc=self.pointLoc,pt1=self.pt1,pt2=self.pt2)
          retVal._update(self)
          return retVal
  
      def invert(self,max=255):
          """
          **SUMMARY**
  
          Do an 8bit invert of the signal. What was black is now
          white, what was 255 is now zero.
  
          **PARAMETERS**
  
          * *max* - The maximum value of a pixel in the image, usually 255.
  
          **RETURNS**
  
          The inverted LineScan object.
  
          **EXAMPLE**
  
          >>>> ls = img.getLineScan(x=10)
          >>>> ls2 = ls.invert()
          >>>> plt.plot(ls)
          >>>> plt.plot(ls2)
          >>>> plt.show()
  
          """
  
          out = []
          for pt in self:
              out.append(255-pt)
          retVal = LineScan(out,image=self.image,pointLoc=self.pointLoc,pt1=self.pt1,pt2=self.pt2)
          retVal._update(self)
          return retVal
  
      def mean(self):
          """
          **SUMMARY**
  
          Computes the statistical mean of the signal.
  
          **RETURNS**
  
          The mean of the LineScan object.
  
          **EXAMPLE**
  
          >>>> ls = img.getLineScan(x=10)
          >>>> avg = ls.mean()
          >>>> plt.plot(ls)
          >>>> plt.axhline(y = avg)
          >>>> plt.show()
  
          """
          return float(sum(self))/len(self)
  
      def variance(self):
          """
          **SUMMARY**
  
          Computes the variance of the signal.
  
          **RETURNS**
  
          The variance of the LineScan object.
  
          **EXAMPLE**
  
          >>>> ls = img.getLineScan(x=10)
          >>>> var = ls.variance()
          >>>> var
  
          """
          mean = float(sum(self))/len(self)
          summation = 0
          for num in self:
              summation += (num - mean)**2
          return summation/len(self)
  
      def std(self):
          """
          **SUMMARY**
  
          Computes the standard deviation of the signal.
  
          **RETURNS**
  
          The standard deviation of the LineScan object.
  
          **EXAMPLE**
  
          >>>> ls = img.getLineScan(x=10)
          >>>> avg = ls.mean()
          >>>> std = ls.std()
          >>>> plt.plot(ls)
          >>>> plt.axhline(y = avg)
          >>>> plt.axhline(y = avg - std, color ='r')
          >>>> plt.axhline(y = avg + std, color ='r')
          >>>> plt.show()
  
          """
          mean = float(sum(self))/len(self)
          summation = 0
          for num in self:
              summation += (num - mean)**2
          return np.sqrt(summation/len(self))
  
      def median(self,sz=5):
          """
          **SUMMARY**
  
          Do a sliding median filter with a window size equal to size.
  
  
          **PARAMETERS**
  
          * *sz* - the size of the median filter.
  
          **RETURNS**
  
          The linescan after being passed through the median filter.
          The last index where the value occurs or None if none is found.
  
  
          **EXAMPLE**
  
          >>>> ls = img.getLineScan(x=10)
          >>>> ls2 = ls.median(7)
          >>>> plt.plot(ls)
          >>>> plt.plot(ls2)
          >>>> plt.show()
  
          """
          if( sz%2==0 ):
              sz = sz+1
          skip = int(np.floor(sz/2))
          out = self[0:skip]
          vsz = len(self)
          for idx in range(skip,vsz-skip):
              val = np.median(self[(idx-skip):(idx+skip)])
              out.append(val)
          for pt in self[-1*skip:]:
              out.append(pt)
          retVal = LineScan(out,image=self.image,pointLoc=self.pointLoc,pt1=self.pt1,pt2=self.pt2)
          retVal._update(self)
          return retVal
  
      def findFirstIdxEqualTo(self,value=255):
          """
          **SUMMARY**
  
          Find the index of the first element of the linescan that has
          a value equal to value. If nothing is found None is returned.
  
          **PARAMETERS**
  
          * *value* - the value to look for.
  
          **RETURNS**
  
          The first index where the value occurs or None if none is found.
  
  
          **EXAMPLE**
  
          >>>> ls = img.getLineScan(x=10)
          >>>> idx = ls.findFIRSTIDXEqualTo()
  
          """
          vals = np.where(np.array(self)==value)[0]
          retVal = None
          if( len(vals) > 0 ):
              retVal = vals[0]
          return retVal
  
      def findLastIdxEqualTo(self,value=255):
          """
          **SUMMARY**
  
          Find the index of the last element of the linescan that has
          a value equal to value. If nothing is found None is returned.
  
          **PARAMETERS**
  
          * *value* - the value to look for.
  
          **RETURNS**
  
          The last index where the value occurs or None if none is found.
  
  
          **EXAMPLE**
  
          >>>> ls = img.getLineScan(x=10)
          >>>> idx = ls.findLastIDXEqualTo()
  
          """
  
          vals = np.where(np.array(self)==value)[0]
          retVal = None
          if( len(vals) > 0 ):
              retVal = vals[-1]
          return retVal
  
      def findFirstIdxGreaterThan(self,value=255):
          """
          **SUMMARY**
  
          Find the index of the first element of the linescan that has
          a value equal to value. If nothing is found None is returned.
  
          **PARAMETERS**
  
          * *value* - the value to look for.
  
          **RETURNS**
  
          The first index where the value occurs or None if none is found.
  
  
          **EXAMPLE**
  
          >>>> ls = img.getLineScan(x=10)
          >>>> idx = ls.findFIRSTIDXEqualTo()
  
          """
          vals = np.where(np.array(self)>=value)[0]
          retVal = None
          if( len(vals) > 0 ):
              retVal = vals[0]
          return retVal
      def applyLUT(self,lut):
          """
          **SUMMARY**
  
          Apply a look up table to the signal.
  
          **PARAMETERS**
  
          * *lut* an array of of length 256, the array elements are the values
            that are replaced via the lut
  
          **RETURNS**
  
          A LineScan object with the LUT applied to the values.
  
          **EXAMPLE**
  
          >>>> ls = img.getLineScan(x=10)
          >>>> lut = ls.createEmptyLUT()
          >>>> ls2 = ls.applyLUT(lut)
          >>>> plt.plot(ls)
          >>>> plt.plot(ls2)
  
          """
          out = []
          for pt in self:
              out.append(lut[pt])
          retVal = LineScan(out,image=self.image,pointLoc=self.pointLoc,pt1=self.pt1,pt2=self.pt2)
          retVal._update(self)
          return retVal
  
      def medianFilter(self, kernel_size=5):
          """
          **SUMMARY**
  
          Apply median filter on the data
  
          **PARAMETERS**
  
          * *kernel_size* - Size of the filter (should be odd int) - int
  
          **RETURNS**
  
          A LineScan object with the median filter applied to the values.
  
          **EXAMPLE**
  
          >>> ls = img.getLineScan(x=10)
          >>> mf = ls.medianFilter()
          >>> plt.plot(ls)
          >>> plt.plot(mf)
          """
          try:
              from scipy.signal import medfilt
          except ImportError:
              warnings.warn("Scipy vesion >= 0.11 requierd.")
              return None
          if kernel_size % 2 == 0:
              kernel_size-=1
              print "Kernel Size should be odd. New kernel size =" , (kernel_size)
          
          medfilt_array = medfilt(np.asarray(self[:]), kernel_size)
          retVal = LineScan(medfilt_array.astype("uint8").tolist(), image=self.image,pointLoc=self.pointLoc,pt1=self.pt1,pt2=self.pt2, x=self.col, y=self.row)
          retVal._update(self)
          return retVal
  
      def detrend(self):
          """
          **SUMMARY**
  
          Detren the data
  
          **PARAMETERS**
  
          **RETURNS**
  
          A LineScan object with detrened data.
  
          **EXAMPLE**
  
          >>> ls = img.getLineScan(x=10)
          >>> dt = ls.detrend()
          >>> plt.plot(ls)
          >>> plt.plot(dt)
          """
          try:
              from scipy.signal import detrend as sdetrend
          except ImportError:
              warnings.warn("Scipy vesion >= 0.11 requierd.")
              return None
          detrend_arr = sdetrend(np.asarray(self[:]))
          retVal = LineScan(detrend_arr.astype("uint8").tolist(), image=self.image,pointLoc=self.pointLoc,pt1=self.pt1,pt2=self.pt2, x=self.col, y=self.row)
          retVal._update(self)
          return retVal
  
      def runningAverage(self, diameter=3, algo="uniform"):
          """
          **SUMMARY**
  
          Finds the running average by either using a uniform kernel or using a gaussian kernel.
          The gaussian kernelis calculated from the standard normal distribution formulae.
  
          **PARAMETERS**
  
          * *diameter* - Size of the window (should be odd int) - int
  
          * *algo* - "uniform" (default) / "gaussian" - used to decide the kernel - string
  
          **RETURNS**
  
          A LineScan object with the kernel of the provided algorithm applied.
  
          **EXAMPLE**
  
          >>> ls = img.getLineScan(x=10)
          >>> ra = ls.runningAverage()
          >>> rag = ls.runningAverage(15,algo="gaussian")
          >>> plt.plot(ls)
          >>> plt.plot(ra)
          >>> plt.plot(rag)
          >>> plt.show()
          
          """
  
          if diameter%2 == 0:
              warnings.warn("Diameter must be an odd integer")
              return None
          if algo=="uniform":
              kernel=list(1/float(diameter)*np.ones(diameter))
          elif algo=="gaussian":
              kernel=list()
              r=float(diameter)/2
              for i in range(-int(r),int(r)+1):
                  kernel.append(np.exp(-i**2/(2*(r/3)**2))/(np.sqrt(2*np.pi)*(r/3)))
          retVal = LineScan(map(int,self.convolve(kernel)))
          retVal._update(self)
          return retVal
  
      def findPeaks(self, window = 30, delta = 3):
          """
          **SUMMARY**
  
          Finds the peaks in a LineScan.
  
          **PARAMETERS**
  
          * *window* - the size of the window in which the peak
           should have the highest value to be considered as a peak.
           By default this is 15 as it gives appropriate results.
           The lower this value the more the peaks are returned
  
          * *delta* - the minimum difference between the peak and 
          all elements in the window
  
          **RETURNS**
  
          A list of (peak position, peak value) tuples.
  
  