@@ -113,12 +113,14 @@ struct Atom <: AbstractAtom
113113 charge:: String
114114 residue:: StructuralElement
115115end
116+ Atom (a:: Atom , r:: StructuralElement ) = Atom (a. serial, a. name, a. alt_loc_id, copy (a. coords), a. occupancy, a. temp_factor, a. element, a. charge, r)
116117
117118" A container to hold different locations of the same atom."
118119struct DisorderedAtom <: AbstractAtom
119120 alt_loc_ids:: Dict{Char, Atom}
120121 default:: Char
121122end
123+ DisorderedAtom (da:: DisorderedAtom , r:: StructuralElement ) = DisorderedAtom (Dict (k => Atom (a, r) for (k, a) in da. alt_loc_ids), da. default)
122124
123125"""
124126A residue (amino acid) or other molecule - either a `Residue` or a
@@ -137,6 +139,14 @@ mutable struct Residue <: AbstractResidue
137139 chain:: StructuralElement
138140 ss_code:: Char
139141end
142+ function Residue (r:: Residue , chain:: StructuralElement )
143+ atoms = Dict {String, AbstractAtom} ()
144+ rnew = Residue (r. name, r. number, r. ins_code, r. het_res, [name for name in r. atom_list], atoms, chain, r. ss_code)
145+ for (name, atom) in r. atoms
146+ atoms[name] = isa (atom, Atom) ? Atom (atom, rnew) : DisorderedAtom (atom, rnew)
147+ end
148+ return rnew
149+ end
140150
141151"""
142152A container to hold different versions of the same residue (point
@@ -146,6 +156,7 @@ struct DisorderedResidue <: AbstractResidue
146156 names:: Dict{String, Residue}
147157 default:: String
148158end
159+ DisorderedResidue (dr:: DisorderedResidue , chain:: StructuralElement ) = DisorderedResidue (Dict (k => Residue (r, chain) for (k, r) in dr. names), dr. default)
149160
150161" A chain (molecule) from a macromolecular structure."
151162mutable struct Chain <: StructuralElement
@@ -154,13 +165,29 @@ mutable struct Chain <: StructuralElement
154165 residues:: Dict{String, AbstractResidue}
155166 model:: StructuralElement
156167end
168+ function Chain (c:: Chain , model:: StructuralElement )
169+ residues = Dict {String, AbstractResidue} ()
170+ cnew = Chain (c. id, [id for id in c. res_list], residues, model)
171+ for (id, res) in c. residues
172+ residues[id] = isa (res, Residue) ? Residue (res, cnew) : DisorderedResidue (res, cnew)
173+ end
174+ return cnew
175+ end
157176
158177" A conformation of a macromolecular structure."
159178struct Model <: StructuralElement
160179 number:: Int
161180 chains:: Dict{String, Chain}
162181 structure:: StructuralElement
163182end
183+ function Model (m:: Model , structure:: StructuralElement )
184+ chains = Dict {String, Chain} ()
185+ mnew = Model (m. number, chains, structure)
186+ for (id, ch) in m. chains
187+ chains[id] = Chain (ch, mnew)
188+ end
189+ return mnew
190+ end
164191
165192"""
166193A container for multiple `Model`s that represents a Protein Data Bank (PDB)
@@ -170,6 +197,14 @@ struct MolecularStructure <: StructuralElement
170197 name:: String
171198 models:: Dict{Int, Model}
172199end
200+ function MolecularStructure (s:: MolecularStructure )
201+ models = Dict {Int, Model} ()
202+ snew = MolecularStructure (s. name, models)
203+ for (number, mo) in s. models
204+ models[number] = Model (mo, snew)
205+ end
206+ return snew
207+ end
173208
174209"""
175210A record for a single atom, e.g. as represented in a Protein Data Bank
338373Base. firstindex (struc:: MolecularStructure ) = first (modelnumbers (struc))
339374Base. lastindex (struc:: MolecularStructure ) = last (modelnumbers (struc))
340375
376+ # recursive copy methods. If we copy a subelement (anything below MolecularStructure), it shares the parent element
377+ Base. copy (a:: Atom ) = Atom (a, a. residue)
378+ Base. copy (da:: DisorderedAtom ) = DisorderedAtom (da, only (unique (a -> a. residue, values (da. alt_loc_ids))). residue)
379+ Base. copy (r:: Residue ) = Residue (r, r. chain)
380+ Base. copy (dr:: DisorderedResidue ) = DisorderedResidue (dr, only (unique (r -> r. chain, values (dr. names))). chain)
381+ Base. copy (c:: Chain ) = Chain (c, c. model)
382+ Base. copy (m:: Model ) = Model (m, m. structure)
383+ Base. copy (s:: MolecularStructure ) = MolecularStructure (s)
384+
341385# Check if an atom name exists in a residue as a whitespace-padded version
342386function findatombyname (res:: Residue , atom_name:: AbstractString )
343387 # Look for atom name directly
0 commit comments