diff --git a/HEADER b/HEADER
index 6d61fb3..dc43bfc 100755
--- a/HEADER
+++ b/HEADER
@@ -1,16 +1,15 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
+# along with saddle-bags. If not, see .
-# Version 1.0
diff --git a/MakeExecutables.bat b/MakeExecutables.bat
index db32d1d..68cbe52 100755
--- a/MakeExecutables.bat
+++ b/MakeExecutables.bat
@@ -1,17 +1,17 @@
-:: This file is part of EMBL-HLA-Submission.
+:: This file is part of saddle-bags.
::
-:: EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+:: saddle-bags is free software: you can redistribute it and/or modify
:: it under the terms of the GNU Lesser General Public License as published by
:: the Free Software Foundation, either version 3 of the License, or
:: (at your option) any later version.
::
-:: EMBL-HLA-Submission is distributed in the hope that it will be useful,
+:: saddle-bags is distributed in the hope that it will be useful,
:: but WITHOUT ANY WARRANTY; without even the implied warranty of
:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
:: GNU Lesser General Public License for more details.
::
:: You should have received a copy of the GNU Lesser General Public License
-:: along with EMBL-HLA-Submission. If not, see .
+:: along with saddle-bags. If not, see .
:: Version 1.0
diff --git a/MakeExecutables.sh b/MakeExecutables.sh
index 1e83bbe..364309b 100755
--- a/MakeExecutables.sh
+++ b/MakeExecutables.sh
@@ -1,19 +1,18 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
+# along with saddle-bags. If not, see .
-# Version 1.0
# This isn't working in it's current state. The spec file is apparently just for windows,
# it's still pulling in windows DLLs.
diff --git a/Run_allele_submission.bat b/Run_allele_submission.bat
index a7152a8..b893555 100755
--- a/Run_allele_submission.bat
+++ b/Run_allele_submission.bat
@@ -1,21 +1,21 @@
-:: This file is part of EMBL-HLA-Submission.
+:: This file is part of saddle-bags.
::
-:: EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+:: saddle-bags is free software: you can redistribute it and/or modify
:: it under the terms of the GNU Lesser General Public License as published by
:: the Free Software Foundation, either version 3 of the License, or
:: (at your option) any later version.
::
-:: EMBL-HLA-Submission is distributed in the hope that it will be useful,
+:: saddle-bags is distributed in the hope that it will be useful,
:: but WITHOUT ANY WARRANTY; without even the implied warranty of
:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
:: GNU Lesser General Public License for more details.
::
:: You should have received a copy of the GNU Lesser General Public License
-:: along with EMBL-HLA-Submission. If not, see .
+:: along with saddle-bags. If not, see .
:: Version 1.0
:: See the file README.MD for how to set up your anaconda environment.
-activate AlleleSubEnvironment && cd src && python AlleleSubmissionEMBL.py && deactivate
+activate AlleleSubEnvironment && cd src && python AlleleSubmissionMain.py && deactivate
diff --git a/Run_allele_submission.sh b/Run_allele_submission.sh
index b8f9331..3da7d12 100755
--- a/Run_allele_submission.sh
+++ b/Run_allele_submission.sh
@@ -1,19 +1,17 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
-
-# Version 1.0
+# along with saddle-bags. If not, see .
# See the file README.MD for how to set up your anaconda environment.
diff --git a/src/AlleleGuiEMBL.py b/src/AlleleGuiEMBL.py
index 38dfe0e..8737461 100755
--- a/src/AlleleGuiEMBL.py
+++ b/src/AlleleGuiEMBL.py
@@ -1,17 +1,17 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
+# along with saddle-bags. If not, see .
import os
@@ -24,7 +24,7 @@
import gzip
import shutil
#import pycurl
-import requests
+#import StringIO
import Tkinter, Tkconstants, tkFileDialog, tkMessageBox
from Tkinter import *
@@ -33,6 +33,7 @@
from AlleleGuiEMBLInputForm import AlleleGuiEMBLInputForm
from AlleleSubCommon import *
from AlleleSubmissionEMBLXml import *
+from AlleleSubmissionEMBLRestMethods import *
#from HLAGene import HLAGene
# The AlleleGui class is an extension of Tkinter. The GUI elements and interactions are specified in this class.
@@ -182,9 +183,42 @@ def writeMd5(self, inputFileName, outputFileName):
# I don't know why 2 spaces, but I'll roll with it.
outputFile.write(str(hashValue) + ' ' + str(split(inputFileName)[1]))
outputFile.close()
+
+ return hashValue
+
+
+
def uploadSubmission(self):
print('Uploading Submission to EMBL')
+
+ # Determine a working directory. Folder underneath executable called temp.
+ try:
+ workingDirectory = join(expanduser("~"), 'temp_upload_directory')
+ print('I can work in this directory:' + workingDirectory)
+
+ if not isdir(workingDirectory):
+ print('Making Directory:' + workingDirectory)
+ makedirs(workingDirectory)
+ except Exception:
+ print 'Cannot Initialize Working Directory'
+ print sys.exc_info()[1]
+ tkMessageBox.showinfo('Working Directory Error',
+ 'Sorry, I failed to create this working directory:\n'
+ + str(workingDirectory)
+ + '\n and I cannot continue.\nMaybe this is a '
+ + 'permissions issue, are these folders read only?\n'
+ + str(sys.exc_info()[1]))
+ return
+
+ restLog = createOutputFile(join(workingDirectory, 'Submission_Log.txt'))
+
+
+
+ # TODO: Make a REST log.
+ # For each step report success or failure. Same as popup messages.
+
+
emblUsername = getConfigurationValue('embl_username')
emblPassword = getConfigurationValue('embl_password')
@@ -195,14 +229,19 @@ def uploadSubmission(self):
tkMessageBox.showinfo('Missing Login Credentials',
'You must provide EMBL username and password.\n'
'Please use the "Submission Options" button.')
+ restLog.write('Missing EMBL Username or Password.' + '\n')
return
+ else:
+ restLog.write('EMBL Username and Password exist.' + '\n')
useTestServers = (int(getConfigurationValue('test_submission')) == 1)
# Are you sure?
if useTestServers:
+ restLog.write('Using Test EMBL Server.' + '\n')
result = tkMessageBox.askquestion("Submit to TEST / DEMO environment", "You are about to submit a sequence to the\n\nTEST / DEMO EMBL environment.\n\nAre You Sure?", icon='warning')
else:
+ restLog.write('Using Production EMBL Server.' + '\n')
result = tkMessageBox.askquestion("Submit to LIVE / PROD environment", "You are about to submit a sequence to the\n\nLIVE / PROD EMBL environment.\n\nAre You Sure?", icon='warning')
if result == 'yes':
@@ -212,47 +251,20 @@ def uploadSubmission(self):
# TODO: Existing project? Maybe I should check if the study/project exists, before I get started
-
-
-
- # Determine a working directory. Folder underneath executable called temp.
- try:
- workingDirectory = join(expanduser("~"), 'temp_upload_directory')
- print('I can work in this directory:' + workingDirectory)
-
- if not isdir(workingDirectory):
- print('Making Directory:' + workingDirectory)
- makedirs(workingDirectory)
- except Exception:
- print 'Cannot Initialize Working Directory'
- print sys.exc_info()[1]
- tkMessageBox.showinfo('Working Directory Error',
- 'Sorry, I failed to create this working directory:\n'
- + str(workingDirectory)
- + '\n and I cannot continue.\nMaybe this is a '
- + 'permissions issue, are these folders read only?\n'
- + str(sys.exc_info()[1]))
- return
+
+
# Give my submission a filename. SOmething with a datetime stamp
try:
# This includes a "seconds" measure, should be pretty unique.
dateTimeNow = '{:%Y_%m_%d_%H_%M_%S}'.format(datetime.datetime.now())
- submissionFileName = join(workingDirectory, 'HLA_Submission_' + dateTimeNow + '.txt')
+ submissionShortFileName = 'HLA_Submission_' + dateTimeNow + '.txt'
+ submissionFileName = join(workingDirectory, submissionShortFileName)
+ zippedShortFileName = submissionShortFileName + '.gz'
+ zippedFileName = join(workingDirectory, zippedShortFileName)
+ md5FileName = zippedFileName + '.md5'
- except Exception:
- print 'Cannot Assign File Name'
- print sys.exc_info()[1]
- tkMessageBox.showinfo('File Name Error',
- 'Sorry, I failed to create this file:\n'
- + str(submissionFileName)
- + '\n and I cannot continue.\n'
- + str(sys.exc_info()[1]))
- return
-
- # Write submission to a file
- try:
submissionText = self.submOutputGuiObject.get('1.0', 'end')
outputFileObject = open(submissionFileName, 'w')
@@ -268,11 +280,14 @@ def uploadSubmission(self):
+ '\n and I cannot continue.\nMaybe this is a '
+ 'permissions issue, are these folders read only?\n'
+ str(sys.exc_info()[1]))
+ restLog.write('Failure to create submission file:' + str(sys.exc_info()[1]) + '\n')
return
+ restLog.write('Submission file was created:' + str(submissionFileName) + '\n')
+
# gzip the submission file. Make a gz file.
try:
- zippedFileName = submissionFileName + '.gz'
+ #zippedFileName = submissionFileName + '.gz'
with open(submissionFileName, 'rb') as fileIn, gzip.open(zippedFileName, 'wb') as fileOut:
shutil.copyfileobj(fileIn, fileOut)
@@ -285,12 +300,15 @@ def uploadSubmission(self):
+ str(zippedFileName)
+ '\n and I cannot continue.\n'
+ str(sys.exc_info()[1]))
+ restLog.write('Failure to create zip file:' + str(sys.exc_info()[1]) + '\n')
return
+ restLog.write('Zip file was created:' + str(zippedFileName) + '\n')
+
# Calculate an MD5SUM
try:
- md5FileName = zippedFileName + '.md5'
- self.writeMd5(zippedFileName,md5FileName)
+ #md5FileName = zippedFileName + '.md5'
+ md5HashValue = self.writeMd5(zippedFileName,md5FileName)
except Exception:
print 'Cannot Calculate MD5'
@@ -298,7 +316,10 @@ def uploadSubmission(self):
tkMessageBox.showinfo('Cannot Calculate an Md5 checksum',
'Sorry, I failed to calculate an md5 checksum\nand I cannot continue.\n'
+ str(sys.exc_info()[1]))
+ restLog.write('Failure to create zip file:' + str(sys.exc_info()[1]) + '\n')
return
+
+ restLog.write('md5 file was created:' + str(md5FileName) + '\n')
# Use FTP to send the file to EMBL
try:
@@ -321,12 +342,10 @@ def uploadSubmission(self):
tkMessageBox.showinfo('Cannot Upload to FTP site',
'Sorry, I failed to upload your submission files to the EMBL FTP site\nand I cannot continue.\n'
+ str(sys.exc_info()[1]))
+ restLog.write('Failure to upload to FTP site:' + str(sys.exc_info()[1]) + '\n')
return
-
- # TODO: I Need a center_name. This is based on the username but it goes into these submissions.
- # Maybe I can get that from REST
-
+ restLog.write('Submission and MD5 successfully uploaded.\n')
# Handle the new project
# effectively, study = project
@@ -337,17 +356,15 @@ def uploadSubmission(self):
# Generate Project and Project Submission XML Files
try:
projectFileName = join(workingDirectory, 'project.xml')
- projectText = createProjectXML(projectFileName
- , getConfigurationValue('study_name')
- , getConfigurationValue('study_description')
- , getConfigurationValue('study_abstract'))
+ projectText = createProjectXML(projectFileName)
- projectSubFileName = join(workingDirectory, 'project_submission.xml')
- projectSubmissionText = createProjectSubmissionXML('proj_sub_' + dateTimeNow
- , projectSubFileName)
+ projectSubmissionFileName = join(workingDirectory, 'project_submission.xml')
+ projectSubmissionText = createProjectSubmissionXML(projectSubmissionFileName
+ ,'proj_sub_' + dateTimeNow
+ ,'project.xml')
- print('I made this project text:\n' + projectText)
- print('I made this project submission text:\n' + projectSubmissionText)
+ #print('I made this project text:\n' + projectText)
+ #print('I made this project submission text:\n' + projectSubmissionText)
except Exception:
print 'Cannot Create Project Submission XML'
@@ -355,84 +372,32 @@ def uploadSubmission(self):
tkMessageBox.showinfo('Cannot Create Project Submission XML',
'Sorry, I failed to create a project XML file\nand I cannot continue.\n'
+ str(sys.exc_info()[1]))
+ restLog.write('Failure to create project submission file:' + str(sys.exc_info()[1]) + '\n')
return
+
+ restLog.write('Project Submission XML files were created.\n')
# Use REST to submit this project
try:
- #"https://www-test.ebi.ac.uk/ena/submit/drop-box/submit/?auth=ENA%20Webin-NNN%20PASSWORD"
- requestURL = (getConfigurationValue('embl_rest_address_test')
- + '?auth=ENA%20'
- + getConfigurationValue('embl_username')
- + '%20'
- + getConfigurationValue('embl_password')
-
-
- )
-
-
- # So i keep getting 415 errors. Trying to figure out what's up with REST.
-
- print ('URL=\n'+str(requestURL))
- #auth=HTTPBasicAuth(getConfigurationValue('embl_username'), getConfigurationValue('embl_password'))
- #requestUser=(getConfigurationValue('embl_username'), getConfigurationValue('embl_password'))
- requestData = {'SUBMISSION':projectSubmissionText
- , 'PROJECT':projectText
- # ,'content-type':'text/xml'
- }
+ # Return value should be a tuple:
+ # (Success, ProjectAccession, Messages[])
+ (projectSubmissionSuccess, projectAccessionNumber, projectErrorMessages) = performProjectSubmission(projectSubmissionFileName,projectFileName)
- requestHeaders = {'content-type':'application/xml'
- # 'HTTP Name':'Content-Type'
-
- }
-
-
-
- postResponse = requests.post(
- requestURL
- , params=requestData
- , headers=requestHeaders
-
-# , auth=requestUser
- #, auth=(getConfigurationValue('embl_username'), getConfigurationValue('embl_password'))
- )
-
- print ('the post response object:\n' + str(postResponse))
-
- print ('response status:\n' + str(postResponse.status_code))
-
- print('response text:' + str(postResponse.text))
-
- print('response content:' + str(postResponse.content))
-
- print('is response okay?:' + str(postResponse.status_code == requests.codes.ok))
-
-
- # headers have the login credentials?
-
- # -k, --insecure Allow connections to SSL sites without certs (H)
- # -F, --form CONTENT Specify HTTP multipart POST data (H)
- # those login credentials are passed plain text in the URL? Why?
- #curl -k -F "SUBMISSION=@sub.xml" -F "PROJECT=@project.xml" "https://www-test.ebi.ac.uk/ena/submit/drop-box/submit/?auth=ENA%20Webin-NNN%20PASSWORD"
- #curl -k -F "SUBMISSION=@"$submissionFileName -F "PROJECT=@"$projectFileName $testEnaSite"?auth=ENA%20"$userName"%20"$password > curlProjResults.xml
-
-
- #data = ['SUBMISSION': '@projectSubFileName'
- # ,
- # 'tx': str(request.GET.get('tx')),
- # 'at': paypal_pdt_test
- # ]
-
- #post = urllib.urlencode(data)
-
- #c = pycurl.Curl()
- #if(useTestServers):
- #c.setopt(pycurl.URL, getConfigurationValue('embl_rest_address_test'))
- #c.setopt(pycurl.HTTPHEADER, ['X-Postmark-Server-Token: API_TOKEN_HERE','Accept: application/json'])
- #c.setopt(pycurl.POST, 1)
- #c.setopt(pycurl.POSTFIELDS, data)
-
- #print ('about to perform curl:' + str(c))
- #c.perform()
+ if(projectSubmissionSuccess):
+ # Great. The project was created successfully.
+ # Lets use this new study accession moving forward.
+ assignConfigurationValue('study_accession', projectAccessionNumber)
+ assignConfigurationValue('choose_project','1')
+ pass
+ else:
+ messageText = ('There was a problem in the Project Submission.\n'
+ + 'I cannot continue.\n'
+ + 'These messages were reported by EMBL:\n')
+ for errorMessage in projectErrorMessages:
+ messageText += ('\n' + errorMessage + '\n')
+ tkMessageBox.showinfo('Cannot Submit Project XML via REST', messageText)
+ restLog.write('Failure to submit project submission file:' + str(sys.exc_info()[1]) + '\n')
+ return
except Exception:
print 'Cannot Submit Project XML'
@@ -440,37 +405,86 @@ def uploadSubmission(self):
tkMessageBox.showinfo('Cannot Submit Project XML',
'Sorry, I failed to submit the project XML file\nand I cannot continue.\n'
+ str(sys.exc_info()[1]))
- return
-
- # Create a new project REST
- # Open Response, determine if success
-
- # If errors:
- # report Errors and give up
- # else:
- # store accession#
-
+ restLog.write('Failure to upload project submission file:' + str(sys.exc_info()[1]) + '\n')
+ return
- else: #(existing project)
+ restLog.write('New study has been uploaded, accession:' + str(getConfigurationValue('study_accession')) + '\n')
+
+ # existing project, we will use the supplied accession #
+ else:
+ restLog.write('Using existing study accession:' + str(getConfigurationValue('study_accession')) + '\n')
+ # projectAccessionNumber = getConfigurationValue('study_accession')
pass
-
- # else (existing project)
- # Store the project accession #
+ # Generate Analysis and Analysis Submission xmls
+ try:
+ analysisFileName = join(workingDirectory, 'analysis.xml')
+ analysisText = createAnalysisXML(analysisFileName, md5HashValue, zippedShortFileName)
+
+ analysisSubmissionFileName = join(workingDirectory, 'analysis_submission.xml')
+ analysisSubmissionText = createAnalysisSubmissionXML(analysisSubmissionFileName
+ ,'analysis_sub_' + dateTimeNow
+ ,'analysis.xml')
+
+ except Exception:
+ print 'Cannot Create Analysis Submission XML'
+ print sys.exc_info()[1]
+ tkMessageBox.showinfo('Cannot Create Analysis Submission XML',
+ 'Sorry, I failed to create a Analysis XML file\nand I cannot continue.\n'
+ + str(sys.exc_info()[1]))
+ restLog.write('Failure to create analysis submission file:' + str(sys.exc_info()[1]) + '\n')
+ return
- # Generate XML Files for new sequence
- # REST the new XML files over to them.
- # Open response determine if success?
- # Gather Important Accession Numbers
- # Store accession number in our config file
+ restLog.write('Analysis Submission XML files were created.\n')
+
+ # Use REST to submit this analysis
+ try:
+ # Return value should be a tuple:
+ # (Success, analysisAccessionNumber, Messages[])
+ (analysisSubmissionSuccess, analysisAccessionNumber, analysisErrorMessages) = performAnalysisSubmission(analysisSubmissionFileName,analysisFileName)
+
+ if(analysisSubmissionSuccess):
+ # Great. The analysis was created successfully.
+ pass
+ else:
+ messageText = ('There was a problem in the Analysis Submission.\n'
+ + 'I cannot continue.\n'
+ + 'These messages were reported by EMBL:\n')
+ for errorMessage in analysisErrorMessages:
+ messageText += ('\n' + errorMessage + '\n')
+ tkMessageBox.showinfo('Cannot Submit Analysis XML via REST', messageText)
+ restLog.write('Failure to submit analysis submission file:' + str(sys.exc_info()[1]) + '\n')
+ return
+
+ except Exception:
+ print 'Cannot Submit Analysis XML'
+ print sys.exc_info()[1]
+ tkMessageBox.showinfo('Cannot Submit Analysis XML via REST',
+ 'Sorry, I failed to submit the analysis XML file\nand I cannot continue.\n'
+ + str(sys.exc_info()[1]))
+ return
+
+ restLog.write('New analysis has been Uploaded, accession:' + str(analysisAccessionNumber) + '\n')
+
+ restLog.close()
+
# Popup message with Results
+ tkMessageBox.showinfo('Success uploading submission to EMBL.',
+ 'The sequence and analysis was uploaded to EMBL ENA Successfully.\n\n'
+ + 'For your reference:\n\n'
+ + 'You can use this Project/Study accession\nnumber on future submissions:\n'
+ + 'Study Accession:' + str(getConfigurationValue('study_accession') + '\n\n')
+ + 'Use the Analysis Accession number if you\ncontact EMBL regarding this\nsequence submission:\n'
+ + 'Analysis Accession:' + str(analysisAccessionNumber) + '\n\n'
+ + 'Find your submission files here:\n'
+ + workingDirectory + '\n\n'
+ + 'If EMBL successfully validates your sequence, you will\n'
+ + 'recieve an email with an EMBL Sequence accession number.\n'
+ + 'This *SEQUENCE* accession number is necessary for IMGT submission.\n'
+ + 'Contact EMBL Support with your\nAnalysis Accession # if it has been\nmore than 48 hours since submission.\n'
+
+ )
- tkMessageBox.showinfo('Success uploading submission.',
- 'Everything worked fine.\n'
- +'Congratulations. TODO: This message should have more information in it.')
-
-
-
def sampleSequence(self):
self.featureInputGuiObject.delete('1.0','end')
@@ -489,10 +503,14 @@ def sampleSequence(self):
assignConfigurationValue('choose_project','2')
- assignConfigurationValue('study_name','HLA_Analysis_Project')
- assignConfigurationValue('study_description','Our laboratory performs HLA typing for Research')
+ assignConfigurationValue('study_identifier','HLA_Analysis_Project')
+ assignConfigurationValue('study_short_title','HLA Typing for Cancer Research.')
assignConfigurationValue('study_abstract','An abstract is a more in-depth description of the nature of the research project.')
+ assignConfigurationValue('analysis_alias','unique_HLA_analysis_alias')
+ assignConfigurationValue('analysis_title','Novel HLA sequence from patient with Leukemia')
+ assignConfigurationValue('analysis_description','This is an HLA-A sequence from a patient. It was discovered that he has Leukemia, so we decided to sequence his HLA.')
+
self.constructSubmission()
# This method should popup some instruction text in a wee window.
@@ -547,7 +565,7 @@ def contactInformation(self):
+ 'm.tilanus@mumc.nl\n\n'
+ 'This code will be hosted at:\n'
- + 'https://github.com/transplantation-\nimmunology/EMBL-HLA-Submission\n'
+ + 'https://github.com/transplantation-\nimmunology/saddle-bags\n'
+ 'You will find more information on\n'
+ 'EMBL\'s data format on that page.'
@@ -578,12 +596,6 @@ def constructSubmission(self):
allGen = SubmissionGeneratorEMBL()
roughFeatureSequence = self.featureInputGuiObject.get('1.0', 'end')
- # TODO: I uncommented these, hope there is no problem.
- #allGen.inputSampleID = getConfigurationValue('sample_id')
- #allGen.inputGene = getConfigurationValue('gene')
- #allGen.inputAllele = getConfigurationValue('allele_name')
- #allGen.inputClass = getConfigurationValue('class')
-
allGen.sequenceAnnotation = annotateRoughInputSequence(roughFeatureSequence)
enaSubmission = allGen.buildENASubmission()
diff --git a/src/AlleleGuiEMBLInputForm.py b/src/AlleleGuiEMBLInputForm.py
index 1dd6b23..44fcbef 100755
--- a/src/AlleleGuiEMBLInputForm.py
+++ b/src/AlleleGuiEMBLInputForm.py
@@ -1,17 +1,17 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
+# along with saddle-bags. If not, see .
import os
@@ -32,21 +32,49 @@ def __init__(self, root):
# To define the exit behavior. Save and exit.
self.parent.protocol('WM_DELETE_WINDOW', self.saveOptions)
+
+ # Define the return behavior. Same as "close window" etc
+ root.bind('', self.returnFunction)
# This window should not be resizeable. I guess.
self.parent.resizable(width=False, height=False)
+ #Standard Inputs widths for the form elements
+ formInputWidth = 30
+ labelInputWidth = 30
+
self.instructionsFrame = Tkinter.Frame(self)
self.instructionText = Tkinter.StringVar()
- self.instructionText.set('\nThese options are required for an EMBL allele submission.\n'
- + 'Login Credentials will not be stored, but they will be sent to EMBL via\n'
- + 'secure https connection.\n')
- Tkinter.Label(self.instructionsFrame, width=85, height=6, textvariable=self.instructionText).pack()
+ self.instructionText.set('\nThese options are required for an EMBL allele submission.\n')
+ Tkinter.Label(self.instructionsFrame, width=85, height=3, textvariable=self.instructionText).pack()
self.instructionsFrame.pack()
- #Standard Inputs widths for the form elements
- formInputWidth = 30
- labelInputWidth = 30
+ self.submissionDetailsInputFrame2 = Tkinter.Frame(self)
+
+ self.sampleIDInstrText = Tkinter.StringVar()
+ self.sampleIDInstrText.set('Sample ID:')
+ self.sampleIDinstrLabel = Tkinter.Label(self.submissionDetailsInputFrame2, width=labelInputWidth, height=1, textvariable=self.sampleIDInstrText).grid(row=0, column=0)
+ self.inputSampleID = Tkinter.StringVar()
+ self.inputSampleIDEntry = Tkinter.Entry(self.submissionDetailsInputFrame2, width=formInputWidth, textvariable=self.inputSampleID).grid(row=0, column=1)
+
+ self.geneInstrStringVar = Tkinter.StringVar()
+ self.geneInstrStringVar.set('Gene:')
+ self.geneInstrLabel = Tkinter.Label(self.submissionDetailsInputFrame2, width=labelInputWidth, height=1, textvariable=self.geneInstrStringVar).grid(row=1, column=0)
+ self.inputGene = Tkinter.StringVar()
+ self.inputGeneEntry = Tkinter.Entry(self.submissionDetailsInputFrame2, width=formInputWidth, textvariable=self.inputGene).grid(row=1, column=1)
+
+ self.chooseClassIntVar = IntVar()
+ self.chooseClassIntVar.set(1)
+ Radiobutton(self.submissionDetailsInputFrame2, text="HLA Class I ", variable=self.chooseClassIntVar, value=1).grid(row=2, column=0)
+ Radiobutton(self.submissionDetailsInputFrame2, text="HLA Class II", variable=self.chooseClassIntVar, value=2).grid(row=2, column=1)
+
+ self.alleleInstrText = Tkinter.StringVar()
+ self.alleleInstrText.set('Allele Local Name:')
+ self.alleleInstrLabel = Tkinter.Label(self.submissionDetailsInputFrame2, width=labelInputWidth, height=1, textvariable=self.alleleInstrText).grid(row=3, column=0)
+ self.inputAllele = Tkinter.StringVar()
+ self.inputAlleleEntry = Tkinter.Entry(self.submissionDetailsInputFrame2, width=formInputWidth, textvariable=self.inputAllele).grid(row=3, column=1)
+
+ self.submissionDetailsInputFrame2.pack()
# Make a frame to contain the Test/Production radio buttons.
@@ -56,8 +84,10 @@ def __init__(self, root):
self.testProductionInstrText.set('\nBy default, you submit to the EMBL test servers,\n'
+ 'where submissions are regularly deleted.\n'
+ 'change this option if you want to submit to the live EMBL environment.\n'
+ + 'Login Credentials will not be stored, but they will be sent\n'
+ + 'to EMBL via secure https connection.\n'
)
- self.alleleInstrLabel = Tkinter.Label(self.testProductionFrame, width=70, height=5, textvariable=self.testProductionInstrText).pack()#.grid(row=2, column=0)
+ self.alleleInstrLabel = Tkinter.Label(self.testProductionFrame, width=70, height=7, textvariable=self.testProductionInstrText).pack()#.grid(row=2, column=0)
# 1 = Test. 0 = Production/live server
self.chooseTestServersIntVar = IntVar()
@@ -83,30 +113,33 @@ def __init__(self, root):
self.inputPassword = Tkinter.StringVar()
self.inputPasswordEntry = Tkinter.Entry(self.submissionDetailsInputFrame, width=formInputWidth, textvariable=self.inputPassword, show="*").grid(row=1, column=1)
- self.sampleIDInstrText = Tkinter.StringVar()
- self.sampleIDInstrText.set('Sample ID:')
- self.sampleIDinstrLabel = Tkinter.Label(self.submissionDetailsInputFrame, width=labelInputWidth, height=1, textvariable=self.sampleIDInstrText).grid(row=2, column=0)
- self.inputSampleID = Tkinter.StringVar()
- self.inputSampleIDEntry = Tkinter.Entry(self.submissionDetailsInputFrame, width=formInputWidth, textvariable=self.inputSampleID).grid(row=2, column=1)
-
- self.geneInstrStringVar = Tkinter.StringVar()
- self.geneInstrStringVar.set('Gene:')
- self.geneInstrLabel = Tkinter.Label(self.submissionDetailsInputFrame, width=labelInputWidth, height=1, textvariable=self.geneInstrStringVar).grid(row=3, column=0)
- self.inputGene = Tkinter.StringVar()
- self.inputGeneEntry = Tkinter.Entry(self.submissionDetailsInputFrame, width=formInputWidth, textvariable=self.inputGene).grid(row=3, column=1)
+ self.submissionDetailsInputFrame.pack()
+
+
+ # Frame to specify Analysis Information
+ self.newAnalysisFrame = Tkinter.Frame(self)
- self.chooseClassIntVar = IntVar()
- self.chooseClassIntVar.set(1)
- Radiobutton(self.submissionDetailsInputFrame, text="HLA Class I ", variable=self.chooseClassIntVar, value=1).grid(row=4, column=0)
- Radiobutton(self.submissionDetailsInputFrame, text="HLA Class II", variable=self.chooseClassIntVar, value=2).grid(row=4, column=1)
+ self.analysisAliasInstrText = Tkinter.StringVar()
+ self.analysisAliasInstrText.set('Analysis Alias:')
+ self.analysisAliasInstrLabel = Tkinter.Label(self.newAnalysisFrame, width=labelInputWidth, height=1, textvariable=self.analysisAliasInstrText).grid(row=0, column=0)
+ self.inputAnalysisAlias = Tkinter.StringVar()
+ self.inputStudyIdEntry = Tkinter.Entry(self.newAnalysisFrame, width=formInputWidth, textvariable=self.inputAnalysisAlias).grid(row=0, column=1)
- self.alleleInstrText = Tkinter.StringVar()
- self.alleleInstrText.set('Allele Local Name:')
- self.alleleInstrLabel = Tkinter.Label(self.submissionDetailsInputFrame, width=labelInputWidth, height=1, textvariable=self.alleleInstrText).grid(row=5, column=0)
- self.inputAllele = Tkinter.StringVar()
- self.inputAlleleEntry = Tkinter.Entry(self.submissionDetailsInputFrame, width=formInputWidth, textvariable=self.inputAllele).grid(row=5, column=1)
+ self.analysisTitleInstrText = Tkinter.StringVar()
+ self.analysisTitleInstrText.set('Analysis Title:')
+ self.analysisTitleInstrLabel = Tkinter.Label(self.newAnalysisFrame, width=labelInputWidth, height=1, textvariable=self.analysisTitleInstrText).grid(row=1, column=0)
+ self.inputAnalysisTitle = Tkinter.StringVar()
+ self.inputAnalysisTitleEntry = Tkinter.Entry(self.newAnalysisFrame, width=formInputWidth, textvariable=self.inputAnalysisTitle).grid(row=1, column=1)
- self.submissionDetailsInputFrame.pack()
+ self.analysisDescriptionInstrText = Tkinter.StringVar()
+ self.analysisDescriptionInstrText.set('Analysis Description:')
+ self.analysisDescriptionInstrLabel = Tkinter.Label(self.newAnalysisFrame, width=labelInputWidth, height=1, textvariable=self.analysisDescriptionInstrText).grid(row=2, column=0)
+ self.inputAnalysisDescription = Tkinter.StringVar()
+ self.inputAnalysisDescriptionEntry = Tkinter.Entry(self.newAnalysisFrame, width=formInputWidth, textvariable=self.inputAnalysisDescription).grid(row=2, column=1)
+
+ self.newAnalysisFrame.pack()
+
+
# A Frame for specifing the details of the Study / Project
self.projectDetailsFrame = Tkinter.Frame(self)
@@ -125,7 +158,7 @@ def __init__(self, root):
self.existingProjectFrame = Tkinter.Frame(self.projectDetailsFrame)
Radiobutton(self.existingProjectFrame, text="Use this study accession:", variable=self.chooseProjectIntVar, value=1).grid(row=0,column=0)
self.inputStudyAccession = Tkinter.StringVar()
- self.inputStudyNameEntry = Tkinter.Entry(self.existingProjectFrame, width=formInputWidth, textvariable=self.inputStudyAccession).grid(row=0, column=1)
+ self.inputStudyIdEntry = Tkinter.Entry(self.existingProjectFrame, width=formInputWidth, textvariable=self.inputStudyAccession).grid(row=0, column=1)
self.existingProjectFrame.pack()
@@ -139,20 +172,20 @@ def __init__(self, root):
self.newProjectFrame = Tkinter.Frame(self.projectDetailsFrame)
- self.studyNameInstrText = Tkinter.StringVar()
- self.studyNameInstrText.set('Study Name:')
- self.studyNameInstrLabel = Tkinter.Label(self.newProjectFrame, width=labelInputWidth, height=1, textvariable=self.studyNameInstrText).grid(row=0, column=0)
- self.inputStudyName = Tkinter.StringVar()
- self.inputStudyNameEntry = Tkinter.Entry(self.newProjectFrame, width=formInputWidth, textvariable=self.inputStudyName).grid(row=0, column=1)
+ self.studyIdInstrText = Tkinter.StringVar()
+ self.studyIdInstrText.set('Short Study Identifier:')
+ self.studyIdInstrLabel = Tkinter.Label(self.newProjectFrame, width=labelInputWidth, height=1, textvariable=self.studyIdInstrText).grid(row=0, column=0)
+ self.inputStudyId = Tkinter.StringVar()
+ self.inputStudyIdEntry = Tkinter.Entry(self.newProjectFrame, width=formInputWidth, textvariable=self.inputStudyId).grid(row=0, column=1)
- self.studyShortDescriptionInstrText = Tkinter.StringVar()
- self.studyShortDescriptionInstrText.set('Short Description:')
- self.studyShortDescriptionInstrLabel = Tkinter.Label(self.newProjectFrame, width=labelInputWidth, height=1, textvariable=self.studyShortDescriptionInstrText).grid(row=1, column=0)
- self.inputStudyShortDescription = Tkinter.StringVar()
- self.inputStudyShortDescriptionEntry = Tkinter.Entry(self.newProjectFrame, width=formInputWidth, textvariable=self.inputStudyShortDescription).grid(row=1, column=1)
+ self.studyShortTitleInstrText = Tkinter.StringVar()
+ self.studyShortTitleInstrText.set('Descriptive Study Title:')
+ self.studyShortTitleInstrLabel = Tkinter.Label(self.newProjectFrame, width=labelInputWidth, height=1, textvariable=self.studyShortTitleInstrText).grid(row=1, column=0)
+ self.inputStudyShortTitle = Tkinter.StringVar()
+ self.inputStudyShortTitleEntry = Tkinter.Entry(self.newProjectFrame, width=formInputWidth, textvariable=self.inputStudyShortTitle).grid(row=1, column=1)
self.studyAbstractInstrText = Tkinter.StringVar()
- self.studyAbstractInstrText.set('Study Abstract:')
+ self.studyAbstractInstrText.set('Study Description / Abstract:')
self.studyAbstractInstrLabel = Tkinter.Label(self.newProjectFrame, width=labelInputWidth, height=1, textvariable=self.studyAbstractInstrText).grid(row=2, column=0)
self.inputStudyAbstract = Tkinter.StringVar()
self.inputStudyAbstractEntry = Tkinter.Entry(self.newProjectFrame, width=formInputWidth, textvariable=self.inputStudyAbstract).grid(row=2, column=1)
@@ -166,8 +199,16 @@ def __init__(self, root):
Tkinter.Button(self.saveOptionsFrame, text='Save Options', command=self.saveOptions).grid(row=0, column=0)
self.saveOptionsFrame.pack()
+ # TODO: Should there be a cancel button, to close this window without saving?
+
self.loadOptions()
+ # I needed a function for the return keypress to latch onto.
+ # It is just a wrapper for the saveOptions method.
+ def returnFunction(self, event):
+ self.saveOptions()
+
+
# submissionOptions is a dictionary, passed by the parent.
def loadOptions(self):
if getConfigurationValue('embl_username') is not None:
@@ -204,11 +245,11 @@ def loadOptions(self):
if getConfigurationValue('study_accession') is not None:
self.inputStudyAccession.set(getConfigurationValue('study_accession'))
- if getConfigurationValue('study_name') is not None:
- self.inputStudyName.set(getConfigurationValue('study_name'))
+ if getConfigurationValue('study_identifier') is not None:
+ self.inputStudyId.set(getConfigurationValue('study_identifier'))
- if getConfigurationValue('study_description') is not None:
- self.inputStudyShortDescription.set(getConfigurationValue('study_description'))
+ if getConfigurationValue('study_short_title') is not None:
+ self.inputStudyShortTitle.set(getConfigurationValue('study_short_title'))
if getConfigurationValue('study_abstract') is not None:
self.inputStudyAbstract.set(getConfigurationValue('study_abstract'))
@@ -216,12 +257,16 @@ def loadOptions(self):
if getConfigurationValue('test_submission') is not None:
# 1 = Test. 0 = Production/live server
self.chooseTestServersIntVar.set(int(getConfigurationValue('test_submission')))
-
-
+ if getConfigurationValue('analysis_alias') is not None:
+ self.inputAnalysisAlias.set(getConfigurationValue('analysis_alias'))
+ if getConfigurationValue('analysis_title') is not None:
+ self.inputAnalysisTitle.set(getConfigurationValue('analysis_title'))
+ if getConfigurationValue('analysis_description') is not None:
+ self.inputAnalysisDescription.set(getConfigurationValue('analysis_description'))
+
def saveOptions(self):
- # TODO: Save the options to our configuration dictionary
# Close the window
if (self.checkOptions()):
print ('Saving Options....')
@@ -236,10 +281,13 @@ def saveOptions(self):
assignConfigurationValue('allele_name', self.inputAllele.get())
assignConfigurationValue('choose_project', str(self.chooseProjectIntVar.get()))
assignConfigurationValue('study_accession', self.inputStudyAccession.get())
- assignConfigurationValue('study_name', self.inputStudyName.get())
- assignConfigurationValue('study_description', self.inputStudyShortDescription.get())
+ assignConfigurationValue('study_identifier', self.inputStudyId.get())
+ assignConfigurationValue('study_short_title', self.inputStudyShortTitle.get())
assignConfigurationValue('study_abstract', self.inputStudyAbstract.get())
assignConfigurationValue('test_submission', str(self.chooseTestServersIntVar.get()))
+ assignConfigurationValue('analysis_alias', str(self.inputAnalysisAlias.get()))
+ assignConfigurationValue('analysis_title', str(self.inputAnalysisTitle.get()))
+ assignConfigurationValue('analysis_description', str(self.inputAnalysisDescription.get()))
self.parent.destroy()
@@ -248,11 +296,8 @@ def saveOptions(self):
pass
def checkOptions(self):
- # TODO this method
- print ('Checking options.')
-
- #chooseProjectIntVar
-
+ #print ('Checking options.')
+
# Don't check the EMBL Username
# Don't check the EMBL Password
@@ -282,12 +327,12 @@ def checkOptions(self):
elif(str(self.chooseProjectIntVar.get()) == '2'):
# Use New Project
- if (not self.inputStudyName.get()):
+ if (not self.inputStudyId.get()):
tkMessageBox.showwarning('Missing Form Value',
'You are missing a Study Name. Please try again.')
return False
- if (not self.inputStudyShortDescription.get()):
+ if (not self.inputStudyShortTitle.get()):
tkMessageBox.showwarning('Missing Form Value',
'You are missing a Study Description. Please try again.')
return False
@@ -299,14 +344,32 @@ def checkOptions(self):
return False
else:
- raise Exception ('Unknown value of self.chooseProjectIntVar. I expect 1 or 2. Observed:' + str(self.chooseProjectIntVar))
+ raise Exception ('Unknown value of self.chooseProjectIntVar. I expect 1 or 2. Observed:' + str(self.chooseProjectIntVar))
+
+
+ if (not self.inputAnalysisAlias.get()):
+ tkMessageBox.showwarning('Missing Form Value',
+ 'You are missing an Analysis Alias. Please try again.')
+ return False
+
+ if (not self.inputAnalysisTitle.get()):
+ tkMessageBox.showwarning('Missing Form Value',
+ 'You are missing an Analysis Title. Please try again.')
+ return False
+
+ if (not self.inputAnalysisDescription.get()):
+ tkMessageBox.showwarning('Missing Form Value',
+ 'You are missing an Analysis Description. Please try again.')
+ return False
+
+
# All options look good, right?
+
+
return True
def closeWindow(self):
- #writeConfigurationFile()
-
self.parent.destroy()
\ No newline at end of file
diff --git a/src/AlleleGuiIMGT.py b/src/AlleleGuiIMGT.py
index 8ba9363..42c53d4 100755
--- a/src/AlleleGuiIMGT.py
+++ b/src/AlleleGuiIMGT.py
@@ -1,19 +1,17 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
-
-
+# along with saddle-bags. If not, see .
import os
from os.path import expanduser
@@ -189,7 +187,7 @@ def sampleSequence(self):
assignConfigurationValue('ethnic_origin', 'Unknown')
assignConfigurationValue('sex', 'Unknown')
- assignConfigurationValue('cosanguinous', 'Unknown')
+ assignConfigurationValue('consanguineous', 'Unknown')
assignConfigurationValue('homozygous', 'Unknown')
@@ -247,7 +245,7 @@ def contactInformation(self):
+ 'm.tilanus@mumc.nl\n\n'
+ 'This code will be hosted at:\n'
- + 'https://github.com/transplantation-\nimmunology/EMBL-HLA-Submission\n'
+ + 'https://github.com/transplantation-\nimmunology/saddle-bags\n'
+ 'You will find more information on\n'
+ 'IMGT\'s data format on that page.'
@@ -275,11 +273,6 @@ def constructSubmission(self):
allGen = SubmissionGeneratorIMGT()
roughFeatureSequence = self.featureInputGuiObject.get('1.0', 'end')
- # Don't assign these, they should already be stored in our configuration.
- #allGen.inputSampleID = getConfigurationValue('sample_id')
- #allGen.inputGene = getConfigurationValue('gene')
- # allGen.inputAllele = getConfigurationValue('allele_name')
-
allGen.sequenceAnnotation = annotateRoughInputSequence(roughFeatureSequence)
imgtSubmission = allGen.buildIMGTSubmission()
diff --git a/src/AlleleGuiIMGTInputForm.py b/src/AlleleGuiIMGTInputForm.py
index 7da8b43..644f275 100755
--- a/src/AlleleGuiIMGTInputForm.py
+++ b/src/AlleleGuiIMGTInputForm.py
@@ -1,17 +1,17 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
+# along with saddle-bags. If not, see .
import os
@@ -47,6 +47,9 @@ def __init__(self, root):
# To define the exit behavior. Save and exit.
self.parent.protocol('WM_DELETE_WINDOW', self.saveOptions)
+ # Define the return behavior. Same as "close window" etc
+ root.bind('', self.returnFunction)
+
self.instructionsFrame = Tkinter.Frame(self.interior)
self.instructionText = Tkinter.StringVar()
self.instructionText.set('\nThese options are required for an IMGT allele submission.\n'
@@ -224,12 +227,12 @@ def __init__(self, root):
self.inputSex = Tkinter.StringVar()
self.inputSexEntry = Tkinter.Entry(self.submissionDetailsInputFrame2, width=formInputWidth, textvariable=self.inputSex).grid(row=4, column=1)
- # Cosanguinous (T/F)
- self.cosanguinousInstrText = Tkinter.StringVar()
- self.cosanguinousInstrText.set('Sample is Cosanguinous:')
- self.cosanguinousInstrLabel = Tkinter.Label(self.submissionDetailsInputFrame2, width=labelInputWidth, height=1, textvariable=self.cosanguinousInstrText).grid(row=5, column=0)
- self.inputCosanguinous = Tkinter.StringVar()
- self.inputCosanguinousEntry = Tkinter.Entry(self.submissionDetailsInputFrame2, width=formInputWidth, textvariable=self.inputCosanguinous).grid(row=5, column=1)
+ # Consanguineous (T/F)
+ self.consanguineousInstrText = Tkinter.StringVar()
+ self.consanguineousInstrText.set('Sample is Consanguineous:')
+ self.consanguineousInstrLabel = Tkinter.Label(self.submissionDetailsInputFrame2, width=labelInputWidth, height=1, textvariable=self.consanguineousInstrText).grid(row=5, column=0)
+ self.inputConsanguineous = Tkinter.StringVar()
+ self.inputConsanguineousEntry = Tkinter.Entry(self.submissionDetailsInputFrame2, width=formInputWidth, textvariable=self.inputConsanguineous).grid(row=5, column=1)
# Homozygous (T/F)
self.homozygousInstrText = Tkinter.StringVar()
@@ -288,6 +291,11 @@ def __init__(self, root):
self.saveOptionsFrame.pack()
self.loadOptions()
+
+ # I needed a function for the return keypress to latch onto.
+ # It is just a wrapper for the saveOptions method.
+ def returnFunction(self, event):
+ self.saveOptions()
# submissionOptions is a dictionary, passed by the parent.
def loadOptions(self):
@@ -343,8 +351,8 @@ def loadOptions(self):
self.inputEthnicOrigin.set(getConfigurationValue('ethnic_origin'))
if getConfigurationValue('sex') is not None:
self.inputSex.set(getConfigurationValue('sex'))
- if getConfigurationValue('cosanguinous') is not None:
- self.inputCosanguinous.set(getConfigurationValue('cosanguinous'))
+ if getConfigurationValue('consanguineous') is not None:
+ self.inputConsanguineous.set(getConfigurationValue('consanguineous'))
if getConfigurationValue('homozygous') is not None:
self.inputHomozygous.set(getConfigurationValue('homozygous'))
@@ -353,7 +361,6 @@ def loadOptions(self):
def saveOptions(self):
- # TODO: Save the options to our configuration dictionary
# Close the window
if (self.checkOptions()):
print ('Saving Options....')
@@ -383,11 +390,9 @@ def saveOptions(self):
assignConfigurationValue('sex', self.inputSex.get())
# TODO: Accepted values are 'Yes', 'No', 'Unknown'
- assignConfigurationValue('cosanguinous', self.inputCosanguinous.get())
+ assignConfigurationValue('consanguineous', self.inputConsanguineous.get())
assignConfigurationValue('homozygous', self.inputHomozygous.get())
-
-
-
+
self.parent.destroy()
else:
@@ -449,9 +454,9 @@ def checkOptions(self):
return False
# TODO: Accepted values are 'Yes', 'No', 'Unknown' I think
- if (not self.inputCosanguinous.get()):
+ if (not self.inputConsanguineous.get()):
tkMessageBox.showwarning('Missing Form Value',
- 'Please indicate if the sample is cosanguinous or not.')
+ 'Please indicate if the sample is consanguineous or not.')
return False
if (not self.inputHomozygous.get()):
tkMessageBox.showwarning('Missing Form Value',
diff --git a/src/AlleleGuiMain.py b/src/AlleleGuiMain.py
index 48ad36c..e49dbd5 100755
--- a/src/AlleleGuiMain.py
+++ b/src/AlleleGuiMain.py
@@ -1,17 +1,17 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
+# along with saddle-bags. If not, see .
import os
@@ -139,7 +139,7 @@ def contactInformation(self):
+ 'm.tilanus@mumc.nl\n\n'
+ 'This code will be hosted at:\n'
- + 'https://github.com/transplantation-\nimmunology/EMBL-HLA-Submission\n'
+ + 'https://github.com/transplantation-\nimmunology/saddle-bags\n'
+ 'You will find more information on\n'
+ 'EMBL\'s data format on that page.'
diff --git a/src/AlleleSubCommon.py b/src/AlleleSubCommon.py
index f1cbea9..f108d8d 100755
--- a/src/AlleleSubCommon.py
+++ b/src/AlleleSubCommon.py
@@ -1,22 +1,17 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
-
-
-#from numpy.compat.setup import configuration
-
-#SoftwareVersion = "Bhast Version 1.0"
+# along with saddle-bags. If not, see .
import xml.etree.ElementTree as ET
import xml.dom.minidom
@@ -30,7 +25,7 @@
import tkMessageBox
import sys
-from os.path import dirname, join, abspath, isfile
+from os.path import dirname, join, abspath, isfile, expanduser
from HLAGene import *
@@ -236,8 +231,6 @@ def annotateRoughInputSequence(inputSequenceText):
return resultGeneLoci
#self.sequenceAnnotation = resultGeneLoci
-
-
# This method is a directory-safe way to open up a write file.
def createOutputFile(outputfileName):
tempDir, tempFilename = split(outputfileName)
@@ -247,8 +240,6 @@ def createOutputFile(outputfileName):
resultsOutput = open(outputfileName, 'w')
return resultsOutput
-
-
# I'm storing global variables in a dictionary for now.
def initializeGlobalVariables():
global globalVariables
@@ -267,26 +258,9 @@ def getConfigurationValue(configurationKey):
print ('Configuration Key Not Found:' + configurationKey)
#raise KeyError('Key Not Found:' + configurationKey)
return None
-
def assignConfigName():
- initializeGlobalVariables()
-
- # Find the directory the program is running from.
- # It is not straight-forward, because sometimes we run this program inside an .exe
- # pyinstaller puts the exe path in sys._MEIPASS
- # This is useful because we want a config file in the same directory.
- if getattr(sys, 'frozen', False):
- globalVariables['saddlebags_application_path'] = sys._MEIPASS
- else:
- globalVariables['saddlebags_application_path'] = dirname(abspath(__file__))
-
- # TODO: Store the directory someone saves in.
- # I should assign the directory to a default value.
-
- print 'This application is running from the following directory:\n' + globalVariables['saddlebags_application_path']
- globalVariables['config_file_location'] = join(globalVariables['saddlebags_application_path'], 'Saddlebags.Config.xml')
-
+ assignConfigurationValue('config_file_location',join(expanduser("~"),'Saddlebags.Config.xml'))
def writeConfigurationFile():
assignConfigName()
@@ -300,8 +274,6 @@ def writeConfigurationFile():
if(key not in [
'embl_password'
,'imgt_password'
- , 'saddlebags_application_path'
- , 'config_file_location'
, 'sequence'
]):
ET.SubElement(root, key).text = globalVariables[key]
@@ -334,9 +306,7 @@ def loadConfigurationFile():
assignConfigurationValue('embl_ftp_upload_site_prod', 'webin.ebi.ac.uk')
assignConfigurationValue('embl_rest_address_test', 'https://www-test.ebi.ac.uk/ena/submit/drop-box/submit/')
assignConfigurationValue('embl_rest_address_prod', 'https://www.ebi.ac.uk/ena/submit/drop-box/submit/')
-
-
-
+
else:
print ('The config file already exists, I will load it:\n' + globalVariables['config_file_location'])
diff --git a/AlleleSubInstallerOptions_Windows.spec b/src/AlleleSubInstallerOptions_Windows.spec
similarity index 71%
rename from AlleleSubInstallerOptions_Windows.spec
rename to src/AlleleSubInstallerOptions_Windows.spec
index 72a4717..4210ec3 100755
--- a/AlleleSubInstallerOptions_Windows.spec
+++ b/src/AlleleSubInstallerOptions_Windows.spec
@@ -1,21 +1,19 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
+# along with saddle-bags. If not, see .
-# Version 1.0
-
-# This file contains specifications for packaging of the MinION Extractor GUI
+# This file contains specifications for packaging of saddlebags
# As a standalone executable. This file is meant to be used with pyinstaller
# http://www.pyinstaller.org/
@@ -25,7 +23,7 @@
block_cipher = None
-a = Analysis(['AlleleSubmissionEMBL.py'],
+a = Analysis(['AlleleSubmissionMain.py'],
binaries=None,
datas=None,
hiddenimports=['six', 'packaging', 'packaging.requirements', 'packaging.version', 'packaging.specifiers', 'Tkinter', 'tkFileDialog', 'Tkconstants'],
@@ -42,7 +40,7 @@ exe = EXE(pyz,
a.binaries,
a.zipfiles,
a.datas,
- name='AlleleSubmissionEMBLWindows',
+ name='SaddlebagsWindows',
debug=False,
strip=False,
upx=True,
diff --git a/src/AlleleSubmissionEMBLRestMethods.py b/src/AlleleSubmissionEMBLRestMethods.py
new file mode 100644
index 0000000..566cb2e
--- /dev/null
+++ b/src/AlleleSubmissionEMBLRestMethods.py
@@ -0,0 +1,129 @@
+# This file is part of saddle-bags.
+#
+# saddle-bags is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# saddle-bags is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with saddle-bags. If not, see .
+
+
+
+
+from AlleleSubCommon import *
+import pycurl
+import StringIO
+
+import xml.etree.ElementTree as ET
+import xml.dom.minidom
+
+# Here we have methods to perform REST interactions necessary for EMBL submission.
+
+def performProjectSubmission(submissionFileName, projectFileName):
+ POST_DATA = [('SUBMISSION', (pycurl.FORM_FILE, submissionFileName)),
+ ('PROJECT', (pycurl.FORM_FILE, projectFileName))]
+
+ responseText = performSubmission(submissionFileName, POST_DATA)
+ return interpretProjectSubmissionResults(responseText)
+
+def performAnalysisSubmission(submissionFileName, analysisFileName):
+ POST_DATA = [('SUBMISSION', (pycurl.FORM_FILE, submissionFileName)),
+ ('ANALYSIS', (pycurl.FORM_FILE, analysisFileName))]
+
+ responseText = performSubmission(submissionFileName, POST_DATA)
+
+ return interpretAnalysisSubmissionResults(responseText)
+
+def performSubmission(submissionFileName, POST_DATA):
+ if (str(getConfigurationValue('test_submission')) == '0'):
+ print 'THIS IS A LIVE SUBMISSION AT EMBL.'
+ requestURL = str(getConfigurationValue('embl_rest_address_prod')) + '?auth=ENA%20' + str(getConfigurationValue('embl_username')) + '%20' + str(getConfigurationValue('embl_password'))
+ else:
+ print 'THIS IS A TEST SUBMISSION AT EMBL.'
+ requestURL = str(getConfigurationValue('embl_rest_address_test')) + '?auth=ENA%20' + str(getConfigurationValue('embl_username')) + '%20' + str(getConfigurationValue('embl_password'))
+
+ curlResponseBuffer = StringIO.StringIO()
+ curlObject = pycurl.Curl()
+ curlObject.setopt(curlObject.URL, requestURL)
+ curlObject.setopt(curlObject.POST, 1)
+ curlObject.setopt(curlObject.HTTPPOST, POST_DATA)
+ curlObject.setopt(curlObject.USERAGENT, 'Curl')
+ curlObject.setopt(curlObject.WRITEFUNCTION, curlResponseBuffer.write)
+ curlObject.setopt(pycurl.HTTPHEADER, ['Accept:application/xml'])
+ # Insecure. Any security experts want to make this better?
+ curlObject.setopt(pycurl.SSL_VERIFYHOST, 0)
+ curlObject.setopt(pycurl.SSL_VERIFYPEER, 0)
+ curlObject.perform()
+ curlObject.close()
+
+ responseText = curlResponseBuffer.getvalue()
+
+ # write XML to file.
+ projectSubResultsFileName = submissionFileName.replace('.xml','_results.xml')
+ resultsFile = createOutputFile(projectSubResultsFileName)
+ resultsFile.write(responseText)
+ resultsFile.close()
+
+ return responseText
+
+def interpretProjectSubmissionResults(responseText):
+ # Open XML to report results:
+ root = ET.fromstring(responseText)
+ submissionSuccess = (root.attrib['success'] == 'true')
+
+ projectAccession = None
+ messages = []
+
+ for child in root:
+ if(child.tag == 'PROJECT'):
+ if ('accession' in child.attrib.keys()):
+ projectAccession = child.attrib['accession']
+ else:
+ projectAccession = None
+ #print('I found a project node.')
+ elif(child.tag == 'MESSAGES'):
+ print('I found some messages.')
+ for messageNode in child:
+ #print (messageNode.tag + ':' + messageNode.text)
+ messages.append(messageNode.tag + ':' + messageNode.text)
+ else:
+ # Don't care about the other nodes
+ pass
+
+ # Return value should be a tuple:
+ # (Success, ProjectAccession, Messages[])
+ return (submissionSuccess,projectAccession,messages)
+
+def interpretAnalysisSubmissionResults(responseText):
+ root = ET.fromstring(responseText)
+ submissionSuccess = (root.attrib['success'] == 'true')
+
+ analysisAccession = None
+ messages = []
+
+ for child in root:
+ if(child.tag == 'ANALYSIS'):
+ if ('accession' in child.attrib.keys()):
+ analysisAccession = child.attrib['accession']
+ else:
+ analysisAccession = None
+ #print('I found a project node.')
+ elif(child.tag == 'MESSAGES'):
+ print('I found some messages.')
+ for messageNode in child:
+ #print (messageNode.tag + ':' + messageNode.text)
+ messages.append(messageNode.tag + ':' + messageNode.text)
+ else:
+ # Don't care about the other nodes
+ pass
+
+ # Return value should be a tuple:
+ # (Success, ProjectAccession, Messages[])
+ return (submissionSuccess,analysisAccession,messages)
+
diff --git a/src/AlleleSubmissionEMBLXml.py b/src/AlleleSubmissionEMBLXml.py
index 107c195..32ae791 100755
--- a/src/AlleleSubmissionEMBLXml.py
+++ b/src/AlleleSubmissionEMBLXml.py
@@ -1,20 +1,17 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
-
-
-#import os
+# along with saddle-bags. If not, see .
from AlleleSubCommon import *
@@ -35,22 +32,26 @@ def writeToXml(fullXmlFilePath, xmlElementTree):
return prettyXmlText
-def createProjectXML(fullXmlFilePath, projectName, projectDescription, projectAbstract):
+def getCenterName():
+ # TODO: Should I use REST here?
+ # Probably not, center_name is not required in the xmls.
+ return 'Center_Name'
+
+def createProjectXML(fullXmlFilePath):
+ # They are called "Project" in xml, but "Study" on the website.
+ # Project = Study
root = ET.Element('PROJECT_SET')
- # TODO: How do I get the center name?
- # Maybe I should get this via REST?
+
+ projectID = getConfigurationValue('study_identifier')
+ projectShortTitle = getConfigurationValue('study_short_title')
+ projectAbstract = getConfigurationValue('study_abstract')
- # Ok this is really confusing.
- # According to the docs, http://ena-docs.readthedocs.io/en/latest/prog_01.html
- # "alias" attribute on the project node contains projectName
- # "title" node contains project description
- # "description" node is the project abstract
- # EMBL should be more consistent in their terminology.
projectElement = ET.SubElement(root, 'PROJECT')
- projectElement.set('alias', projectName)
- projectElement.set('center_name', 'Maastricht University Medical Center' )
+ projectElement.set('alias', projectID)
+ # Center Name is optional according to schemas. Forget it. EMBL Knows our login info.
+ #projectElement.set('center_name', getCenterName() )
titleElement = ET.SubElement(projectElement, 'TITLE')
- titleElement.text = projectDescription
+ titleElement.text = projectShortTitle
descriptionElement = ET.SubElement(projectElement, 'DESCRIPTION')
descriptionElement.text = projectAbstract
submissionProjectElement = ET.SubElement(projectElement, 'SUBMISSION_PROJECT')
@@ -58,18 +59,60 @@ def createProjectXML(fullXmlFilePath, projectName, projectDescription, projectAb
return writeToXml(fullXmlFilePath, root)
-def createProjectSubmissionXML(submissionAlias, fullXmlFilePath):
+def createProjectSubmissionXML(fullXmlFilePath, submissionAlias, shortProjectFileName):
root = ET.Element('SUBMISSION')
- # TODO: How do I get the center name?
- # Maybe I should get this via REST?
root.set('alias', submissionAlias)
- root.set('center_name', 'Maastricht University Medical Center' )
+ # Center Name is optional according to schemas. Forget it.
+ #root.set('center_name', getCenterName() )
actionsElement = ET.SubElement(root, 'ACTIONS')
actionElement = ET.SubElement(actionsElement, 'ACTION')
addElement = ET.SubElement(actionElement, 'ADD')
- addElement.set('source','project.xml')
+ addElement.set('source',shortProjectFileName)
addElement.set('schema','project')
return writeToXml(fullXmlFilePath, root)
+
+def createAnalysisXML(fullXmlFilePath, checksumValue, flatfileZipFileName):
+ # An analysis xml is just a wrapper for a sequence submission.
+ root = ET.Element('ANALYSIS_SET')
+
+ # TODO: I haven't created these three analysis configuration values yet.
+ # Probably need to add this to the GUI, or somehow generate them automagically.
+ analysisElement = ET.SubElement(root, 'ANALYSIS')
+ analysisElement.set('alias', getConfigurationValue('analysis_alias'))
+
+ titleElement = ET.SubElement(analysisElement, 'TITLE')
+ titleElement.text = (getConfigurationValue('analysis_title'))
+
+ descriptionElement = ET.SubElement(analysisElement, 'DESCRIPTION')
+ descriptionElement.text = (getConfigurationValue('analysis_description'))
+
+ studyRefElement = ET.SubElement(analysisElement, 'STUDY_REF')
+ studyRefElement.set('accession', getConfigurationValue('study_accession'))
+
+ analysisTypeElement = ET.SubElement(analysisElement, 'ANALYSIS_TYPE')
+ sequenceFlatfileElement = ET.SubElement(analysisTypeElement, 'SEQUENCE_FLATFILE')
+
+ filesElement = ET.SubElement(analysisElement, 'FILES')
+
+ fileElement = ET.SubElement(filesElement, 'FILE')
+ fileElement.set('checksum', checksumValue)
+ fileElement.set('checksum_method', 'MD5')
+ fileElement.set('filename', flatfileZipFileName)
+ fileElement.set('filetype', 'flatfile')
+
+ return writeToXml(fullXmlFilePath, root)
+
+def createAnalysisSubmissionXML(fullXmlFilePath, submissionAlias, shortAnalysisFileName):
+ root = ET.Element('SUBMISSION')
+
+ root.set('alias', submissionAlias)
+ actionsElement = ET.SubElement(root, 'ACTIONS')
+ actionElement = ET.SubElement(actionsElement, 'ACTION')
+ addElement = ET.SubElement(actionElement, 'ADD')
+ addElement.set('source',shortAnalysisFileName)
+ addElement.set('schema','analysis')
+
+ return writeToXml(fullXmlFilePath, root)
diff --git a/src/AlleleSubmissionMain.py b/src/AlleleSubmissionMain.py
index 7a06468..e7f8274 100755
--- a/src/AlleleSubmissionMain.py
+++ b/src/AlleleSubmissionMain.py
@@ -1,25 +1,25 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
-
-SoftwareVersion = "Bhast Version 1.0"
+# along with saddle-bags. If not, see .
import Tkinter
import sys
from AlleleGuiMain import AlleleGuiMain
from AlleleSubCommon import *
+
+SoftwareVersion = 'saddlebags Version 1.1'
if __name__=='__main__':
try:
@@ -46,6 +46,8 @@
sys.argv[1].lower() == '-version')
):
print (SoftwareVersion)
+ pass
+ #
# You executed the software wrong. Sorry.
else:
@@ -53,7 +55,7 @@
"\tRun this program using standard python call:\n" +
"\t$python AlleleSubmissionMain.py\n" +
"\tbiopython must be accessible in your python environment. To run using Anaconda,\n"
- "\tCheck readme at https://github.com/transplantation-immunology/EMBL-HLA-Submission\n"
+ "\tCheck readme at https://github.com/transplantation-immunology/saddle-bags\n"
)
diff --git a/src/HLAGene.py b/src/HLAGene.py
index 3e39c4c..d9940b3 100755
--- a/src/HLAGene.py
+++ b/src/HLAGene.py
@@ -1,17 +1,17 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
+# along with saddle-bags. If not, see .
# The GeneLocus class specifies a locus on a Gene,
# Either an Exon, intron, or UTR.
diff --git a/src/ScrolledWindow.py b/src/ScrolledWindow.py
index f4c06b8..15e00f8 100644
--- a/src/ScrolledWindow.py
+++ b/src/ScrolledWindow.py
@@ -1,17 +1,25 @@
-from Tkinter import Scrollbar, Frame, Canvas, VERTICAL, RIGHT, Y, LEFT, BOTH, TRUE, FALSE, NW
-#from ttk import *
+# This file is part of saddle-bags.
+#
+# saddle-bags is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# saddle-bags is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with saddle-bags. If not, see .
+
-#Obviously this doesn't work. Fix it, I want to be mroe specific witht he imports'
+
+from Tkinter import Scrollbar, Frame, Canvas, VERTICAL, RIGHT, Y, LEFT, BOTH, TRUE, FALSE, NW
# http://tkinter.unpythonic.net/wiki/VerticalScrolledFrame
class VerticalScrolledFrame(Frame):
- """A pure Tkinter scrollable frame that actually works!
- * Use the 'interior' attribute to place widgets inside the scrollable frame
- * Construct and pack/place/grid normally
- * This frame only allows vertical scrolling
-
- """
def __init__(self, parent, *args, **kw):
Frame.__init__(self, parent, *args, **kw)
@@ -23,6 +31,9 @@ def __init__(self, parent, *args, **kw):
yscrollcommand=vscrollbar.set)
canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)
vscrollbar.config(command=canvas.yview)
+
+ # TODO: Fix the vertical scrolling behavior. The Mouse does not work.
+
# reset the view
canvas.xview_moveto(0)
diff --git a/src/SubmissionGeneratorEMBL.py b/src/SubmissionGeneratorEMBL.py
index 17bf6d0..15b7fe1 100755
--- a/src/SubmissionGeneratorEMBL.py
+++ b/src/SubmissionGeneratorEMBL.py
@@ -1,17 +1,17 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
+# along with saddle-bags. If not, see .
from Bio.Seq import Seq
from Bio.Alphabet import generic_dna
@@ -29,19 +29,7 @@
class SubmissionGeneratorEMBL():
def __init__(self):
-
- # TODO: These values are stored in a config file. I don't think I need to assign them.
- # Except the HLAGene value, initialize that.
- # Comment out the rest of these initializations.
-
- #self.inputFileName = ''
- #self.outputFileName = ''
self.sequenceAnnotation = HLAGene()
- #getConfigurationValue('sample_id') = 0
- #getConfigurationValue('gene') = ''
- #getConfigurationValue('allele_name') = ''
- #s#elf.inputClass = ''
- #self.isPseudoGene = False
def printHeader(self):
diff --git a/src/SubmissionGeneratorIMGT.py b/src/SubmissionGeneratorIMGT.py
index c7e8892..2365d70 100755
--- a/src/SubmissionGeneratorIMGT.py
+++ b/src/SubmissionGeneratorIMGT.py
@@ -1,20 +1,18 @@
-# This file is part of EMBL-HLA-Submission.
+# This file is part of saddle-bags.
#
-# EMBL-HLA-Submission is free software: you can redistribute it and/or modify
+# saddle-bags is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# EMBL-HLA-Submission is distributed in the hope that it will be useful,
+# saddle-bags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with EMBL-HLA-Submission. If not, see .
+# along with saddle-bags. If not, see .
-#from Bio.Seq import Seq
-#from Bio.Alphabet import generic_dna
import sys
import datetime
@@ -145,7 +143,7 @@ def printSource(self):
sourceText += 'FT /cell_id="' + str(getConfigurationValue('sample_id')) + '"\n'
sourceText += 'FT /ethnic_origin="' + str(getConfigurationValue('ethnic_origin')) + '"\n'
sourceText += 'FT /sex="' + str(getConfigurationValue('sex')) + '"\n'
- sourceText += 'FT /consanguineous="Unknown"\n'
+ sourceText += 'FT /consanguineous="' + str(getConfigurationValue('consanguineous')) + '"\n'
sourceText += 'FT /homozygous="Yes"\n'
sourceText += 'FT /lab_of_origin="**IMGT_SUBMITTING_LAB_NAME**"\n'
sourceText += 'FT /lab_contact="**IMGT_SUBMITTER_NAME**"\n'
@@ -395,275 +393,3 @@ def validateInputs(self):
return True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#I assume the rest of this code is outdated and deprectaed:
-
-"""
-
-
-
-
-
- def printMRNA(self):
- mRNAText = ''
- # Print mRNA
- mRNAText += ('FT mRNA join(')
-
- # Iterate through the indices of the UTRs and exons.
- # The 3' and 5' UTR are included in the mRNA
- for x in range(0,len(self.sequenceAnnotation.loci)):
- geneLocus = self.sequenceAnnotation.loci[x]
- # If it is an exon or UTR
- if (geneLocus.exon or 'UT' in geneLocus.name):
- mRNAText += str(geneLocus.beginIndex) + '..' + str(geneLocus.endIndex) + ','
-
- # Trim off the last comma and add a parenthese
- mRNAText = mRNAText[0:len(mRNAText)-1] + ')\n'
-
- mRNAText += ('FT /gene="' + str(getConfigurationValue('gene')) + '"\n')
- mRNAText += ('FT /allele="' + str(self.inputAllele) + '"\n')
- mRNAText += ('FT /product=\"MHC class I antigen\"\n')
-
- return mRNAText
-
-
- def printFeatures(self):
- cdsText = ''
-
- # Print CDS
- # CDS is the coding sequence. It should include the exons, but not the UTRs/Introns
- # The range 1:featureCount-1 will exclude the UTRs.
- cdsText += ('FT CDS join(')
- for x in range(0,len(self.sequenceAnnotation.loci)):
- geneLocus = self.sequenceAnnotation.loci[x]
- if (geneLocus.exon):
- cdsText += str(geneLocus.beginIndex) + '..' + str(geneLocus.endIndex)
- if not x==len(self.sequenceAnnotation.loci)-2:
- cdsText += ','
- else:
- cdsText += ')\n'
-
- cdsText += ('FT /transl_table=1\n')
- cdsText += ('FT /codon_start=1\n')
- cdsText += ('FT /gene="' + str(getConfigurationValue('gene')) + '"\n')
- cdsText += ('FT /allele="' + str(self.inputAllele) + '"\n')
-
- # TODO: This is a problem. I need to specify Class I or Class II
- cdsText += ('FT /product=\"MHC class I antigen\"\n')
- cdsText += ('FT /translation=\"')
-
- # Some simple formatting for the peptide sequence, making it human and computer readable.
- # 80 peptides per line. Except the first line, which is 66.
- # 66 is 80-14, where 14 is the length of { /translation=" }
- peptideSequence = self.translateSequence(self.sequenceAnnotation.getExonSequence())
- if(len(peptideSequence) < 66):
- cdsText += (peptideSequence) + '\"\n'
- else:
- cdsText += peptideSequence[0:66] + '\n'
- i=66
- while (i < len(peptideSequence)):
- cdsText += 'FT ' + peptideSequence[i:i+80]
- i += 80
-
- # If we're not yet at the end of the sequence, go to the next line
- if(i < len(peptideSequence)):
- cdsText += '\n'
- # We're at the end. close the quote and new line.
- else:
- cdsText += '\"\n'
-
- return cdsText
-
- def printFeatures(self):
- featureText = ''
-
- exonIndex = 1
- intronIndex = 1
-
- geneHas3UTR = False
- geneHas5UTR = False
-
- for x in range(0,len(self.sequenceAnnotation.loci)):
- currentFeature = self.sequenceAnnotation.loci[x]
-
- # 3' UTR
- if(currentFeature.name == '3UT'):
- featureText += ('FT 3\'UTR ' + str(currentFeature.beginIndex) + '..' + str(currentFeature.endIndex) + '\n')
- featureText += ('FT /note=\"3\'UTR\"\n')
- featureText += ('FT /gene="' + str(getConfigurationValue('gene')) + '"\n')
- featureText += ('FT /allele="' + str(self.inputAllele) + '"\n')
- geneHas3UTR = True
-
- # 5' UTR
- elif(currentFeature.name == '5UT'):
- featureText += ('FT 5\'UTR ' + str(currentFeature.beginIndex) + '..' + str(currentFeature.endIndex) + '\n')
- featureText += ('FT /note=\"5\'UTR\"\n')
- featureText += ('FT /gene="' + str(getConfigurationValue('gene')) + '"\n')
- featureText += ('FT /allele="' + str(self.inputAllele) + '"\n')
- geneHas5UTR = True
-
- # Exon
- elif(currentFeature.exon):
- featureText += ('FT exon ' + str(currentFeature.beginIndex)
- + '..' + str(currentFeature.endIndex) + '\n')
- featureText += ('FT /number=' + str(exonIndex) + '\n')
- featureText += ('FT /gene="' + str(getConfigurationValue('gene')) + '"\n')
- featureText += ('FT /allele="' + str(self.inputAllele) + '"\n')
- exonIndex += 1
-
- # Intron
- else:
- featureText += ('FT intron ' + str(currentFeature.beginIndex)
- + '..' + str(currentFeature.endIndex) + '\n')
- featureText += ('FT /number=' + str(intronIndex) + '\n')
- featureText += ('FT /gene="' + str(getConfigurationValue('gene')) + '"\n')
- featureText += ('FT /allele="' + str(self.inputAllele) + '"\n')
- intronIndex += 1
-
-
- featureText += ('XX\n')
-
- # Do a quick sanity check. If we are missing either UTR I should warn the user.
- # But move on with your life, this is not worth getting upset over.
- if (not geneHas3UTR and not geneHas5UTR):
- tkMessageBox.showinfo('Missing UTRs',
- 'This sequence has no 5\' or 3\' UTR.\n\n' +
- 'Use lowercase nucleotides at the\n' +
- 'beginning and end of your DNA\n' +
- 'sequence to specify the 5\' and 3\' UTRs.' )
- elif (not geneHas5UTR):
- tkMessageBox.showinfo('Missing 5\' UTR',
- 'This sequence has no 5\' UTR.\n\n' +
- 'Use lowercase nucleotides at the\n' +
- 'beginning and end of your DNA\n' +
- 'sequence to specify the 5\' and 3\' UTRs.' )
- elif (not geneHas3UTR):
- tkMessageBox.showinfo('Missing 3\' UTR',
- 'This sequence has no 3\' UTR.\n\n' +
- 'Use lowercase nucleotides at the\n' +
- 'beginning and end of your DNA\n' +
- 'sequence to specify the 5\' and 3\' UTRs.' )
- else:
- print('The UTRs look fine.')
- pass
-
- return featureText
-
- def printSequence(self):
- sequenceText = ''
-
- completeSequence = self.sequenceAnnotation.getCompleteSequence().upper()
-
- cCount = completeSequence.count('C')
- gCount = completeSequence.count('G')
- tCount = completeSequence.count('T')
- aCount = completeSequence.count('A')
- otherCount = self.sequenceAnnotation.totalLength() - (cCount + gCount + tCount + aCount)
-
- sequenceText += ('SQ Sequence ' + str(self.sequenceAnnotation.totalLength()) + ' BP; '
- + str(aCount) + ' A; ' + str(cCount) + ' C; '
- + str(gCount) + ' G; ' + str(tCount) + ' T; '
- + str(otherCount) + ' other;\n')
-
- # Here's some logic to print the sequence information in groups of 10.
- # This format is specified in the User manual specified by IMGT.
- currentSeqIndex = 0
-
- while (currentSeqIndex < self.sequenceAnnotation.totalLength()):
- # The character code for a sequence region is two blank spaces,
- # followed by three blank spaces, for a total of 5 blanks.
- sequenceText += ' '
- sequenceRow = self.sequenceAnnotation.getCompleteSequence()[currentSeqIndex : currentSeqIndex + 60]
-
- # A sequenceChunk is 10 nucleotides in this context.
- # Format specifies up to six "chunks" per line.
- for i in range(0,6):
- sequenceChunk = sequenceRow[i*10 : (i+1)*10]
- sequenceText += sequenceChunk + ' '
-
- # If line is complete (=60 bp), we can print the nucleotide index and move on to the next row.
- if(len(sequenceRow) == 60):
- sequenceText += str(currentSeqIndex + 60) + '\n'
- # but if line is not complete (this is more likely, and more complicated.)
- else:
- # Fill with spaces to align the nucleotide indices at the end of the sequence.
- numberSpaces = 60-len(sequenceRow)
- for n in range (0, numberSpaces):
- sequenceText += ' '
- sequenceText += (str(len(sequenceRow) + currentSeqIndex) + '\n')
-
- # The next row of the sequence
- currentSeqIndex += 60
-
- return sequenceText
-
-
-"""