class_docstr: Create 3 maps of connected component detection:
  tpc_map shows each detected ref cc (having at least on seg cc that
  overlaps) and the union of all overlapping seg ccs
  fnc_map shows all ref ccs that were not detected
  fpc_map shows all seg ccs that did not overlap any ref ccs
  Note we currently arbitrarily limit image generation to binary problems
class_docstr_tok: ["Create","3","maps","of","connected","component","detection",":","tpc_map","shows","each","detected","ref","cc","(","having","at","least","on","seg","cc","that","overlaps",")","and","the","union","of","all","overlapping","seg","ccs","fnc_map","shows","all","ref","ccs","that","were","not","detected","fpc_map","shows","all","seg","ccs","that","did","not","overlap","any","ref","ccs","Note","we","currently","arbitrarily","limit","image","generation","to","binary","problems"]
code: def layer_op(self, subject_id, data):
      analyses = self.app_param.evaluation_units.split(",")
      if "label" not in analyses and "foreground" not in analyses:
          raise ValueError(
              "ErrorMaps work with label or foreground " "analyses only"
          )
      if self.app_param.num_classes > 2:
          raise ValueError(
              "ErrorMaps work with binary segmentations only"
          )
  
      binarizer = cached_label_binarizer(1, self.app_param.output_prob)
      seg, ref = binarizer(data)
      cc_func = connected_components
      cc_seg, cc_ref = cc_func(seg, ref, self.app_param.output_prob)
  
      cc_aggregator = union_of_seg_for_each_ref_cc
      ccs = cc_aggregator(cc_ref, cc_seg)
  
      tp_seg_labels = set(s for seg_l, ref_l in ccs for s in seg_l)
      tp_ref_labels = set(
          r for seg_l, ref_l in ccs for r in ref_l if len(seg_l)
      )
      fn_ref_labels = set(range(1, cc_ref[1])) - tp_ref_labels
      fp_seg_labels = set(range(1, cc_seg[1])) - tp_seg_labels
      maps = {}
      maps["tpc_map"] = np.logical_or(
          cc_seg in tp_seg_labels, cc_ref in tp_ref_labels
      )
      maps["fnc_map"] = cc_ref in fn_ref_labels
      maps["fpc_map"] = cc_seg in fp_seg_labels
  
      image_idx = self.reader.get_image_index(subject_id)
      file_path = os.path.join(self.eval_param.save_csv_dir, "images")
      out = {"subject_id": subject_id}
      for key in maps:
          out[key] = os.path.join(
              file_path, subject_id + "_" + key + ".nii"
          )
          save_data_array(
              file_path,
              subject_id + "_" + key + ".nii",
              maps[key],
              self.reader.output_list[image_idx]["label"],
              0,
          )
      pdf = pd.DataFrame.from_records([out], ("subject_id",))
      return [pdf]
  
file_path: NiftyNet/niftynet/contrib/evaluation/segmentation_evaluations.py
imports: import os
  import numpy
  import pandas
  from scipy import ndimage
  from niftynet.evaluation.base_evaluations import BaseEvaluation
  from niftynet.evaluation.segmentation_evaluations import PerComponentEvaluation, connected_components, cached_label_binarizer, union_of_seg_for_each_ref_cc
  from niftynet.io.misc_io import save_data_array
label_desc: Use image node_id 1 for calling the ErrorMapsCC obj's underlying member method code with example usage: obj.layer_op(subject_id, data) and returns: list