




import argparse
import collections
import json
import os
import re
import string
import sys

import numpy as np


_lowerCAmelCase  :      List[Any]						=      re.compile(r"\b(a|an|the)\b", re.UNICODE)

_lowerCAmelCase  :      Dict						=      None



def   lowerCAmelCase						(						):




 """simple docstring"""







 UpperCAmelCase__							       =  argparse.ArgumentParser("Official evaluation script for SQuAD version 2.0."		)
 parser.add_argument("data_file"  ,							metavar="data.json"  ,							help="Input data JSON file."		)
 parser.add_argument("pred_file"  ,							metavar="pred.json"  ,							help="Model predictions."		)
 parser.add_argument(
     "--out-file"  ,							"-o"  ,							metavar="eval.json"  ,							help="Write accuracy metrics to file (default is stdout)."		)
 parser.add_argument(
     "--na-prob-file"  ,							"-n"  ,							metavar="na_prob.json"  ,							help="Model estimates of probability of no answer."		)
 parser.add_argument(
     "--na-prob-thresh"  ,							"-t"  ,							type=_UpperCamelCase  ,							default=1.0  ,							help="Predict \"\" if no-answer probability exceeds this (default = 1.0)."  ,							)
 parser.add_argument(
     "--out-image-dir"  ,							"-p"  ,							metavar="out_images"  ,							default=_UpperCamelCase  ,							help="Save precision-recall curves to directory."		)
 parser.add_argument("--verbose"  ,							"-v"  ,							action="store_true"		)
 if len(sys.argv		) == 1:
  parser.print_help()
  sys.exit(1		)
 return parser.parse_args()



def   lowerCAmelCase						(						_lowerCAmelCase							:      Optional[int]		):




 """simple docstring"""







 UpperCAmelCase__							       =  {}
 for article in dataset:
  for p in article["paragraphs"]:
   for qa in p["qas"]:
    UpperCAmelCase__							       =  bool(qa["answers"]["text"]		)
 return qid_to_has_ans



def   lowerCAmelCase						(						_lowerCAmelCase							:      Optional[int]		):




 """simple docstring"""







 def remove_articles(_lowerCAmelCase							:      List[Any]		):
  return ARTICLES_REGEX.sub(" "  ,							_UpperCamelCase		)

 def white_space_fix(_lowerCAmelCase							:      List[Any]		):
  return " ".join(text.split()		)

 def remove_punc(_lowerCAmelCase							:      Tuple		):
  UpperCAmelCase__							       =  set(string.punctuation		)
  return "".join(ch for ch in text if ch not in exclude		)

 def lower(_lowerCAmelCase							:      List[Any]		):
  return text.lower()

 return white_space_fix(remove_articles(remove_punc(lower(_UpperCamelCase		)		)		)		)



def   lowerCAmelCase						(						_lowerCAmelCase							:      Optional[Any]		):




 """simple docstring"""







 if not s:
  return []
 return normalize_answer(_UpperCamelCase		).split()



def   lowerCAmelCase						(						_lowerCAmelCase							:      Tuple  ,							_lowerCAmelCase							:      Tuple		):




 """simple docstring"""







 return int(normalize_answer(_UpperCamelCase		) == normalize_answer(_UpperCamelCase		)		)



def   lowerCAmelCase						(						_lowerCAmelCase							:      List[str]  ,							_lowerCAmelCase							:      Any		):




 """simple docstring"""







 UpperCAmelCase__							       =  get_tokens(_UpperCamelCase		)
 UpperCAmelCase__							       =  get_tokens(_UpperCamelCase		)
 UpperCAmelCase__							       =  collections.Counter(_UpperCamelCase		) & collections.Counter(_UpperCamelCase		)
 UpperCAmelCase__							       =  sum(common.values()		)
 if len(_UpperCamelCase		) == 0 or len(_UpperCamelCase		) == 0:
  # If either is no-answer, then F1 is 1 if they agree, 0 otherwise
  return int(gold_toks == pred_toks		)
 if num_same == 0:
  return 0
 UpperCAmelCase__							       =  1.0 * num_same / len(_UpperCamelCase		)
 UpperCAmelCase__							       =  1.0 * num_same / len(_UpperCamelCase		)
 UpperCAmelCase__							       =  (2 * precision * recall) / (precision + recall)
 return fa



def   lowerCAmelCase						(						_lowerCAmelCase							:      int  ,							_lowerCAmelCase							:      Dict		):




 """simple docstring"""







 UpperCAmelCase__							       =  {}
 UpperCAmelCase__							       =  {}
 for article in dataset:
  for p in article["paragraphs"]:
   for qa in p["qas"]:
    UpperCAmelCase__							       =  qa["id"]
    UpperCAmelCase__							       =  [t for t in qa["answers"]["text"] if normalize_answer(_UpperCamelCase		)]
    if not gold_answers:
     # For unanswerable questions, only correct answer is empty string
     UpperCAmelCase__							       =  [""]
    if qid not in preds:
     print(F'''Missing prediction for {qid}'''		)
     continue
    UpperCAmelCase__							       =  preds[qid]
    # Take max over all gold answers
    UpperCAmelCase__							       =  max(compute_exact(_UpperCamelCase  ,							_UpperCamelCase		) for a in gold_answers		)
    UpperCAmelCase__							       =  max(compute_fa(_UpperCamelCase  ,							_UpperCamelCase		) for a in gold_answers		)
 return exact_scores, fa_scores



def   lowerCAmelCase						(						_lowerCAmelCase							:      Tuple  ,							_lowerCAmelCase							:      List[str]  ,							_lowerCAmelCase							:      Any  ,							_lowerCAmelCase							:      Tuple		):




 """simple docstring"""







 UpperCAmelCase__							       =  {}
 for qid, s in scores.items():
  UpperCAmelCase__							       =  na_probs[qid] > na_prob_thresh
  if pred_na:
   UpperCAmelCase__							       =  float(not qid_to_has_ans[qid]		)
  else:
   UpperCAmelCase__							       =  s
 return new_scores



def   lowerCAmelCase						(						_lowerCAmelCase							:      str  ,							_lowerCAmelCase							:      int  ,							_lowerCAmelCase							:      Optional[Any]=None		):




 """simple docstring"""







 if not qid_list:
  UpperCAmelCase__							       =  len(_UpperCamelCase		)
  return collections.OrderedDict(
      [
          ("exact", 100.0 * sum(exact_scores.values()		) / total),
          ("f1", 100.0 * sum(fa_scores.values()		) / total),
          ("total", total),
      ]		)
 else:
  UpperCAmelCase__							       =  len(_UpperCamelCase		)
  return collections.OrderedDict(
      [
          ("exact", 100.0 * sum(exact_scores[k] for k in qid_list		) / total),
          ("f1", 100.0 * sum(fa_scores[k] for k in qid_list		) / total),
          ("total", total),
      ]		)



def   lowerCAmelCase						(						_lowerCAmelCase							:      Optional[int]  ,							_lowerCAmelCase							:      List[Any]  ,							_lowerCAmelCase							:      Dict		):




 """simple docstring"""







 for k in new_eval:
  UpperCAmelCase__							       =  new_eval[k]



def   lowerCAmelCase						(						_lowerCAmelCase							:      int  ,							_lowerCAmelCase							:      List[str]  ,							_lowerCAmelCase							:      Any  ,							_lowerCAmelCase							:      int		):




 """simple docstring"""







 plt.step(_UpperCamelCase  ,							_UpperCamelCase  ,							color="b"  ,							alpha=0.2  ,							where="post"		)
 plt.fill_between(_UpperCamelCase  ,							_UpperCamelCase  ,							step="post"  ,							alpha=0.2  ,							color="b"		)
 plt.xlabel("Recall"		)
 plt.ylabel("Precision"		)
 plt.xlim([0.0, 1.05]		)
 plt.ylim([0.0, 1.05]		)
 plt.title(_UpperCamelCase		)
 plt.savefig(_UpperCamelCase		)
 plt.clf()



def   lowerCAmelCase						(						_lowerCAmelCase							:      Any  ,							_lowerCAmelCase							:      Optional[int]  ,							_lowerCAmelCase							:      Union[str, Any]  ,							_lowerCAmelCase							:      str  ,							_lowerCAmelCase							:      Tuple=None  ,							_lowerCAmelCase							:      Tuple=None		):




 """simple docstring"""







 UpperCAmelCase__							       =  sorted(_UpperCamelCase  ,							key=lambda _lowerCAmelCase		: na_probs[k]		)
 UpperCAmelCase__							       =  0.0
 UpperCAmelCase__							       =  1.0
 UpperCAmelCase__							       =  0.0
 UpperCAmelCase__							       =  [1.0]
 UpperCAmelCase__							       =  [0.0]
 UpperCAmelCase__							       =  0.0
 for i, qid in enumerate(_UpperCamelCase		):
  if qid_to_has_ans[qid]:
   true_pos += scores[qid]
  UpperCAmelCase__							       =  true_pos / float(i + 1		)
  UpperCAmelCase__							       =  true_pos / float(_UpperCamelCase		)
  if i == len(_UpperCamelCase		) - 1 or na_probs[qid] != na_probs[qid_list[i + 1]]:
   # i.e., if we can put a threshold after this point
   avg_prec += cur_p * (cur_r - recalls[-1])
   precisions.append(_UpperCamelCase		)
   recalls.append(_UpperCamelCase		)
 if out_image:
  plot_pr_curve(_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase		)
 return {"ap": 100.0 * avg_prec}



def   lowerCAmelCase						(						_lowerCAmelCase							:      Any  ,							_lowerCAmelCase							:      int  ,							_lowerCAmelCase							:      Union[str, Any]  ,							_lowerCAmelCase							:      str  ,							_lowerCAmelCase							:      Tuple  ,							_lowerCAmelCase							:      Any		):




 """simple docstring"""







 if out_image_dir and not os.path.exists(_UpperCamelCase		):
  os.makedirs(_UpperCamelCase		)
 UpperCAmelCase__							       =  sum(1 for v in qid_to_has_ans.values() if v		)
 if num_true_pos == 0:
  return
 UpperCAmelCase__							       =  make_precision_recall_eval(
     _UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							out_image=os.path.join(_UpperCamelCase  ,							"pr_exact.png"		)  ,							title="Precision-Recall curve for Exact Match score"  ,							)
 UpperCAmelCase__							       =  make_precision_recall_eval(
     _UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							out_image=os.path.join(_UpperCamelCase  ,							"pr_f1.png"		)  ,							title="Precision-Recall curve for F1 score"  ,							)
 UpperCAmelCase__							       =  {k: float(_UpperCamelCase		) for k, v in qid_to_has_ans.items()}
 UpperCAmelCase__							       =  make_precision_recall_eval(
     _UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							out_image=os.path.join(_UpperCamelCase  ,							"pr_oracle.png"		)  ,							title="Oracle Precision-Recall curve (binary task of HasAns vs. NoAns)"  ,							)
 merge_eval(_UpperCamelCase  ,							_UpperCamelCase  ,							"pr_exact"		)
 merge_eval(_UpperCamelCase  ,							_UpperCamelCase  ,							"pr_f1"		)
 merge_eval(_UpperCamelCase  ,							_UpperCamelCase  ,							"pr_oracle"		)



def   lowerCAmelCase						(						_lowerCAmelCase							:      str  ,							_lowerCAmelCase							:      Dict  ,							_lowerCAmelCase							:      Tuple  ,							_lowerCAmelCase							:      str		):




 """simple docstring"""







 if not qid_list:
  return
 UpperCAmelCase__							       =  [na_probs[k] for k in qid_list]
 UpperCAmelCase__							       =  np.ones_like(_UpperCamelCase		) / float(len(_UpperCamelCase		)		)
 plt.hist(_UpperCamelCase  ,							weights=_UpperCamelCase  ,							bins=20  ,							range=(0.0, 1.0)		)
 plt.xlabel("Model probability of no-answer"		)
 plt.ylabel("Proportion of dataset"		)
 plt.title(F'''Histogram of no-answer probability: {name}'''		)
 plt.savefig(os.path.join(_UpperCamelCase  ,							F'''na_prob_hist_{name}.png'''		)		)
 plt.clf()



def   lowerCAmelCase						(						_lowerCAmelCase							:      Any  ,							_lowerCAmelCase							:      Dict  ,							_lowerCAmelCase							:      Any  ,							_lowerCAmelCase							:      List[Any]		):




 """simple docstring"""







 UpperCAmelCase__							       =  sum(1 for k in qid_to_has_ans if not qid_to_has_ans[k]		)
 UpperCAmelCase__							       =  num_no_ans
 UpperCAmelCase__							       =  cur_score
 UpperCAmelCase__							       =  0.0
 UpperCAmelCase__							       =  sorted(_UpperCamelCase  ,							key=lambda _lowerCAmelCase		: na_probs[k]		)
 for i, qid in enumerate(_UpperCamelCase		):
  if qid not in scores:
   continue
  if qid_to_has_ans[qid]:
   UpperCAmelCase__							       =  scores[qid]
  else:
   if preds[qid]:
    UpperCAmelCase__							       =  -1
   else:
    UpperCAmelCase__							       =  0
  cur_score += diff
  if cur_score > best_score:
   UpperCAmelCase__							       =  cur_score
   UpperCAmelCase__							       =  na_probs[qid]
 return 100.0 * best_score / len(_UpperCamelCase		), best_thresh



def   lowerCAmelCase						(						_lowerCAmelCase							:      str  ,							_lowerCAmelCase							:      str  ,							_lowerCAmelCase							:      Any  ,							_lowerCAmelCase							:      Optional[int]  ,							_lowerCAmelCase							:      Tuple  ,							_lowerCAmelCase							:      int		):




 """simple docstring"""







 UpperCAmelCase__       ,       UpperCAmelCase__							       =  find_best_thresh(_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase		)
 UpperCAmelCase__       ,       UpperCAmelCase__							       =  find_best_thresh(_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase		)
 UpperCAmelCase__							       =  best_exact
 UpperCAmelCase__							       =  exact_thresh
 UpperCAmelCase__							       =  best_fa
 UpperCAmelCase__							       =  fa_thresh



def   lowerCAmelCase						(						):




 """simple docstring"""







 with open(OPTS.data_file		) as f:
  UpperCAmelCase__							       =  json.load(_UpperCamelCase		)
  UpperCAmelCase__							       =  dataset_json["data"]
 with open(OPTS.pred_file		) as f:
  UpperCAmelCase__							       =  json.load(_UpperCamelCase		)
 if OPTS.na_prob_file:
  with open(OPTS.na_prob_file		) as f:
   UpperCAmelCase__							       =  json.load(_UpperCamelCase		)
 else:
  UpperCAmelCase__							       =  {k: 0.0 for k in preds}
 UpperCAmelCase__							       =  make_qid_to_has_ans(_UpperCamelCase		)  # maps qid to True/False
 UpperCAmelCase__							       =  [k for k, v in qid_to_has_ans.items() if v]
 UpperCAmelCase__							       =  [k for k, v in qid_to_has_ans.items() if not v]
 UpperCAmelCase__       ,       UpperCAmelCase__							       =  get_raw_scores(_UpperCamelCase  ,							_UpperCamelCase		)
 UpperCAmelCase__							       =  apply_no_ans_threshold(_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							OPTS.na_prob_thresh		)
 UpperCAmelCase__							       =  apply_no_ans_threshold(_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							OPTS.na_prob_thresh		)
 UpperCAmelCase__							       =  make_eval_dict(_UpperCamelCase  ,							_UpperCamelCase		)
 if has_ans_qids:
  UpperCAmelCase__							       =  make_eval_dict(_UpperCamelCase  ,							_UpperCamelCase  ,							qid_list=_UpperCamelCase		)
  merge_eval(_UpperCamelCase  ,							_UpperCamelCase  ,							"HasAns"		)
 if no_ans_qids:
  UpperCAmelCase__							       =  make_eval_dict(_UpperCamelCase  ,							_UpperCamelCase  ,							qid_list=_UpperCamelCase		)
  merge_eval(_UpperCamelCase  ,							_UpperCamelCase  ,							"NoAns"		)
 if OPTS.na_prob_file:
  find_all_best_thresh(_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase		)
 if OPTS.na_prob_file and OPTS.out_image_dir:
  run_precision_recall_analysis(_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							_UpperCamelCase  ,							OPTS.out_image_dir		)
  histogram_na_prob(_UpperCamelCase  ,							_UpperCamelCase  ,							OPTS.out_image_dir  ,							"hasAns"		)
  histogram_na_prob(_UpperCamelCase  ,							_UpperCamelCase  ,							OPTS.out_image_dir  ,							"noAns"		)
 if OPTS.out_file:
  with open(OPTS.out_file  ,							"w"		) as f:
   json.dump(_UpperCamelCase  ,							_UpperCamelCase		)
 else:
  print(json.dumps(_UpperCamelCase  ,							indent=2		)		)


if __name__ == "__main__":
  _lowerCAmelCase  :      List[Any]						=      parse_args()
  if OPTS.out_image_dir:
    import matplotlib

    matplotlib.use("Agg")
    import matplotlib.pyplot as plt
  main()








'''simple docstring'''
# Copyright 2023 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import numpy as np
import torch

from ..models.clipseg import CLIPSegForImageSegmentation
from ..utils import is_vision_available, requires_backends
from .base import PipelineTool


if is_vision_available():
     from PIL import Image







class 							A__    (       A__  ):
  A__		 =				(
      'This is a tool that creates a segmentation mask of an image according to a label. It cannot create an image.'
      'It takes two arguments named `image` which should be the original image, and `label` which should be a text '
      'describing the elements what should be identified in the segmentation mask. The tool returns the mask.'
  )
  A__		 =				'CIDAS/clipseg-rd64-refined'
  A__		 =				'image_segmenter'
  A__		 =				CLIPSegForImageSegmentation

  A__		 =				['image', 'text']
  A__		 =				['image']





  def __init__(		self      :	Any							,					*_a      :	Dict							,					**_a      :	str )	->    Any:





       '''simple docstring'''






       requires_backends(self							,					['vision'] )
       super().__init__(*_a							,					**_a )





  def 						A  (		self      :	int							,					_a      :	"Image"							,					_a      :	str )	->    Optional[Any]:





       '''simple docstring'''






       return self.pre_processor(text=[label]							,					images=[image]							,					padding=_a							,					return_tensors='pt' )





  def 						A  (		self      :	Dict							,					_a      :	Dict )	->    str:





       '''simple docstring'''






       with torch.no_grad():
            _SCREAMING_SNAKE_CASE							    =self.model(**_a ).logits
       return logits





  def 						A  (		self      :	Any							,					_a      :	str )	->    Union[str, Any]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							    =outputs.cpu().detach().numpy()
       _SCREAMING_SNAKE_CASE							    =0
       _SCREAMING_SNAKE_CASE							    =1
       return Image.fromarray((array * 255).astype(np.uinta ) )
