text: #!/usr/bin/env python3
  # -*- coding: utf-8 -*-
  
  # ##################################################
  # 適応法を用いた音の最小知覚移動角度の心理測定実験
  #
  # Tetsu Takizawa (tt20805@tomakomai.kosen-ac.jp)
  # 2020
  # ##################################################
  
  import json
  import re
  import signal
  import sys
  
  import fire
  import matplotlib.pyplot as plt
  import numpy as np
  import pandas as pd
  import scipy.stats
  
  signal.signal(signal.SIGINT, signal.SIG_DFL)
  
  plt.rcParams['xtick.direction'] = 'in'
  plt.rcParams['ytick.direction'] = 'in'
  plt.rcParams['xtick.top'] = True
  plt.rcParams['ytick.right'] = True
  plt.rcParams['font.size'] = 8
  # plt.rcParams['figure.figsize'] = (10, 6)
  plt.rcParams['figure.dpi'] = 200
  
  
  def norm_cdf(x, mu, sd, gamma, lambda_):
      """mu: mean, sd_: standard diviation, gamma: lower_asymptote, delta: lapse_rate
      """
      norm = scipy.stats.norm(loc=mu, scale=sd)
      return gamma + (1 - gamma - lambda_) * norm.cdf(x)
  
  
  # def plot_result_only_PF(
  #         subjects=None,
  #         stim_const_val: str = "mt0080",
  #         angles=None,
  #         test_number: str = "1",
  # ):
  #     if angles is None:
  #         angles = ["0000", "0450", "0900"]
  #     if subjects is None:
  #         subjects = ["ISHISAKI", "AKAISHI", "SATOU", "IZUMI", "ASADA", "CONNOLLY", "KUBOTA", "TORIKI", "SEINO"]
  #         # angles = str(angles).zfill(4)
  #
  #     # 引数の刺激条件のバリデーション
  #     mt_pattern = re.compile("mt\d{4}")  # mtXXX (mt + 4桁の数字))
  #     w_pattern = re.compile("w\d{4}")
  #
  #     if not mt_pattern.match(stim_const_val) and not w_pattern.match(stim_const_val):
  #         print("error: invalid stimulation_constant_value", file=sys.stderr)
  #         sys.exit(1)
  #
  #     # --------------- 心理測定法の決定 --------------- #
  #     for angle in angles:
  #         for subject_num, subject in enumerate(subjects):
  #             subject_dir = f"SUBJECTS/{subject}"
  #             answer_dir = f"{subject_dir}/angle_{angle}/ANSWER"
  #             result_file_name = f"{answer_dir}/answer_{subject}_{stim_const_val}_{angle}_{test_number}.csv"
  #             qp_params_file_name = f"qp_params/qp_params_{stim_const_val}_{angle}.json"
  #             try:
  #                 with open(qp_params_file_name, "r") as f:
  #                     qp_params = json.load(f)
  #                 df_result = pd.read_csv(result_file_name)
  #             except FileNotFoundError:
  #                 continue
  #             m_est = df_result.iloc[-1]["mean_estimation"]
  #             s_est = df_result.iloc[-1]["sd_estimation"]
  #             la_est = df_result.iloc[-1]["lapse_rate_estimation"]
  #
  #             x = np.arange(0, 100, 0.1)
  #
  #             fig, ax = plt.subplots(tight_layout=True)
  #             ax.set_xlabel("Intensity x", fontsize=38)
  #             ax.set_ylabel("Probability", fontsize=38)
  #             ax.set_xlim([min(qp_params["stim_domain"]["intensity"]), max(qp_params["stim_domain"]["intensity"])])
  #             ax.set_ylim([0.5, 1.0])
  #             ax.plot(x, norm_cdf(x, m_est, s_est, 0.5, la_est), "red")
  #             fig.patch.set_alpha(0)
  #             fig.savefig(f"PF_{subject}_{angle}.png")
  
  def plot_result_only_PF(
          subjects=None,
          stim_const_val: str = "mt0080",
          angles=None,
          test_number: str = "1",
  ):
      if angles is None:
          angles = ["0000", "0450", "0900"]
      if subjects is None:
          subjects = ["ISHISAKI", "AKAISHI", "SATOU", "IZUMI", "ASADA", "CONNOLLY", "KUBOTA", "TORIKI", "SEINO"]
          # angles = str(angles).zfill(4)
  
      # 引数の刺激条件のバリデーション
      mt_pattern = re.compile("mt\d{4}")  # mtXXX (mt + 4桁の数字))
      w_pattern = re.compile("w\d{4}")
  
      if not mt_pattern.match(stim_const_val) and not w_pattern.match(stim_const_val):
          print("error: invalid stimulation_constant_value", file=sys.stderr)
          sys.exit(1)
  
      # fig = plt.figure()
      # fig = plt.figure(tight_layout=True)
      fig = plt.figure(figsize=(7, 6), tight_layout=True)
      # fig = plt.figure(figsize=(7, 6))
      # --------------- 心理測定法の決定 --------------- #
      idx = 0
      for subject_num, subject in enumerate(subjects):
          for angle_num, angle in enumerate(angles):
              idx += 1
              subject_dir = f"SUBJECTS/{subject}"
              answer_dir = f"{subject_dir}/angle_{angle}/ANSWER"
              result_file_name = f"{answer_dir}/answer_{subject}_{stim_const_val}_{angle}_{test_number}.csv"
              qp_params_file_name = f"qp_params/qp_params_{stim_const_val}_{angle}.json"
              try:
                  with open(qp_params_file_name, "r") as f:
                      qp_params = json.load(f)
                  df_result = pd.read_csv(result_file_name)
              except FileNotFoundError:
                  continue
              m_est = df_result.iloc[-1]["mean_estimation"]
              s_est = df_result.iloc[-1]["sd_estimation"]
              la_est = df_result.iloc[-1]["lapse_rate_estimation"]
  
              x = np.arange(0, 100, 0.1)
  
              plt.subplot(9, 3, idx)
              if subject_num == len(subjects) - 1 :
                  plt.xlabel("Intensity x", fontsize=6)
              if angle_num == 0:
                  plt.ylabel("Probability", fontsize=6)
                  # plt.ylabel("Probability", fontsize=16)
              plt.xlim([min(qp_params["stim_domain"]["intensity"]), max(qp_params["stim_domain"]["intensity"])])
              plt.ylim([0.5, 1.0])
              plt.plot(x, norm_cdf(x, m_est, s_est, 0.5, la_est), "red")
      fig.patch.set_alpha(0)
      fig.savefig(f"PFs.png")
  
  
  if __name__ == "__main__":
      fire.Fire(plot_result_only_PF)
  