class_docstr: Class containing a list of trios, with extra functionality.
  
  :param trios: list of trio objects to include in pedigree
  :type trios: list of :class:`.Trio`
docstr: Read a PLINK .fam file and return a pedigree object.
  
  **Examples**
  
  >>> ped = hl.Pedigree.read('data/test.fam')
  
  Notes
  -------
  
  See `PLINK .fam file <https://www.cog-genomics.org/plink2/formats#fam>`_ for
  the required format.
  
  :param str fam_path: path to .fam file.
  
  :param str delimiter: Field delimiter.
  
  :rtype: :class:`.Pedigree`
docstr_tok: ["Read","a","PLINK",".fam","file","and","return","a","pedigree","object",".","*","*","Examples","*","*",">",">",">","ped","=","hl.Pedigree.read","(","'data\/test.fam","'",")","Notes","--","--","--","-","See","`","PLINK",".fam","file","<","https",":","\/\/www.cog-genomics.org\/plink2\/formats","#","fam",">","`","_","for","the","required","format",".",":","param","str","fam_path",":","path","to",".fam","file",".",":","param","str","delimiter",":","Field","delimiter",".",":","rtype",":",":","class",":","`",".Pedigree","`"]
code: def read(cls, fam_path, delimiter="\\s+") -> "Pedigree":
      """Read a PLINK .fam file and return a pedigree object.
  
      **Examples**
  
      >>> ped = hl.Pedigree.read('data/test.fam')
  
      Notes
      -------
  
      See `PLINK .fam file <https://www.cog-genomics.org/plink2/formats#fam>`_ for
      the required format.
  
      :param str fam_path: path to .fam file.
  
      :param str delimiter: Field delimiter.
  
      :rtype: :class:`.Pedigree`
      """
  
      trios = []
      missing_sex_count = 0
      missing_sex_values = set()
      with Env.fs().open(fam_path) as file:
          for line in file:
              split_line = re.split(delimiter, line.strip())
              num_fields = len(split_line)
              if num_fields != 6:
                  raise FatalError(
                      "Require 6 fields per line in .fam, but this line has {}: {}".format(
                          num_fields, line
                      )
                  )
              (fam, kid, dad, mom, sex, _) = tuple(split_line)
              # 1 is male, 2 is female, 0 is unknown.
              is_female = (
                  sex == "2" if sex == "1" or sex == "2" else None
              )
  
              if is_female is None:
                  missing_sex_count += 1
                  missing_sex_values.add(kid)
  
              trio = Trio(
                  kid,
                  fam if fam != "0" else None,
                  dad if dad != "0" else None,
                  mom if mom != "0" else None,
                  is_female,
              )
              trios.append(trio)
  
      only_ids = [trio.s for trio in trios]
      duplicate_ids = [
          id for id, count in Counter(only_ids).items() if count > 1
      ]
      if duplicate_ids:
          raise FatalError(
              "Invalid pedigree: found duplicate proband IDs\n{}".format(
                  duplicate_ids
              )
          )
  
      if missing_sex_count > 0:
          warning(
              "Found {} samples with missing sex information (not 1 or 2).\n Missing samples: [{}]".format(
                  missing_sex_count, missing_sex_values
              )
          )
  
      return Pedigree(trios)
  
imports: import re
  from collections import Counter
  from hail.typecheck import typecheck_method, nullable, sequenceof
  from hail.utils.java import Env, FatalError, warning
label_desc: Use image node_id 5 for calling the Pedigree obj's underlying member method code with example usage: obj.read(cls, fam_path, delimiter) and returns: Pedigree