def __iadd__(self, other): """ 'Magic' method to implement the '+=' operator (eg struc1 += struc2) Compare global IDs of particles and reassign globalIDs for particle container using the max ID between the two lists. Tracks these changes for all other (bond, angle, dihedral) containers that reference particleIDs """ self.verbose = False # Empty container checks if len(other) == 0: # If struc2 is empty (has no particles) return self # simply return unchanged current container if len(self ) == 0: # If struc1 (this struc) is empty (has no particles) return copy.deepcopy(other) # full copy other and return # # Special method for connecting building blocks # # Count number of connectors connect_along_bond = False if (self.type != "mol" and other.type != "mol"): # IF not complete molecules that will just be added # connect along bonds connect_along_bond = True self.cnt_connectors() other.cnt_connectors() if (self.verbose): log_line = "\n building block 1 type {} ".format(self.type) log_line += "\n building block 1 has {} connections ".format( self.connect_cnt) log_line += "\n building block 1 has {} func connections ".format( self.func_connect_cnt) log_line += "\n building block 2 type {} ".format(other.type) log_line += "\n building block 2 has {} connections ".format( other.connect_cnt) log_line += "\n building block 2 has {} func connections ".format( other.func_connect_cnt) print log_line self.connect_id = "term_" self.cap_id = "termcap_" other.connect_id = "term_" other.cap_id = "termcap_" if (self.type == "unit" and other.type == "unit"): self.connectionpoint = 1 other.connectionpoint = 0 new_termpoint = 1 elif (self.type == "term" and other.type == "unit"): # elif( self.connect_cnt == 1 and other.connect_cnt == 2 ): self.connectionpoint = 0 other.connectionpoint = 0 new_termpoint = 0 elif (self.type == "term" and other.type == "term"): # elif( self.connect_cnt == 1 and other.connect_cnt == 1 ): self.connectionpoint = 0 other.connectionpoint = 0 new_termpoint = -1 elif (self.type == "unit" and other.type == "term"): #elif( self.connect_cnt == 2 and other.connect_cnt == 1 ): self.connectionpoint = 1 other.connectionpoint = 0 new_termpoint = -1 elif (self.type == "unit" and other.type == "func"): #elif( self.connect_cnt == 2 and other.connect_cnt == 1 ): self.connect_id = "func_" self.cap_id = "funccap_" # this is zero since each functional possition will be removed once a functional group is added self.connectionpoint = 0 other.connect_id = "term_" other.connectionpoint = 0 new_termpoint = -1 else: error_line = " Unknow connection configuration {} - {} \n".format( self.type, other.type) error_line += " building block 1 has {} connnections \n".format( self.connect_cnt) error_line += " building block 2 has {} connnections \n".format( other.connect_cnt) sys.exit(error_line) if (self.verbose): log_line = "\n Adding connection along bond " log_line += "\n Connecting block 2 {} at point {} ".format( other.connect_id, other.connectionpoint) log_line += "\n to block 1 {} at point {} ".format( self.connect_id, self.connectionpoint) print log_line # Shift second buildingblock so first connector is bonded to the second connector of first buildingblock if (self.verbose): print " Shift along bonds " self.align_termbond(self.connectionpoint, origin="term") other.align_termbond(other.connectionpoint, origin="termcap") if (self.verbose): print " Find terminal atoms " self.get_connectors(self.connectionpoint) other.get_connectors(other.connectionpoint) bond_length = np.array([ self.ptclC[self.pid_term].radii + other.ptclC[other.pid_term].radii, 0.0, 0.0 ]) # Shift second building block to have the correct bond length other.ptclC.shift( (bond_length - 1.0 * np.array(other.ptclC[other.pid_term].position))) # Delete termcaps self.bondC.deletepid(self.pid_termcap) other.bondC.deletepid(other.pid_termcap) del self.ptclC[self.pid_termcap] del other.ptclC[other.pid_termcap] # Reset term tags to null self.ptclC[self.pid_term].tagsDict["cplytag"] = "" other.ptclC[other.pid_term].tagsDict["cplytag"] = "" # If an intern ring connection is made change the fftype if (self.ptclC[self.pid_term].tagsDict["ring"] > 0 and other.ptclC[other.pid_term].tagsDict["ring"] > 0): #print " ring self ", self.ptclC[self.pid_term].tagsDict["ring"] #print " ring other ", other.ptclC[other.pid_term].tagsDict["ring"] self.ptclC[self.pid_term].tagsDict["fftype"] = 'C!' other.ptclC[other.pid_term].tagsDict["fftype"] = 'C!' # sys.exit(" ring test ") idFromToDict = dict( ) # Need to keep track of all ptcl ID changes at once # {fromID1:toID1, fromID2:toID2...} # eg {1:3, 3:5, 2:20...} bondC = BondContainer() # Local bond container copy so ptclIDs angleC = AngleContainer() # Local angle container copy so ptclIDs dihC = DihedralContainer() # Local dihedral container copy so ptclIDs bondC = copy.deepcopy( other.bondC) # inside can be changed (for adding below) angleC = copy.deepcopy( other.angleC) # inside can be changed (for adding below) dihC = copy.deepcopy( other.dihC) # inside can be changed (for adding below) impC = copy.deepcopy( other.impC) # inside can be changed (for adding below) keys1 = self.ptclC.particles.keys( ) # global IDs of particles in this object keys2 = other.ptclC.particles.keys( ) # global IDs in object being added self.ptclC.maxgid = max( keys1 + keys2) # find max globalID in keys, set this object maxID self.get_max() other.get_max() # Update chain, residue and charge group number if (self.max_chain == other.max_chain): other.shift_tag("qgroup", self.max_qgroup) other.shift_tag("residue", self.max_residue) other.shift_tag("ring", self.max_ring) else: other.add_chain(self.max_chain) for ptclkey2 in other.ptclC.particles: self.ptclC.put(other.ptclC.particles[ptclkey2] ) # Pushes ptcl to this struc's ptcl container fromPtclID = ptclkey2 # Track IDs from--->to toPtclID = self.ptclC.maxgid # --> toID (to is the maxid of this ptclC) idFromToDict[fromPtclID] = toPtclID # Store ID changes if (connect_along_bond): # Add inter building block bond if (self.verbose): print " Add inter building block bond " bb_bb = Bond(self.pid_term, idFromToDict[other.pid_term]) self.bondC.put(bb_bb) bondC.replacePtclIDs(idFromToDict) # Use tracked list of ID changes self.bondC += bondC # Now add bondC with 'corrected' IDs angleC.replacePtclIDs( idFromToDict) # Now add angleC with 'corrected' IDs self.angleC += angleC # Use tracked list of ID changes dihC.replacePtclIDs(idFromToDict) # Use tracked list of ID changes self.dihC += dihC # Now add dihC with 'corrected' IDs impC.replacePtclIDs(idFromToDict) # Use tracked list of ID changes self.impC += impC # Now add impC with 'corrected' IDs if (connect_along_bond): self.compressPtclIDs() self.bondC_nblist() if (new_termpoint >= 0): if (self.verbose): print " Add new cplytag to " self.get_connectors(new_termpoint) self.ptclC[ self.pid_term].tagsDict["cplytag"] = "term_C({})".format( self.pid_term) self.ptclC[self.pid_termcap].tagsDict[ "cplytag"] = "termcap_H({})_on_C({})".format( self.pid_termcap, self.pid_term) # Append segments for seg_i in other.segments: self.segments.append(seg_i) return self
def main(): """ This shows operations on empty StructureContainer objects for 'robustness' """ print "************************************************************************************" print " This shows operations on empty StructureContainer objects for 'robustness'" print "************************************************************************************ \n" atoms1 = ParticleContainer() bonds1 = BondContainer() p1 = Particle([0.2, 1.3, 33.0], "Si", 2.0, 1.23) p2 = Particle([5.0, 2.3, -22.1], "C", 1.0, 2.34) p3 = Particle([5.0, 2.3, -20.1], "C", 1.0, 2.34) b1 = Bond(1, 2, 1.233, "hooke") b2 = Bond(2, 3, 0.500, "hooke") atoms1.put(p1) atoms1.put(p2) atoms1.put(p3) bonds1.put(b1) bonds1.put(b2) atoms2 = ParticleContainer() bonds2 = BondContainer() polymer1 = StructureContainer(atoms1, bonds1) # Non-empty structure 1 polymer2 = StructureContainer(atoms2, bonds2) # Empty structure 2 # ------------------------------------------------------------------------------------------------------------------------ print "Non-empty container", polymer1 print "Empty container", polymer2 print "Testing empty dump" polymer2.dump("empty") print "Testing empty compressPtclIDs" polymer2.compressPtclIDs() print "Testing empty getSubStructure" subStruc = polymer2.getSubStructure([]) print "subStruc = ", subStruc print "Testing empty getPtclPositions" posList = polymer2.getPtclPositions() print "posList = ", posList print "------------------------------------------------------------------------------------ \n" print "Testing struc add --> non-empty (polymer1) += empty (polymer2)" polymer1 += polymer2 print "polymer1 = ", polymer1 print "------------------------------------------------------------------------------------ \n" print "polymer2 = ", polymer2 print "------------------------------------------------------------------------------------ \n" print "Testing struc add --> empty (polymer2) += non-empty (polymer1)" polymer2 += polymer1 print "polymer2 = ", polymer2 print "------------------------------------------------------------------------------------ \n" print "polymer1 = ", polymer1 print "------------------------------------------------------------------------------------ \n" print "Testing empty getSubStructure with non-zero id list (should return ERROR)" polymer3 = StructureContainer() subStruc = polymer3.getSubStructure([1, 2]) print "subStruc = ", subStruc
def read_cply(self, cply_file, debug=False): """ Read cply file """ # Load periodic table pt = periodictable() read_lattice = False read_segment = False with open(cply_file) as f: for line in f: col = line.split() if (read_lattice): self.latvec[lv_cnt][0] = float(col[0]) self.latvec[lv_cnt][1] = float(col[1]) self.latvec[lv_cnt][2] = float(col[2]) if (lv_cnt == 2): read_lattice = False lv_cnt += 1 elif (read_segment): if (debug): print " Readin degment line ", col if (str(col[0]) == 'unit'): if (len(col) > 2): error_line = "Each segment can only have 1 unit " error_line += "\n {} in unit line will be ignored ".format( str(col[2::])) print error_line segment_i['unit'] = col[1] if (str(col[0]) == 'func'): segment_i['func'] = col[1::] if (str(col[0]) == 'end'): read_segment = False elif (len(col) >= 4 and col[0] != "bond" and col[0] != "#"): pt_i = Particle() pt_i.type = str(col[0]) pt_i.position = [ float(col[1]), float(col[2]), float(col[3]) ] add_dict = pt_i.tagsDict el = pt.getelementWithSymbol(str(col[0])) add_dict["symbol"] = str(col[0]) add_dict["number"] = el.number add_dict["mass"] = el.mass add_dict["cplytag"] = "" add_dict["linkid"] = "" add_dict["link"] = "" pt_i.mass = el.mass add_dict["chain"] = 1 add_dict["ring"] = 0 add_dict["residue"] = 1 add_dict["resname"] = "RES" add_dict["qgroup"] = 1 add_dict["fftype"] = "??" add_dict["label"] = el.symbol add_dict["cov_radii"] = el.cov_radii add_dict["vdw_radii"] = el.vdw_radii add_dict["lmptype"] = -1 if (len(col) >= 14): add_dict["label"] = str(col[4]) add_dict["fftype"] = str(col[5]) add_dict["mass"] = float(col[6]) pt_i.mass = float(col[6]) pt_i.charge = float(col[7]) add_dict["qgroup"] = int(col[8]) add_dict["ring"] = int(col[9]) add_dict["residue"] = int(col[10]) add_dict["resname"] = str(col[11]) add_dict["chain"] = int(col[12]) add_dict["cplytag"] = str(col[13]) elif (len(col) == 13): add_dict["label"] = str(col[4]) add_dict["fftype"] = str(col[5]) add_dict["mass"] = float(col[6]) pt_i.mass = float(col[6]) pt_i.charge = float(col[7]) add_dict["qgroup"] = int(col[8]) add_dict["ring"] = int(col[9]) add_dict["residue"] = int(col[10]) add_dict["resname"] = str(col[11]) add_dict["chain"] = int(col[12]) elif (len(col) == 8): add_dict["residue"] = int(col[5]) add_dict["resname"] = str(col[6]) add_dict["cplytag"] = str(col[7]) elif (len(col) == 7): pt_i.charge = float(col[4]) add_dict["residue"] = int(col[5]) add_dict["resname"] = str(col[6]) elif (len(col) == 5): add_dict["cplytag"] = str(col[4]) pt_i.setTagsDict(add_dict) self.ptclC.put(pt_i) # # # print "debug pt_i ",len(col),pt_i elif (len(col) >= 3): if (col[0] == "bond"): b_i = int(col[1]) b_j = int(col[2]) bnd = Bond(b_i, b_j) #print "process_line bond line ",col self.bondC.put(bnd) # Key word search if (len(col) > 0): if (str(col[0]) == 'lattice'): read_lattice = True lv_cnt = 0 if (str(col[0]) == 'segment'): read_segment = True segment_i = {} #segment(str(col[1])) # segment_i = segment() segment_i['tag'] = str(col[1]) segment_i['segment'] = {} self.segments.append(segment_i) if (debug): print segments sys.exit("debug in read_cply is True ")