Ejemplo n.º 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()
Ejemplo n.º 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)


    
Ejemplo n.º 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:
Ejemplo n.º 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)


Ejemplo n.º 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
Ejemplo n.º 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)
Ejemplo n.º 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])
Ejemplo n.º 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)
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):
Ejemplo n.º 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")
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>
Ejemplo n.º 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)
Ejemplo n.º 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')




Ejemplo n.º 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')
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(
Ejemplo n.º 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))
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)

Ejemplo n.º 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")
Ejemplo n.º 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)
Ejemplo n.º 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