Пример #1
0
def run_pelicun(DL_input_path,
                EDP_input_path,
                DL_method,
                realization_count,
                BIM_file,
                EDP_file,
                DM_file,
                DV_file,
                output_path=None,
                detailed_results=True,
                coupled_EDP=False,
                log_file=True,
                event_time=None,
                ground_failure=False,
                auto_script_path=None,
                resource_dir=None):

    DL_input_path = os.path.abspath(DL_input_path)  # BIM file
    EDP_input_path = os.path.abspath(EDP_input_path)  # dakotaTab

    # If the output dir was not specified, results are saved in the directory of
    # the input file.
    if output_path is None:
        output_path = ntpath.dirname(DL_input_path)

    # delete output files from previous runs
    files = os.listdir(output_path)
    for filename in files:
        if (filename[-3:] == 'csv') and (('DL_summary' in filename) or
                                         ('DMG' in filename) or
                                         ('DV_' in filename) or
                                         ('EDP' in filename)):
            try:
                os.remove(posixpath.join(output_path, filename))
            except:
                pass

    # If the event file is specified, we expect a multi-stripe analysis...
    try:
        # Collect stripe and rate information for every event
        with open(DL_input_path, 'r') as f:
            event_list = json.load(f)['Events'][0]

        df_event = pd.DataFrame(columns=['name', 'stripe', 'rate', 'IM'],
                                index=np.arange(len(event_list)))

        for evt_i, event in enumerate(event_list):
            df_event.iloc[evt_i] = [
                event['name'], event['stripe'], event['rate'], event['IM']
            ]

        # Create a separate EDP input for each stripe
        EDP_input_full = pd.read_csv(EDP_input_path,
                                     sep='\s+',
                                     header=0,
                                     index_col=0)

        # EDP_input_full.to_csv(EDP_input_path[:-4]+'_1.out', sep=' ')

        stripes = df_event['stripe'].unique()
        EDP_files = []
        IM_list = []
        num_events = []
        num_collapses = []
        for stripe in stripes:
            events = df_event[df_event['stripe'] == stripe]['name'].values

            EDP_input = EDP_input_full[EDP_input_full['MultipleEvent'].isin(
                events)]

            EDP_files.append(EDP_input_path[:-4] + '_{}.out'.format(stripe))

            EDP_input.to_csv(EDP_files[-1], sep=' ')

            IM_list.append(
                df_event[df_event['stripe'] == stripe]['IM'].values[0])

            # record number of collapses and number of events per stripe
            PID_columns = [col for col in list(EDP_input)
                           if 'PID' in col]  # list of column headers with PID
            num_events.append(EDP_input.shape[0])
            count = 0
            for row in range(num_events[-1]):
                print(row)
                for col in PID_columns:
                    if EDP_input.iloc[row][
                            col] >= 0.20:  # TODO: PID collapse limit as argument
                        count += 1
                        break
            num_collapses.append(count)

        # fit lognormal distribution to all points by maximum likelihood estimation (MLE)
        theta, beta = lognormal_MLE(IM_list, num_events, num_collapses)
        beta_adj = np.sqrt(
            beta**2 + 0.35**2
        )  # TODO: adjust dispersion by 0.35 to account for modeling uncertainty
        print("theta: " + str(theta))
        print("beta_adj: " + str(beta_adj))

        # write BIM file with new probability of collapse for each IM
        DL_files = []
        for i in range(len(stripes)):
            DL_input_stripe = update_collapsep(DL_input_path, stripes[i],
                                               theta, beta_adj, IM_list[i])
            DL_files.append(DL_input_stripe)

    except:  # run analysis for single IM
        stripes = [1]
        EDP_files = [EDP_input_path]
        DL_files = [DL_input_path]

    # run the analysis and save results separately for each stripe
    #print(stripes, EDP_files)

    for s_i, stripe in enumerate(stripes):

        DL_input_path = DL_files[s_i]

        # read the type of assessment from the DL input file
        with open(DL_input_path, 'r') as f:
            DL_input = json.load(f)

        # check if the DL input file has information about the loss model
        if 'DamageAndLoss' in DL_input:
            pass
        else:
            # if the loss model is not defined, give a warning
            print(
                'WARNING No loss model defined in the BIM file. Trying to auto-populate.'
            )

            EDP_input_path = EDP_files[s_i]

            # and try to auto-populate the loss model using the BIM information
            DL_input, DL_input_path = auto_populate(
                DL_input_path, EDP_input_path, DL_method, realization_count,
                coupled_EDP, event_time, ground_failure, auto_script_path)

        DL_method = DL_input['DamageAndLoss']['_method']

        stripe_str = '' if len(stripes) == 1 else str(stripe) + '_'

        # Copy the resources to the specified location - if needed
        if resource_dir is not None:
            resource_dir = os.path.abspath(resource_dir)

            AT = DL_method_to_AT[DL_method]

            resources = get_required_resources(DL_input_path, AT)

            # take each resource file
            for name, resource in resources.items():

                resource_filename = os.path.basename(resource)

                # copy it to the designated location
                if ((AT == 'HAZUS_HU') and (name == 'component')):
                    # hurricane assessments require two files
                    temp_resource = resource.replace('.hdf', '_FL.hdf')
                    temp_filename = os.path.basename(temp_resource)
                    new_path = os.path.join(resource_dir, temp_filename)
                    if not os.path.exists(new_path):
                        shutil.copy(temp_resource, new_path)

                    temp_resource = resource.replace('.hdf', '_HU.hdf')
                    temp_filename = os.path.basename(temp_resource)
                    new_path = os.path.join(resource_dir, temp_filename)
                    if not os.path.exists(new_path):
                        shutil.copy(temp_resource, new_path)

                    new_path = new_path[:-7] + '.hdf'

                else:
                    new_path = os.path.join(resource_dir, resource_filename)
                    if not os.path.exists(new_path):
                        shutil.copy(resource, new_path)

                # and update the DL config file to point to that location
                if name == 'component':
                    DL_input['DamageAndLoss']['ComponentDataFolder'] = new_path
                elif name == 'population':
                    DL_input['DamageAndLoss']['LossModel']['Inhabitants'][
                        'PopulationDataFile'] = new_path
                elif name == 'combination':
                    DL_input['DamageAndLoss']['CombinationDataFile'] = new_path

            with open(DL_input_path, 'w') as f:
                json.dump(DL_input, f, indent=2)

        log_msg('Running damage and loss simulation...')
        if DL_method == 'FEMA P58':
            A = FEMA_P58_Assessment(log_file=log_file)
        elif DL_method in ['HAZUS MH EQ', 'HAZUS MH', 'HAZUS MH EQ IM']:
            A = HAZUS_Assessment(hazard='EQ', log_file=log_file)
        elif DL_method == 'HAZUS MH HU':
            A = HAZUS_Assessment(hazard='HU', log_file=log_file)
        elif DL_method == 'HAZUS MH FL':
            A = HAZUS_Assessment(hazard='FL', log_file=log_file)

        A.read_inputs(
            DL_input_path, EDP_files[s_i],
            verbose=False)  # make DL inputs into array of all BIM files

        A.define_random_variables()

        A.define_loss_model()

        A.calculate_damage()

        A.calculate_losses()

        A.aggregate_results()

        A.save_outputs(output_path,
                       BIM_file,
                       EDP_file,
                       DM_file,
                       DV_file,
                       stripe_str,
                       detailed_results=detailed_results)

    return 0
def run_pelicun(DL_input_path,
                EDP_input_path,
                DL_method,
                realization_count,
                EDP_file,
                DM_file,
                DV_file,
                output_path=None,
                detailed_results=True,
                log_file=True):

    DL_input_path = os.path.abspath(DL_input_path)  # BIM file
    EDP_input_path = os.path.abspath(EDP_input_path)  # dakotaTab

    # If the output dir was not specified, results are saved in the directory of
    # the input file.
    if output_path is None:
        output_path = ntpath.dirname(DL_input_path)

    # delete output files from previous runs
    files = os.listdir(output_path)
    for filename in files:
        if (filename[-3:] == 'csv') and (('DL_summary' in filename) or
                                         ('DMG' in filename) or
                                         ('DV_' in filename) or
                                         ('EDP' in filename)):
            try:
                os.remove(posixpath.join(output_path, filename))
            except:
                pass

    # If the event file is specified, we expect a multi-stripe analysis...
    try:
        # Collect stripe and rate information for every event
        with open(DL_input_path, 'r') as f:
            event_list = json.load(f)['Events'][0]

        df_event = pd.DataFrame(columns=['name', 'stripe', 'rate', 'IM'],
                                index=np.arange(len(event_list)))

        for evt_i, event in enumerate(event_list):
            df_event.iloc[evt_i] = [
                event['name'], event['stripe'], event['rate'], event['IM']
            ]

        # Create a separate EDP input for each stripe
        EDP_input_full = pd.read_csv(EDP_input_path,
                                     sep='\s+',
                                     header=0,
                                     index_col=0)

        # EDP_input_full.to_csv(EDP_input_path[:-4]+'_1.out', sep=' ')

        stripes = df_event['stripe'].unique()
        EDP_files = []
        IM_list = []
        num_events = []
        num_collapses = []
        for stripe in stripes:
            events = df_event[df_event['stripe'] == stripe]['name'].values

            EDP_input = EDP_input_full[EDP_input_full['MultipleEvent'].isin(
                events)]

            EDP_files.append(EDP_input_path[:-4] + '_{}.out'.format(stripe))

            EDP_input.to_csv(EDP_files[-1], sep=' ')

            IM_list.append(
                df_event[df_event['stripe'] == stripe]['IM'].values[0])

            # record number of collapses and number of events per stripe
            PID_columns = [col for col in list(EDP_input)
                           if 'PID' in col]  # list of column headers with PID
            num_events.append(EDP_input.shape[0])
            count = 0
            for row in range(num_events[-1]):
                print(row)
                for col in PID_columns:
                    if EDP_input.iloc[row][
                            col] >= 0.20:  # TODO: PID collapse limit as argument
                        count += 1
                        break
            num_collapses.append(count)

        # fit lognormal distribution to all points by maximum likelihood estimation (MLE)
        theta, beta = lognormal_MLE(IM_list, num_events, num_collapses)
        beta_adj = np.sqrt(
            beta**2 + 0.35**2
        )  # TODO: adjust dispersion by 0.35 to account for modeling uncertainty
        print("theta: " + str(theta))
        print("beta_adj: " + str(beta_adj))

        # write BIM file with new probability of collapse for each IM
        DL_files = []
        for i in range(len(stripes)):
            DL_input_stripe = update_collapsep(DL_input_path, stripes[i],
                                               theta, beta_adj, IM_list[i])
            DL_files.append(DL_input_stripe)

    except:  # run analysis for single IM
        stripes = [1]
        EDP_files = [EDP_input_path]
        DL_files = [DL_input_path]

    # run the analysis and save results separately for each stripe
    #print(stripes, EDP_files)

    for s_i, stripe in enumerate(stripes):

        DL_input_path = DL_files[s_i]

        # read the type of assessment from the DL input file
        with open(DL_input_path, 'r') as f:
            DL_input = json.load(f)

        # check if the DL input file has information about the loss model
        if 'DamageAndLoss' in DL_input:
            pass
        else:
            # if the loss model is not defined, give a warning
            print(
                'WARNING No loss model defined in the BIM file. Trying to auto-populate.'
            )

            EDP_input_path = EDP_files[s_i]

            # and try to auto-populate the loss model using the BIM information
            DL_input, DL_input_path = auto_populate(DL_input_path,
                                                    EDP_input_path, DL_method,
                                                    realization_count)

        DL_method = DL_input['DamageAndLoss']['_method']

        stripe_str = '' if len(stripes) == 1 else str(stripe) + '_'

        if DL_method == 'FEMA P58':
            A = FEMA_P58_Assessment(log_file=log_file)
        elif DL_method in ['HAZUS MH EQ', 'HAZUS MH']:
            A = HAZUS_Assessment(hazard='EQ', log_file=log_file)
        elif DL_method == 'HAZUS MH HU':
            A = HAZUS_Assessment(hazard='HU', log_file=log_file)

        A.read_inputs(
            DL_input_path, EDP_files[s_i],
            verbose=False)  # make DL inputs into array of all BIM files

        A.define_random_variables()

        A.define_loss_model()

        A.calculate_damage()

        A.calculate_losses()

        A.aggregate_results()

        A.save_outputs(output_path,
                       EDP_file,
                       DM_file,
                       DV_file,
                       stripe_str,
                       detailed_results=detailed_results)

    return 0