class_docstr: Class that performs the reading of the csv_input and select the lines
  according to the subject id if available
class_docstr_tok: ["Class","that","performs","the","reading","of","the","csv_input","and","select","the","lines","according","to","the","subject","id","if","available"]
docstr: Perform the csv_reading and assignment to dictionary
  :param idx: index of the image
  :param subject_id: subject id
  :param mode: chosen mode (multi or single)
  :param reject: if some elements should be rejected
  :return:
docstr_tok: ["Perform","the","csv_reading","and","assignment","to","dictionary",":","param","idx",":","index","of","the","image",":","param","subject_id",":","subject","id",":","param","mode",":","chosen","mode","(","multi","or","single",")",":","param","reject",":","if","some","elements","should","be","rejected",":","return",":"]
code: def layer_op(
      self, idx=None, subject_id=None, mode="single", reject=True
  ):
      """
      Perform the csv_reading and assignment to dictionary
      :param idx: index of the image
      :param subject_id: subject id
      :param mode: chosen mode (multi or single)
      :param reject: if some elements should be rejected
      :return:
      """
      if idx is None and subject_id is not None:
          print("Need to decide upon idx from subject %s" % subject_id)
          idx_dict = {}
          if mode == "single":
              print("Taking only one index among other valid")
              #  Take the list of idx corresponding to subject id and randomly
              # sample from there
              for name in self.names:
                  relevant_indices = (
                      self.df_by_task[name]
                      .reset_index()[
                          self.df_by_task[name].reset_index()[0]
                          == subject_id
                      ]
                      .index.values
                  )
                  if reject:
                      relevant_valid = np.asarray(
                          np.where(
                              np.abs(
                                  self.valid_by_task[name][
                                      relevant_indices
                                  ]
                              )
                              > 0
                          )[0]
                      )
                      if relevant_valid is None:
                          relevant_valid = []
                      print(relevant_valid, reject)
                  else:
                      relevant_valid = np.arange(len(relevant_indices))
                      print(
                          relevant_valid,
                          " is list of indices to sample " "from",
                      )
                  print(
                      np.asarray(relevant_valid).shape[0],
                      "is shape of " "relevant_valid",
                  )
                  relevant_final = (
                      [relevant_indices[v] for v in relevant_valid]
                      if np.asarray(relevant_valid).shape[0] > 0
                      else []
                  )
                  print(relevant_final, "is relevant final")
                  idx_dict[name] = (
                      random.choice(relevant_final)
                      if list(relevant_final)
                      else []
                  )
  
          else:  # self.df_by_task[self.df_by_task[name] == subject_id]
              # mode full i.e. output all the lines corresponding to
              # subject_id
              print(" Taking all valid indices")
              for name in self.names:
                  relevant_indices = (
                      self.df_by_task[name]
                      .reset_index()[
                          self.df_by_task[name].reset_index()[0]
                          == subject_id
                      ]
                      .index.values
                  )
                  if reject:
                      relevant_valid = np.asarray(
                          np.where(
                              np.abs(
                                  self.valid_by_task[name][
                                      relevant_indices
                                  ]
                              )
                              > 0
                          )[0]
                      )
                      if relevant_valid is None:
                          relevant_valid = []
                  else:
                      relevant_valid = np.arange(len(relevant_indices))
                  relevant_final = (
                      [relevant_indices[v] for v in relevant_valid]
                      if np.asarray(relevant_valid).shape[0] > 0
                      else []
                  )
                  idx_dict[name] = relevant_final
  
      elif idx is None and subject_id is None:
          idx_dict = {}
          print("Need to also choose subject id")
          for name in self.names:
              if subject_id is None:
                  idx_dict[name] = np.random.randint(
                      self.df_by_task[name].shape[0]
                  )
                  subject_id = (
                      self.df_by_task[name].iloc[idx_dict[name]].name
                  )
                  print("new subject id is ", subject_id)
              if mode == "single":
                  #  Take the list of idx corresponding to subject id
                  # and randomly sample from there
                  print("Need to find index in single mode")
  
                  relevant_indices = np.asarray(
                      np.where(
                          self.df_by_task[name].index.get_loc(
                              subject_id
                          )
                      )[0]
                  )
                  # print("Found initial relevant", relevant_indices,
                  #       set(self.df_by_task[name].index), name,
                  #       self.df_by_task[name].index.get_loc(subject_id).shape)
                  if reject:
                      relevant_valid = np.asarray(
                          np.where(
                              np.abs(
                                  self.valid_by_task[name][
                                      relevant_indices
                                  ]
                              )
                              > 0
                          )[0]
                      )
                  else:
                      relevant_valid = np.arange(len(relevant_indices))
                  # print("Found corresponding valid", relevant_valid,
                  #       np.max(relevant_valid), relevant_indices.shape)
                  relevant_final = [
                      relevant_indices[v] for v in relevant_valid
                  ]
                  # print(relevant_indices, subject_id)
                  # relevant_indices = self._df.loc[subject_id]
                  assert list(relevant_final), (
                      "no valid index for subject "
                      "%s and field %s" % (subject_id, name)
                  )
                  idx_dict[name] = random.choice(relevant_final)
              else:  # mode full i.e. output all the lines corresponding to
                  # subject_id
                  relevant_indices = np.asarray(
                      np.where(
                          self.df_by_task[name].index.get_loc(
                              subject_id
                          )
                      )[0]
                  )
                  # print("Found initial relevant", relevant_indices,
                  #       set(self.df_by_task[name].index), name,
                  #       self.df_by_task[name].index.get_loc(subject_id).shape)
                  if reject:
                      relevant_valid = np.asarray(
                          np.where(
                              np.abs(
                                  self.valid_by_task[name][
                                      relevant_indices
                                  ]
                              )
                              > 0
                          )[0]
                      )
                  else:
                      relevant_valid = np.ones_like(relevant_indices)
                  # print("Found corresponding valid", relevant_valid,
                  #       np.max(relevant_valid), relevant_indices.shape)
                  relevant_final = [
                      relevant_indices[v] for v in relevant_valid
                  ]
                  assert list(relevant_final), (
                      "no valid index for subject "
                      "%s and field %s" % (subject_id, name)
                  )
                  idx_dict[name] = relevant_final
      elif not isinstance(idx, dict):
          idx_dict = {}
          for name in self.names:
              idx_dict[name] = idx
              if subject_id is None:
                  subject_id = (
                      self.df_by_task[name].iloc[idx_dict[name]].name
                  )
      else:
          idx_dict = {}
          for name in self.names:
              idx_dict[name] = idx[name]
              assert list(idx[name]), "no valid index for %s" % name
              if subject_id is None:
                  subject_id = (
                      self.df_by_task[name].iloc[idx_dict[name]].name
                  )
  
      if self._indexable_output is not None:
          output_dict = {
              k: self.apply_niftynet_format_to_data(
                  self.tile_nsamples(
                      np.asarray(self._indexable_output[k])[idx_dict[k]]
                  )
              )
              for k in idx_dict.keys()
          }
          # print(idx_dict, self._indexable_output['modality_label'][
          #     idx_dict['modality_label']])
          return idx_dict, output_dict, subject_id
      raise Exception("Invalid mode")
  
imports: import random
  import numpy
  import pandas
  import tensorflow
  from tensorflow.python.data.util import nest
  from niftynet.layer.base_layer import Layer
  from niftynet.io.image_reader import param_to_dict
label_desc: Use image node_id 6 for calling the CSVReader obj's underlying member method code with example usage: obj.layer_op(idx, subject_id, mode, reject) and returns: idx_dict,  output_dict,  subject_id