code: def buttord(wp, ws, gpass, gstop, analog=False, fs=None):
      """Butterworth filter order selection.
  
      Return the order of the lowest order digital or analog Butterworth filter
      that loses no more than `gpass` dB in the passband and has at least
      `gstop` dB attenuation in the stopband.
  
      Parameters
      ----------
      wp, ws : float
          Passband and stopband edge frequencies.
  
          For digital filters, these are in the same units as `fs`. By default,
          `fs` is 2 half-cycles/sample, so these are normalized from 0 to 1,
          where 1 is the Nyquist frequency. (`wp` and `ws` are thus in
          half-cycles / sample.) For example:
  
              - Lowpass:   wp = 0.2,          ws = 0.3
              - Highpass:  wp = 0.3,          ws = 0.2
              - Bandpass:  wp = [0.2, 0.5],   ws = [0.1, 0.6]
              - Bandstop:  wp = [0.1, 0.6],   ws = [0.2, 0.5]
  
          For analog filters, `wp` and `ws` are angular frequencies
          (e.g., rad/s).
      gpass : float
          The maximum loss in the passband (dB).
      gstop : float
          The minimum attenuation in the stopband (dB).
      analog : bool, optional
          When True, return an analog filter, otherwise a digital filter is
          returned.
      fs : float, optional
          The sampling frequency of the digital system.
  
          .. versionadded:: 1.2.0
  
      Returns
      -------
      ord : int
          The lowest order for a Butterworth filter which meets specs.
      wn : ndarray or float
          The Butterworth natural frequency (i.e. the "3dB frequency"). Should
          be used with `butter` to give filter results. If `fs` is specified,
          this is in the same units, and `fs` must also be passed to `butter`.
  
      See Also
      --------
      scipy.signal.buttord
      butter : Filter design using order and critical points
      cheb1ord : Find order and critical points from passband and stopband spec
      cheb2ord, ellipord
      iirfilter : General filter design using order and critical frequencies
      iirdesign : General filter design using passband and stopband spec
  
      """
      _validate_gpass_gstop(gpass, gstop)
      wp, ws, filter_type = _validate_wp_ws(wp, ws, fs, analog)
      passb, stopb = _pre_warp(wp, ws, analog)
      nat, passb = _find_nat_freq(
          stopb, passb, gpass, gstop, filter_type, "butter"
      )
  
      GSTOP = 10 ** (0.1 * cupy.abs(gstop))
      GPASS = 10 ** (0.1 * cupy.abs(gpass))
      ord = int(
          cupy.ceil(
              cupy.log10((GSTOP - 1.0) / (GPASS - 1.0))
              / (2 * cupy.log10(nat))
          )
      )
  
      # Find the Butterworth natural frequency WN (or the "3dB" frequency")
      # to give exactly gpass at passb.
      try:
          W0 = (GPASS - 1.0) ** (-1.0 / (2.0 * ord))
      except ZeroDivisionError:
          W0 = 1.0
          warnings.warn(
              "Order is zero...check input parameters.",
              RuntimeWarning,
              2,
          )
  
      # now convert this frequency back from lowpass prototype
      # to the original analog filter
  
      if filter_type == 1:  # low
          WN = W0 * passb
      elif filter_type == 2:  # high
          WN = passb / W0
      elif filter_type == 3:  # stop
          WN = cupy.empty(2, float)
          discr = cupy.sqrt(
              (passb[1] - passb[0]) ** 2
              + 4 * W0**2 * passb[0] * passb[1]
          )
          WN[0] = ((passb[1] - passb[0]) + discr) / (2 * W0)
          WN[1] = ((passb[1] - passb[0]) - discr) / (2 * W0)
          WN = cupy.sort(cupy.abs(WN))
      elif filter_type == 4:  # pass
          W0 = cupy.array([-W0, W0], dtype=float)
          WN = -W0 * (passb[1] - passb[0]) / 2.0 + cupy.sqrt(
              W0**2 / 4.0 * (passb[1] - passb[0]) ** 2
              + passb[0] * passb[1]
          )
          WN = cupy.sort(cupy.abs(WN))
      else:
          raise ValueError("Bad type: %s" % filter_type)
  
      wn = _postprocess_wn(WN, analog, fs)
  
      return ord, wn
  
imports: import warnings
  import math
  from math import pi, prod
  import cupy
  from cupyx.scipy.special import binom
  import cupyx.scipy.special
  from cupyx.scipy.signal import _optimize
  from cupyx.scipy.signal._polyutils import roots, poly
  from cupyx.scipy.signal._lti_conversion import abcd_normalize
label_desc: Use image node_id 43 for calling a global function with example usage: buttord(wp, ws, gpass, gstop, analog, fs) and returns: ord,  wn