def test_create_inp_build_instructions():

    inp.create_inp_build_instructions(MODEL_XSECTION_BASELINE,
                                      MODEL_XSECTION_ALT_03, 'vc_dir',
                                      'test_version_id', 'cool comments')

    latest_bi = vc_utils.newest_file('vc_dir')
    bi = inp.BuildInstructions(latest_bi)

    juncs = bi.instructions['[JUNCTIONS]']
    assert (all(j in juncs.altered.index
                for j in ['dummy_node1', 'dummy_node5']))
def test_create_inp_build_instructions():

    inp.create_inp_build_instructions(MODEL_XSECTION_BASELINE,
                                      MODEL_XSECTION_ALT_03,
                                      'vc_dir',
                                      'test_version_id', 'cool comments')

    latest_bi = vc_utils.newest_file('vc_dir')
    bi = inp.BuildInstructions(latest_bi)

    juncs = bi.instructions['[JUNCTIONS]']
    assert(all(j in juncs.altered.index for j in [
           'dummy_node1', 'dummy_node5']))
Exemple #3
0
def test_inp_diff_from_bi():

    change = INPSectionDiff(build_instr_file=BUILD_INSTR_01,
                            section='JUNCTIONS')

    alt_juncs = change.altered
    assert alt_juncs.loc['dummy_node1',
                         'InvertElev'] == pytest.approx(-15, 0.01)
    assert alt_juncs.loc['dummy_node5',
                         'InvertElev'] == pytest.approx(-6.96, 0.01)

    with tempfile.TemporaryDirectory() as tempdir:
        # test with spaces in path
        temp_dir_01 = os.path.join(tempdir, 'path with spaces')
        makedirs(temp_dir_01)
        shutil.copy(BUILD_INSTR_01, temp_dir_01)
        BUILD_INSTR_01_spaces = os.path.join(temp_dir_01, BUILD_INSTR_01)

        change = INPSectionDiff(build_instr_file=BUILD_INSTR_01_spaces,
                                section='[JUNCTIONS]')

        alt_juncs = change.altered
        assert alt_juncs.loc['dummy_node1',
                             'InvertElev'] == pytest.approx(-15, 0.01)
        assert alt_juncs.loc['dummy_node5',
                             'InvertElev'] == pytest.approx(-6.96, 0.01)

        # test with parent models in directory structure with spaces in path
        temp_dir_02 = os.path.join(tempdir, 'root with spaces')
        temp_dir_03 = os.path.join(temp_dir_02, 'vc_dir')
        makedirs(temp_dir_02)
        shutil.copy(MODEL_XSECTION_BASELINE, temp_dir_02)
        shutil.copy(MODEL_XSECTION_ALT_03, temp_dir_02)
        MODEL_XSECTION_BASELINE_spaces = os.path.join(temp_dir_02,
                                                      MODEL_XSECTION_BASELINE)
        MODEL_XSECTION_ALT_03_spaces = os.path.join(temp_dir_02,
                                                    MODEL_XSECTION_ALT_03)

        inp.create_inp_build_instructions(MODEL_XSECTION_BASELINE_spaces,
                                          MODEL_XSECTION_ALT_03_spaces,
                                          temp_dir_03, 'test_version_id',
                                          'cool comments')

        latest_bi_spaces = vc_utils.newest_file(temp_dir_03)
        change = INPSectionDiff(build_instr_file=latest_bi_spaces,
                                section='[JUNCTIONS]')
        alt_juncs = change.altered
        assert alt_juncs.loc['dummy_node1',
                             'InvertElev'] == pytest.approx(-15, 0.01)
        assert alt_juncs.loc['dummy_node5',
                             'InvertElev'] == pytest.approx(-6.96, 0.01)
Exemple #4
0
def test_create_inp_build_instructions():
    with tempfile.TemporaryDirectory() as tempdir:
        temp_vc_dir_01 = os.path.join(tempdir, 'vc_dir')
        temp_vc_dir_02 = os.path.join(tempdir, 'vc root with spaces')
        temp_vc_dir_03 = os.path.join(temp_vc_dir_02, 'vc_dir')
        inp.create_inp_build_instructions(MODEL_XSECTION_BASELINE,
                                          MODEL_XSECTION_ALT_03,
                                          temp_vc_dir_01, 'test_version_id',
                                          'cool comments')

        latest_bi = vc_utils.newest_file(temp_vc_dir_01)
        bi = inp.BuildInstructions(latest_bi)
        juncs = bi.instructions['JUNCTIONS']

        assert (all(j in juncs.altered.index
                    for j in ['dummy_node1', 'dummy_node5']))

        # reproduce test with same files in a directory structure with spaces in path
        makedirs(temp_vc_dir_02)
        shutil.copy(MODEL_XSECTION_BASELINE, temp_vc_dir_02)
        shutil.copy(MODEL_XSECTION_ALT_03, temp_vc_dir_02)
        MODEL_XSECTION_BASELINE_spaces = os.path.join(temp_vc_dir_02,
                                                      MODEL_XSECTION_BASELINE)
        MODEL_XSECTION_ALT_03_spaces = os.path.join(temp_vc_dir_02,
                                                    MODEL_XSECTION_ALT_03)

        inp.create_inp_build_instructions(MODEL_XSECTION_BASELINE_spaces,
                                          MODEL_XSECTION_ALT_03_spaces,
                                          temp_vc_dir_03, 'test_version_id',
                                          'cool comments')

        latest_bi_spaces = vc_utils.newest_file(temp_vc_dir_03)
        bi_sp = inp.BuildInstructions(latest_bi_spaces)

        juncs_sp = bi_sp.instructions['JUNCTIONS']
        print(juncs_sp.altered)
        assert (all(j in juncs_sp.altered.index
                    for j in ['dummy_node1', 'dummy_node5']))
Exemple #5
0
def propagate_changes_from_baseline(baseline_dir,
                                    alternatives_dir,
                                    combi_dir,
                                    version_id='',
                                    comments=''):

    #stuff
    """
    if the baseline model has changes that need to be propogated to all models,
    iterate through each model and rebuild the INPs with the new baseline and
    existing build instructions. update the build instructions to reflect the
    revision date of the baseline.
    """
    version_id += '_' + datetime.now().strftime("%y%m%d%H%M%S")

    #collect the directories of all models
    #model_dirs = [os.listdir(os.path.join(alternatives_dir, x)) for x in os.listdir(alternatives_dir)]
    model_dirs = [
    ]  #[os.path.join(alternatives_dir, alt, imp_level) for imp_level in os.listdir(os.path.join(alternatives_dir, alt)) for alt in os.listdir(alternatives_dir)]
    for alt in os.listdir(alternatives_dir):
        #print alt
        #iterate through each implementation level of each alternative
        for imp_level in os.listdir(os.path.join(alternatives_dir, alt)):
            #create or refresh the build instructions file for the alternatives
            model_dirs.append(os.path.join(alternatives_dir, alt, imp_level))

    model_dirs += [os.path.join(combi_dir, x) for x in os.listdir(combi_dir)]
    #print model_dirs
    baseline = Model(baseline_dir)
    baseinp = baseline.inp.filePath

    for model_dir in model_dirs:
        model = Model(model_dir)
        vc_directory = os.path.join(model_dir, 'vc')
        latest_bi = vc_utils.newest_file(vc_directory)

        #update build instructions metdata and build the new inp
        bi = inp.BuildInstructions(latest_bi)
        bi.metadata['Parent Models']['Baseline'] = {
            baseinp: vc_utils.modification_date(baseinp)
        }
        bi.metadata['Log'].update({version_id: comments})
        bi.save(vc_directory, version_id + '.txt')
        print 'rebuilding {} with changes to baseline'.format(model.name)
        bi.build(baseline_dir, model.inp.filePath)  #overwrite old inp
Exemple #6
0
def propagate_changes_from_baseline(baseline_dir, alternatives_dir, combi_dir,
                                    version_id='', comments=''):

    #stuff
    """
    if the baseline model has changes that need to be propogated to all models,
    iterate through each model and rebuild the INPs with the new baseline and
    existing build instructions. update the build instructions to reflect the
    revision date of the baseline.
    """
    version_id += '_' + datetime.now().strftime("%y%m%d%H%M%S")

    #collect the directories of all models
    model_dirs = []
    for alt in os.listdir(alternatives_dir):
        #print alt
        #iterate through each implementation level of each alternative
        for imp_level in os.listdir(os.path.join(alternatives_dir, alt)):
            #create or refresh the build instructions file for the alternatives
            model_dirs.append(os.path.join(alternatives_dir, alt, imp_level))

    model_dirs += [os.path.join(combi_dir, x) for x in os.listdir(combi_dir)]
    #print model_dirs
    baseline = Model(baseline_dir)
    baseinp = baseline.inp.path

    for model_dir in model_dirs:
        model = Model(model_dir)
        vc_directory = os.path.join(model_dir, 'vc')
        latest_bi = vc_utils.newest_file(vc_directory)

        #update build instructions metdata and build the new inp
        bi = inp.BuildInstructions(latest_bi)
        bi.metadata['Parent Models']['Baseline'] = {baseinp:vc_utils.modification_date(baseinp)}
        bi.metadata['Log'].update({version_id:comments})
        bi.save(vc_directory, version_id+'.txt')
        print('rebuilding {} with changes to baseline'.format(model.name))
        bi.build(baseline_dir, model.inp.path) #overwrite old inp
Exemple #7
0
def create_combinations(baseline_dir, rsn_dir, combi_dir, version_id='',
                        comments=''):

    """
    Generate SWMM5 models of each logical combination of all implementation
    phases (IP) across all relief sewer networks (RSN).

    Inputs:
        baseline_dir -> path to directory containing the baseline SWMM5 model
        rsn_dir ->      path to directory containing subdirectories for each RSN
                        containing directories for each IP within the network
        combi_dir ->    target directory in which child models will be created
        version_id ->   identifier for a given version (optional)
        comments ->     comments tracked within build instructions log for
                        each model scenario (optional)

    Calling create_combinations will update child models if parent models have
    been changed.

    """

    baseinp = Model(baseline_dir).inp.path
    version_id += '_' + datetime.now().strftime("%y%m%d%H%M%S")

    #create a list of directories pointing to each IP in each RSN
    RSN_dirs = [os.path.join(rsn_dir, rsn) for rsn in os.listdir(rsn_dir)]
    IP_dirs = [os.path.join(d, ip) for d in RSN_dirs for ip in os.listdir(d)]

    #list of lists of each IP within each RSN, including a 'None' phase.
    IPs = [[None] + os.listdir(d) for d in RSN_dirs]

    #identify all scenarios (cartesian product of sets of IPs between each RSN)
    #then isolate child scenarios with atleast 2 parents (sets with one parent
    #are already modeled as IPs within the RSNs)
    all_scenarios = [[_f for _f in s if _f] for s in itertools.product(*IPs)]
    child_scenarios = [s for s in all_scenarios if len(s) > 1]

    #notify user of what was initially found
    str_IPs = '\n'.join([', '.join([_f for _f in i if _f]) for i in IPs])
    print(('Found {} implementation phases among {} networks:\n{}\n'
           'This yeilds {} combined scenarios ({} total)'.format(len(IP_dirs),
            len(RSN_dirs),str_IPs,len(child_scenarios),len(all_scenarios) - 1)))

    # ==========================================================================
    # UPDATE/CREATE THE PARENT MODEL BUILD INSTRUCTIONS
    # ==========================================================================
    for ip_dir in IP_dirs:
        ip_model = Model(ip_dir)
        vc_dir = os.path.join(ip_dir, 'vc')

        if not os.path.exists(vc_dir):
            print('creating new build instructions for {}'.format(ip_model.name))
            inp.create_inp_build_instructions(baseinp, ip_model.inp.path,
                                              vc_dir,
                                              version_id, comments)
        else:
            #check if the alternative model was changed since last run of this tool
            #--> compare the modification date to the BI's modification date meta data
            latest_bi = vc_utils.newest_file(vc_dir)
            if not vc_utils.bi_is_current(latest_bi):
                #revision date of the alt doesn't match the newest build
                #instructions for this 'imp_level', so we should refresh it
                print('updating build instructions for {}'.format(ip_model.name))
                inp.create_inp_build_instructions(baseinp, ip_model.inp.path,
                                                  vc_dir, version_id,
                                                  comments)

    # ==========================================================================
    # UPDATE/CREATE THE CHILD MODELS AND CHILD BUILD INSTRUCTIONS
    # ==========================================================================
    for scen in child_scenarios:
        newcombi = '_'.join(sorted(scen))
        new_dir = os.path.join(combi_dir, newcombi)
        vc_dir = os.path.join(combi_dir, newcombi, 'vc')

        #parent model build instr files
        #BUG (this breaks with model IDs with more than 1 char)
        parent_vc_dirs = [os.path.join(rsn_dir, f[0], f, 'vc') for f in scen]
        latest_parent_bis = [vc_utils.newest_file(d) for d in parent_vc_dirs]
        build_instrcts = [inp.BuildInstructions(bi) for bi in latest_parent_bis]

        if not os.path.exists(new_dir):

            os.mkdir(new_dir)
            newinppath = os.path.join(new_dir, newcombi + '.inp')

            print('creating new child model: {}'.format(newcombi))
            new_build_instructions = sum(build_instrcts)
            new_build_instructions.save(vc_dir, version_id+'.txt')
            new_build_instructions.build(baseline_dir, newinppath)

        else:
            #check if the alternative model was changed since last run
            #of this tool --> compare the modification date to the BI's
            #modification date meta data
            latest_bi = vc_utils.newest_file(os.path.join(new_dir,'vc'))
            if not vc_utils.bi_is_current(latest_bi):
                #revision date of the alt doesn't match the newest build
                #instructions for this 'imp_level', so we should refresh it
                print('updating child build instructions for {}'.format(newcombi))
                newinppath = os.path.join(new_dir, newcombi + '.inp')
                new_build_instructions = sum(build_instrcts)
                new_build_instructions.save(vc_dir, version_id+'.txt')
                new_build_instructions.build(baseline_dir, newinppath)
Exemple #8
0
def create_combinations(baseline_dir,
                        rsn_dir,
                        combi_dir,
                        version_id='',
                        comments=''):
    """
    Generate SWMM5 models of each logical combination of all implementation
    phases (IP) across all relief sewer networks (RSN).

    Inputs:
        baseline_dir -> path to directory containing the baseline SWMM5 model
        rsn_dir ->      path to directory containing subdirectories for each RSN
                        containing directories for each IP within the network
        combi_dir ->    target directory in which child models will be created
        version_id ->   identifier for a given version (optional)
        comments ->     comments tracked within build instructions log for
                        each model scenario (optional)

    Calling create_combinations will update child models if parent models have
    been changed.

    """

    baseinp = Model(baseline_dir).inp.path
    version_id += '_' + datetime.now().strftime("%y%m%d%H%M%S")

    #create a list of directories pointing to each IP in each RSN
    RSN_dirs = [os.path.join(rsn_dir, rsn) for rsn in os.listdir(rsn_dir)]
    IP_dirs = [os.path.join(d, ip) for d in RSN_dirs for ip in os.listdir(d)]

    #list of lists of each IP within each RSN, including a 'None' phase.
    IPs = [[None] + os.listdir(d) for d in RSN_dirs]

    #identify all scenarios (cartesian product of sets of IPs between each RSN)
    #then isolate child scenarios with atleast 2 parents (sets with one parent
    #are already modeled as IPs within the RSNs)
    all_scenarios = [[_f for _f in s if _f] for s in itertools.product(*IPs)]
    child_scenarios = [s for s in all_scenarios if len(s) > 1]

    #notify user of what was initially found
    str_IPs = '\n'.join([', '.join([_f for _f in i if _f]) for i in IPs])
    print(('Found {} implementation phases among {} networks:\n{}\n'
           'This yeilds {} combined scenarios ({} total)'.format(
               len(IP_dirs), len(RSN_dirs), str_IPs, len(child_scenarios),
               len(all_scenarios) - 1)))

    # ==========================================================================
    # UPDATE/CREATE THE PARENT MODEL BUILD INSTRUCTIONS
    # ==========================================================================
    for ip_dir in IP_dirs:
        ip_model = Model(ip_dir)
        vc_dir = os.path.join(ip_dir, 'vc')

        if not os.path.exists(vc_dir):
            print('creating new build instructions for {}'.format(
                ip_model.name))
            inp.create_inp_build_instructions(baseinp, ip_model.inp.path,
                                              vc_dir, version_id, comments)
        else:
            #check if the alternative model was changed since last run of this tool
            #--> compare the modification date to the BI's modification date meta data
            latest_bi = vc_utils.newest_file(vc_dir)
            if not vc_utils.bi_is_current(latest_bi):
                #revision date of the alt doesn't match the newest build
                #instructions for this 'imp_level', so we should refresh it
                print('updating build instructions for {}'.format(
                    ip_model.name))
                inp.create_inp_build_instructions(baseinp, ip_model.inp.path,
                                                  vc_dir, version_id, comments)

    # ==========================================================================
    # UPDATE/CREATE THE CHILD MODELS AND CHILD BUILD INSTRUCTIONS
    # ==========================================================================
    for scen in child_scenarios:
        newcombi = '_'.join(sorted(scen))
        new_dir = os.path.join(combi_dir, newcombi)
        vc_dir = os.path.join(combi_dir, newcombi, 'vc')

        #parent model build instr files
        #BUG (this breaks with model IDs with more than 1 char)
        parent_vc_dirs = [os.path.join(rsn_dir, f[0], f, 'vc') for f in scen]
        latest_parent_bis = [vc_utils.newest_file(d) for d in parent_vc_dirs]
        build_instrcts = [
            inp.BuildInstructions(bi) for bi in latest_parent_bis
        ]

        if not os.path.exists(new_dir):

            os.mkdir(new_dir)
            newinppath = os.path.join(new_dir, newcombi + '.inp')

            print('creating new child model: {}'.format(newcombi))
            new_build_instructions = sum(build_instrcts)
            new_build_instructions.save(vc_dir, version_id + '.txt')
            new_build_instructions.build(baseline_dir, newinppath)

        else:
            #check if the alternative model was changed since last run
            #of this tool --> compare the modification date to the BI's
            #modification date meta data
            latest_bi = vc_utils.newest_file(os.path.join(new_dir, 'vc'))
            if not vc_utils.bi_is_current(latest_bi):
                #revision date of the alt doesn't match the newest build
                #instructions for this 'imp_level', so we should refresh it
                print('updating child build instructions for {}'.format(
                    newcombi))
                newinppath = os.path.join(new_dir, newcombi + '.inp')
                new_build_instructions = sum(build_instrcts)
                new_build_instructions.save(vc_dir, version_id + '.txt')
                new_build_instructions.build(baseline_dir, newinppath)
Exemple #9
0
def create_combinations(baseline_dir,
                        alternatives_dir,
                        combi_dir,
                        version_id='',
                        comments=''):
    """
    given a set of main alternatives split into models varying levels of
    implementation, this function combines all implementation levels of all
    alternatives into all logical combinations.
    """

    basemodel = Model(baseline_dir)
    baseinp = basemodel.inp.filePath
    alt_directories = os.listdir(
        alternatives_dir)  #list of dirs holding alt models
    implementation_levels = []
    newmodels = []
    version_id += '_' + datetime.now().strftime("%y%m%d%H%M%S")

    for alt in alt_directories:

        #iterate through each implementation level of each alternative
        for imp_level in os.listdir(os.path.join(alternatives_dir, alt)):

            implementation_levels.append(os.path.join(alt, imp_level))

            #create or refresh the build instructions file for the alternatives
            alt_imp_level_dir = os.path.join(alternatives_dir, alt, imp_level)
            alt_imp_inp = Model(alt_imp_level_dir).inp.filePath
            vc_directory = os.path.join(alt_imp_level_dir, 'vc')

            if not os.path.exists(vc_directory):
                print 'creating new build instructions for {}'.format(
                    imp_level)
                inp.create_inp_build_instructions(baseinp, alt_imp_inp,
                                                  vc_directory, version_id,
                                                  comments)

            else:
                #check if the alternative model was changed since last run of this tool
                #--> compare the modification date to the BI's modification date meta data
                latest_bi = vc_utils.newest_file(vc_directory)
                if not vc_utils.bi_is_current(latest_bi):
                    #revision date of the alt doesn't match the newest build
                    #instructions for this 'imp_level', so we should refresh it
                    print 'updating build instructions for {}'.format(
                        imp_level)
                    inp.create_inp_build_instructions(baseinp, alt_imp_inp,
                                                      vc_directory, version_id,
                                                      comments)

    #creat directories for new model combinations
    for L in range(1, len(implementation_levels) + 1):

        #break
        for subset in itertools.combinations(implementation_levels, L):
            #subset e.g. = 'A\A01'

            #newcombi = '_'.join(subset)
            newcombi = '_'.join([os.path.split(s)[1] for s in subset])
            new_combi_dir = os.path.join(combi_dir, newcombi)
            vc_directory = os.path.join(new_combi_dir, 'vc')

            #create a list of the parent directories, use that to prevent
            #two or more from same alternative
            alternative_dirs = [os.path.split(s)[0] for s in subset]

            if len(alternative_dirs) == len(
                    set(alternative_dirs)) and len(subset) > 1:
                #confirming the list length is equal to the set length (hashable)
                #confirms that there are not duplicates in the items list
                parent_vc_dirs = [
                    os.path.join(alternatives_dir, f, 'vc') for f in subset
                ]
                latest_parent_bis = [
                    vc_utils.newest_file(d) for d in parent_vc_dirs
                ]
                build_instrcts = [
                    inp.BuildInstructions(bi) for bi in latest_parent_bis
                ]

                if not os.path.exists(
                        new_combi_dir):  #and newcombi not in flavors:
                    #check to make sure new model doesn't repeat two or more from
                    #a particular genre.
                    #print new_combi_dir

                    os.mkdir(new_combi_dir)
                    newinppath = os.path.join(new_combi_dir, newcombi + '.inp')

                    #collect build instructions from each alt's implementation
                    #level for this combination. Select those with the current
                    #version id, or the latest version.
                    print 'creating new child model: {}'.format(newcombi)
                    new_build_instructions = sum(build_instrcts)
                    new_build_instructions.save(vc_directory,
                                                version_id + '.txt')
                    new_build_instructions.build(baseline_dir, newinppath)

                else:
                    #check if the alternative model was changed since last run
                    #of this tool --> compare the modification date to the BI's
                    #modification date meta data
                    latest_bi = vc_utils.newest_file(
                        os.path.join(new_combi_dir, 'vc'))
                    if not vc_utils.bi_is_current(latest_bi):
                        #revision date of the alt doesn't match the newest build
                        #instructions for this 'imp_level', so we should refresh it
                        print 'updating child build instructions for {}'.format(
                            newcombi)
                        newinppath = os.path.join(new_combi_dir,
                                                  newcombi + '.inp')
                        new_build_instructions = sum(build_instrcts)
                        new_build_instructions.save(vc_directory,
                                                    version_id + '.txt')
                        new_build_instructions.build(baseline_dir, newinppath)