by Leo d'Espaux leodespaux@gmail.com.
Other development by: Joshua Nixon, William Zhuang
Current as of 9/18/2017
For a detailed user manual and feedback, please go to https://docs.google.com/document/d/11YNoUBtit4rkWZQr_ZclzAOTE_HGMtgB3H_6cvq1Y24/edit?usp=sharing
Click on the "play" button in the top bar
You may need to wait a minute.
If you get stuck at any time, Kernel/restart/restart, then repeat 1-2.
Then follow the simple in-line instructions.
In [ ]:
'''
CLICK HERE
'''
# import libraries we're using
%matplotlib inline
from Bio.Seq import Seq
from Bio.SeqRecord import SeqRecord
from Bio import SeqIO
from Bio.SeqUtils import MeltingTemp
import copy
from pandas import *
from pandas import DataFrame, read_csv
import pandas as pd
import matplotlib.pyplot as plt
import sys
from IPython.display import Image
from IPython.display import display
from Bio import Alphabet
from Bio.SeqFeature import SeqFeature, FeatureLocation #SeptAdd
from Bio.Alphabet import IUPAC #SeptAddoverh
from pygenome import sg
import random
import re
# define global variables
HomologyLength = 1000
PrimerMaxTm = 55 # As calculated by statluc, more like 65C by Thermo's Phusion program
PrimerMaxLen = 60
OverhangMaxFrac = 1
PromoterLength = 600
TerminatorLength = 250
Post20merLength = 14
nLinker = Seq("GGAGGTGGTGGAGGTGGA")
cLinker = Seq("GGTAGCGGTAGCGGCAGC")
def askUser():
print('Python version ' + sys.version+"\n\n\n\n")
print("\nHi, welcome to CASdesigner.\n")
print("Refer to this community google doc for documentation and feedback:")
print("https://casdesigner.jbei.org/static/cassette/casdesigner-manual.pdf")
print("\n\n\n\nWHAT DO YOU WANT TO DO TO S288C? Type \"1\", \"2\", or \"3\".\n")
print("\t 1 \t add to empty (insert DNA into a well-characterized site)\n")
print("\t 2 \t edit existing (delete or replace a gene of interest)\n")
print("\t 3 \t stitch (get primers to stich together N fragments)\n")
areCTags = []
areNTags = []
Action= input("Your answer: ")
if Action == "1":
fragments, areCTags, areNTags = editEmpty()
elif Action == "2":
fragments, areCTags, areNTags = editExisting()
elif Action == "3": # This is more for stitching things together not necessarily for CRISPR
fragments = buildCustom()
#stitch makes the primers to Gibson/in vivo HR your cassette
stitch(fragments, areCTags, areNTags)
#write to a genbank file
write2gb(fragments)
print("You can find information on the manual on what to do next.")
print("https://casdesigner.jbei.org/static/cassette/casdesigner-manual.pdf")
def editEmpty():
# I have an excel file where we keep cut site information
# and load it as a pandas dataframe called cutFrame
cutFrame = pd.read_excel("locusTable.xlsx", index_col="cutName")
#print(cutFrame)
#LocusPic=Image("LocusLevelExp.png")
#display(LocusPic)
cutName=input("WHICH CUT SITE DO YOU WANT from the above list? e.g., \"208a\":")
# cutName is a string that should correspond to one of the variables
# of the "cutName" column in dataFrame, e.g., 208a
# cutFrame has the 20nt sequence of the gRNA saved, which we load
# It also has some more information we'll get to later
cutSequence=cutFrame.loc[cutName,'cutSequence']
# We need to load the chromosome where the cut site is
location=cutFrame.loc[cutName,'cutChr']+".fasta"
ChromosomeSeq=SeqIO.read(location, "fasta").seq
if ChromosomeSeq.find(cutSequence)==-1:
ChromosomeSeq=ChromosomeSeq.reverse_complement()
if ChromosomeSeq.find(cutSequence)==-1:
print("CAN'T FIND THE CUT SITE IN YOUR SEQUENCE")
StartIndex=ChromosomeSeq.find(cutSequence)
EndIndex=StartIndex+20+Post20merLength
UpSeq=ChromosomeSeq[StartIndex-HomologyLength:StartIndex]
DownSeq=ChromosomeSeq[EndIndex:EndIndex+HomologyLength]
UpHomRec = SeqRecord(UpSeq, name="up"+cutName)
DownHomRec = SeqRecord(DownSeq, name="dn"+cutName)
print("\n\n\n\nWhat do you want to do to " + cutName + "?\n")
print("\t1\t You have a CDS but want help picking promoter and terminator\n")
print("\t2\t You already have a one-piece cassette and just want to integrate it\n\n")
# Coming later
# print("\t3\t You want to construct a donor containing two standard cassettes (pointing away from each other\n")
areNTags = []
areCTags = []
typeEdit=input("Your answer: ")
if typeEdit=="1":
cassette, areCTags, areNTags = buildCassette()
areNTags = list(map(lambda x: x+1, areNTags))
areCTags = list(map(lambda x: x+1, areCTags))
fragments = [UpHomRec] + cassette + [DownHomRec]
elif typeEdit == "2":
orfName=input("What's the name of your custom gene or cassette?")
orfSeq=Seq(input("What's the sequence? "))
orfRecord=SeqRecord(orfSeq,name=orfName)
fragments=[UpHomRec, orfRecord, DownHomRec]
elif typeEdit == "3":
print("Your construct will look like this: ")
print("up hom-<terminator1-gene1-promoter1<->promoter2-gene2-terminator2>-downhom")
print("OK, let's build your FIRST cassette")
PromoterRec1, orfRecord1, TerminatorRec1 = buildCassette()
#now in the construction, these will be in the antisense direction, so let's change their sequences
rTerminatorRec1=flipRecord(TerminatorRec1)
rorfRecord1=flipRecord(orfRecord1)
rPromoterRec1=flipRecord(PromoterRec1)
print("OK, let's build your SECOND cassette")
PromoterRec2, orfRecord2, TerminatorRec2 = buildCassette()
fragments=[UpHomRec, rTerminatorRec1, rorfRecord1, rPromoterRec1,PromoterRec2,orfRecord2, TerminatorRec2,DownHomRec]
return fragments, areCTags, areNTags
print("\n\n\n\n\n\n\n\n")
def editExisting():
print(" ")
print("WHICH GENE DO YOU WANT TO EDIT? Tell me a common name, e.g., \"OAF1\"")
print("I'm smart and pretty and I can fetch it for you.\n")
GeneName= input("Your answer: ")
OrigGeneRecord=fetchGene(GeneName)
# note that this returns a seqrecord
print("\nI found "+GeneName+", "+OrigGeneRecord.description+".")
dice=random.random()
if dice>.38:
dice2=random.random()
if dice2>.3:
print("\nI have a good feeling about this one.")
else:
print("\nI like it.")
else:
dice2=random.random()
if dice2>.3:
print("\nInteresting choice.")
else:
print("\nI don't think this will work out well for you but let's proceed.")
# We make seqrecords since that's what we carry through later in the program
UpHomRec = fetchNeighbor(OrigGeneRecord, "upstream", HomologyLength )
UpHomRec.name="up"+UpHomRec.name
DownHomRec = fetchNeighbor(OrigGeneRecord, "downstream", HomologyLength )
DownHomRec.name="dn"+DownHomRec.name
print("\n\n\n\nWHAT DO YOU WANT TO DO TO " + GeneName + "?\n")
print("\t1\t DELETE the CDS cleanly (from start to stop codon)\n")
print("\t2\t replace the CDS with another CDS (or custom one-piece cassette)\n")
print("\t3\t replace the CDS with a standard cassette (I will help you build it)\n")
#print("\t4\t replace a specified region near your target gene with another specified region\n")
typeEdit=input("Your answer: ")
# Now let's pick the cut site. This is independent from the donor cassette
# We have an excel sheet with genes and pre-picked cut sites
# Or let the user pick
#print("\n\n\n\nHave you heard of CRISPR/Cas9? We will need a gRNA targeting "+GeneName+".")
#cutSequence=input("Please enter your 20-nt gRNA here.\n")
areNTags = []
areCTags = []
#note that in all the below, we want to have fragments be records
if typeEdit=="1":
fragments=[UpHomRec,DownHomRec]
if typeEdit=="2":
print(" ")
NewGeneName=input("\n\n\n\nWhat's the name of the gene you're inserting?")
NewGeneSeq=Seq(input("\n\n\n\nWhat's the sequence of your new gene? "))
InsertRec = SeqRecord(NewGeneSeq, name=NewGeneName)
fragments=[UpHomRec, InsertRec, DownHomRec]
if typeEdit=="3":
cassette, areNTags, areCTags = buildCassette()
areNTags = list(map(lambda x: x+1, areNTags))
areCTags = list(map(lambda x: x+1, areCTags))
fragments=[UpHomRec] + cassette + [DownHomRec] #we need to finish buildcassette to add InsertRec here
if typeEdit=="4":
print("How many pieces (other than homology fragments) are you stitching together.")
Npieces=input("Your answer: ")
output = buildCassette()
fragments=[UpHomRec, DownHomRec] #we need to finish buildcassette to add InsertRec here
print("\n\n\n\nHave you heard of CRISPR? We will need a guideRNA. In the future I will help you pick it.")
cutChoice=input("Please enter your 20-nt gRNA here.\n")
if cutChoice=="p":
cutSequence=cutFinder(GeneName)
elif len(cutChoice)==20:
cutSequence=cutChoice
else:
cutSequence = 'NNNNNNNNNNNNNNNNNNNN'
# Later should check that the sequence is present and unique
return fragments, areNTags, areCTags
# Now we feed the design to a tool to pick primers which amplify each fragment
# and add terminal homology to the neighboring fragments
def buildCustom():
N = int(input("How many pieces in your custom cassette: "))
return variableCassette(N)[0]
#------------------------------ FETCH FUNCTIONS -------------------------------------
def fetchGene(GeneName):
#let's create a record for the oldGene
DesiredSeq = sg.gene[GeneName].cds.seq
GeneRecord = SeqRecord(DesiredSeq, name=GeneName)
#now let's add some more information to make it useful
GeneRecord.features=str(sg.gene[GeneName])[-7:]
GeneRecord.description=sg.gene[GeneName].short_description
return GeneRecord
def fetchNeighbor(NeighborRecord, direction, distance):
# let's load the appropriate chromosome file. The record of the gene we looked up
# contains in the "features" the systematic name, wherein the second letter
# corresponds to chromosome number, e.g., 1=A etc
if NeighborRecord.features[1]=="A":
ChromosomeRec=SeqIO.read("Scer01.fasta", "fasta")
if NeighborRecord.features[1]=="B":
ChromosomeRec=SeqIO.read("Scer02.fasta", "fasta")
if NeighborRecord.features[1]=="C":
ChromosomeRec=SeqIO.read("Scer03.fasta", "fasta")
if NeighborRecord.features[1]=="D":
ChromosomeRec=SeqIO.read("Scer04.fasta", "fasta")
if NeighborRecord.features[1]=="E":
ChromosomeRec=SeqIO.read("Scer05.fasta", "fasta")
if NeighborRecord.features[1]=="F":
ChromosomeRec=SeqIO.read("Scer06.fasta", "fasta")
if NeighborRecord.features[1]=="G":
ChromosomeRec=SeqIO.read("Scer07.fasta", "fasta")
if NeighborRecord.features[1]=="H":
ChromosomeRec=SeqIO.read("Scer08.fasta", "fasta")
if NeighborRecord.features[1]=="I":
ChromosomeRec=SeqIO.read("Scer09.fasta", "fasta")
if NeighborRecord.features[1]=="J":
ChromosomeRec=SeqIO.read("Scer10.fasta", "fasta")
if NeighborRecord.features[1]=="K":
ChromosomeRec=SeqIO.read("Scer11.fasta", "fasta")
if NeighborRecord.features[1]=="L":
ChromosomeRec=SeqIO.read("Scer12.fasta", "fasta")
if NeighborRecord.features[1]=="M":
ChromosomeRec=SeqIO.read("Scer13.fasta", "fasta")
if NeighborRecord.features[1]=="N":
ChromosomeRec=SeqIO.read("Scer14.fasta", "fasta")
if NeighborRecord.features[1]=="O":
ChromosomeRec=SeqIO.read("Scer15.fasta", "fasta")
if NeighborRecord.features[1]=="P":
ChromosomeRec=SeqIO.read("Scer16.fasta", "fasta")
# let's explicitely name the sequences from the seq record
NeighborSeq=NeighborRecord.seq
ChromosomeSeq=ChromosomeRec.seq
# flip the sequence to orient with respect to the old gene
if ChromosomeSeq.find(NeighborSeq)==-1:
ChromosomeSeq=ChromosomeSeq.reverse_complement()
StartIndex=ChromosomeSeq.find(NeighborSeq)
EndIndex=StartIndex+len(NeighborSeq)
if direction=="upstream":
DesiredSeq=Seq(str(ChromosomeSeq[StartIndex-distance:StartIndex]),IUPAC.unambiguous_dna)
NeighborRec=SeqRecord(DesiredSeq, name=NeighborRecord.name)
if direction=="downstream":
DesiredSeq=Seq(str(ChromosomeSeq[EndIndex:EndIndex+distance]),IUPAC.unambiguous_dna)
NeighborRec=SeqRecord(DesiredSeq, name=NeighborRecord.name)
return NeighborRec
#------------------------------------ CONSTRUCTING STUFF --------------------------------------
def getPrimer(currRecord):
mp = 0
length = 0
primer = Seq("")
seq=currRecord.seq
while mp <= PrimerMaxTm and length < PrimerMaxLen:
primer = primer + seq[length]
mp = MeltingTemp.Tm_staluc(primer)
length += 1
return primer
def overhangPrimer(currRecord,prevSeq, linker = ""):
#let's get the template-binding primer first
primer=getPrimer(currRecord)
#OK let's work on the overhang
maxOhLen=PrimerMaxLen-len(primer)
maxFrac=1
#let's decide on a max overhang length
if round(len(primer)*(OverhangMaxFrac+1)) < 60:
maxOhLen=round(len(primer)*OverhangMaxFrac)
#the index must be an integer!!!
maxOhLen=int(maxOhLen)
ohprimer=prevSeq.seq[-maxOhLen:]+ linker + primer #we add the .seq so that it returns a string
if len(ohprimer)>60:
ohprimer=ohprimer[-60:]
return ohprimer
def buildCassette():
def removeStartCodon(CDS):
# this alternate method would be useful for error handling
# i = CDS.find('ATG')
# return (CDS[:i], CDS[:i])
return (CDS[:3], CDS[3:])
def removeStopCodon(CDS):
#this alternate method would be useful for error handling
# stops = ['TAG', 'TAA', 'TAG']
# for codon in stops:
# i = CDS.rfind(codon)
# print(i)
# if i != -1:
# return (CDS[:i], CDS[:i])
l = len(CDS)
return (CDS[:l - 3], CDS[l - 3:])
# Let's display data
#PromPic=Image("PromoterLevelExp.png")
#display(PromPic)
PromoterName=input("Which PROMOTER do you want to use, e.g., \"TDH3\": ")
PromoterGeneRec=fetchGene(PromoterName)
PromoterRec=fetchNeighbor(PromoterGeneRec,"upstream",600)
PromoterRec.name=PromoterRec.name+"ps"
#second, the terminator
TerminatorName = input("\n\n\n\nWhich TERMINATOR do you want to use, e.g., \"ADH1\": ")
TerminatorGeneRec=fetchGene(TerminatorName)
TerminatorRec=fetchNeighbor(TerminatorGeneRec,"downstream",250)
TerminatorRec.name=TerminatorRec.name+"ts"
#and last, the gene
orfName = input("\n\n\n\nWhat is the name of your CDS, e.g., \"KlGapDH\": ")
orfSeq=input("\n\n\n\nWhat's the sequence: ")
#LocTags=Image("LocTags.png")
#display(LocTags)
def makeTags(text):
if text in validTags():
return SeqRecord(Seq(tagFinder(text)), name = text+"tag")
else:
n, s = text.split()
return SeqRecord(Seq(s), name = n+"tag")
nTerminalTags = input("Would you like to add an N-TERMINAL PROTEIN TAG? \n*If you don't want a tag, leave blank\n*If you want one of the tags I know, type it's name, e.g. \"MBP\"\n*If you want multiple tags seperate with commas\nIf you want a custom tag type its name followed by a space then the sequence; no commas.")
nTerminalTags = nTerminalTags.split(',')
nTerminalTags = list(filter(None, map(lambda x: x.strip(), nTerminalTags)))
cTerminalTags = input("Would you like to add a C-TERMINAL PROTEIN TAG? \n*If you don't want a tag, leave blank\n*If you want one of the tags I know, type it's name, e.g. \"MBP\"\n*If you want multiple tags seperate with commas\nIf you want a custom tag type its name followed by a space then the sequence; no commas.")
cTerminalTags = cTerminalTags.split(',')
cTerminalTags = list(filter(None, map(lambda x: x.strip(), cTerminalTags)))
nTerminals = len(nTerminalTags)
cTerminals = len(cTerminalTags)
if nTerminals > 0:
nTerminalTags = list(map(makeTags, nTerminalTags))
start, orfSeq = removeStartCodon(orfSeq)
nTerminalTags[0] = start + nTerminalTags[0]
if cTerminals > 0:
cTerminalTags = list(map(makeTags, cTerminalTags))
orfSeq, stop = removeStopCodon(orfSeq)
cTerminalTags[cTerminals-1] += stop
areNTags = [i + 1 for i in range(nTerminals)]
areCTags = [i + 2 + nTerminals for i in range(cTerminals)]
orfRecord=SeqRecord(Seq(orfSeq), name=orfName)
return ([PromoterRec] + nTerminalTags + [orfRecord] + cTerminalTags + [TerminatorRec], areNTags, areCTags)
def variableCassette(N, toVary = 0, variants = 0):
print("")
print("Let's start building.")
print("")
# Store both name and sequence in a SeqRecord
# Append them to a list
# Return list as fragments to be stitched
records = []
for n in range(N):
name = input("What is the name of sequence " + str(n+1) +":")
sequence = input("What is the sequence of this fragment:\n")
Rec = SeqRecord(Seq(sequence), id = str(n+1))
Rec.name = name
records.append(Rec)
variantRecords = []
variantRecords.append(records)
# This only happens if there are variants.
if variants > 0:
print("Time to make those variants you wanted.")
for n in range(variants-1):
name = input("What is the name of variant " + str(n+1) + ":")
sequence = input("What is the sequence of this variant:")
Rec = SeqRecord(Seq(sequence), id = str(n+1))
Rec.name = name
# Make a copy of the original, switch the fragments and add it to the list.
# Deep-copy ensures there are no pointer issues
tempVariant = copy.deepcopy(records)
tempVariant[toVary - 1] = Rec
variantRecords.append(copy.deepcopy(tempVariant))
# Returns a list of lists of the SeqRecords of the fragments
return variantRecords
def stitch(fragments, areNTags = [], areCTags = []):
#this function takes seq records and prints primers
#let's make an empty sequence file
Nfrags=len(fragments)
donor=Seq("")
index=[]
print("\n\n\n\nHere are the primers to amplify your fragments and construct your donor DNA cassette:\n")
for i in range (0, Nfrags):
if i in areCTags:
#add the linker before bin
donor += SeqRecord(cLinker, name="cLinker")
donor=donor+fragments[i]
if i in areNTags:
#add linker after bin
donor += SeqRecord(nLinker, name="nLinker")
start = Seq("")
stop = Seq("")
# The names include information on
# the homology provided by the overhang
# Note that some primers don't have overhangs
for i in range (0, Nfrags):
FLinker = ""
RLinker = ""
# this section treats the start and stop codons as linkers that need to be primer-introduced if tags are used
if i + 1 in areNTags and i not in areNTags:
#add start codon to reverse primer
start = fragments[i+1][:3].seq
fragments[i+1] = fragments[i+1][3:]
RLinker = start.reverse_complement()
if i in areNTags and i-1 not in areNTags:
#add start codon to forward primer
FLinker = start
if i in areCTags and i+1 not in areCTags:
#add a stop codon to the reverse primer
l = len(fragments[i])
stop = fragments[i][l-3:].seq
fragments[i] = fragments[i][:l-3]
RLinker = stop.reverse_complement()
if i-1 in areCTags and i not in areCTags:
FLinker = stop
#this section introduces the protein linkers for tags
if i in areNTags:
# reverse primer will need a liniker
RLinker = nLinker.reverse_complement()
if i-1 in areNTags:
# forward primer will need a linker
FLinker = nLinker
if i+1 in areCTags:
# reverse primer will need a linker
RLinker = cLinker.reverse_complement()
if i in areCTags:
# forward primer will need a linker
FLinker = cLinker
if len(FLinker)>60:
FLinker=FLinker[-60:]
if len(RLinker)>60:
RLinker=RLinker[-60:]
if i==0:
print("F"+ fragments[i].name + " " + getPrimer(donor))
print("R"+ fragments[i].name + "(" + fragments[i+1].name + ") " + overhangPrimer(fragments[i].reverse_complement(),fragments[i+1].reverse_complement(), RLinker))
elif i==Nfrags-1:
print("F"+ fragments[i].name + "(" + fragments[i-1].name + ") " + overhangPrimer(fragments[i],fragments[i-1], FLinker))
print("R"+ fragments[i].name + " " + getPrimer(donor.reverse_complement()))
else:
print("F"+ fragments[i].name + "(" + fragments[i-1].name + ") " + overhangPrimer(fragments[i],fragments[i-1], FLinker))
print("R"+ fragments[i].name + "(" + fragments[i+1].name + ") " + overhangPrimer(fragments[i].reverse_complement(),fragments[i+1].reverse_complement(), RLinker))
print("\n\nThe size and sequence of your donor DNA is below.")
print(len(donor.seq))
print(donor.seq)
print("\n\n\n\nGOOD LUCK! Refer to the this link for user guide, feedback, and community tips.")
print("https://docs.google.com/document/d/11YNoUBtit4rkWZQr_ZclzAOTE_HGMtgB3H_6cvq1Y24/edit?usp=sharing\n")
def write2gb(fragments):
# This function takes the seqRecord fragments, which contains records for every fragment, and writes and annotates a genbank file.
Nfrags=len(fragments)
AnnotatedDonorSeq=Seq("", IUPAC.unambiguous_dna) #donor is of seq class.
start_index=0
AnnotatedDonorRecord=SeqRecord(AnnotatedDonorSeq)
for i in range (0, Nfrags):
AnnotatedDonorRecord.seq=AnnotatedDonorRecord.seq+Seq(str(fragments[i].seq), IUPAC.unambiguous_dna) #convert fragment to string then to unambiguous_dna alphabet
end_index=start_index+len(fragments[i])
#print("start and stop at "+str(start_index)+", "+str(end_index))
if fragments[i].name[0:2] == "up":
upstream_homology = SeqFeature(FeatureLocation(start_index, end_index), type="homology_region", strand=+1)
upstream_homology.qualifiers["name"] = fragments[i].name
upstream_homology.qualifiers["source"] = "BY4742 genomic DNA"
AnnotatedDonorRecord.features.append(upstream_homology)
elif fragments[i].name[0:2] == "dn":
downstream_homology = SeqFeature(FeatureLocation(start_index, end_index), type="homology_region", strand=+1)
downstream_homology.qualifiers["name"] = fragments[i].name
downstream_homology.qualifiers["source"] = "BY4742 genomic DNA"
AnnotatedDonorRecord.features.append(downstream_homology)
elif fragments[i].name[-3:] == "tag":
protein_tag = SeqFeature(FeatureLocation(start_index, end_index), type="protein_tag", strand=+1)
protein_tag.qualifiers["name"] = fragments[i].name
protein_tag.qualifiers["source"] = "BY4742 genomic DNA"
AnnotatedDonorRecord.features.append(protein_tag)
elif fragments[i].name[-2:] == "ps":
promoter = SeqFeature(FeatureLocation(start_index, end_index), type="promoter", strand=+1)
promoter.qualifiers["name"] = fragments[i].name
promoter.qualifiers["source"] = "BY4742 genomic DNA"
AnnotatedDonorRecord.features.append(promoter)
elif fragments[i].name[-2:] == "ts":
terminator = SeqFeature(FeatureLocation(start_index, end_index), type="terminator", strand=+1)
terminator.qualifiers["name"] = fragments[i].name
terminator.qualifiers["source"] = "BY4742 genomic DNA"
AnnotatedDonorRecord.features.append(terminator)
else:
CDS = SeqFeature(FeatureLocation(start_index, end_index), type="CDS", strand=+1)
CDS.qualifiers["name"] = fragments[i].name
CDS.qualifiers["source"] = "Custom template"
AnnotatedDonorRecord.features.append(CDS)
start_index=end_index
SeqIO.write(AnnotatedDonorRecord, "CASdesigner_Output.gb", "genbank")
def flipRecord(origRecord):
origRecord.seq=origRecord.seq.reverse_complement()
origRecord.name="r"+origRecord.name
return origRecord
def cutFinder(GeneName):
cutFrame = pd.read_excel("cutsTable.xlsx", index_col="cutName")
# cutFrame has the 20nt sequence of the gRNA saved, which we load
# It also has some more information we'll get to later
cutSequence=cutFrame.loc[GeneName,'cutSequence']
print("\nI picked the following cut site for you "+cutSequence)
return cutSequence
def validTags():
tagFrame = pd.read_excel("ProteinTags.xlsx")
return tagFrame["tagName"].tolist()
def tagFinder(tagName):
tagFrame = pd.read_excel("ProteinTags.xlsx", index_col="tagName")
sequence = tagFrame.loc[tagName,'sequence']
return sequence
askUser()
'''
Hold on a moment, it's working...
The interface should appear below momentarily.
'''
In [ ]: