Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7110578
Update run.py
bethac07 May 13, 2020
19964e9
Delete fabfile.py
bethac07 May 13, 2020
bb81d2e
Move previous fab functions into run.py
bethac07 May 13, 2020
d15f63c
Debugging from lambda
bethac07 May 15, 2020
13058a4
tabs to spaces, issues/112
bethac07 Nov 3, 2020
e680795
merged in master
bethac07 Nov 3, 2020
dc73956
issues/105
bethac07 Nov 3, 2020
49a5d15
issues/110, fix passing USE_PLUGINS
bethac07 Nov 3, 2020
f307e29
fix tabs to spaces in run.py
bethac07 Nov 3, 2020
c4cb09c
tab/space error in run_batch_general
bethac07 Nov 3, 2020
e2ec8a0
issues/107
bethac07 Nov 3, 2020
a779061
issues/107
bethac07 Nov 3, 2020
50fe2f4
add 'cheapest' mode to monitor
bethac07 Nov 3, 2020
7ee2149
get credentials working
bethac07 Nov 3, 2020
e05c9d1
move machine type/price/date out of fleet file
bethac07 Nov 3, 2020
e6ded49
move machine type/price/date out of fleet file
bethac07 Nov 3, 2020
de17c9f
support running of monitor in cheapest mode
bethac07 Nov 3, 2020
318d78a
fix indentation in CHECK_IF_DONE
bethac07 Nov 3, 2020
dee8ea3
move cpDone
bethac07 Nov 3, 2020
5264a14
don't move done file, you still need to check it
bethac07 Nov 3, 2020
6d9e2ab
don't move done file, you still need to check it
bethac07 Nov 3, 2020
3deaa20
fix cmdstm for batch files
bethac07 Nov 3, 2020
0a0b27b
fixes to make log export work
bethac07 Nov 4, 2020
08e7fe8
python 3 support in run.py
bethac07 Nov 4, 2020
bc0afc6
move Python2 files to their own folder
bethac07 Nov 4, 2020
33a3a23
pin watchtower to last python2 version
bethac07 Nov 4, 2020
6e3c36f
support for CellProfiler 4
bethac07 Nov 4, 2020
54f77d0
fix alarm time designation
bethac07 Nov 4, 2020
186af22
Update README.md
bethac07 Nov 4, 2020
14c444e
Update requirements.txt
bethac07 Nov 4, 2020
dcfa1f7
Update LICENSE
bethac07 Nov 4, 2020
e0fcb72
Add a bit about run_batch_general
bethac07 Nov 5, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
merged in master
  • Loading branch information
bethac07 committed Nov 3, 2020
commit e680795e912747f1ec081f91d458c9b7c9efe97c
3 changes: 3 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@
CHECK_IF_DONE_BOOL = 'True' #True or False- should it check if there are a certain number of non-empty files and delete the job if yes?
EXPECTED_NUMBER_FILES = 7 #What is the number of files that trigger skipping a job?
MIN_FILE_SIZE_BYTES = 1 #What is the minimal number of bytes an object should be to "count"?

# PLUGINS
USE_PLUGINS = 'True'
155 changes: 155 additions & 0 deletions run_batch_general.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import json
import boto3
import string
import os
import posixpath
class JobQueue():

def __init__(self,name=None):
self.sqs = boto3.resource('sqs')
self.queue = self.sqs.get_queue_by_name(QueueName=name+'Queue')
self.inProcess = -1
self.pending = -1

def scheduleBatch(self, data):
msg = json.dumps(data)
response = self.queue.send_message(MessageBody=msg)
print 'Batch sent. Message ID:',response.get('MessageId')

#project specific stuff
topdirname='' #PROJECTNAME
projectname='' #PROJECTNAME
batchsuffix='' #BATCHNAME
rows=list(string.ascii_uppercase)[0:8]
columns=range(1,13)
sites=range(1,18)
platelist=[] # PLATEFOLDERNAMES
illumpipename='illum.cppipe'
qcpipename='qc.cppipe'
analysispipename='analysis.cppipe'
batchpipenameillum='Batch_data_illum.h5'
batchpipename='Batch_data.h5'

#not project specific, unless you deviate from the structure
startpath=posixpath.join('projects',topdirname)
pipelinepath=posixpath.join(startpath,os.path.join('workspace/pipelines',batchsuffix))
illumoutpath=posixpath.join(startpath,os.path.join(batchsuffix,'illum'))
QCoutpath=posixpath.join(startpath,os.path.join('workspace/qc',os.path.join(batchsuffix,'results')))
analysisoutpath=posixpath.join(startpath,os.path.join('workspace/analysis',batchsuffix))
inputpath=posixpath.join(startpath,os.path.join('workspace/qc',os.path.join(batchsuffix,'rules')))
datafilepath=posixpath.join(startpath,os.path.join('workspace/load_data_csv',batchsuffix))
anlysisoutputstructure="Metadata_Plate/analysis/Metadata_Plate-Metadata_Well-Metadata_Site"
batchpath=posixpath.join(startpath,os.path.join('workspace/batchfiles',batchsuffix))

def MakeIllumJobs(mode='repurp'):
illumqueue = JobQueue(projectname+'_Illum')
for toillum in platelist:
if mode=='repurp':
templateMessage_illum = {'Metadata': 'Metadata_Plate='+toillum,
'pipeline': posixpath.join(pipelinepath,illumpipename),'output': illumoutpath,
'input': inputpath, 'data_file':posixpath.join(datafilepath,toillum+'.csv')}
elif mode=='batch':
templateMessage_illum = {'Metadata': 'Metadata_Plate='+toillum,
'pipeline': posixpath.join(batchpath,batchpipenameillum),
'output': illumoutpath,
'input':inputpath,
'data_file': posixpath.join(batchpath,batchpipenameillum)
}
else:
templateMessage_illum = {'Metadata': 'Metadata_Plate='+toillum,
'pipeline': posixpath.join(pipelinepath,illumpipename),'output': illumoutpath,
'input': inputpath, 'data_file':posixpath.join(datafilepath,untruncatedplatedict[toillum],'load_data.csv')}

illumqueue.scheduleBatch(templateMessage_illum)

print 'Illum job submitted. Check your queue'

def MakeQCJobs(repurp=False):
qcqueue = JobQueue(projectname+'_QC')
for toqc in platelist:
for eachrow in rows:
for eachcol in columns:
if repurp==False:
templateMessage_qc = {'Metadata': 'Metadata_Plate='+toqc+',Metadata_Well='+eachrow+'%02d' %eachcol,
'pipeline': posixpath.join(pipelinepath,qcpipename),
'output': QCoutpath,
'input': inputpath,
'data_file': posixpath.join(datafilepath,toqc+'.csv')
}
else:
templateMessage_qc = {'Metadata': 'Metadata_Plate='+toqc+',Metadata_Well='+eachrow+'%02d' %eachcol,
'pipeline': posixpath.join(pipelinepath,qcpipename),
'output': QCoutpath,
'input': inputpath,
'data_file': posixpath.join(datafilepath,untruncatedplatedict[toqc],'load_data.csv')
}
qcqueue.scheduleBatch(templateMessage_qc)

print 'QC job submitted. Check your queue'

def MakeQCJobs_persite(repurp=False):
qcqueue = JobQueue(projectname+'_QC')
for toqc in platelist:
for eachrow in rows:
for eachcol in columns:
for eachsite in sites:
if repurp==False:
templateMessage_qc = {'Metadata': 'Metadata_Plate='+toqc+',Metadata_Well='+eachrow+'%02d' %eachcol+',Metadata_Site='+str(eachsite),
'pipeline': posixpath.join(pipelinepath,qcpipename),
'output': QCoutpath,
'input': inputpath,
'data_file': posixpath.join(datafilepath,toqc+'.csv')
}
else:
templateMessage_qc = {'Metadata': 'Metadata_Plate='+toqc+',Metadata_Well='+eachrow+'%02d' %eachcol+',Metadata_Site='+str(eachsite),
'pipeline': posixpath.join(pipelinepath,qcpipename),
'output': QCoutpath,
'input': inputpath,
'data_file': posixpath.join(datafilepath,untruncatedplatedict[toqc],'load_data.csv')
}

qcqueue.scheduleBatch(templateMessage_qc)

print 'QC job submitted. Check your queue'


def MakeAnalysisJobs(mode='repurp'):
analysisqueue = JobQueue(projectname+'_Analysis')
for toanalyze in platelist:
for eachrow in rows:
for eachcol in columns:
for eachsite in sites:
if mode=='repurp':
templateMessage_analysis = {'Metadata': 'Metadata_Plate='+toanalyze+',Metadata_Well='+eachrow+'%02d' %eachcol+',Metadata_Site='+str(eachsite),
'pipeline': posixpath.join(pipelinepath,analysispipename),
'output': analysisoutpath,
'output_structure':anlysisoutputstructure,
'input':inputpath,
'data_file': posixpath.join(datafilepath,toanalyze+'_with_illum.csv')
}
elif mode=='batch':
templateMessage_analysis = {'Metadata': 'Metadata_Plate='+toanalyze+',Metadata_Well='+eachrow+'%02d' %eachcol+',Metadata_Site='+str(eachsite),
'pipeline': posixpath.join(batchpath,batchpipename),
'output': analysisoutpath,
'output_structure':anlysisoutputstructure,
'input':inputpath,
'data_file': posixpath.join(batchpath,batchpipename)
}
else:
templateMessage_analysis = {'Metadata': 'Metadata_Plate='+toanalyze+',Metadata_Well='+eachrow+'%02d' %eachcol+',Metadata_Site='+str(eachsite),
'pipeline': posixpath.join(pipelinepath,analysispipename),
'output': analysisoutpath,
'output_structure':anlysisoutputstructure,
'input':inputpath,
'data_file': posixpath.join(datafilepath,untruncatedplatedict[toanalyze],'load_data_with_illum.csv')
}

analysisqueue.scheduleBatch(templateMessage_analysis)

print 'Analysis job submitted. Check your queue'

#MakeIllumJobs(mode='batch')
#MakeQCJobs(repurp=True)
#MakeQCJobs_persite(repurp=True)
#MakeAnalysisJobs(mode='batch')

7 changes: 7 additions & 0 deletions worker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# This wraps the cellprofiler docker registry
#


FROM cellprofiler/cellprofiler:3.1.9

# Install S3FS
Expand Down Expand Up @@ -56,6 +57,12 @@ COPY instance-monitor.py .
COPY run-worker.sh .
RUN chmod 755 run-worker.sh

RUN git clone https://github.com/CellProfiler/CellProfiler-plugins.git
WORKDIR /home/ubuntu/CellProfiler-plugins
RUN \
pip install -r requirements.txt

WORKDIR /home/ubuntu
ENTRYPOINT ["./run-worker.sh"]
CMD [""]

16 changes: 11 additions & 5 deletions worker/cp-worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

DATA_ROOT = '/home/ubuntu/bucket'
LOCAL_OUTPUT = '/home/ubuntu/local_output'
PLUGIN_DIR = '/home/ubuntu/CellProfiler-plugins'
QUEUE_URL = os.environ['SQS_QUEUE_URL']
AWS_BUCKET = os.environ['AWS_BUCKET']
LOG_GROUP_NAME= os.environ['LOG_GROUP_NAME']
Expand All @@ -26,6 +27,10 @@
MIN_FILE_SIZE_BYTES = 1
else:
MIN_FILE_SIZE_BYTES = int(os.environ['MIN_FILE_SIZE_BYTES'])
if 'USE_PLUGINS' not in os.environ:
USE_PLUGINS = 'False'
else:
USE_PLUGINS = os.environ['USE_PLUGINS']

#################################
# CLASS TO HANDLE THE SQS QUEUE
Expand Down Expand Up @@ -127,18 +132,19 @@ def runCellProfiler(message):
remoteOut= os.path.join(message['output'],metadataID)
replaceValues = {'PL':message['pipeline'], 'OUT':localOut, 'FL':message['data_file'],
'DATA': DATA_ROOT, 'Metadata': message['Metadata'], 'IN': message['input'],
'MetadataID':metadataID }
'MetadataID':metadataID, 'PLUGINS':PLUGIN_DIR }
# See if this is a message you've already handled, if you've so chosen
if CHECK_IF_DONE_BOOL.upper() == 'TRUE':
try:
s3client=boto3.client('s3')
bucketlist=s3client.list_objects(Bucket=AWS_BUCKET,Prefix=remoteOut+'/')
objectsizelist=[k['Size'] for k in bucketlist['Contents']]
objectsizelist = [i for i in objectsizelist if i >= MIN_FILE_SIZE_BYTES]
if len(objectsizelist)>=int(EXPECTED_NUMBER_FILES):
return 'SUCCESS'
except KeyError: #Returned if that folder does not exist
pass
if len(objectsizelist)>=int(EXPECTED_NUMBER_FILES):
logger.removeHandler(watchtowerlogger)
return 'SUCCESS'
except KeyError: #Returned if that folder does not exist
pass

# Start loggging now that we have a job we care about
watchtowerlogger=watchtower.CloudWatchLogHandler(log_group=LOG_GROUP_NAME, stream_name=metadataID,create_log_group=False)
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.