class_docstr: A ``Thread`` to monitor a specific PID with a certain frequency
  to a file
class_docstr_tok: ["A","``","Thread","``","to","monitor","a","specific","PID","with","a","certain","frequency","to","a","file"]
docstr: Stop monitoring.
docstr_tok: ["Stop","monitoring","."]
code: def stop(self):
      """Stop monitoring."""
      if not self._event.is_set():
          self._event.set()
          self.join()
          self._sample()
          self._logfile.flush()
          self._logfile.close()
  
      retval = {
          "mem_peak_gb": None,
          "cpu_percent": None,
      }
  
      # Read .prof file in and set runtime values
      vals = np.loadtxt(self._fname, delimiter=",")
      if vals.size:
          vals = np.atleast_2d(vals)
          retval["mem_peak_gb"] = vals[:, 2].max() / 1024
          retval["cpu_percent"] = vals[:, 1].max()
          retval["prof_dict"] = {
              "time": vals[:, 0].tolist(),
              "cpus": vals[:, 1].tolist(),
              "rss_GiB": (vals[:, 2] / 1024).tolist(),
              "vms_GiB": (vals[:, 3] / 1024).tolist(),
          }
      return retval
  
imports: import os
  import numpy
  import threading
  from time import time
  from ..None import config, logging
label_desc: Use image node_id 3 for calling the ResourceMonitor obj's underlying member method code with example usage: obj.stop() and returns: retval