コード例 #1
0
def computePlateArtifacts(channelName, imageArr, bucket, plateId, embeddingName):
    flatFieldKey = "artifact/plate/" + plateId + "/" + embeddingName + "/channel-" + channelName + "-flatfield.npy"
    if bi.s3ObjectExists(bucket, flatFieldKey):
        print("FlatfieldKey already exists, skipping bucket={} key={}".format(bucket, flatFieldKey))
        return
    else:
        print("FlatfieldKey does not exist, computing bucket={} key={}".format(bucket, flatFieldKey))

    plateImgArr=[]

    for imageBucket, imageKey in imageArr:
        print("Loading bucket={} key={}".format(imageBucket, imageKey))
        imageObject = s3c.get_object(Bucket=imageBucket, Key=imageKey)
        file_stream = imageObject['Body']
        im = Image.open(file_stream)
        pix = np.array(im)
        plateImgArr.append(pix)

    print("Computing flat field image")
    npAllImages=np.array(plateImgArr).astype(np.float32)
    npAllImages = npAllImages / 65536.0

    s1 = npAllImages.shape
    s2 = s1[1:]

    npAvg = np.zeros(shape=s2, dtype=np.float32);

    for ni in range(npAllImages.shape[0]):
        npAvg = npAvg+(npAllImages[ni]/(npAllImages.shape[0]))

    h1 = histogram(npAvg, 100)

    pcut = bi.findHistCutoff(h1, 0.30)

    bi.applyImageCutoff(npAvg, pcut)

    g1 = gaussian(npAvg, 50)

    image_type = flatFieldKey[-3:]
    tmpDir = bi.getTmpDir()
    fn = tmpDir + '/' + su.uuid() + '.' + image_type

    if image_type.lower() == 'npy':
        with open(fn, 'wb') as f:
            np.save(f, g1)
        with open(fn, 'rb') as fdata:
            print("s3c.upload_fileobj: bucket={} flatFieldKey={}".format(bucket, flatFieldKey))
            s3c.upload_fileobj(fdata, bucket, flatFieldKey)
            
    else:
        max1=np.max(g1)
        min1=np.min(g1)
        g1 = (g1-min1)/(max1-min1)
        img=Image.fromarray(g1)
        img.save(fn)
        with open(fn, 'rb') as fdata:
            s3c.upload_fileobj(fdata, bucket, flatFieldKey)

    artifactClient = bioims.client('artifact')
    artifactKey = "s3key#" + flatFieldKey
    artifact = {
        "contextId" : args.plateId,
        "trainId" : "origin",
        "artifact" : artifactKey
    }
    artifactClient.createArtifact(artifact)
            
    fnPath = Path(fn)
    fnPath.unlink()
    tPath = Path(tmpDir)
    tPath.rmdir()
コード例 #2
0
import sys
import json
import boto3
sys.path.insert(0, "../src")
import bioims

tagClient = bioims.client('tag')

# for i in range(10):
#     tag = 'testTag_{}'.format(i)
#     r = tagClient.createTag(tag)
#     print(r)
    
# for i in range(10):
#     tag = 'testTag_{}'.format(i)
#     r = tagClient.getTagByValue(tag)
#     print(r)
    
# for i in range(10):
#     tag = 'testTag_{}'.format(i)
#     r = tagClient.getTagById(i)
#     print(r)
    
r = tagClient.getAllTags()
print(r)


    
コード例 #3
0
parser = argparse.ArgumentParser()

parser.add_argument('--region', type=str, help='AWS region')
parser.add_argument('--bucket', type=str, help='Bucket name for artifacts')
parser.add_argument('--plateId', type=str, help='plateId')
parser.add_argument('--embeddingName', type=str, help='embeddingName')

args = parser.parse_args()

print("region={} bucket={} plateId={} embeddingName={}".format(args.region, args.bucket, args.plateId, args.embeddingName))

os.environ['AWS_DEFAULT_REGION'] = args.region

s3c = boto3.client('s3')

imageManagementClient = bioims.client('image-management')

imlist = imageManagementClient.getImagesByPlateId(args.plateId)

channelImages = {}

for image in imlist:
    item = image['Item']
    imageBucket = item['bucket']
    imageKeyPrefix = item['key']
    channelKeys = item['channelKeys']
    for channel in channelKeys:
        name = channel['name']
        keysuffix = channel['keysuffix']
        fullpath = (imageBucket, imageKeyPrefix + keysuffix)
        if name in channelImages:
コード例 #4
0
import sys
import json
import boto3
sys.path.insert(0, "../src")
import bioims

trainClient = bioims.client('train')

embeddingName='bbbc021'
filterBucket=''
filterKey=''
executeProcessPlate='true'
useSpot='false'

r = trainClient.train(embeddingName, filterBucket, filterKey, executeProcessPlate, useSpot)
print(r)


コード例 #5
0
def handler(event, context):
    trainId = event['trainId']
    useSpotArg = event['useSpot']
    useSpot = True
    if useSpotArg.lower() == 'false':
        useSpot = False
    uniqueId = su.uuid()
    trainingConfigurationClient = bioims.client('training-configuration')
    trainInfo = trainingConfigurationClient.getTraining(trainId)
    embeddingName = trainInfo['embeddingName']
    embeddingInfo = trainingConfigurationClient.getEmbeddingInfo(embeddingName)
    trainScriptBucket = embeddingInfo['modelTrainingScriptBucket']
    trainScriptKey = embeddingInfo['modelTrainingScriptKey']
    localTrainingScript = '/tmp/bioims-training-script.py'
    getS3TextObjectWriteToPath(trainScriptBucket, trainScriptKey,
                               localTrainingScript)
    trainListArtifactKey = bp.getTrainImageListArtifactPath(trainId)
    sagemaker_session = sagemaker.Session()
    sagemaker_bucket = sagemaker_session.default_bucket()
    sagemaker_role = sagemaker.get_execution_role()
    py_version = '1.6.0'
    instance_type = embeddingInfo['trainingInstanceType']
    trainingHyperparameters = embeddingInfo['trainingHyperparameters']
    fsxInfo = getFsxInfo()
    print(fsxInfo)
    directory_path = '/' + fsxInfo['mountName']
    sgIds = []
    sgIds.append(fsxInfo['securityGroup'])
    jobName = 'bioims-' + trainId + '-' + uniqueId
    checkpoint_s3_uri = "s3://" + sagemaker_bucket + "/checkpoints/" + jobName

    file_system_input = FileSystemInput(file_system_id=fsxInfo['fsxId'],
                                        file_system_type='FSxLustre',
                                        directory_path=directory_path,
                                        file_system_access_mode='ro')

    trainingHyperparameters['train_list_file'] = trainListArtifactKey

    if useSpot:
        estimator = PyTorch(
            entry_point=localTrainingScript,
            role=sagemaker_role,
            framework_version=py_version,
            instance_count=1,
            instance_type=instance_type,
            py_version='py36',
            image_name=
            '763104351884.dkr.ecr.us-east-1.amazonaws.com/pytorch-training:1.6.0-gpu-py36-cu101-ubuntu16.04',
            subnets=fsxInfo['subnetIds'],
            security_group_ids=sgIds,
            hyperparameters=trainingHyperparameters,
            train_use_spot_instances=True,
            train_max_wait=100000,
            train_max_run=100000,
            checkpoint_s3_uri=checkpoint_s3_uri,
            debugger_hook_config=False)
    else:
        estimator = PyTorch(
            entry_point=localTrainingScript,
            role=sagemaker_role,
            framework_version=py_version,
            instance_count=1,
            instance_type=instance_type,
            py_version='py36',
            image_name=
            '763104351884.dkr.ecr.us-east-1.amazonaws.com/pytorch-training:1.6.0-gpu-py36-cu101-ubuntu16.04',
            subnets=fsxInfo['subnetIds'],
            security_group_ids=sgIds,
            hyperparameters=trainingHyperparameters,
            train_use_spot_instances=False,
            checkpoint_s3_uri=checkpoint_s3_uri,
            debugger_hook_config=False)

    trainingConfigurationClient.updateTraining(trainId, 'sagemakerJobName',
                                               jobName)

    estimator.fit(file_system_input, wait=False, job_name=jobName)

    responseInfo = {'trainingJobName': jobName}

    response = {'statusCode': 200, 'body': responseInfo}

    return response
コード例 #6
0
s3c = boto3.client('s3')

parser = argparse.ArgumentParser()
parser.add_argument('--plate', type=str, help='bbbc-021 test plate')
parser.add_argument('--extension', type=str, help='either tif or npy')
args = parser.parse_args()

PYTHON = 'python3.8'
PROJECT_TOP_DIR = '/home/ec2-user/environment/bioimage-search'
BBBC_021_BUCKET = 'bioimagesearchbbbc021stack-bbbc021bucket544c3e64-10ecnwo51127'
TEST_BUCKET = 'bioimagesearchbasestack-bioimagesearchtestbucket3-djdwcbvul5zb'

testId = shortuuid.uuid()
testPlateName = args.plate
platePreprocessingClient = bioims.client('plate-preprocessing')

testDir = '/home/ec2-user/tmp/' + testId
os.system('mkdir -p ' + testDir)
generateImageListScript = PROJECT_TOP_DIR + '/datasets/bbbc-021/scripts/list_plate_image_keys_for_channel.py'
channelList = [ 'dapi', 'tubulin', 'actin']

for channel in channelList:
    imageFilePrefix = testPlateName + '-' + channel + '-flatfield'
    imageListFilename =  imageFilePrefix + '.txt'
    imageListLocalFile = testDir + '/' + imageListFilename
    cmdList = []
    cmdList.append(PYTHON)
    cmdList.append(generateImageListScript)
    cmdList.append('--bucket')
    cmdList.append(BBBC_021_BUCKET)
コード例 #7
0
import sys
import json
from random import seed
from random import randint
import boto3
sys.path.insert(0, "../src")
import bioims

messageClient = bioims.client('message')

seed(1)

mids=[]

for i in range(10):
    r = messageClient.createMessage("message test "+str(i))
    mids.append(r)

for i in range(10):
    r = messageClient.getMessage(mids[i])
    print(r)

for i in range(10):
    print(i)
    print(mids[i])
    r = messageClient.addMessage(mids[i], "message test add3 "+str(i))
    print(r)

for i in range(10):
    print(i)
    print(mids[i])
コード例 #8
0
import sys
import json
from random import seed
from random import randint
import boto3
sys.path.insert(0, "../src")
import bioims

artifactClient = bioims.client('artifact')

# print(artifactClient.getLambdaArn())

# seed(1)

# mids=[]

# for i in range(10):
#     artifact = {
#         "contextId" : 'plate-'+str(i),
#         "trainId" : 'train-id-'+str(i),
#         "artifact" : 's3key#'+str(i),
#         "s3bucket" : 's3bucket-'+str(i),
#         "description" : 'type-'+str(i)
#     }
#     r = artifactClient.createArtifact(artifact)
#     print(r)

# for i in range(10):
#     r = artifactClient.getArtifacts('plate-'+str(i), 'train-id-'+str(i))
#     print(r)
コード例 #9
0
response = table.scan(IndexName=PLATE_INDEX)
items = response['Items']
while 'LastEvaluatedKey' in response:
    response = table.scan(IndexName=PLATE_INDEX,
                          ExclusiveStartKey=response['LastEvaluatedKey'])
    items.extend(response['Items'])

itemsLength = len(items)
print("Found {} plate:image rows".format(itemsLength))

for imageItem in items:
    allImageIds.append(imageItem['imageId'])

# Step 2: Get all valid trainIds - note this includes 'origin'

trainingConfigurationClient = bioims.client('training-configuration')
trainingsToKeep = {}
for embedding in embeddingsToKeep:
    trainList = trainingConfigurationClient.getEmbeddingTrainings('bbbc021')
    for training in trainList:
        trainId = training['trainId']
        trainingsToKeep[trainId] = True

trainCount = len(trainingsToKeep)
print("Found {} trainIds".format(trainCount))

# Step 3: iterate through allImageIds[] and delete rows
# corresponding to trainIds not on the keep list.

totalRowsDeleted = 0
for i, imageId in enumerate(allImageIds):
コード例 #10
0
import sys
import json
from random import seed
from random import randint
import boto3
sys.path.insert(0, "../src")
import bioims

labelClient = bioims.client('label')

# seed(1)

# labelClient.createCategory("category2", "description1")

# for i in range(10):
#     r = labelClient.createLabel("category2", "label"+str(i))
#     print(r)

# r = labelClient.listLabels("category2")
# print(r)

# r = labelClient.updateCategoryDescription("category2", "description3")
# print(r)

# r = labelClient.listCategories()
# print(r)

# r = labelClient.getIndex("category2", "label9")
# print(r)

# r = labelClient.deleteCategory("category2")
コード例 #11
0
import sys
import json
import boto3
import io
sys.path.insert(0, "../src")
import bioims

TEST_INPUT_BUCKET = "bioimage-search-input"
TEST_OUTPUT_BUCKET = "bioimage-search-output"

trainingConfigurationClient = bioims.client('training-configuration')
imageManagementClient = bioims.client('image-management')

# NOTE: 'origin' is not actually a valid trainId

# training = {
#     "train_id": "origin",
#     "filterBucket": "bioimage-search-input",
#     "filterIncludeKey": "",
#     "filterExcludeKey": "",
#     "embeddingName": "embedding-name1",
#     "sagemakerTrainId": "sagemaker-train-id1",
#     "trainMessageId": "train-message-id1",
#     "modelBucket" : "model-bucket1",
#     "modelKey" : "model-key1"
# }

#  SourcePlateInfo {
#     plateSourceId: <string>
#     images: [
#       wellSourceId: <string>
コード例 #12
0
import sys
import json
import boto3
sys.path.insert(0, "../src")
import bioims

searchClient = bioims.client('search')

r = searchClient.loadTagLabelMap();
print(r)

r = searchClient.startTagLoad('bbbc021')
print(r)

# trainId = 'hqTvRAmUVR5amUiAABqv85'
# imageId = 'bgzxxYiiuKEYawB7wEX8pW'
# r = searchClient.searchByImageId(trainId, imageId)
# print(r)
コード例 #13
0
import sys
import json
import boto3
sys.path.insert(0, "../src")
import bioims
import numpy as np
import base64

searchClient = bioims.client('search')
trainingConfigurationClient = bioims.client('training-configuration')

trainList = trainingConfigurationClient.getEmbeddingTrainings('bbbc021')

# This will log the current loaded trainId list to the log of the search servcie, which might be useful:
searchClient.logTrainList()

for training in trainList:
    trainId = training['trainId']
    if trainId != 'origin':
        print(trainId)
        searchClient.deleteTraining(trainId)

# Examples for deleting specific trainIds:
# searchClient.deleteTraining('7g9h5c2cS8HjAs4kdcDdRK')
# searchClient.deleteTraining('7jFcXLieHNyRTRyQ5gaDRA')




コード例 #14
0
Steps:

1. Read in the info for the trainId and its embedding
2. Read in the filter list for the trainId, if there is a list
3. Create a list to accumulate train file prefix paths
4. Get the list of compatible plateIds for the Embedding associated the trainId
5. For each plateId, get its corresponding list of imageIds
6. Filter out imageIds in the exclusion list
7. For included imageIds, generate and add paths to the train file prefix list
8. Once the entire list is generated, write to artifact path and add entries in both the train and artifact tables

"""

s3c = boto3.client('s3')

imageClient = bioims.client('image-management')
stacksDescription = imageClient.getStacksDescription()
params = {"stacksDescription": stacksDescription}
trainConfigurationClient = bioims.client('training-configuration', params)
artifactClient = bioims.client('artifact', params)


def getCompatiblePlates(embeddingInfo):
    width = embeddingInfo['inputWidth']
    height = embeddingInfo['inputHeight']
    depth = embeddingInfo['inputDepth']
    channels = embeddingInfo['inputChannels']
    request = '{{ "method": "listCompatiblePlates", "width": {}, "height": {}, "depth": {}, "channels": {}}}'.format(
        width, height, depth, channels)
    payload = bytes(request, encoding='utf-8')
    lambdaClient = boto3.client('lambda')
コード例 #15
0
import sys
import json
import boto3
sys.path.insert(0, "../src")
import bioims

imageArtifactClient = bioims.client('image-artifact')

#{
#  "input_bucket": "bioimagesearchbbbc021stack-bbbc021bucket544c3e64-1t2bv8cktyrtq",
#  "input_keys": [
#    "Week10_40111/Week10_200907_B02_s1_w18E215662-2CF7-4739-93F3-DBD0C40B78DB.tif",
#    "Week10_40111/Week10_200907_B02_s1_w2D492FCE4-15C2-4C66-99A5-E2235A93A3CC.tif",
#    "Week10_40111/Week10_200907_B02_s1_w436D0A3BC-098D-4271-B5AA-361CA0A7DC88.tif"
#  ],
#  "output_bucket": "bioimage-search-output",
#  "medium_artifact_key": "test-medium.png",
#  "thumbnail_artifact_key": "test-thumbnail.png"
#}

input_key_list = [
    "Week10_40111/Week10_200907_B02_s1_w18E215662-2CF7-4739-93F3-DBD0C40B78DB.tif",
    "Week10_40111/Week10_200907_B02_s1_w2D492FCE4-15C2-4C66-99A5-E2235A93A3CC.tif",
    "Week10_40111/Week10_200907_B02_s1_w436D0A3BC-098D-4271-B5AA-361CA0A7DC88.tif"
]

artifact_keys = ["test-medium.png", "test-thumbnail.png"]

artifact_sizes = [1000, 200]

r = imageArtifactClient.generateDefaultArtifacts(
コード例 #16
0
    sourceCompoundMap[imageSourceId] = compound

bbbc021ImageCount = len(image_df.index)
print("BBBC-021 image count={}".format(bbbc021ImageCount))

#imagesRemovedByCompound={}
moaDict = {}
i = 0
for k, v in compound_moa_map.items():
    print("i={} key={} value={}".format(i, k, v))
    moaDict[v] = True
    #    removedList = []
    #    imagesRemovedByCompound[k]=removedList
    i += 1

imageClient = bioims.client('image-management')
trainingConfigurationClient = bioims.client('training-configuration')
tagClient = bioims.client('tag')

embeddingInfo = trainingConfigurationClient.getEmbeddingInfo(EMBEDDING)
print(embeddingInfo)
width = embeddingInfo['inputWidth']
height = embeddingInfo['inputHeight']
depth = embeddingInfo['inputDepth']
channels = embeddingInfo['inputChannels']

print("list compatible plates: width={} height={} depth={} channels={}".format(
    width, height, depth, channels))
plateList = imageClient.listCompatiblePlates(width, height, depth, channels)
pl = len(plateList)
print("found {} compatible plates".format(pl))
コード例 #17
0
import sys
import json
import boto3
import io
sys.path.insert(0, "../src")
import bioims

INPUT_BUCKET = 'bioimage-search-input'
INPUT_KEY_1 = 'sourcePlateInfo_Week1_22141.json'
INPUT_KEY_2 = 'sourcePlateInfo_Week1_22123.json'
INPUT_KEY_3 = 'sourcePlateInfo_Week1_22401.json'

processPlateClient = bioims.client('process-plate')

r1 = processPlateClient.uploadSourcePlate(INPUT_BUCKET, INPUT_KEY_1)

print(r1)

# r2 = processPlateClient.uploadSourcePlate(INPUT_BUCKET, INPUT_KEY_2)

# print(r2)

# r3 = processPlateClient.uploadSourcePlate(INPUT_BUCKET, INPUT_KEY_3)

# print(r3)

コード例 #18
0
import sys
sys.path.insert(0, "../src")
import bioims

configurationClient = bioims.client('configuration')

configurationClient.setParameter("default-image-artifact-sizes", "100,1000")
configurationClient.setParameter("default-image-artifact-keys", "thumbnail-2d.png,medium-2d.png")
configurationClient.setParameter("image-preprocessing-roi-size", "128")
configurationClient.setParameter("image-preprocessing-min-voxels", "200")
コード例 #19
0
import bioims

# Inputs
#trainId = "r6KEudzQCuUtDwCzziiMZT"
#imageId = "17Sk8AHeX1idyJDBnMwEhX"

# trainingConfigurationClient = bioims.client('training-configuration')
# stacksDescription = trainingConfigurationClient.getStacksDescription()

# params = {
#     'stacksDescription': stacksDescription
# }
# imageManagementClient = bioims.client('image-management', params)

#embeddingClient = bioims.client('embedding', params)
embeddingClient = bioims.client('embedding')

# trainInfo = trainingConfigurationClient.getTraining(trainId)
# embeddingName = trainInfo['embeddingName']
# embeddingInfo = trainingConfigurationClient.getEmbeddingInfo(embeddingName)
# imageOriginItem = imageManagementClient.getImageInfo(imageId, 'origin')
# imageOrigin = imageOriginItem['Item']
# plateId = imageOrigin['plateId']

# print(trainInfo)
# print(embeddingName)
# print(embeddingInfo)
# print(imageOrigin)
# print(plateId)

#r = embeddingClient.executeImageEmbeddingCompute(trainInfo, embeddingInfo, plateId, imageId)
コード例 #20
0
def handler(event, context):
    s3c = boto3.client('s3')

    imageId = event['imageId']
    describeStacks = event['describeStacks']['Payload']['body']
    contextId = describeStacks['contextId']
    trainId = describeStacks['trainId']
    key = describeStacks['key']

    print("imageId={}".format(imageId))
    print("contextId={}".format(contextId))
    print("trainId={}".format(trainId))
    print("key={}".format(key))
    print("dataBucket={}".format(dataBucket))

    ######################################

    describeStacksParams = {"bucket": dataBucket, "key": key}

    imageManagementClient = bioims.client('image-management',
                                          describeStacksParams)
    imageInfo = imageManagementClient.getImageInfo(imageId, "origin")

    configurationClient = bioims.client('configuration', describeStacksParams)

    artifactClient = bioims.client('artifact', describeStacksParams)

    sizesStr = configurationClient.getParameter(CONFIG_SIZES_PARAM)
    artifact_sizes = sizesStr.split(',')

    keysStr = configurationClient.getParameter(CONFIG_KEYS_PARAM)
    artifact_keys = keysStr.split(',')

    # artifact/plate/<plate>/default/image/<imageId>/<key>.tif

    # {'Item':
    #     {   'trainCategory': 'moa',
    #         'imageId': 'ecG7rUcJL2asM4AvoEmom9',
    #         'plateId': 'bWb5wnbxsPPUyTVhfjV8Wh',
    #         'trainId': 'origin',
    #         'depth': '1',
    #         'plateSourceId': 'Week1_22401',
    #         'bucket': 'bioimagesearchbbbc021stack-bbbc021bucket544c3e64-10ecnwo51127',
    #         'experiment': 'BBBC021_v1',
    #         'channelKeys': [
    #             {'name': 'dapi',
    #             'keysuffix': 'Week1_22401/Week1_150607_G11_s4_w1FD01EB31-90F9-4856-AD6B-B5160E2C5BA3.tif'},
    #             {'name': 'tubulin',
    #             'keysuffix': 'Week1_22401/Week1_150607_G11_s4_w2E853D1E6-2637-488D-829C-D6AB6AD8A2E2.tif'},
    #             {'name': 'actin', 'keysuffix': 'Week1_22401/Week1_150607_G11_s4_w4768D7DAA-05D3-48FA-9223-954979D8C802.tif'}
    #             ],
    #         'wellId': 'amTSiU11M5knT9DKvgtmm5',
    #         'imageSourceId': 'Week1_150607_G11_s4_w1FD01EB31-90F9-4856-AD6B-B5160E2C5BA3',
    #         'messageId': '0e366bc9-ab55-4eeb-9d79-9f661e3ce712',
    #         'searchReady': 'VALIDATED',
    #         'height': '1024',
    #         'width': '1280',
    #         'wellSourceId': 'G11',
    #         'channels': '3',
    #         'trainLabel': 'DMSO',
    #         'key': '',
    #         'createTimestamp': '1608160666210'
    #     }
    # }

    ######################################

    plateId = imageInfo['Item']['plateId']

    input_bucket = imageInfo['Item']['bucket']

    input_keys = []
    keyPrefix = imageInfo['Item']['key']
    channelKeys = imageInfo['Item']['channelKeys']
    for channel in channelKeys:
        fullKey = keyPrefix + channel['keysuffix']
        input_keys.append(fullKey)

    artifact_key_prefix = "artifact/plate/{}/default/image/{}/".format(
        plateId, imageId)

    input_data = []

    if len(input_keys) == 0:
        return {
            'success': "False",
            'errorMsg': "one or more input keys required"
        }

    if len(artifact_keys) == 0:
        return {
            'success': "False",
            'errorMsg': "one or more artifact_keys required"
        }

    if len(artifact_sizes) != len(artifact_keys):
        return {
            'success': "False",
            'errorMsg':
            "each artifact_key must have corresponding artifact_size"
        }

    elif len(input_keys) == 1:
        input_key = input_keys[0]
        fileObject = s3c.get_object(Bucket=input_bucket, Key=input_key)
        file_stream = fileObject['Body']
        im = Image.open(file_stream)
        input_data = np.array(im)
        if len(input_data.shape) == 2:
            input_data = np.expand_dims(input_data, axis=0)

    else:
        input_arr = []
        input_shape = []
        for input_key in input_keys:
            retries = 3
            while retries > 0:
                try:
                    print("Loading {} {} remaining tries {}".format(
                        input_bucket, input_key, retries))
                    fileObject = s3c.get_object(Bucket=input_bucket,
                                                Key=input_key)
                    file_stream = fileObject['Body']
                    im = Image.open(file_stream)
                    break
                except:
                    time.sleep(1)
                    retries -= 1
            if retries == 0:
                raise Exception(
                    "Ran out of retries for accessing {} {}".format(
                        input_bucket, input_key))
            pix = np.array(im)
            input_shape.append(pix.shape)
            input_arr.append(pix)

        if not bi.checkPixShape(input_shape):
            return {
                'success': "False",
                'errorMsg': "input channel dimensions do not match"
            }

        input_data = np.array(input_arr)

    print("input_data shape=", input_data.shape)
    input_data = bi.normImageData(input_data)

    bavgFill = np.zeros(shape=input_data[0].shape, dtype=input_data.dtype)
    for c in range(input_data.shape[0]):
        channelData = input_data[c]
        h1 = histogram(channelData, 100)
        bcut = bi.findHistCutoff(h1, 0.20)
        bavg = bi.findCutoffAvg(channelData, bcut)
        bavgFill.fill(bavg)
        bi.normalizeChannel(bavgFill, channelData)

    ca = bi.getColors(input_data.shape[0])
    mip = bi.calcMip(input_data, ca)
    img = Image.fromarray(mip)

    height = input_data.shape[-2]
    width = input_data.shape[-1]
    for artifact_key, artifact_size in zip(artifact_keys, artifact_sizes):
        artifactFullKey = artifact_key_prefix + artifact_key
        image_type = artifact_key[-3:]
        asize = float(artifact_size)
        if height > width:
            artifact_height = int(asize)
            artifact_width = int((width / height) * artifact_height)
        else:
            artifact_width = int(asize)
            artifact_height = int((height / width) * artifact_width)

        artifact_img = img.resize((artifact_width, artifact_height))
        artifact_buffer = BytesIO()
        artifact_img.save(artifact_buffer, format=image_type)
        artifact_buffer.seek(0)
        s3c.upload_fileobj(artifact_buffer, dataBucket, artifactFullKey)
        artifactTableKey = "s3key#" + artifactFullKey
        artifact = {
            "contextId": imageId,
            "trainId": "origin",
            "artifact": artifactTableKey
        }
        artifactClient.createArtifact(artifact)

    return imageId