code: def get_ptms(self, ptm_df):
          
          logger.info('Processing PTMs...')
          # Iterate over the rows of the dataframe
          for ix, row in ptm_df.iterrows():
              # Check the modification type; if we can't make an INDRA statement
              # for it, then skip it
              ptm_class = _ptm_map[row['MOD_TYPE']]
              if ptm_class is None:
                  continue
              # Use the Refseq protein ID for the substrate to make sure that
              # we get the right Uniprot ID for the isoform
              sub_ag = self._make_agent(row['HPRD_ID'],
                                        refseq_id=row['REFSEQ_PROTEIN'])
  
              # If we couldn't get the substrate, skip the statement
              if sub_ag is None:
                  continue
              enz_id = _nan_to_none(row['ENZ_HPRD_ID'])
              enz_ag = self._make_agent(enz_id)
              res = _nan_to_none(row['RESIDUE'])
              pos = _nan_to_none(row['POSITION'])
              if pos is not None and ';' in pos:
                  pos, dash = pos.split(';')
                  assert dash == '-'
              # As a fallback for later site mapping, we also get the protein
              # sequence information in case there was a problem with the
              # RefSeq->Uniprot mapping
              assert res
              assert pos
              motif_dict = self._get_seq_motif(row['REFSEQ_PROTEIN'], res, pos)
              # Get evidence
              ev_list = self._get_evidence(
                      row['HPRD_ID'], row['HPRD_ISOFORM'], row['PMIDS'],
                      row['EVIDENCE'], 'ptms', motif_dict)
              stmt = ptm_class(enz_ag, sub_ag, res, pos, evidence=ev_list)
              self.statements.append(stmt)
docs: Generate Modification statements from the HPRD PTM data.
  
          Parameters
          ----------
          ptm_df : pandas.DataFrame
              DataFrame loaded from the POST_TRANSLATIONAL_MODIFICATIONS.txt file.