docs: def select_ch(self, val=None, key=None, log='any', touch=None, out=bool):
          """ Return a channels index array
  
          Return a boolean or integer index array, hereafter called 'ind'
          The array refers to the reference channel/'X' vector self.ddataRef['X']
  
          There are 3 different ways of selecting channels, by refering to:
              - The 'X' vector/array values in self.dataRef['X']
              - The dict of channels keys/values (if self.dchans != None)
              - which element each LOS touches (if self.lCam != None)
  
          Parameters
          ----------
          val :   None / str / float / np.array / list / tuple
              The value against which to dicriminate.
              Behaviour depends whether key is provided:
                  - key is None => val compares vs self.ddataRef['X']
                  - key provided => val compares vs self.dchans[key]
              If key is None, the behaviour is similar to self.select_indt():
                  - None : ind matches all channels
                  - float : ind is True only for X closest to val
                  - np.ndarray : ind is True only for X closest to val
                  - list (len()==2): ind is True for X inside [val[0],val[1]]
                  - tuple (len()==2): ind is True for X outside ]val[0];val[1][
  
          key :   None / str
              If provided, dict key to indicate which self.dchans[key] to use
  
          log :   str
              If key provided, val can be a list of criteria
              Then, log indicates whether all / any / none should be matched
  
          touch : None
              If key and val are None, return the indices of the LOS touching the
              elements indicated in touch.
              Requires that self.dgeom['lCam'] is not None (tf.geom.Cam.select())
  
          out :   type
              Specifies the type of the output index array:
                  - bool : return a boolean array of shape (self.ddataRef['nt'],)
                  - int : return the array as integers indices
  
          Return
          ------
          ind :   np.ndarray
              The array of indices, of dtype specified by keywordarg out
  
          """
          assert out in [int,bool]
          assert log in ['any','all','not']
          lc = [val is None, key is None, touch is None]
          lC = [all(lc), all(lc[:2]) and not lc[2],
                not lc[0] and all(lc[1:]), not any(lc[:2]) and lc[2]]
          assert np.sum(lC)==1
  
          if lC[0]:
              # get all channels
              ind = np.ones((self._ddataRef['nch'],),dtype=bool)
  
          elif lC[1]:
              # get touch
              if self._dgeom['lCam'] is None:
                  msg = "self.dgeom['lCam'] must be set to use touch !"
                  raise Exception(msg)
              if any([type(cc) is str for cc in self._dgeom['lCam']]):
                  msg = "self.dgeom['lCam'] contains pathfiles !"
                  msg += "\n  => Run self.strip(0)"
                  raise Exception(msg)
              ind = []
              for cc in self._dgeom['lCam']:
                  ind.append(cc.select(touch=touch, log=log, out=bool))
              if len(ind)==1:
                  ind = ind[0]
              else:
                  ind = np.concatenate(tuple(ind))
  
          elif lC[2]:
              # get values on X
              if self._ddataRef['nnch']==1:
                  ind = _select_ind(val, self._ddataRef['X'], self._ddataRef['nch'])
              else:
                  ind = np.zeros((self._ddataRef['nt'],self._ddataRef['nch']),dtype=bool)
                  for ii in range(0,self._ddataRef['nnch']):
                      iind = self._ddataRef['indtX']==ii
                      ind[iind,:] =  _select_ind(val, self._ddataRef['X'],
                                                 self._ddataRef['nch'])[np.newaxis,:]
  
          else:
              if not (type(key) is str and key in self._dchans.keys()):
                  msg = "Provided key not valid!\n"
                  msg += "    - key: %s\n"%str(key)
                  msg += "Please provide a valid key of self.dchans():\n"
                  msg += "    - " + "\n    - ".join(self._dchans.keys())
                  raise Exception(msg)
  
              ltypes = [str,int,float,np.int64,np.float64]
              C0 = type(val) in ltypes
              C1 = type(val) in [list,tuple,np.ndarray]
              assert C0 or C1
              if C0:
                  val = [val]
              else:
                  assert all([type(vv) in ltypes for vv in val])
              ind = np.vstack([self._dchans[key]==ii for ii in val])
              if log=='any':
                  ind = np.any(ind,axis=0)
              elif log=='all':
                  ind = np.all(ind,axis=0)
              else:
                  ind = ~np.any(ind,axis=0)
          if out is int:
              ind = ind.nonzero()[0]
          return ind