docs: def from_txt(cls, pfe, out='object',
                   Exp=None, Name=None, shot=None, Type=None,
                   mobile=False, color=None, SavePath=os.path.abspath('./')):
          """ Return the polygon and pos/extent stored in a .txt file
  
          The file must have been generated by the method save_to_txt()
          All arguments appart from pfe and out are:
              - fed to the relevant tofu.geom.Struct subclass to instanciate it
              - used only if out = 'object'
  
          Parameters
          ----------
          pfe:    str
              Unique string containing the path and file name to be read
              The file must be formatted as if generated by self.save_to_txt():
                  - Must contain a (N,2) array
                  - Line 0 must contain 2 integers:
                      - npts : the nb. of points of the polygon
                      - noccur : the nb. of occurences (=0 if axisymmetric)
                  - Hence the number of lines hould be N = npts + noccur + 1
                  - Lines 1:npts+1 contain the polygon points
                  - Lines npts+1: contain positions and extent of each occurence
          out:    str
              Flag indicating whether to return:
                  - 'dict'  : a dictionnary of np.ndarrays
                  - 'object': a tofu.geom.Struct subclass, using the other kwdargs
  
          Return
          ------
          obj:    tf.geom.Struct sublass instance  / dict
              Depending on the value of out, obj can be:
                  - An instance of the relevant tofu.geom.Struct subclass
                  - A dict with keys 'poly', 'pos' and 'extent'
          """
  
          if not out in [object,'object','dict']:
              msg = "Arg out must be either:"
              msg += "    - 'object': return a %s instance\n"%cls.__name__
              msg += "    - 'dict' : return a dict with polygon, pos and extent"
              raise Exception(msg)
          if not pfe[-4:]=='.txt':
              msg = "Only accepts .txt files (fed to np.loadtxt) !\n"
              msg += "    file:  %s"%pfe
              raise Exception(msg)
          oo = np.loadtxt(pfe)
          if not (oo.ndim==2 and oo.shape[1]==2):
              msg = "The file should contain a (N,2) array !\n"
              msg += "    file : %s\n"%pfe
              msg += "    shape: {0}".format(oo.shape)
              raise Exception(msg)
          C0 = (oo[0,0]==int(oo[0,0]) and oo[0,1]==int(oo[0,1]))
          C1 = oo.shape == (oo[0,0] + oo[0,1] + 1, 2)
          if not (C0 and C1):
              sha = (oo[0,0]+oo[0,1]+1,2)
              msg = "The shape of the array is not as expected!\n"
              msg += "    file : %s\n"%pfe
              if not C0:
                  msg += "  The first line should contain integers!\n"
                  msg += "    First line : {0}".format(oo[0,:])
              else:
                  msg += "    Expected shape: {0}".format(sha)
                  msg += " = ({0} + {1} + 1, 2)\n".format(oo[0,0], oo[0,1])
                  msg += "    Observed shape: {0}".format(oo.shape)
              raise Exception(msg)
          npts, noccur = int(oo[0,0]), int(oo[0,1])
          poly = oo[1:1+npts,:]
          if noccur>0:
              pos, extent = oo[1+npts:,0], oo[1+npts:,1]
          else:
              pos, extent = None, None
  
           # Try reading Exp and Name if not provided
          if Exp is None:
              Exp = cls._from_txt_extract_params(pfe, 'Exp')
          if Name is None:
              Name = cls._from_txt_extract_params(pfe, 'Name')
  
          if out=='dict':
              return {'poly':poly, 'pos':pos, 'extent':extent}
          else:
              SavePath = os.path.abspath(SavePath)
              obj = cls(Name=Name, Exp=Exp, shot=shot,
                        Type=Type, mobile=mobile,
                        Poly=poly, pos=pos, extent=extent,
                        SavePath=SavePath, color=color)
              return obj