docs: def countrate(self,binned=True,range=None,force=False):
          """Calculate effective stimulus in count/s.
          Also see :ref:`pysynphot-formula-countrate` and
          :ref:`pysynphot-formula-effstim`.
  
          .. note::
  
              This is the calculation performed when the ETC invokes
              ``countrate``.
  
          Parameters
          -----------
          binned : bool
              If `True` (default), use binned data.
              Otherwise, use native data.
  
          range : tuple or `None`
              If not `None`, it must be a sequence with two floating-point
              elements specifying the wavelength range (*inclusive*) in the
              unit of ``self.waveunits`` in the form of ``(low, high)``;
              This is the range over which the integration will be performed.
              If the specified range does not exactly match a value in the
              wavelength set:
  
                  * If ``binned=True``, the bin containing the range value will
                    be used. This assumes ``self.binwave`` contains bin centers.
                  * If ``binned=False``, native dataset will be interpolated to
                    the specified values. (*Not Implemented.*)
  
          force : bool
              If `False` (default), partially overlapping ranges
              will raise an exception. If `True`, a partial overlap will
              return the calculated value instead. Disjoint ranges raise
              an exception regardless.
  
          Returns
          -------
          ans : float
              Count rate.
  
          Raises
          ------
          NotImplementedError
              Wavelength range is defined for unbinned data.
  
          pysynphot.exceptions.DisjointError
              Wavelength range does not overlap with observation.
  
          pysynphot.exceptions.PartialOverlap
              Wavelength range only partially overlaps with observation.
  
          """
  
          if self._binflux is None:
            self.initbinflux()
  
          myfluxunits = self.fluxunits.name
          self.convert('counts')
          warn=False
          if binned:
              #No range specified - use full range
              if range is None:
                  lx,ux=(None,None)
              #Range is disjoint from binwave
              elif (range[0]>self.binwave[-1] or
                    range[1]<self.binwave[0]):
                  raise exceptions.DisjointError("%s is disjoint from obs.binwave %s"%(range,
                                                                         [self.binwave[0],self.binwave[-1]]))
              #Partial overlap
              else:
  
                  if range[0] < self._bin_edges[0]:
                      warn=True
                      lx=None
                  else:
                      lx=np.searchsorted(self._bin_edges,range[0])-1
  
                  if range[1] > self._bin_edges[-1]:
                      warn=True
                      ux=None
                  else:
                      ux=np.searchsorted(self._bin_edges,range[1])
  
  
              ans = math.fsum(self.binflux[lx:ux])
              if warn and not force:
                  raise exceptions.PartialOverlap("%s does not fully overlap binwave range %s. Countrate in overlap area is %f"%(range,[self.binwave[0],self.binwave[-1]],ans))
  
          else:
              if range is None:
                  ans = math.fsum(self.flux)
              else:
                  raise NotImplementedError("Sorry, range+binned=False not yet implemented")
          self.convert(myfluxunits)
          return ans