Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added DNA sequences in SBOL #5

Merged
merged 1 commit into from
Jul 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
341 changes: 341 additions & 0 deletions Debug.csv

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions python-only/Data.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
c'(ab+b')
b(a'c'+c)
4
(c+(b'+a)')'
(Arabinose+(aTc'+IPTG)')'
(b'+(c+a')')'
(aTc'+(Arabinose+IPTG')')'
2 changes: 1 addition & 1 deletion python-only/Genetech.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def saveImageDialog(self):
QMessageBox.about(self, "Alert", "A file name can't contain any of the following \n \ / : * ? < > |")
else:
item = self.CircuitList.currentItem() #the selected item
saveimg = Image.open(str(item.text())+".png") #use this image to save
saveimg = Image.open('user_files/'+str(item.text())+".png") #use this image to save
saveimg.save(str(UserfileName)+".png") #save image as

#or "?" in UserfileName or "/" in UserfileName or "*" in UserfileName or "<" in UserfileName or ">" in UserfileName or "|" in UserfileName or '"' in UserfileName:
Expand Down
157 changes: 129 additions & 28 deletions python-only/SBOL_File.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,37 @@
from sbol2 import *
from functions import *
import pandas as pd

class SBOL_File:
def __init__(self, total_gates, total_time, option, num):
DeleteExistingFiles()
circuits = ReadFile()
Component_strings = self.ListOfLines(circuits)
self.geneticPartsDf = None #dataframe containing information of genetic parts such as DNA sequence
self.gateRBS = {} #gets rbs corresponding to the gate
self.readGeneticParts()
self.gateRBSMapping()
self.CreateFile(Component_strings, len(Component_strings), total_gates, total_time, option, num)

def readGeneticParts(self):
"""
This function loads the csv file genetic_parts.csv into a
pandas dataframe for better access when adding sequences
"""
self.geneticPartsDf = pd.read_csv("genetic_parts.csv")


def gateRBSMapping(self):
"""
This function creates a mapping between a gate and it's corresponding
RBS (AmeR is mappedd to A1, PhlF mapped to P1, and so on) as given in the
genetic_parts.csv file
"""
listGates = self.geneticPartsDf.loc[self.geneticPartsDf.type == "CDS"].part
for i in listGates:
if i != "YFP":
rbs = self.geneticPartsDf.loc[self.geneticPartsDf.gate == i].part.values[0]
self.gateRBS[i] = rbs

def ListOfLines(self, circuits):
#This function filters out the unwanted characters from every line of each circuit
Expand All @@ -25,7 +50,6 @@ def ListOfLines(self, circuits):
return Component_strings

def CreateFile(self, input_list, circuits, total_gates, total_time, option, num):

for i in range(circuits): #iter for each circuit
file_num = SortNum(i, option) + 1
if Total_Gates(i) <= total_gates and Total_time(i) <= total_time and file_num <= num: #If Total Delay and number of gates are less than the input
Expand All @@ -38,43 +62,96 @@ def CreateFile(self, input_list, circuits, total_gates, total_time, option, num)
componentDef_string = [] #A list to contain name of the objects
count=1 #A variable to assign number to terminators

#Create ComponentDefinition for the whole Device which will contain the Components of each part and the SequenceConstraints
Device = ComponentDefinition('Output_Device_' + str(i+1))
Device.name = 'Output_Device ' + str(i+1) + ' Component'
doc.addComponentDefinition(Device)

#Create ModuleDefinition of the device, which will contain the FunctionalComponent of the device connected to its ComponentDefinition
Circuit = ModuleDefinition('Output_Circuit_' + str(i+1))
Circuit.name = 'Output Circuit Module'
doc.addModuleDefinition(Circuit)

#Create ComponentDefinition for the whole Device which will contain the Components of each part and the SequenceConstraints
Device = ComponentDefinition('Output_Device_' + str(i+1))
Device.name = 'Output_Device ' + str(i+1) + ' Component'
doc.addComponentDefinition(Device)


Circuit_fc = Circuit.functionalComponents.create('Device')
Circuit_fc.name = 'Device'
#This Functional Component needs a unique ID of the part it belongs to, in this case it belongs to the Device itself
Circuit_fc.definition = Device.identity
Circuit_fc.access = SBOL_ACCESS_PUBLIC
Circuit_fc.direction = SBOL_DIRECTION_NONE


### Terminator ###
terminator = self.geneticPartsDf.loc[self.geneticPartsDf.type == "Terminator"]
terminatorName = terminator.part.values[0]
terminatorSeq = terminator.sequence.values[0]
terminatorSeqObj = Sequence(terminatorName+"_sequence", terminatorSeq)

sequences = [terminatorSeqObj] #these will be added later to the doc
finalSequenceList = []
Terminator = ComponentDefinition(terminatorName, BIOPAX_DNA)
Terminator.roles = SO_TERMINATOR
Terminator.sequence = terminatorSeqObj
doc.addComponentDefinition(Terminator)

for j in range(len(input_list[i])): #iter for each line of the circuit
splitted_components = input_list[i][j].split() #each part in a line
name_line = [] #List to contain names of each part
def_line = [] #List to contain Component Definitions of each part
for k in range(len(splitted_components)): #Loop to get the individual names of promotors and coding sequences in the list
if splitted_components[k][0] == '(': #if the part is a coding sequence
Comp = ComponentDefinition(splitted_components[k][1:-1], BIOPAX_DNA)
name = splitted_components[k][1:-1]
Comp = ComponentDefinition(name, BIOPAX_DNA)
Comp.roles = SO_CDS
seqCDS = self.geneticPartsDf.loc[self.geneticPartsDf.part == name]
#print(name, seqCDS)
seqName = seqCDS.part.values[0]
seqValue = seqCDS.sequence.values[0]
seqObj = Sequence(seqName+"_sequence", seqValue)
sequences.append(seqObj)
Comp.sequence = seqObj

if name != "YFP":
rbs = self.gateRBS[name]
seqCDS = self.geneticPartsDf.loc[self.geneticPartsDf.part == rbs]
seqName = seqCDS.part.values[0]
seqValue = seqCDS.sequence.values[0]
seqObj = Sequence(seqName+"_sequence", seqValue)
sequences.append(seqObj)
RBS = ComponentDefinition(rbs, BIOPAX_DNA)
RBS.roles = SO_RBS
RBS.sequence = seqObj

doc.addComponentDefinition(RBS)

def_line.append(RBS)
name_line.append(rbs)

def_line.append(Comp)
name_line.append(splitted_components[k])

Terminator = ComponentDefinition('Terminator' + str(count), BIOPAX_DNA)
Terminator = ComponentDefinition(terminatorName+"__"+str(count), BIOPAX_DNA)
Terminator.roles = SO_TERMINATOR
doc.addComponentDefinition(Terminator)
Terminator.sequence = terminatorSeqObj
def_line.append(Terminator)
name_line.append('Terminator' + str(count))
name_line.append(terminatorName+"__"+str(count))

#Terminator = ComponentDefinition('Terminator' + str(count), BIOPAX_DNA)
#Terminator.roles = SO_TERMINATOR
#doc.addComponentDefinition(Terminator)
#def_line.append(Terminator)
#name_line.append('Terminator' + str(count))
count+=1
else:
Comp = ComponentDefinition(splitted_components[k], BIOPAX_DNA)
Comp.roles = SO_PROMOTER
seqCDS = self.geneticPartsDf.loc[self.geneticPartsDf.part == splitted_components[k]]
#print(name, seqCDS)
seqName = seqCDS.part.values[0]
seqValue = seqCDS.sequence.values[0]
seqObj = Sequence(seqName+"_sequence", seqValue)
sequences.append(seqObj)
Comp.sequence = seqObj

def_line.append(Comp)
name_line.append(splitted_components[k])

Expand All @@ -83,6 +160,20 @@ def CreateFile(self, input_list, circuits, total_gates, total_time, option, num)
component_defs.append(def_line)
componentDef_string.append(name_line)

#if circuit has 2 lines, add the 2nd line to the start of the first to match sbol visaul
if len(component_defs) > 1:
finalComp = component_defs[1][:]
finalCompString = componentDef_string[1][:]
finalComp.extend(component_defs[0][:])
finalCompString.extend(componentDef_string[0][:])
else:
finalComp = component_defs[0][:]
finalCompString = componentDef_string[0][:]
#print(finalComp)
#print(componentDef_string)
#print(finalCompString)
Device.assemblePrimaryStructure(finalComp)
print("DNA : ", Device.compile())
#For the Flourescent Protein, which is the last element of the first line of the circuit
FP_protein = ComponentDefinition(componentDef_string[0][-2][1:-1]+'_Protein', BIOPAX_PROTEIN)
doc.addComponentDefinition(FP_protein)
Expand All @@ -95,32 +186,40 @@ def CreateFile(self, input_list, circuits, total_gates, total_time, option, num)
for j in range(len(componentDef_string)): #This loop creates those Components
Components_line = []
for k in range(len(componentDef_string[j])):
name = componentDef_string[j][k] + "_component"

if componentDef_string[j][k][0] == '(':
name_c = Device.components.create(componentDef_string[j][k][1:-1])
else:
name_c = Device.components.create(componentDef_string[j][k])
name = componentDef_string[j][k][1:-1] + "_component"

name_c = Device.components.create(name)
name_c.definition = component_defs[j][k].identity
name_c.access = SBOL_ACCESS_PUBLIC
Components_line.append(name_c)

Components.append(Components_line)

s_contraint_list = []
for j in range(len(componentDef_string)): #This loop is to create the SequenceConstraints class to defines the Orientation of the device
for k in range(len(componentDef_string[j])-1):

if componentDef_string[j][k+1][0] == '(':
S_constraint = Device.sequenceConstraints.create(componentDef_string[j][k] + '_precedes_' + componentDef_string[j][k+1][1:-1])
name = componentDef_string[j][k] + '_precedes_' + componentDef_string[j][k+1][1:-1]
#S_constraint = Device.sequenceConstraints.create(componentDef_string[j][k] + '_precedes_' + componentDef_string[j][k+1][1:-1])

elif componentDef_string[j][k][0] == '(':
S_constraint = Device.sequenceConstraints.create(componentDef_string[j][k][1:-1] + '_precedes_' + componentDef_string[j][k+1])
name = componentDef_string[j][k][1:-1] + '_precedes_' + componentDef_string[j][k+1]
#S_constraint = Device.sequenceConstraints.create(componentDef_string[j][k][1:-1] + '_precedes_' + componentDef_string[j][k+1])

else:
S_constraint = Device.sequenceConstraints.create(componentDef_string[j][k] + '_precedes_' + componentDef_string[j][k+1])

name = componentDef_string[j][k] + '_precedes_' + componentDef_string[j][k+1]
#S_constraint = Device.sequenceConstraints.create(componentDef_string[j][k] + '_precedes_' + componentDef_string[j][k+1])

S_constraint.subject = Components[j][k].identity #Subject is the part that comes first
S_constraint.object = Components[j][k+1].identity #Object is the part that comes later
S_constraint.restriction = SBOL_RESTRICTION_PRECEDES #This describes the order we have defined for this Constraint
if name not in s_contraint_list:
s_contraint_list.append(name)
S_constraint = Device.sequenceConstraints.create(name)
S_constraint.subject = Components[j][k].identity #Subject is the part that comes first
S_constraint.object = Components[j][k+1].identity #Object is the part that comes later
S_constraint.restriction = SBOL_RESTRICTION_PRECEDES #This describes the order we have defined for this Constraint

if j == 0 and componentDef_string[j][k][0] == '(': #for the coding sequences in the first line of the circuit
#For the Module Definition, we only need the coding sequence and the output promotor
Expand Down Expand Up @@ -200,8 +299,9 @@ def CreateFile(self, input_list, circuits, total_gates, total_time, option, num)
S_constraint.restriction = SBOL_RESTRICTION_PRECEDES

if componentDef_string[j][k][0] == '(':
cds_fc = Circuit.functionalComponents.create(componentDef_string[j][1][1:-1])
cds_fc.definition = component_defs[j][1].identity
print("BUG HERE") # componentDef_string[j][1] instead of componentDef_string[j][k]
cds_fc = Circuit.functionalComponents.create(componentDef_string[j][k][1:-1])
cds_fc.definition = component_defs[j][k].identity
cds_fc.access = SBOL_ACCESS_PUBLIC
cds_fc.direction = SBOL_DIRECTION_NONE

Expand Down Expand Up @@ -262,9 +362,10 @@ def CreateFile(self, input_list, circuits, total_gates, total_time, option, num)
P_map.refinement = SBOL_REFINEMENT_USE_REMOTE
P_map.local = P_fc.identity
P_map.remote = Components[1][index_of_myP].identity

result = doc.write("user_files/SBOL File " + str(file_num) +".xml") #To save the SBOL File
print("here")
result = doc.write("user_files/"+"SBOL File " + str(file_num) +".xml") #To save the SBOL File
print("here ", result)

if __name__ == '__main__':
inputExp = "IPTG'.aTc'.Arabinose'+IPTG'.aTc.Arabinose'+IPTG.aTc'.Arabinose'"
#inputExp = "IPTG'.aTc'.Arabinose'+IPTG'.aTc.Arabinose'+IPTG.aTc'.Arabinose'"
f = SBOL_File(1000, 1000)
6 changes: 4 additions & 2 deletions python-only/circuits.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
******************* Genetic Circuit 1 *****************

PTet-> (AmtR) ----|PAmtR-> PTac-> (HlYllR) ----|PHlYllR-> PBad-> (BM3R1) ----|PBM3R1-> (YFP)
PTac-> (HlYllR) ----|PHlYllR-> PBad-> (AmtR) ----|PAmtR-> PAmeR-> (Betl) ----|PBetl-> (YFP)
PTet-> (AmeR)-----------------------------------------------^

******************* Genetic Circuit 2 *****************

PTet-> (AmtR) ----|PAmtR-> PTac-> (HlYllR) ----|PHlYllR-> PBad-> (SrpR) ----|PSrpR-> (YFP)
PTac-> (HlYllR) ----|PHlYllR-> PBad-> (SrpR) ----|PSrpR-> PAmtR-> (PhlF) ----|PPhlF-> (YFP)
PTet-> (AmtR)-----------------------------------------------^

11 changes: 9 additions & 2 deletions python-only/functions.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
from sbol2 import *
#
import sbol2
print(sbol2.__version__)
import glob, os

def baseList():
Expand Down Expand Up @@ -85,12 +89,14 @@ def Delay(promotor1, CDS, promotor2 = None):
return Check_NOR(promotor1, promotor2, Output_P, Gates[3])
else:
return Check_NOR(promotor1, promotor2, Output_P, Gates[4])

return 0

def Check_NOT(promotor, Output_P, Gates):
"""Check the whole list and returns the delay of the gate matching with inputs"""
for i in Gates:
if i[0] == promotor and i[1] == Output_P:
return i[2]
return 0

def Check_NOR(promotor1, promotor2, Output_P, Gates):
"""Check the whole list and returns the delay of the gate matching with inputs"""
Expand All @@ -100,7 +106,8 @@ def Check_NOR(promotor1, promotor2, Output_P, Gates):
return i[3]
elif i[0] == promotor2 and i[1] == promotor1 and i[2] == Output_P: #e.g. if P1=PBetl and P2=PAmtR
return i[3]

return 0

def GatherGates():
f = open("GatesLib.txt")
lst = []
Expand Down
Loading