class_docstr: Analyzer.
  
  Given a run_id, we can do lots of fun things!
class_docstr_tok: ["Analyzer",".","Given","a","run_id",",","we","can","do","lots","of","fun","things","!"]
docstr: Save results to a certain path.
docstr_tok: ["Save","results","to","a","certain","path","."]
code: def save_results(self, path: str = None):
      """
      Save results to a certain path.
      """
      if not hasattr(self, "significance_df"):
          self.get_matchup_totals_with_significance()
      if path is None:
          path = self.outdir
  
      # Save raw dataframe
      self.dataframe.to_csv(
          f"{path}/{self.run_id}.full.csv", index=False
      )
  
      with open(
          "{}/{}.significance.csv".format(path, self.run_id), "w"
      ) as f:
          f.write(self.significance_df.to_csv(index=False))
      print(
          "To visualize significance result, try cat {} | column -t -s, | less -S".format(
              "{}/{}.significance.csv".format(path, self.run_id)
          )
      )
      with open("{}/{}.grid.csv".format(path, self.run_id), "w") as f:
          f.write(self.get_win_fractions().to_csv(index=True))
      with open(
          f"{path}/{self.run_id}.grid.winners_as_rows.csv", "w"
      ) as f:
          f.write(
              self.get_win_fractions().transpose().to_csv(index=True)
          )
      print(
          "To visualize grid result, try cat {} | column -t -s, | less -S".format(
              "{}/{}.grid.csv".format(path, self.run_id)
          )
      )
  
      # Save stats on how many ratings each worker did
      ratings_per_worker = (
          self.dataframe.groupby("worker")["run_id"]
          .count()
          .sort_values(ascending=False)
      )
      ratings_per_worker.to_csv(
          f"{path}/{self.run_id}.ratings_per_worker.csv"
      )
  
      # Save stats on how often Turkers selected each checkbox that represents one
      # reason to pick the speaker they did
      if any(
          col.startswith(self.checkbox_prefix)
          for col in self.dataframe.columns
      ):
          checkbox_stats_dataframes = self._compile_checkbox_stats()
          for group_type, stats in checkbox_stats_dataframes.items():
              stats.to_csv(
                  f"{path}/{self.run_id}.checkbox_stats.{group_type}.csv"
              )
  
      if not hasattr(self, "pairings"):
          print(
              "No pairing file found, skipping conversation visualizations."
          )
  
      else:
          with open(
              "{}/{}.reason.html".format(path, self.run_id), "w"
          ) as f:
              f.write(
                  render_conversations_per_matchups(
                      self.dataframe, True
                  ).data
              )
          print(
              "To visualize conversations with reasons only result, "
              "try scp username@devfair:{} to your local machine".format(
                  " {}/{}.reason.html".format(path, self.run_id)
              )
          )
          with open(
              "{}/{}.all.html".format(path, self.run_id), "w"
          ) as f:
              f.write(
                  render_conversations_per_matchups(
                      self.dataframe, False
                  ).data
              )
          print(
              "To visualize conversations result, try scp username@devfair:{}"
              " to your local machine".format(
                  "{}/{}.all.html".format(path, self.run_id)
              )
          )
  
          # Write all pairs of dialogues, as well as the Turkers' choices and reasons, as
          # a text file
          compiled_text = self._compile_convos_and_reasons()
          with open(
              f"{path}/{self.run_id}.all_convo_pairs.txt", "w"
          ) as f:
              f.write(compiled_text)
  
imports: import hashlib
  import json
  import os
  from copy import deepcopy
  from datetime import datetime
  from typing import Dict, Any, List, Optional
  import numpy
  import pandas
  from IPython.core.display import HTML
  from mephisto.tools.data_browser import DataBrowser
  from mephisto.abstractions.databases.local_database import LocalMephistoDB
  from mephisto.data_model.unit import Unit
  from mephisto.data_model.worker import Worker
  from scipy.stats import binom_test
  from parlai.core.params import ParlaiParser
  from parlai.crowdsourcing.tasks.acute_eval.acute_eval_blueprint import BLUEPRINT_TYPE
  from parlai.crowdsourcing.tasks.acute_eval.fast_acute_blueprint import FAST_ACUTE_BLUEPRINT_TYPE
  from parlai.crowdsourcing.tasks.acute_eval.util import get_hashed_combo_path
label_desc: Use image node_id 18 for calling the AcuteAnalyzer obj's underlying member method code with example usage: obj.save_results(path) without return types