code: def pulse_doppler(x, window=None, nfft=None):
      """
      Pulse doppler processing yields a range/doppler data matrix that represents
      moving target data that's separated from clutter. An estimation of the
      doppler shift can also be obtained from pulse doppler processing. FFT taken
      across slow-time (pulse) dimension.
  
      Parameters
      ----------
      x : ndarray
          Received signal, assume 2D array with [num_pulses, sample_per_pulse]
  
      window : array_like, callable, string, float, or tuple, optional
          Specifies the window applied to the signal in the Fourier
          domain.
  
      nfft : int, size of FFT for pulse compression. Default is number of
          samples per pulse
  
      Returns
      -------
      pd_dataMatrix : ndarray
          Pulse-doppler output (range/doppler matrix)
      """
      num_pulses, samples_per_pulse = x.shape
  
      if nfft is None:
          nfft = num_pulses
  
      xT = _pulse_preprocess(x.T, False, window)
      return cupy.fft.fft(xT, nfft).T
  
imports: import cupy
  from cupyx.scipy.signal import windows
label_desc: Use image node_id 3 for calling a global function with example usage: pulse_doppler(x, window, nfft) and returns: cupy