class_docstr: This is a class to represent multiple ROI objects, where the
  reference to a given domain is explicit.
  
  A multiple ROI object is a set of ROI defined on a given domain,
  each having its own 'region-level' characteristics (ROI features).
  
  Every voxel of the domain can have its own characteristics yet,
  defined at the 'voxel-level', but those features can only be accessed
  familywise (i.e. the values are grouped by ROI).
  
  Parameters
  ----------
  k : int
    Number of ROI in the SubDomains object
  label : array of shape (domain.size), dtype=np.int_
    An array use to define which voxel belongs to which ROI.
    The label values greater than -1 correspond to subregions
    labelling. The labels are recomputed so as to be consecutive
    integers.
    The labels should not be accessed outside this class. One has to
    use the API mapping methods instead.
  features : dict {str: list of object, length=self.k}
    Describe the voxels features, grouped by ROI
  roi_features : dict {str: array-like, shape=(self.k, roi_feature_dim)
    Describe the ROI features. A special feature, `id`, is read-only and
    is used to give an unique identifier for region, which is persistent
    through the MROI objects manipulations. On should access the different
    ROI's features using ids.
class_docstr_tok: ["This","is","a","class","to","represent","multiple","ROI","objects",",","where","the","reference","to","a","given","domain","is","explicit",".","A","multiple","ROI","object","is","a","set","of","ROI","defined","on","a","given","domain",",","each","having","its","own","'region-level","'","characteristics","(","ROI","features",")",".","Every","voxel","of","the","domain","can","have","its","own","characteristics","yet",",","defined","at","the","'voxel-level","'",",","but","those","features","can","only","be","accessed","familywise","(","i.e",".","the","values","are","grouped","by","ROI",")",".","Parameters","--","--","--","--","--","k",":","int","Number","of","ROI","in","the","SubDomains","object","label",":","array","of","shape","(","domain.size",")",",","dtype=np.int_","An","array","use","to","define","which","voxel","belongs","to","which","ROI",".","The","label","values","greater","than","-1","correspond","to","subregions","labelling",".","The","labels","are","recomputed","so","as","to","be","consecutive","integers",".","The","labels","should","not","be","accessed","outside","this","class",".","One","has","to","use","the","API","mapping","methods","instead",".","features",":","dict","{","str",":","list","of","object",",","length=self.k","}","Describe","the","voxels","features",",","grouped","by","ROI","roi_features",":","dict","{","str",":","array-like",",","shape=","(","self.k",",","roi_feature_dim",")","Describe","the","ROI","features",".","A","special","feature",",","`","id","`",",","is","read-only","and","is","used","to","give","an","unique","identifier","for","region",",","which","is","persistent","through","the","MROI","objects","manipulations",".","On","should","access","the","different","ROI","'s","features","using","ids","."]
docstr: Append or modify a feature
  
  Parameters
  ----------
  fid : str
    feature identifier
  data: list or array
    The feature data. Can be a list of self.k arrays of
    shape(self.size[k], p) or array of shape(self.size[k])
  id: any hashable type, optional
    Id of the ROI from which we want to set the feature.
    Can be None (default) if we want to set all ROIs's features.
  override: bool, optional
    Allow feature overriding
  
  Note that we cannot create a feature having the same name than
  a ROI feature.
docstr_tok: ["Append","or","modify","a","feature","Parameters","--","--","--","--","--","fid",":","str","feature","identifier","data",":","list","or","array","The","feature","data",".","Can","be","a","list","of","self.k","arrays","of","shape","(","self.size","[","k","]",",","p",")","or","array","of","shape","(","self.size","[","k","]",")","id",":","any","hashable","type",",","optional","Id","of","the","ROI","from","which","we","want","to","set","the","feature",".","Can","be","None","(","default",")","if","we","want","to","set","all","ROIs","'s","features",".","override",":","bool",",","optional","Allow","feature","overriding","Note","that","we","can","not","create","a","feature","having","the","same","name","than","a","ROI","feature","."]
code: def set_feature(self, fid, data, id=None, override=False):
      """Append or modify a feature
  
      Parameters
      ----------
      fid : str
        feature identifier
      data: list or array
        The feature data. Can be a list of self.k arrays of
        shape(self.size[k], p) or array of shape(self.size[k])
      id: any hashable type, optional
        Id of the ROI from which we want to set the feature.
        Can be None (default) if we want to set all ROIs's features.
      override: bool, optional
        Allow feature overriding
  
      Note that we cannot create a feature having the same name than
      a ROI feature.
  
      """
      # ensure that the `id` field will not be modified
      if fid == "id":
          override = False
      # check the feature is already present if setting a single roi
      if fid not in self.features and len(data) != self.k:
          raise ValueError(
              f"`{fid}` feature does not exist, create it first"
          )
      if fid in self.roi_features:
          raise ValueError(
              f"a roi_feature called `{fid}` already exists"
          )
      # check we will not override anything
      if fid in self.features and not override:
          # TODO: raise a warning
          return
      # modify one particular region
      if id is not None:
          # check data size
          roi_size = self.get_size(id)
          if len(data) != roi_size:
              raise ValueError(
                  "data for region `%i` should have length %i"
                  % (id, roi_size)
              )
          # update feature
          the_feature = self.get_feature(fid, id)
          the_feature[self.select_id(id)] = data
      # modify all regions
      else:
          # check data size
          if len(data) != self.k:
              raise ValueError("data should have length %i" % self.k)
          for k in self.get_id():
              if len(data[self.select_id(k)]) != self.get_size(k):
                  raise ValueError(
                      "Wrong data size for region `%i`" % k
                  )
          self.features.update({fid: data})
  
imports: import numpy
  from nibabel import Nifti1Image, load
  from nipy.io.nibcompat import get_affine, get_header
  from .None import discrete_domain
label_desc: Use image node_id 12 for calling the SubDomains obj's underlying member method code with example usage: obj.set_feature(fid, data, id, override) without return types