docs: def SelectFromListId(LId, Val=None, Crit='Name',
                       PreExp=None, PostExp=None, Log='any',
                       InOut='In', Out=bool):
      """ Return the indices or instances of all LOS matching criteria
  
      The selection can be done according to 2 different mechanisms
  
      Mechanism (1): provide the value (Val) a criterion (Crit) should match
      The criteria are typically attributes of :class:`~tofu.pathfile.ID`
      (i.e.: name, or user-defined attributes like the camera head...)
  
      Mechanism (2): (used if Val=None)
      Provide a str expression (or a list of such) to be fed to eval()
      Used to check on quantitative criteria.
          - PreExp: placed before the criterion value (e.g.: 'not ' or '<=')
          - PostExp: placed after the criterion value
          - you can use both
  
      Other parameters are used to specify logical operators for the selection
      (match any or all the criterion...) and the type of output.
  
      Parameters
      ----------
      Crit :      str
          Flag indicating which criterion to use for discrimination
          Can be set to:
              - any attribute of :class:`~tofu.pathfile.ID`
                (e.g.: 'Name','SaveName','SavePath'...)
              - any key of ID.USRdict (e.g.: 'Exp'...)
      Val :       None / list / str
          The value to match for the chosen criterion, can be a list
          Used for selection mechanism (1)
      PreExp :    None / list / str
          A str (or list of such) expression to be fed to eval(),
          Placed before the criterion value
          Used for selection mechanism (2)
      PostExp :   None / list / str
          A str (or list of such) expression to be fed to eval()
          Placed after the criterion value
          Used for selection mechanism (2)
      Log :       str
          Flag indicating whether the criterion shall match:
              - 'all': all provided values
              - 'any': at least one of them
      InOut :     str
          Flag indicating whether the returned indices are:
              - 'In': the ones matching the criterion
              - 'Out': the ones not matching it
      Out :       type / str
          Flag indicating in which form to return the result:
              - int: as an array of integer indices
              - bool: as an array of boolean indices
              - 'Name': as a list of names
              - 'LOS': as a list of :class:`~tofu.geom.LOS` instances
  
      Returns
      -------
      ind :       list / np.ndarray
          The computed output, of nature defined by parameter Out
  
      """
      C0 = type(Crit) is str
      C1 = type(Crit) is list and all([type(cc) is str for cc in Crit])
      assert C0 or C1, "Arg Crit must be a str or list of str !"
      for rr in [PreExp,PostExp]:
          if rr is not None:
              C0 = type(rr) is str
              C1 = type(rr) is list and all([type(ee) is str for ee in rr])
              assert C0 or C1,  "Args %S must be a str or list of str !"%rr
      assert Log in ['any','all'], "Arg Log must be in ['any','all'] !"
      assert InOut in ['In','Out'], "Arg InOut must be in ['In','Out'] !"
      if Val is None and PreExp is None and PostExp is None:
          ind = np.ones((1,len(LId)),dtype=bool)
      elif not Val is None:
          if type(Val) is str:
              Val=[Val]
          N = len(Val)
          ind = np.zeros((N,len(LId)),dtype=bool)
          if Crit in dir(ID):
              for ii in range(0,N):
                  ind[ii,:] = np.asarray([getattr(iid,Crit)==Val[ii]
                                          for iid in LId],dtype=bool)
          else:
              for ii in range(0,N):
                  ind[ii,:] = np.asarray([iid.USRdict[Crit]==Val[ii]
                                          for iid in LId],dtype=bool)
      else:
          if type(PreExp) is str:
              PreExp = [PreExp]
          if type(PostExp) is str:
              PostExp = [PostExp]
          if PreExp is None:
              PreExp = ["" for ss in PostExp]
          if PostExp is None:
              PostExp = ["" for ss in PreExp]
          assert len(PreExp)==len(PostExp), "len(PreExp) should be =len(PostExp)"
          N = len(PreExp)
          ind = np.zeros((N,len(LId)),dtype=bool)
          if Crit in dir(ID):
              for ii in range(0,N):
                  List = [eval(PreExp[ii]+" getattr(iid,'%s') "%Crit+PostExp[ii])
                          for iid in LId]
                  ind[ii,:] = np.array(List,dtype=bool)
          else:
              for ii in range(0,N):
                  List = [eval(PreExp[ii]+" iid.USRdict['%s'] "%Crit+PostExp[ii])
                          for iid in LId]
                  ind[ii,:] = np.asarray(List,dtype=bool)
      ind = np.any(ind,axis=0) if Log=='any' else np.all(ind,axis=0)
      if InOut=='Out':
          ind = ~ind
      if Out==int:
          ind = ind.nonzero()[0]
      elif Out is not bool and hasattr(ID,Out):
          ind = [getattr(LId[ii],Out) for ii in ind.nonzero()[0]]
      elif Out is not bool and Out in LId[0].USRdict.keys():
          ind = [LId[ii].USRdict[Out] for ii in ind.nonzero()[0]]
      return ind