docs: def _add_snps(
          self,
          snps,
          discrepant_snp_positions_threshold,
          discrepant_genotypes_threshold,
          save_output,
      ):
          """ Add SNPs to this Individual.
  
          Parameters
          ----------
          snps : SNPs
              SNPs to add
          discrepant_snp_positions_threshold : int
              see above
          discrepant_genotypes_threshold : int
              see above
          save_output
              see above
  
          Returns
          -------
          discrepant_positions : pandas.DataFrame
          discrepant_genotypes : pandas.DataFrame
          """
          discrepant_positions = pd.DataFrame()
          discrepant_genotypes = pd.DataFrame()
  
          if snps.snps is None:
              return discrepant_positions, discrepant_genotypes
  
          build = snps.build
          source = [s.strip() for s in snps.source.split(",")]
  
          if not snps.build_detected:
              print("build not detected, assuming build {}".format(snps.build))
  
          if self._build is None:
              self._build = build
          elif self._build != build:
              print(
                  "build / assembly mismatch between current build of SNPs and SNPs being loaded"
              )
  
          # ensure there area always two X alleles
          snps = self._double_single_alleles(snps.snps, "X")
  
          if self._snps is None:
              self._source.extend(source)
              self._snps = snps
          else:
              common_snps = self._snps.join(snps, how="inner", rsuffix="_added")
  
              discrepant_positions = common_snps.loc[
                  (common_snps["chrom"] != common_snps["chrom_added"])
                  | (common_snps["pos"] != common_snps["pos_added"])
              ]
  
              if 0 < len(discrepant_positions) < discrepant_snp_positions_threshold:
                  print(
                      str(len(discrepant_positions)) + " SNP positions were discrepant; "
                      "keeping original positions"
                  )
  
                  if save_output:
                      self._discrepant_positions_file_count += 1
                      lineage.save_df_as_csv(
                          discrepant_positions,
                          self._output_dir,
                          self.get_var_name()
                          + "_discrepant_positions_"
                          + str(self._discrepant_positions_file_count)
                          + ".csv",
                      )
              elif len(discrepant_positions) >= discrepant_snp_positions_threshold:
                  print(
                      "too many SNPs differ in position; ensure same genome build is being used"
                  )
                  return discrepant_positions, discrepant_genotypes
  
              # remove null genotypes
              common_snps = common_snps.loc[
                  ~common_snps["genotype"].isnull()
                  & ~common_snps["genotype_added"].isnull()
              ]
  
              # discrepant genotypes are where alleles are not equivalent (i.e., alleles are not the
              # same and not swapped)
              discrepant_genotypes = common_snps.loc[
                  (
                      (common_snps["genotype"].str.len() == 1)
                      & (common_snps["genotype_added"].str.len() == 1)
                      & ~(
                          common_snps["genotype"].str[0]
                          == common_snps["genotype_added"].str[0]
                      )
                  )
                  | (
                      (common_snps["genotype"].str.len() == 2)
                      & (common_snps["genotype_added"].str.len() == 2)
                      & ~(
                          (
                              common_snps["genotype"].str[0]
                              == common_snps["genotype_added"].str[0]
                          )
                          & (
                              common_snps["genotype"].str[1]
                              == common_snps["genotype_added"].str[1]
                          )
                      )
                      & ~(
                          (
                              common_snps["genotype"].str[0]
                              == common_snps["genotype_added"].str[1]
                          )
                          & (
                              common_snps["genotype"].str[1]
                              == common_snps["genotype_added"].str[0]
                          )
                      )
                  )
              ]
  
              if 0 < len(discrepant_genotypes) < discrepant_genotypes_threshold:
                  print(
                      str(len(discrepant_genotypes)) + " SNP genotypes were discrepant; "
                      "marking those as null"
                  )
  
                  if save_output:
                      self._discrepant_genotypes_file_count += 1
                      lineage.save_df_as_csv(
                          discrepant_genotypes,
                          self._output_dir,
                          self.get_var_name()
                          + "_discrepant_genotypes_"
                          + str(self._discrepant_genotypes_file_count)
                          + ".csv",
                      )
              elif len(discrepant_genotypes) >= discrepant_genotypes_threshold:
                  print(
                      "too many SNPs differ in their genotype; ensure file is for same "
                      "individual"
                  )
                  return discrepant_positions, discrepant_genotypes
  
              # add new SNPs
              self._source.extend(source)
              self._snps = self._snps.combine_first(snps)
              self._snps.loc[discrepant_genotypes.index, "genotype"] = np.nan
  
              # combine_first converts position to float64, so convert it back to int64
              self._snps["pos"] = self._snps["pos"].astype(np.int64)
  
          self._snps = sort_snps(self._snps)
  
          return discrepant_positions, discrepant_genotypes