Creates a Methionine residue
176762
def makeMet(segID, N, CA, C, O, geo):
    ''''''
    ##R-Group
    CA_CB_length=geo.CA_CB_length
    C_CA_CB_angle=geo.C_CA_CB_angle
    N_C_CA_CB_diangle=geo.N_C_CA_CB_diangle

    CB_CG_length=geo.CB_CG_length
    CA_CB_CG_angle=geo.CA_CB_CG_angle
    N_CA_CB_CG_diangle=geo.N_CA_CB_CG_diangle
    
    CG_SD_length=geo.CG_SD_length
    CB_CG_SD_angle=geo.CB_CG_SD_angle
    CA_CB_CG_SD_diangle=geo.CA_CB_CG_SD_diangle
    
    SD_CE_length=geo.SD_CE_length
    CG_SD_CE_angle=geo.CG_SD_CE_angle
    CB_CG_SD_CE_diangle=geo.CB_CG_SD_CE_diangle
    
    carbon_b= calculateCoordinates(N, C, CA, CA_CB_length, C_CA_CB_angle, N_C_CA_CB_diangle)
    CB= Atom("CB", carbon_b, 0.0 , 1.0, " "," CB", 0,"C")
    carbon_g= calculateCoordinates(N, CA, CB, CB_CG_length, CA_CB_CG_angle, N_CA_CB_CG_diangle)
    CG= Atom("CG", carbon_g, 0.0, 1.0, " ", " CG", 0, "C")
    sulfur_d= calculateCoordinates(CA, CB, CG, CG_SD_length, CB_CG_SD_angle, CA_CB_CG_SD_diangle)
    SD= Atom("SD", sulfur_d, 0.0, 1.0, " ", " SD", 0, "S")
    carbon_e= calculateCoordinates(CB, CG, SD, SD_CE_length, CG_SD_CE_angle, CB_CG_SD_CE_diangle)
    CE= Atom("CE", carbon_e, 0.0, 1.0, " ", " CE", 0, "C")

    ##Create Residue Data Structure
    res= Residue((' ', segID, ' '), "MET", '    ')
    res.add(N)
    res.add(CA)
    res.add(C)
    res.add(O)
    res.add(CB)
    res.add(CG)
    res.add(SD)
    res.add(CE)
    return res
973190
def renumber_system(self, offset):
        

        self.universe.protein = self.universe.select_atoms("protein")
        self.universe.protein.residues.resids = self.universe.protein.residues.resids+int(offset)
320538
def make_inst():
    """"""
    F,c,d = multidict({       # cost # composition
        "QPounder" :  [ 1.84, {"Cal":510, "Carbo":34, "Protein":28,
                               "VitA":15, "VitC":  6, "Calc":30, "Iron":20}],
        "McLean"   :  [ 2.19, {"Cal":370, "Carbo":35, "Protein":24, "VitA":15,
                               "VitC": 10, "Calc":20, "Iron":20}],
        "Big Mac"  :  [ 1.84, {"Cal":500, "Carbo":42, "Protein":25,
                               "VitA": 6, "VitC":  2, "Calc":25, "Iron":20}],
        "FFilet"   :  [ 1.44, {"Cal":370, "Carbo":38, "Protein":14,
                               "VitA": 2, "VitC":  0, "Calc":15, "Iron":10}],
        "Chicken"  :  [ 2.29, {"Cal":400, "Carbo":42, "Protein":31,
                               "VitA": 8, "VitC": 15, "Calc":15, "Iron": 8}],
        "Fries"    :  [  .77, {"Cal":220, "Carbo":26, "Protein": 3,
                               "VitA": 0, "VitC": 15, "Calc": 0, "Iron": 2}],
        "McMuffin" :  [ 1.29, {"Cal":345, "Carbo":27, "Protein":15,
                               "VitA": 4, "VitC":  0, "Calc":20, "Iron":15}],
        "1% LFMilk":  [  .60, {"Cal":110, "Carbo":12, "Protein": 9,
                               "VitA":10, "VitC":  4, "Calc":30, "Iron": 0}],
        "OrgJuice" :  [  .72, {"Cal": 80, "Carbo":20, "Protein": 1,
                               "VitA": 2, "VitC":120, "Calc": 2, "Iron": 2}],
        })

    N,a,b = multidict({       # min,max intake
        "Cal"     : [ 2000,  None ],
        "Carbo"   : [  350,  375 ],
        "Protein" : [   55,  None ],
        "VitA"    : [  100,  None ],
        "VitC"    : [  100,  None ],
        "Calc"    : [  100,  None ],
        "Iron"    : [  100,  None ],
     })

    return F,N,a,b,c,d
86097
public void addResidue(Residue residue) {
        if (residues == null) residues = new ArrayList<Residue>();

        //Check if exists
        if (residues.contains(residue)) {
            System.out.println("Residue: " + residue.getName() + " already present in molecule: " + getID());
            return;
        }

        residues.add(residue);
    }
459546
private static void displayStructure(Structure structure,
			ResidueNumber[] residues) {
		//Display each structure
		BiojavaJmol jmol = new BiojavaJmol();
		jmol.setStructure(structure);

		//Highlight non-null atoms
		jmol.evalString("select *; spacefill off; wireframe off; color chain; backbone 0.4;  ");
		String selectionCmd = buildJmolSelection(residues);
		jmol.evalString(selectionCmd);
		jmol.evalString("backbone 1.0; select none;");
	}
1348302
public void identify(final List<Chain> chains,
			final Set<ProteinModification> potentialModifications) {

		if (chains==null) {
			throw new IllegalArgumentException("Null structure.");
		}

		if (potentialModifications==null) {
			throw new IllegalArgumentException("Null potentialModifications.");
		}


		reset();

		if (potentialModifications.isEmpty()) {
			return;
		}


		residues = new ArrayList<Group>();
		List<Group> ligands = new ArrayList<Group>();
		Map<Component, Set<Group>> mapCompGroups = new HashMap<Component, Set<Group>>();

		for (Chain chain : chains) {

			List<Group> ress = StructureUtil.getAminoAcids(chain);

			//List<Group> ligs = chain.getAtomLigands();
			List<Group> ligs = StructureTools.filterLigands(chain.getAtomGroups());
			residues.addAll(ress);
			residues.removeAll(ligs);
			ligands.addAll(ligs);
			addModificationGroups(potentialModifications, ress, ligs, mapCompGroups);
		}

		if (residues.isEmpty()) {
			String pdbId = "?";
			if ( chains.size() > 0) {
				Structure struc = chains.get(0).getStructure();
				if ( struc != null)
					pdbId = struc.getPDBCode();
			}
			logger.warn("No amino acids found for {}. Either you did not parse the PDB file with alignSEQRES records, or this record does not contain any amino acids.", pdbId);
		}
		List<ModifiedCompound> modComps = new ArrayList<ModifiedCompound>();

		for (ProteinModification mod : potentialModifications) {
			ModificationCondition condition = mod.getCondition();
			List<Component> components = condition.getComponents();
			if (!mapCompGroups.keySet().containsAll(components)) {
				// not all components exist for this mod.
				continue;
			}

			int sizeComps = components.size();
			if (sizeComps==1) {

				processCrosslink1(mapCompGroups, modComps, mod, components);

			} else {

				processMultiCrosslink(mapCompGroups, modComps, mod, condition);
			}
		}

		if (recordAdditionalAttachments) {
			// identify additional groups that are not directly attached to amino acids.
			for (ModifiedCompound mc : modComps) {
				identifyAdditionalAttachments(mc, ligands, chains);
			}
		}

		mergeModComps(modComps);

		identifiedModifiedCompounds.addAll(modComps);


		// record unidentifiable linkage
		if (recordUnidentifiableModifiedCompounds) {
			recordUnidentifiableAtomLinkages(modComps, ligands);
			recordUnidentifiableModifiedResidues(modComps);
		}
	}
1205759
private static float calculateExtinctionFromPeptide(List<Monomer> monomers) throws IOException, HELM2HandledException {

    if (null == monomers || monomers.isEmpty()) {
      return 0.0f;
    }

    Map<String, Integer> countMap = new HashMap<String, Integer>();
    for (Monomer monomer : monomers) {
      if (aminoAcidMap.containsKey(monomer.getAlternateId())) {
        int count = 1;
        if (countMap.containsKey(monomer.getAlternateId())) {
          count = count + countMap.get(monomer.getAlternateId());
        }
        countMap.put(monomer.getAlternateId(), count);
      }
    }

    float result = 0.0f;
    Set<String> keys = countMap.keySet();
    for (Iterator<String> it = keys.iterator(); it.hasNext();) {
      String key = it.next();
      int count = countMap.get(key);
      float factor = aminoAcidMap.get(key);
      result = result + factor * count;
    }

    return BigDecimal.valueOf(result).floatValue();

  }
174292
def fix_residue_numbering(self):
        """"""

        resid_list = self.aa_resids()
        resid_set  = set(resid_list)
        resid_lst1 = list(resid_set)
        resid_lst1.sort()
        map_res_id = {}

        x = 1
        old_chain = resid_lst1[0][0]
        for resid in resid_lst1:
            map_res_id[resid] = resid[0] + '%4.i' % x
            if resid[0] == old_chain:
                x+=1
            else:
                x = 1
                old_chain = resid[0]

        atomlines = []
        for line in self.lines:
            if line[0:4] == "ATOM" and line[21:26] in resid_set and line[26] == ' ':
                lst = [char for char in line]
                #lst.remove('\n')
                lst[21:26] = map_res_id[line[21:26]]
                atomlines.append( string.join(lst,'') )
                #print string.join(lst,'')
            else:
                atomlines.append(line)

        self.lines = atomlines
        return map_res_id
123913
def find_charged(self, mol):
        """"""
        data = namedtuple('pcharge', 'atoms atoms_orig_idx type center restype resnr reschain')
        a_set = []
        # Iterate through all residue, exclude those in chains defined as peptides
        for res in [r for r in pybel.ob.OBResidueIter(mol.OBMol) if not r.GetChain() in config.PEPTIDES]:
            if config.INTRA is not None:
                if res.GetChain() != config.INTRA:
                    continue
            a_contributing = []
            a_contributing_orig_idx = []
            if res.GetName() in ('ARG', 'HIS', 'LYS'):  # Arginine, Histidine or Lysine have charged sidechains
                for a in pybel.ob.OBResidueAtomIter(res):
                    if a.GetType().startswith('N') and res.GetAtomProperty(a, 8) \
                            and not self.Mapper.mapid(a.GetIdx(), mtype='protein') in self.altconf:
                        a_contributing.append(pybel.Atom(a))
                        a_contributing_orig_idx.append(self.Mapper.mapid(a.GetIdx(), mtype='protein'))
                if not len(a_contributing) == 0:
                    a_set.append(data(atoms=a_contributing,
                                      atoms_orig_idx=a_contributing_orig_idx,
                                      type='positive',
                                      center=centroid([ac.coords for ac in a_contributing]),
                                      restype=res.GetName(),
                                      resnr=res.GetNum(),
                                      reschain=res.GetChain()))
            if res.GetName() in ('GLU', 'ASP'):  # Aspartic or Glutamic Acid
                for a in pybel.ob.OBResidueAtomIter(res):
                    if a.GetType().startswith('O') and res.GetAtomProperty(a, 8) \
                            and not self.Mapper.mapid(a.GetIdx(), mtype='protein') in self.altconf:
                        a_contributing.append(pybel.Atom(a))
                        a_contributing_orig_idx.append(self.Mapper.mapid(a.GetIdx(), mtype='protein'))
                if not len(a_contributing) == 0:
                    a_set.append(data(atoms=a_contributing,
                                      atoms_orig_idx=a_contributing_orig_idx,
                                      type='negative',
                                      center=centroid([ac.coords for ac in a_contributing]),
                                      restype=res.GetName(),
                                      resnr=res.GetNum(),
                                      reschain=res.GetChain()))
        return a_set
767466
def create_pymol_selection_from_PDB_residue_ids(residue_list):
    ''''''
    residues_by_chain = {}
    for residue_id in residue_list:
        chain_id = residue_id[0]
        pruned_residue_id = residue_id[1:]
        residues_by_chain[chain_id] = residues_by_chain.get(chain_id, [])
        residues_by_chain[chain_id].append(pruned_residue_id)

    str = []
    for chain_id, residue_list in sorted(residues_by_chain.iteritems()):
        str.append('(chain %s and resi %s)' % (chain_id, '+'.join(map(string.strip, sorted(residue_list)))))
    return ' or '.join(str)
245706
def parseFullScan(self, i, modifications=False):
        
        scanObj = PeptideObject()
        peptide = str(i[1])
        pid=i[2]
        scanObj.acc = self.protein_map.get(i[4], i[4])
        if pid is None:
            return None
        if modifications:
            sql = 'select aam.ModificationName,pam.Position,aam.DeltaMass from peptidesaminoacidmodifications pam left join aminoacidmodifications aam on (aam.AminoAcidModificationID=pam.AminoAcidModificationID) where pam.PeptideID=%s'%pid
            for row in self.conn.execute(sql):
                scanObj.addModification(peptide[row[1]], str(row[1]), str(row[2]), row[0])
        else:
            mods = self.mods.get(int(pid))
            if mods is not None:
                for modId, modPosition in zip(mods[0].split(','),mods[1].split(',')):
                    modEntry = self.modTable[str(modId)]
                    scanObj.addModification(peptide[int(modPosition)], modPosition, modEntry[1], modEntry[0])
            tmods = self.tmods.get(int(pid))
            if tmods is not None:
                for modIds in tmods:
                    for modId in modIds.split(','):
                        modEntry = self.modTable[str(modId)]
                        scanObj.addModification('[', 0, modEntry[1], modEntry[0])
        scanObj.peptide = peptide
        if self.decompressScanInfo(scanObj, i[0]):
            return scanObj
        return None
545524
def add_isoquant_data(peptides, quantpeptides, quantacc, quantfields):
    """"""
    for peptide in base_add_isoquant_data(peptides, quantpeptides, 
                                          peptabledata.HEADER_PEPTIDE,
                                          quantacc, quantfields):
        yield peptide
459022
private static MonomerNotation generateMonomerNotationPeptide(MonomerNotation current)
			throws AnalogSequenceException {
		MonomerNotation change = null;
		try {
			/* simple MonomerNotationUnit */
			if (current instanceof MonomerNotationUnit) {

				String id = aminoacids.get(current.getUnit().replace("[", "").replace("]", "")).getNaturalAnalog();
				change = new MonomerNotationUnit(id, current.getType());
				change.setCount(current.getCount());
				if (current.getAnnotation() != null) {
					change.setAnnotation(current.getAnnotation());
				}
			} else if (current instanceof MonomerNotationGroup) {
				if (current instanceof MonomerNotationGroupOr) {
					StringBuilder sb = new StringBuilder();
					String id = current.getUnit();
					for (String element : id.split(",")) {
						sb.append(aminoacids.get(element.replace("[", "").replace("]", "")).getNaturalAnalog() + ",");
					}
					sb.setLength(sb.length() - 1);
					change = new MonomerNotationList(sb.toString(), current.getType());

				} else if (current instanceof MonomerNotationGroupMixture) {
					StringBuilder sb = new StringBuilder();
					String id = current.getUnit();
					for (String element : id.split("\\+")) {
						sb.append(aminoacids.get(element.replace("[", "").replace("]", "")).getNaturalAnalog() + "+");
					}
					sb.setLength(sb.length() - 1);
					change = new MonomerNotationList(sb.toString(), current.getType());

				} else {
					/* throw new exception */
					throw new AnalogSequenceException("MonomerNotationGroup is unknown" + current.getClass());
				}

			} else if (current instanceof MonomerNotationList) {
				StringBuilder sb = new StringBuilder();
				String id = current.getUnit();
				for (String element : id.split("\\.")) {
					sb.append(aminoacids.get(element.replace("[", "").replace("]", "")).getNaturalAnalog() + ".");
				}
				sb.setLength(sb.length() - 1);
				change = new MonomerNotationList(sb.toString(), current.getType());

			} else {
				throw new AnalogSequenceException("MonomerNotation is unknown" + current.getClass());
			}

			change.setCount(current.getCount());
			if (current.getAnnotation() != null) {
				change.setAnnotation(current.getAnnotation());
			}

			return change;
		} catch (NotationException e) {
			e.printStackTrace();
			throw new AnalogSequenceException(
					"MonomerNotation can not be converted to its natural analogue sequence " + e.getMessage());

		}

	}
912680
def makeHis(segID, N, CA, C, O, geo):
    ''''''
    ##R-Group
    CA_CB_length=geo.CA_CB_length
    C_CA_CB_angle=geo.C_CA_CB_angle
    N_C_CA_CB_diangle=geo.N_C_CA_CB_diangle

    CB_CG_length=geo.CB_CG_length
    CA_CB_CG_angle=geo.CA_CB_CG_angle
    N_CA_CB_CG_diangle=geo.N_CA_CB_CG_diangle
    
    CG_ND1_length=geo.CG_ND1_length
    CB_CG_ND1_angle=geo.CB_CG_ND1_angle
    CA_CB_CG_ND1_diangle=geo.CA_CB_CG_ND1_diangle
    
    CG_CD2_length=geo.CG_CD2_length
    CB_CG_CD2_angle=geo.CB_CG_CD2_angle
    CA_CB_CG_CD2_diangle=geo.CA_CB_CG_CD2_diangle
    
    ND1_CE1_length=geo.ND1_CE1_length
    CG_ND1_CE1_angle=geo.CG_ND1_CE1_angle
    CB_CG_ND1_CE1_diangle=geo.CB_CG_ND1_CE1_diangle
    
    CD2_NE2_length=geo.CD2_NE2_length
    CG_CD2_NE2_angle=geo.CG_CD2_NE2_angle
    CB_CG_CD2_NE2_diangle=geo.CB_CG_CD2_NE2_diangle
    
    carbon_b= calculateCoordinates(N, C, CA, CA_CB_length, C_CA_CB_angle, N_C_CA_CB_diangle)
    CB= Atom("CB", carbon_b, 0.0 , 1.0, " "," CB", 0,"C")
    carbon_g= calculateCoordinates(N, CA, CB, CB_CG_length, CA_CB_CG_angle, N_CA_CB_CG_diangle)
    CG= Atom("CG", carbon_g, 0.0, 1.0, " ", " CG", 0, "C")
    nitrogen_d1= calculateCoordinates(CA, CB, CG, CG_ND1_length, CB_CG_ND1_angle, CA_CB_CG_ND1_diangle)
    ND1= Atom("ND1", nitrogen_d1, 0.0, 1.0, " ", " ND1", 0, "N")
    carbon_d2= calculateCoordinates(CA, CB, CG, CG_CD2_length, CB_CG_CD2_angle, CA_CB_CG_CD2_diangle)
    CD2= Atom("CD2", carbon_d2, 0.0, 1.0, " ", " CD2", 0, "C")
    carbon_e1= calculateCoordinates(CB, CG, ND1, ND1_CE1_length, CG_ND1_CE1_angle, CB_CG_ND1_CE1_diangle)
    CE1= Atom("CE1", carbon_e1, 0.0, 1.0, " ", " CE1", 0, "C")
    nitrogen_e2= calculateCoordinates(CB, CG, CD2, CD2_NE2_length, CG_CD2_NE2_angle, CB_CG_CD2_NE2_diangle)
    NE2= Atom("NE2", nitrogen_e2, 0.0, 1.0, " ", " NE2", 0, "N")

    ##Create Residue Data Structure
    res= Residue((' ', segID, ' '), "HIS", '    ')
    res.add(N)
    res.add(CA)
    res.add(C)
    res.add(O)
    res.add(CB)
    res.add(CG)
    res.add(ND1)
    res.add(CD2)
    res.add(CE1)
    res.add(NE2)
    return res
413847
def parse_atoms(self):
        ''''''

        atom_site_header_tag = self.main_tag.getElementsByTagName("PDBx:atom_siteCategory")
        assert(len(atom_site_header_tag) == 1)
        atom_site_header_tag = atom_site_header_tag[0]

        atom_site_tags = atom_site_header_tag.getElementsByTagName("PDBx:atom_site")

        residue_map = {}
        residues_read = {}
        int_type = types.IntType
        for t in atom_site_tags:
            r, seqres, ResidueAA, Residue3AA = PDBML_slow.parse_atom_site(t, self.modified_residues)
            if r:
                # skip certain ACE residues
                if not(self.pdb_id in cases_with_ACE_residues_we_can_ignore and Residue3AA == 'ACE'):
                    full_residue_id = str(r)
                    if residues_read.get(full_residue_id):
                        assert(residues_read[full_residue_id] == (r.ResidueAA, seqres))
                    else:
                        residues_read[full_residue_id] = (r.ResidueAA, seqres)
                        residue_map[r.Chain] = residue_map.get(r.Chain, {})
                        assert(type(seqres) == int_type)
                        residue_map[r.Chain][str(r)] = seqres

        ## Create SequenceMap objects to map the ATOM Sequences to the SEQRES Sequences
        atom_to_seqres_sequence_maps = {}
        for chain_id, atom_seqres_mapping in residue_map.iteritems():
            atom_to_seqres_sequence_maps[chain_id] = SequenceMap.from_dict(atom_seqres_mapping)

        self.atom_to_seqres_sequence_maps = atom_to_seqres_sequence_maps
600797
def makePro(segID, N, CA, C, O, geo):
    ''''''
    ##R-Group
    CA_CB_length=geo.CA_CB_length
    C_CA_CB_angle=geo.C_CA_CB_angle
    N_C_CA_CB_diangle=geo.N_C_CA_CB_diangle
    
    CB_CG_length=geo.CB_CG_length
    CA_CB_CG_angle=geo.CA_CB_CG_angle
    N_CA_CB_CG_diangle=geo.N_CA_CB_CG_diangle
    
    CG_CD_length=geo.CG_CD_length
    CB_CG_CD_angle=geo.CB_CG_CD_angle
    CA_CB_CG_CD_diangle=geo.CA_CB_CG_CD_diangle
    
    carbon_b= calculateCoordinates(N, C, CA, CA_CB_length, C_CA_CB_angle, N_C_CA_CB_diangle)
    CB= Atom("CB", carbon_b, 0.0 , 1.0, " "," CB", 0,"C")
    carbon_g= calculateCoordinates(N, CA, CB, CB_CG_length, CA_CB_CG_angle, N_CA_CB_CG_diangle)
    CG= Atom("CG", carbon_g, 0.0, 1.0, " ", " CG", 0, "C")
    carbon_d= calculateCoordinates(CA, CB, CG, CG_CD_length, CB_CG_CD_angle, CA_CB_CG_CD_diangle)
    CD= Atom("CD", carbon_d, 0.0, 1.0, " ", " CD", 0, "C")

    ##Create Residue Data Structure
    res= Residue((' ', segID, ' '), "PRO", '    ')
    
    res.add(N)
    res.add(CA)
    res.add(C)
    res.add(O)
    res.add(CB)
    res.add(CG)
    res.add(CD)

    return res
944213
def GetRosettaResidueMap(self, ConvertMSEToAtom = False, RemoveIncompleteFinalResidues = False, RemoveIncompleteResidues = False):
        ''''''
        raise Exception('This code looks to be deprecated. Use construct_pdb_to_rosetta_residue_map instead.')
        chain = None
        sequences = {}
        residue_map = {}
        resid_set = set()
        resid_list = []

        DNA_residues = set([' DA', ' DC', ' DG', ' DT'])
        chains = []
        self.RAW_ATOM_SEQUENCE = []
        essential_atoms_1 = set(['CA', 'C', 'N'])#, 'O'])
        essential_atoms_2 = set(['CA', 'C', 'N'])#, 'OG'])
        current_atoms = set()
        atoms_read = {}
        oldchainID = None
        removed_residue = {}
        for line in self.lines:
            if line[0:4] == 'ATOM' or (ConvertMSEToAtom and (line[0:6] == 'HETATM') and (line[17:20] == 'MSE')):
                chainID = line[21]
                if missing_chain_ids.get(self.pdb_id):
                    chainID = missing_chain_ids[self.pdb_id]
                if chainID not in chains:
                    chains.append(chainID)
                residue_longname = line[17:20]
                if residue_longname in DNA_residues:
                    # Skip DNA
                    continue
                if residue_longname == 'UNK':
                    # Skip unknown residues
                    continue
                if residue_longname not in allowed_PDB_residues_types and not(ConvertMSEToAtom and residue_longname == 'MSE'):
                    if not self.strict:
                        # Skip unknown residues
                        continue
                    else:
                        raise NonCanonicalResidueException("Residue %s encountered: %s" % (line[17:20], line))
                else:
                    resid = line[21:27]
                    #print(chainID, residue_longname, resid)
                    #print(line)
                    #print(resid_list)
                    if resid not in resid_set:
                        removed_residue[chainID] = False
                        add_residue = True
                        if current_atoms:
                            if RemoveIncompleteResidues and essential_atoms_1.intersection(current_atoms) != essential_atoms_1 and essential_atoms_2.intersection(current_atoms) != essential_atoms_2:
                                oldChain = resid_list[-1][0]
                                oldResidueID = resid_list[-1][1:]
                                print("The last residue '%s', %s, in chain %s is missing these atoms: %s." % (resid_list[-1], residue_longname, oldChain, essential_atoms_1.difference(current_atoms) or essential_atoms_2.difference(current_atoms)))
                                resid_set.remove(resid_list[-1])
                                #print("".join(resid_list))
                                resid_list = resid_list[:-1]
                                if oldchainID:
                                    removed_residue[oldchainID] = True
                                #print("".join(resid_list))
                                #print(sequences[oldChain])
                                if sequences.get(oldChain):
                                    sequences[oldChain] = sequences[oldChain][:-1]

                                if residue_map.get(oldChain):
                                    residue_map[oldChain] = residue_map[oldChain][:-1]

                                #print(sequences[oldChain]
                        else:
                            assert(not(resid_set))
                        current_atoms = set()
                        atoms_read[chainID] = set()
                        atoms_read[chainID].add(line[12:15].strip())
                        resid_set.add(resid)
                        resid_list.append(resid)
                        chainID = line[21]

                        sequences[chainID] = sequences.get(chainID, [])
                        if residue_longname in non_canonical_amino_acids:
                            sequences[chainID].append(non_canonical_amino_acids[residue_longname])
                        else:
                            sequences[chainID].append(residue_type_3to1_map[residue_longname])

                        residue_map[chainID] = residue_map.get(chainID, [])
                        if residue_longname in non_canonical_amino_acids:
                            residue_map[chainID].append((resid, non_canonical_amino_acids[residue_longname]))
                        else:
                            residue_map[chainID].append((resid, residue_type_3to1_map[residue_longname]))

                        oldchainID = chainID
                    else:
                        #atoms_read[chainID] = atoms_read.get(chainID, set())
                        atoms_read[chainID].add(line[12:15].strip())
                    current_atoms.add(line[12:15].strip())
        if RemoveIncompleteFinalResidues:
            # These are (probably) necessary for Rosetta to keep the residue. Rosetta does throw away residues where only the N atom is present if that residue is at the end of a chain.
            for chainID, sequence_list in sequences.iteritems():
                if not(removed_residue[chainID]):
                    if essential_atoms_1.intersection(atoms_read[chainID]) != essential_atoms_1 and essential_atoms_2.intersection(atoms_read[chainID]) != essential_atoms_2:
                        print("The last residue %s of chain %s is missing these atoms: %s." % (sequence_list[-1], chainID, essential_atoms_1.difference(atoms_read[chainID]) or essential_atoms_2.difference(atoms_read[chainID])))
                        oldResidueID = sequence_list[-1][1:]
                        residue_map[chainID] = residue_map[chainID][0:-1]
                        sequences[chainID] = sequence_list[0:-1]


        for chainID, sequence_list in sequences.iteritems():
            sequences[chainID] = "".join(sequence_list)
            assert(sequences[chainID] == "".join([res_details[1] for res_details in residue_map[chainID]]))
        for chainID in chains:
            for a_acid in sequences.get(chainID, ""):
                self.RAW_ATOM_SEQUENCE.append((chainID, a_acid))

        residue_objects = {}
        for chainID in residue_map.keys():
            residue_objects[chainID] = []
        for chainID, residue_list in residue_map.iteritems():
            for res_pair in residue_list:
                resid = res_pair[0]
                resaa = res_pair[1]
                assert(resid[0] == chainID)
                residue_objects[chainID].append((resid[1:].strip(), resaa))

        return sequences, residue_objects