code: def processData(self, data):
      times = data.xvals("Time")
      dt = times[1] - times[0]
  
      data1 = data.asarray()
      ft = np.fft.fft(data1)
  
      ## determine frequencies in fft data
      df = 1.0 / (len(data1) * dt)
  
      ## flatten spikes at f0 and harmonics
      f0 = self.ctrls["f0"].value()
      for i in range(1, self.ctrls["harmonics"].value() + 2):
          f = f0 * i  # target frequency
  
          ## determine index range to check for this frequency
          ind1 = int(np.floor(f / df))
          ind2 = int(np.ceil(f / df)) + (
              self.ctrls["samples"].value() - 1
          )
          if ind1 > len(ft) / 2.0:
              break
          mag = (abs(ft[ind1 - 1]) + abs(ft[ind2 + 1])) * 0.5
          for j in range(ind1, ind2 + 1):
              phase = np.angle(
                  ft[j]
              )  ## Must preserve the phase of each point, otherwise any transients in the trace might lead to large artifacts.
              re = mag * np.cos(phase)
              im = mag * np.sin(phase)
              ft[j] = re + im * 1j
              ft[len(ft) - j] = re - im * 1j
  
      data2 = np.fft.ifft(ft).real
  
      ma = metaarray.MetaArray(data2, info=data.infoCopy())
      return ma
  
imports: import numpy
  from ...None import Point, PolyLineROI
  from ...None import functions
  from ...None import metaarray
  from .None import functions
  from .common import CtrlNode, PlottingCtrlNode, metaArrayWrapper
label_desc: Use image node_id 1 for calling the RemovePeriodic obj's underlying member method code with example usage: obj.processData(data) and returns: ma