def upload_reagent_prep_info(rdict, sheetobject):
    uploadtarget = sheetobject.range('D3:F11')
    uploadlist = []
    reagentcount = 1
    for reagentnum, reagentobject in rdict.items():
        while int(reagentnum) > reagentcount:
            uploadlist.extend(
                ['null'] * 3
            )  #3 setby number of steps in reagent prep (see if section below)
            reagentcount += 1
        if int(reagentnum) == reagentcount:
            uploadlist.append(reagentobject.preptemperature)
            uploadlist.append(reagentobject.prepstirrate)
            uploadlist.append(reagentobject.prepduration)
            reagentcount += 1
    count = 0
    for cell in uploadtarget:
        try:
            cell.value = uploadlist[count]
            count += 1
        except:
            count += 1
    sheetobject.update_cells(uploadtarget)

    # Upload prerxntemps
    prerxn_temp_cells = _get_reagent_header_cells(column='H')
    num_reagents = int(
        lab_safeget(config.lab_vars, globals.get_lab(), 'max_reagents')) + 1
    for i in range(1, num_reagents):
        try:
            payload = rdict[str(i)].prerxntemp
        except KeyError:
            payload = 'null'

        sheetobject.update_acell(prerxn_temp_cells[i - 1], payload)
Esempio n. 2
0
def quasirandom_generation_pipeline(vardict, chemdf, rxndict, edict, rdict,
                                    old_reagents, climits):
    """

    TODO: Document rdict
    :param vardict: dictionary built from devconfig
    :param chemdf: chemical dataframe with descriptions of all chemicals in the reaction
    :param rxndict: complete key-value pairing from specification interface (front end xlsx as of 2.56)
    :param edict: dictionary of experiments (see documentation)
    :param rdict: dictionary of reagents defining the concentration space to be sampled.  (see documentation)
    :param old_reagents: dictionary of reagents to subtract from statespace (same structure as rdict)
    :param climits:
    :return:
    """
    erdf, ermmoldf, emsumdf, model_info_df = qrandom.preprocess_and_sample(
        chemdf, vardict, rxndict, edict, rdict, old_reagents, climits)
    # Clean up dataframe for robot file -> create xls --> upload
    erdf = expint.cleanvolarray(erdf,
                                maxr=lab_safeget(config.lab_vars,
                                                 globals.get_lab(),
                                                 'max_reagents'))

    # Export additional information files for later use / storage
    ermmolcsv = ('localfiles/%s_mmolbreakout.csv' % rxndict['RunID'])
    abstract_reagent_colnames(ermmoldf)
    ermmoldf.to_csv(ermmolcsv)
    emsumcsv = ('localfiles/%s_nominalMolarity.csv' % rxndict['RunID'])
    emsumdf.to_csv(emsumcsv)
    # List to send for uploads
    secfilelist = [ermmolcsv, emsumcsv, vardict['exefilename']]
    return emsumdf, secfilelist, erdf, model_info_df
def prebuildvalidation(rxndict, vardict):
    '''handles validation functions for xls input file

    takes the rxndict as input and performs validation on the input to ensure the proper structure
    -- currently underdeveloped
    '''
    reagent_alias = lab_safeget(config.lab_vars, globals.get_lab(),
                                'reagent_alias')
    modlog = logging.getLogger('capture.prebuildvalidation')
    validate_experiment_form_and_number(rxndict)
    expcount(rxndict)
    expwellcount(rxndict)
    reagconcdefs(rxndict)
    used_reagents_are_specified(rxndict, vardict['exefilename'], reagent_alias)

    # multi_stock only supported for wolfram
    if rxndict.get('multi_stock_sampling'):
        modlog.warning('Using Multi Stock Sampling')
        if config.sampler != 'wolfram':
            raise ValueError(
                'Multistock sampling is activated but sampler is set to "{}"'.
                format(config.sampler),
                'Sampler must be "wolfram" to use multistock sampling')
    modlog.info('User entry is configured correctly.  Proceeding with run')

    if not rxndict['lab'] in config.lab_vars.keys():
        modlog.error('User selected a lab that was not supported. Closing run')
        sys.exit()
def upload_reagent_specifications(finalexportdf, sheet):
    """upload rxndict, finalexportdf to gc target, returns the used gsheets object

    :param finalexportdf: datframe containing pre-ordered and normalized abbreviations, nomial amounts and units \n
    :type finalexportdf: pandas dataframe object \n 
    :param sheet: google sheet string indicating the target file for uploading the finalexport df \n
    :type sheet: str \n

    :return: NONE - creates online object in run directory
    """

    # get lab-specific config variables
    reagent_interface_amount_startrow = lab_safeget(
        config.lab_vars, globals.get_lab(),
        'reagent_interface_amount_startrow')
    max_reagents = lab_safeget(config.lab_vars, globals.get_lab(),
                               'max_reagents')

    update_sheet_column(sheet,
                        finalexportdf['chemabbr'],
                        col_index='B',
                        start_row=reagent_interface_amount_startrow)
    update_sheet_column(sheet,
                        finalexportdf['nominal_amount'],
                        col_index='C',
                        start_row=reagent_interface_amount_startrow)
    update_sheet_column(sheet,
                        finalexportdf['Unit'],
                        col_index='E',
                        start_row=reagent_interface_amount_startrow)

    # add in actual amount column for specified reagents
    # only adds null to rows where there is no chemical
    nulls = finalexportdf['actualsnull'].values.tolist()
    nulls = [val if val == 'null' else '' for val in nulls]
    update_sheet_column(sheet,
                        nulls,
                        col_index='D',
                        start_row=reagent_interface_amount_startrow)

    # add nulls to actual amount column for unspecified reagents
    null_start = reagent_interface_amount_startrow + len(finalexportdf)
    maxreagentchemicals = lab_safeget(config.lab_vars, globals.get_lab(),
                                      'maxreagentchemicals')
    num_nulls = (max_reagents - len(finalexportdf.reagentnames.unique())) * (
        maxreagentchemicals + 1)
    nulls = ['null'] * num_nulls
Esempio n. 5
0
def upload_files_to_gdrive(opdir, secdir, secfilelist, filelist, runID,
                           eclogfile):
    """Upload files to Google Drive

    :param opdir: main google drive directory to upload to
    :param secdir: subdirectory in opdir in which logfiles and executables are written
    :param secfilelist: files to be written to secdir
    :param filelist: files that go in opdir
    :param runID: the ID of this run of ESCALATE
    :param eclogfile: local path to logfile for the run
    :return: None
    """
    drive = get_drive_auth()

    for file in filelist:
        outfile = drive.CreateFile(
            {"parents": [{
                "kind": "drive#fileLink",
                "id": opdir
            }]})
        outfile.SetContentFile(file)
        outfile['title'] = file.split('/')[1]
        outfile.Upload()

    #  Data files that need to be stored but are not crucial for performers
    for secfile in secfilelist:
        outfile = drive.CreateFile(
            {"parents": [{
                "kind": "drive#fileLink",
                "id": secdir
            }]})
        outfile.SetContentFile(secfile)
        outfile['title'] = secfile.split('/')[1]
        outfile.Upload()

    requested_folders = lab_safeget(config.lab_vars, globals.get_lab(),
                                    'required_folders')
    if requested_folders:
        for folder in requested_folders:
            create_drive_folder(folder, opdir)

    logfile = drive.CreateFile(
        {"parents": [{
            "kind": "drive#fileLink",
            "id": opdir
        }]})
    logfile.SetContentFile(eclogfile)
    logfile['title'] = '%s.log' % runID
    logfile.Upload()
    wdir = drive.CreateFile({'id': opdir})
    swdir = drive.CreateFile({'id': secdir})
    modlog.info('%s successfully uploaded to %s' %
                (logfile['title'], swdir['title']))

    for item in filelist:
        modlog.info('%s successfully uploaded to %s' % (item, wdir['title']))
    for item in secfilelist:
        modlog.info('%s successfully uploaded to %s' % (item, swdir['title']))
    print('File Upload Complete')
Esempio n. 6
0
def stateset_generation_pipeline(vardict, chemdf, rxndict, edict, rdict,
                                 volspacing):
    """Generate stateset and associated files
    """
    erdf, ermmoldf, emsumdf = statespace.preprocess_and_enumerate(
        chemdf, rxndict, edict, rdict, volspacing)

    # Clean up dataframe for robot file -> create xls --> upload
    erdfrows = erdf.shape[0]
    erdf = expint.cleanvolarray(
        erdf, lab_safeget(config.lab_vars, globals.get_lab(), 'max_reagents'))
    abstract_reagent_colnames(erdf)

    ermmolcsv = 'localfiles/%s_mmolbreakout.csv' % rxndict['RunID']
    abstract_reagent_colnames(ermmoldf)
    ermmoldf.to_csv(ermmolcsv)

    # has no reagent names
    emsumcsv = 'localfiles/%s_nominalMolarity.csv' % rxndict['RunID']
    emsumdf.to_csv(emsumcsv)

    statesetfile = 'localfiles/%sstateset.csv' % rdict['2'].chemicals
    prerun = 'localfiles/%sstateset.link.csv' % rdict['2'].chemicals

    # Hardcode the inchikey lookup for the "amine" aka chemical 3 for the time being, though there must be a BETTER WAY!
    inchilist = [(chemdf.loc[rdict['2'].chemicals[1], "InChI Key (ID)"])
                 ] * erdfrows
    inchidf = pd.DataFrame(inchilist, columns=['_rxn_organic-inchikey'])

    #highly specific curation for the wf1 cp dataflow # drops solvent column
    for chemical in emsumdf.columns:
        chemicalname = chemical.split(' ')[0]
        if chemicalname in vardict['solventlist'] and chemicalname != "FAH":
            solventheader = chemical

    emsumdf.drop(columns=[solventheader], inplace=True)
    emsumdf.rename(columns={
        "%s [M]" % rdict['2'].chemicals[0]: "_rxn_M_inorganic",
        "%s [M]" % rdict['2'].chemicals[1]: "_rxn_M_organic",
        "%s [M]" % rdict['7'].chemicals[0]: "_rxn_M_acid"
    },
                   inplace=True)

    modlog.warning(
        "The following chemicals have been assigned generic column names:")
    modlog.warning("%s [M] --> _rxn_M_inorganic" % rdict['2'].chemicals[0])
    modlog.warning("%s [M] --> _rxn_M_organic" % rdict['2'].chemicals[1])
    modlog.warning("%s [M] --> _rxn_M_acid" % rdict['7'].chemicals[0])

    ddf = stateset.augdescriptors(inchidf, rxndict, erdfrows)
    prerun_df = pd.concat([erdf, emsumdf, ddf], axis=1)
    stateset_df = pd.concat([emsumdf, ddf], axis=1)
    # stateset_df = emsumdf #toggle to prevent state space from having all of the features added # todo ??
    prerun_df.to_csv(prerun)
    stateset_df.to_csv(statesetfile)

    uploadlist = [prerun, statesetfile]
    secfilelist = [ermmolcsv, emsumcsv, vardict['exefilename']]
    return emsumdf, uploadlist, secfilelist, rdict
def _get_reagent_header_cells(column: str):
    """Get all cells in the rows that start each reagent for a given colum

    :param column: (str) in {A, B, ..., Z, AA, AB, ...}
    """
    startrow = lab_safeget(config.lab_vars, globals.get_lab(),
                           'reagent_interface_amount_startrow')
    reagent_interface_step = int(
        lab_safeget(config.lab_vars, globals.get_lab(),
                    'maxreagentchemicals')) + 1
    num_reagents = lab_safeget(config.lab_vars, globals.get_lab(),
                               'max_reagents')
    stoprow = startrow + reagent_interface_step * num_reagents
    result = [
        column + str(i)
        for i in range(startrow, stoprow, reagent_interface_step)
    ]
    return result
def postbuildvalidation(rxndict, vardict, rdict, edict, chemdf):
    reagent_alias = lab_safeget(config.lab_vars, globals.get_lab(),
                                'reagent_alias')

    modlog = logging.getLogger('capture.postbuildvalidation')
    #        modlog.error("Fatal error. Reagents and chemicals are over constrained. Recheck user options!")
    validate_solvent_positions(rdict, vardict['solventlist'], reagent_alias,
                               chemdf)
    modlog.info('Experiment successfully constructed.')
Esempio n. 9
0
def abstract_reagent_colnames(df, inplace=True):
    """Replace instances of 'Reagent' with devconfig.REAGENT_ALIAS

    :param df: dataframe to rename
    :return: None or pandas.DataFrame (depending on inplace)
    """
    reagent_alias = lab_safeget(config.lab_vars, globals.get_lab(),
                                'reagent_alias')
    result = df.rename(
        columns=lambda x: re.sub('[Rr]eagent', reagent_alias, x),
        inplace=inplace)
    return result
def build_reagent_spec_df(rxndict, vardict, erdf, rdict, chemdf):
    """Build the dataframe for the bottom portion of the reagent preparation_interface

    :param rxndict:
    :param vardict:
    :param erdf:
    :param rdict:
    :param chemdf:
    :return:
    """
    modlog.info('Starting reagent interface upload')
    chemical_names_df = build_chemical_names_df(
        rdict,
        lab_safeget(config.lab_vars, globals.get_lab(), 'maxreagentchemicals'))
    reagent_target_volumes = get_reagent_target_volumes(
        erdf, rxndict['reagent_dead_volume'] * 1000)
    nominals_df = build_nominals_v1(
        rdict, chemical_names_df, reagent_target_volumes,
        vardict['solventlist'],
        lab_safeget(config.lab_vars, globals.get_lab(),
                    'maxreagentchemicals'), chemdf)
    reagent_spec_df = pd.concat([chemical_names_df, nominals_df], axis=1)
    return reagent_spec_df
def upload_aliased_cells(sheet):
    """Upload cells containing reagent alias to the reagent interface"""

    # Value used in googlesheet as placeholder for reagent alias
    cell_alias_pat = '<Reagent>'

    # Cells in googlesheet containing reagent alias:
    aliased_cells = ['C1', 'C2']

    # Reagent<i> cells at bottom of sheet (all in col A, regularly spaced):
    aliased_cells.extend(_get_reagent_header_cells('A'))

    reagent_alias = lab_safeget(config.lab_vars, globals.get_lab(),
                                'reagent_alias')
    for cell in aliased_cells:
        current_value = sheet.acell(cell).value
        new_value = current_value.replace(cell_alias_pat, reagent_alias)
        sheet.update_acell(cell, new_value)

    return
Esempio n. 12
0
def ChemicalData(lab):
    """
    Uses google api to gather the chemical inventory targeted by labsheet 'chemsheetid' in dev config

    Parameters
    ----------
    lab : abbreviation of the lab
        lab is specified as the suffix of a folder and the available
        options are included in the lab_vars of the devconfig.py file

    Returns 
    --------
    chemdf : pandas df of the chemical inventory
    """
    sleep_timer = 0
    chemdf = 0  #just create a 'blank' object
    while not isinstance(chemdf, pd.DataFrame):
        try:
            gc = get_gdrive_client()
            chemsheetid = globals.lab_safeget(lab_vars, lab, 'chemsheetid')
            ChemicalBook = gc.open_by_key(chemsheetid)
            chemicalsheet = ChemicalBook.get_worksheet(0)
            chemical_list = chemicalsheet.get_all_values()
            chemdf = pd.DataFrame(chemical_list, columns=chemical_list[0])
            chemdf = chemdf.iloc[1:]
            chemdf = chemdf.reset_index(drop=True)
            chemdf = chemdf.set_index(['InChI Key (ID)'])
        except APIError as e:
            modlog.info(e.response)
            modlog.info(sys.exc_info())
            modlog.info(
                'During download of {} chemical inventory sever request limit was met'
                .format(lab))
            sleep_timer = 15.0
            time.sleep(sleep_timer)
    modlog.info(f'Successfully loaded the chemical inventory from {lab}')
    return (chemdf)
def upload_modelinfo_observation_interface(model_info_df, gc, interface_uid):
    '''push the model information to the observation interface

    :param model_info_df: 2xN data frame with 'modelname' and 'participantname' 
                          as columns and N being the total number of experiments
    :param interface_uid: google sheets observation UID 
    :return: NULL
    '''
    sheet = gc.open_by_key(interface_uid).sheet1

    observation_dict = lab_safeget(config.lab_vars, globals.get_lab(),
                                   'observation_interface')
    modeluid_col = observation_dict['modeluid_col']
    participantuid_col = observation_dict['participantuid_col']

    update_sheet_column(sheet,
                        data=model_info_df['modelname'],
                        col_index=modeluid_col,
                        start_row=2)
    update_sheet_column(sheet,
                        data=model_info_df['participantname'],
                        col_index=participantuid_col,
                        start_row=2)
    return
Esempio n. 14
0
def copy_drive_templates(opdir, RunID, includedfiles):
    """Copy template gdrive files into gdrive directory for this run

    :param opdir: gdrive directory for this run
    :param RunID: ID of this run
    :param includedfiles: files to be copied from template gdrive directory
    :return: a referenced dictionary of files (title, Gdrive ID)
    """
    drive = get_drive_auth()
    template_folder = lab_safeget(config.lab_vars, globals.get_lab(),
                                  'template_folder')
    file_template_list = drive.ListFile({
        'q':
        "'%s' in parents and trashed=false" % template_folder
    }).GetList()
    for templatefile in file_template_list:
        basename = templatefile['title']
        if basename in includedfiles:
            drive.auth.service.files().copy(fileId=templatefile['id'],
                                            body={
                                                "parents": [{
                                                    "kind": "drive#fileLink",
                                                    "id": opdir
                                                }],
                                                'title':
                                                '%s_%s' % (RunID, basename)
                                            }).execute()

    newdir_list = drive.ListFile({
        'q':
        "'%s' in parents and trashed=false" % opdir
    }).GetList()
    new_dict = {}
    for file1 in newdir_list:
        new_dict[file1['title']] = file1['id']
    return new_dict
Esempio n. 15
0
def get_reagent_number_as_string(reagent_str):
    """Get the number from a string representation"""
    reagent_alias = lab_safeget(config.lab_vars, globals.get_lab(),
                                'reagent_alias')
    reagent_pat = re.compile('([Rr]eagent|{})(\d+)'.format(reagent_alias))
    return reagent_pat.match(reagent_str).group(2)
def upload_observation_interface_data(rxndict, vardict, gc, interface_uid):
    """

    :param gc:
    :param interface_uid:
    :return:
    """

    sheet = gc.open_by_key(interface_uid).sheet1

    # todo: only build this once: we now read the manual spec sheet three times...
    experiment_names = build_experiment_names_df(rxndict, vardict)
    #    experiment_index = range(1, len(experiment_names) + 1)
    total_exp_entries = int(rxndict['wellcount'])
    #TODO: organize code around workflow handling... at this moment moving to specify level seems appropriate
    # Maybe setting the variables for actions in dictionaries that can be created through some interface
    # TODO: This needs to be moved to a dict in the devconfig with clear configuration standards
    uploadlist = []
    if rxndict['ExpWorkflowVer'] >= 3 and rxndict['ExpWorkflowVer'] < 4:
        uploadtarget = sheet.range(f'A2:D{total_exp_entries+1}')

        df = MakeWellList_WF3_small("nothing", total_exp_entries)

        exp_counter = list(range(1,
                                 total_exp_entries + 1))  # +1 to fix off by 1
        wellnamelist = df['Vial Site'].values.tolist()
        letter_list = [x[:1] for x in wellnamelist]
        number_list = [x[1:] for x in wellnamelist]

        count = 0
        while count < len(exp_counter):
            uploadlist.append(exp_counter[count])
            uploadlist.append(letter_list[count])
            uploadlist.append(number_list[count])
            uploadlist.append(wellnamelist[count])
            count += 1

        count = 0
        for cell in uploadtarget:
            try:
                cell.value = uploadlist[count]
                count += 1
            except:
                count += 1
        sheet.update_cells(uploadtarget)

    else:
        if globals.get_lab() == 'MIT_PVLab':
            uploadtarget = sheet.range(f'A2:A{total_exp_entries+1}')
            df = MakeWellList("nothing", total_exp_entries)

            uploadlist = list(range(1, total_exp_entries +
                                    1))  # +1 to fix off by 1

            count = 0
            for cell in uploadtarget:
                try:
                    cell.value = uploadlist[count]
                    count += 1
                except:
                    count += 1
            sheet.update_cells(uploadtarget)

        else:
            uploadtarget = sheet.range(f'A2:D{total_exp_entries+1}')

            df = MakeWellList("nothing", total_exp_entries)

            exp_counter = list(range(1, total_exp_entries +
                                     1))  # +1 to fix off by 1
            wellnamelist = df['Vial Site'].values.tolist()
            letter_list = [x[:1] for x in wellnamelist]
            number_list = [x[1:] for x in wellnamelist]

            count = 0
            while count < len(exp_counter):
                uploadlist.append(exp_counter[count])
                uploadlist.append(letter_list[count])
                uploadlist.append(number_list[count])
                uploadlist.append(wellnamelist[count])
                count += 1

            count = 0
            for cell in uploadtarget:
                try:
                    cell.value = uploadlist[count]
                    count += 1
                except:
                    count += 1
            sheet.update_cells(uploadtarget)

    obs_columns = lab_safeget(config.lab_vars, globals.get_lab(),
                              'observation_interface')
    update_sheet_column(sheet,
                        data=experiment_names['Experiment Names'],
                        col_index=obs_columns['uid_col'],
                        start_row=2)
    return
def LBLrobotfile(rxndict, vardict, erdf):
    """Write to excel file for LBL Nimbus and return filename
    TODO: denote these as LBL specific, generalize action specification and sequences

    :param erdf: should contain the experimental reaction data frame which consists of the volumes of each
    reagent in each experiment to be performed.

    ALSO CONTAINS:
    New Development code .... needs debugging 
    Write to excel file for MIT Human and return filename

    todo:
        * write this file for ALL experiments
        * robot just reads this general representation and writes to specific format
            * e.g. Nimbus gets its own format
        * This solves report issue
            * report looks for specification file, and if it cant find it looks for RobotInput.xls


    :param erdf: should contain the experimental reaction data frame which consists of the volumes of each
    reagent in each experiment to be performed.
    """
    vol_ar = volarray(erdf, lab_safeget(config.lab_vars, globals.get_lab(), 'max_reagents'))

    # If the additional actions were not specified, just leave the cells blank.
    # TODO: CLEAN UP THE ABOVE AFTER THE IMMEDIATE MIT PUSH.
    userAction0 = rxndict.get('Additional_action_1_description', 0)
    userAction1 = rxndict.get('Additional_action_2_description', '')
    userActionValue0 = rxndict.get('Additional_action_1_value', 0)
    userActionValue1 = rxndict.get('Additional_action_2_value', '')
    if userAction0 == 0:
        userAction0 = ""
        userActionValue0 = ''
    if userAction1 == 0:
        userAction1 = ""
        userActionValue1 = ''

    reagent_alias = lab_safeget(config.lab_vars, globals.get_lab(), 'reagent_alias')
    rxn_conditions = pd.DataFrame({
        reagent_alias + 's': [reagent_alias + str(i+1) for i in range(len(vol_ar))],
        reagent_alias + ' identity': [str(i+1) for i in range(len(vol_ar))],
        'Liquid Class': vol_ar,
        reagent_alias + ' Temperature': [rxndict['reagents_prerxn_temperature']] * len(vol_ar)
    })

    robotfiles = []

    if rxndict['ExpWorkflowVer'] >= 3 and rxndict['ExpWorkflowVer'] < 4:
        rxn_parameters = pd.DataFrame({
            'Reaction Parameters': ['Temperature (C):', 
                                    'Stir Rate (rpm):',
                                    'Mixing time (s):',
                                    'Mixing time2 (s):',
                                    'Reaction time (s):',
                                    'Temperature Cool (C):',
                                    userAction0,
                                    userAction1
                                    ],
            'Parameter Values': [rxndict['temperature1_nominal'],
                                 rxndict['stirrate'],
                                 rxndict['duratation_stir1'], 
                                 rxndict['duratation_stir2'],
                                 rxndict['duration_reaction'],
                                 rxndict['temperature2_nominal'],
                                 userActionValue0,
                                 userActionValue1
                                 ],
        })

        rxn_parameters_small = pd.DataFrame({
            'Reaction Parameters': ['Temperature (C):', 
                                    'Stir Rate (rpm):',
                                    'Mixing time (s):',
                                    '',
                                    '',
                                    '',
                                    '',
                                    ''
                                    ],
            'Parameter Values': [rxndict['temperature1_nominal'],
                                 rxndict['stirrate'],
                                 rxndict['duratation_stir1'],
                                    '',
                                    '',
                                    '',
                                    '',
                                    ''
                                 ],
        })

        # For WF3 tray implementation to work
        df_Tray2 = MakeWellList_WF3(rxndict['plate_container'], rxndict['wellcount']*2)
        erdf_new = WF3_split(erdf, rxndict['WF3_split'])
        outframe1 = pd.concat([df_Tray2.iloc[:, 0],
                               erdf_new, df_Tray2.iloc[:, 1],
                               rxn_parameters_small, rxn_conditions],
                              sort=False, axis=1)
        
        if globals.get_lab() == 'LBL':
            robotfile = ('localfiles/%s_RUNME_RobotFile.xls' %rxndict['RunID'])
        else:
            robotfile = ('localfiles/%s_RUNME_RobotFile.xls' %rxndict['RunID'])

        ## For report code to work
        df_Tray = MakeWellList_WF3_small(rxndict['plate_container'], rxndict['wellcount']*1)
        outframe2 = pd.concat([df_Tray.iloc[:, 0], erdf, df_Tray.iloc[:,1],rxn_parameters, rxn_conditions],
                              sort=False, axis=1)
        robotfile2 = ('localfiles/%s_RobotInput.xls' % rxndict['RunID'])

        outframe1.to_excel(robotfile, sheet_name='NIMBUS_reaction', index=False)
        outframe2.to_excel(robotfile2, sheet_name='NIMBUS_reaction', index=False)
        robotfiles.append(robotfile)
        robotfiles.append(robotfile2)

    else:
        if globals.get_lab() == 'MIT_PVLab':
            rxn_parameters = pd.DataFrame({
                'Reaction Parameters': ['Spincoating Temperature ( C )',
                                        'Spincoating Speed (rpm):',
                                        'Spincoating Duration (s)',
                                        'Spincoating Duration 2 (s)',
                                        'Annealing Temperature ( C )',
                                        'Annealing Duration (s)',
                                        userAction0,
                                        userAction1,
                                        ""],

                'Parameter Values': [rxndict['temperature1_nominal'],
                                     rxndict['stirrate'],
                                     rxndict['duratation_stir1'],
                                     rxndict['duratation_stir2'],
                                     rxndict['temperature2_nominal'],
                                     rxndict['duration_reaction'],
                                     userActionValue0,
                                     userActionValue1,
                                     ''],
            })
            experiment_names = build_experiment_names_df(rxndict, vardict)
            df_Tray = pd.DataFrame({
                'Experiment Index': range(1, int(rxndict['wellcount']) + 1),
                'Labware ID': rxndict['plate_container']
            })
            outframe = pd.concat([df_Tray.iloc[:, 0], experiment_names, erdf, df_Tray.iloc[:, 1], rxn_parameters, rxn_conditions],
                                 sort=False, axis=1)
        else:
            rxn_parameters = pd.DataFrame({
                    'Reaction Parameters': ['Temperature (C):', 
                                            'Stir Rate (rpm):',
                                            'Mixing time1 (s):',
                                            'Mixing time2 (s):',
                                            'Reaction time (s):',
                                            'Preheat Temperature (C):',
                                            userAction0,
                                            userAction1
                                            ],
                    'Parameter Values': [rxndict['temperature2_nominal'],
                                         rxndict['stirrate'],
                                         rxndict['duratation_stir1'], 
                                         rxndict['duratation_stir2'],
                                         rxndict['duration_reaction'], 
                                         rxndict['temperature1_nominal'],
                                         userActionValue0,
                                         userActionValue1
                                         ],
            })
            df_Tray = MakeWellList(rxndict['plate_container'], rxndict['wellcount'])
            outframe = pd.concat([df_Tray.iloc[:, 0], erdf, df_Tray.iloc[:, 1], rxn_parameters, rxn_conditions],
                                 sort=False, axis=1)

        if globals.get_lab() == 'LBL':
            volume_file = ('localfiles/%s_RobotInput.xls' % rxndict['RunID'])
        else:
            volume_file = ('localfiles/%s_ExperimentSpecification.xls' %rxndict['RunID'])
            
        outframe = abstract_reagent_colnames(outframe, inplace=False)

        robotfiles.append(volume_file)

        outframe.to_excel(volume_file, sheet_name='NIMBUS_reaction', index=False)

    return robotfiles
Esempio n. 18
0
def parse_exp_volumes(exp_volume_spec_fname, experiment_lab):
    """ Parses the experiment interface.  
        For example of the complete structure see:
        https://drive.google.com/open?id=1rNPfcOiseQSTTB8E7VsKp77h8hv8VSCj
        Link targets 4-DataDebug Robotinput example

    Parameters
    ----------
    exp_volume_spec_fname  : filename which contains volumes actions
        predifined structure is hardcoded based on a specific labs needs

    experiment_lab : name of lab
        all labs except MIT are handled the same, this is hard coded and brittle
    
    Returns
    -------
    lists and dataframes, complex return

    Notes:
    TODO: Generalize this function to any new lab
    TODO: clean up the return of this function
    If this function breaks pytest will catch the malfunction

    """

    robot_dict = pd.read_excel(open(exp_volume_spec_fname, 'rb'),
                               header=[0],
                               sheet_name=0)
    reagentlist = []
    for header in robot_dict.columns:
        reagent_alias_name = lab_safeget(config.lab_vars, experiment_lab,
                                         'reagent_alias')
        if reagent_alias_name in header and "ul" in header:
            reagentlist.append(header)
    rnum = len(reagentlist)

    pipette_list = range(0, rnum + 2)

    #MIT_PVLab has an additional column in the second row 'Experiment Name' in additiona
    # to the 'Experiment Index'.  The +1 accounts for that during parsing
    if experiment_lab == 'MIT_PVLab':
        rnum += 1
        pipette_list = [0]
        pipette_list.extend(range(2, rnum + 2))

    pipette_volumes = pd.read_excel(exp_volume_spec_fname,
                                    sheet_name=0,
                                    usecols=pipette_list)
    pipette_volumes.dropna(how='all', inplace=True)

    reaction_parameters = pd.read_excel(exp_volume_spec_fname,
                                        sheet_name=0,
                                        usecols=[rnum + 2, rnum + 3]).dropna()
    reagent_info = pd.read_excel(
        exp_volume_spec_fname,
        sheet_name=0,
        usecols=[rnum + 4, rnum + 5, rnum + 6, rnum + 7]).dropna()

    validate_experimental_volumes(pipette_volumes)
    validate_reaction_parameters(reaction_parameters)
    validate_reagent_info(reagent_info)

    pipette_dump = json.dumps(pipette_volumes.values.tolist())
    reaction_dump = json.dumps(reaction_parameters.values.tolist())
    reagent_dump = json.dumps(reagent_info.values.tolist())
    return pipette_dump, reaction_dump, reagent_dump