Beispiel #1
0
def library_sizes():
    result = session.query(Material.run_id,
                           func.count(Material.id)).group_by(Material.run_id)
    print("\nrun-id\t\t\t\t|\tlibrary size")
    print("{}+{}".format("-" * 32, "-" * 32))
    for row in result:
        print("{}\t|\t{}".format(row[0], row[1]))
Beispiel #2
0
def last_generation(run_id):
    """Finds latest generation present in database.

    Args:
        run_id (str): identification string for run.

    Returns:
        Last generation(int) to be included in database.

    """
    return session.query(func.max(Material.generation)).filter(
        Material.run_id == run_id, )[0][0]
Beispiel #3
0
def mutate(run_id, generation, parent):
    """Query mutation_strength for bin and adjust as necessary.

    Args:
        run_id (str): identification string for run.
        generation (int): iteration in bin-mutate-simulate routine.
        parent (sqlalchemy.orm.query.Query): parent-material corresponding to
            the bin being queried.

    Returns:
        mutation_strength.strength (float): mutation strength to be used for
        parents in the bin being queried. If the fraction of children from
        previous generation which populate the SAME bin as their parent is LESS
        THAN 10% then the mutation strength is REDUCED BY HALF. If the fraction
        of these children populating the SAME bin as their parent is GREATER
        THAN 50% then the mutation strength is INCREASED BY 200%.

    """
    mutation_strength_key = [run_id, generation] + parent.bin
    mutation_strength = session.query(MutationStrength).get(
        mutation_strength_key)

    if mutation_strength:
        print(
            "Mutation strength already calculated for this bin and generation."
        )
    else:
        print("Calculating mutation strength...")
        mutation_strength = MutationStrength.get_prior(
            *mutation_strength_key).clone()
        mutation_strength.generation = generation

        try:
            fraction_in_parent_bin = parent.calculate_percent_children_in_bin()
            if fraction_in_parent_bin < 0.1:
                mutation_strength.strength *= 0.5
            elif fraction_in_parent_bin > 0.5 and mutation_strength.strength <= 0.5:
                mutation_strength.strength *= 2
        except ZeroDivisionError:
            print("No prior generation materials in this bin with children.")

        try:
            session.add(mutation_strength)
            session.commit()
        except (FlushError, sqlalchemy.exc.IntegrityError) as e:
            print(
                "Somebody beat us to saving a row with this generation. That's ok!"
            )
            session.rollback()
            # it's ok b/c this calculation should always yield the exact same result!
    sys.stdout.flush()
    return mutation_strength.strength
Beispiel #4
0
def materials_in_generation(run_id, generation):
    """Count number of materials in a generation.

    Args:
        run_id (str): identification string for run.
        generation (int): iteration in overall bin-mutate-simulate rountine.

    Returns:
        Number(int) of materials in a particular generation that are present in
        the database (the final step in bin-mutate-simulate routine).

    """
    return session.query(Material).filter(
        Material.run_id == run_id, Material.generation == generation).count()
Beispiel #5
0
    def calculate_generation_index(self):
        """Determine material's generation-index.

        Args:
            self (class): row in material table.

        Returns:
            The generation-index is used to count the number of materials
            present in the database (that is to have all definition-files in
            the RASPA library and simulation data in the materials datatable).
            This attribute is used to determine when to stop adding new
            materials to one generation and start another.

        """
        return session.query(Material).filter(
            Material.run_id == self.run_id,
            Material.generation == self.generation,
            Material.id < self.id,
        ).count()
    def get_prior(cls, run_id, generation, gas_adsorption_bin,
                  surface_area_bin, void_fraction_bin):
        """
        Looks for the most recent mutation_strength row. If a row doesn't exist
        for this bin, the default value is used from the configuration file.

        Args:
            cls (classmethod): here MutationStrength.__init__ .
            run_id (str): identification string for run.
            gas_adsorption_bin (int): value representing a region of gas
                loading parameter-space.
            surface_area_bin (int): value representing a region of surface area
                parameter-space.
            void_fraction_bin (int): value representing a region of void fraction
                parameter-space.

        Returns:
            ms (float): either the mutation strength specified in the mutation
                stength datatable, or the default mutation strength if there is
                no row in the datatable corresponding to the bin.

        """

        ms = session.query(MutationStrength) \
                .filter(
                    MutationStrength.run_id == run_id,
                    MutationStrength.gas_adsorption_bin == gas_adsorption_bin,
                    MutationStrength.surface_area_bin == surface_area_bin,
                    MutationStrength.void_fraction_bin == void_fraction_bin,
                    MutationStrength.generation <= generation) \
                .order_by(MutationStrength.generation.desc()) \
                .first()

        if ms:
            return ms
        else:
            return MutationStrength(run_id, generation, gas_adsorption_bin,
                                    surface_area_bin, void_fraction_bin,
                                    config['initial_mutation_strength'])
Beispiel #7
0
def worker_run_loop(run_id):
    """
    Args:
        run_id (str): identification string for run.

    Writes seed generation and simulates properties, then manages overall
    bin-mutate-simualte routine until convergence cutt-off or maximum
    number of generations is reached.

    """
    gen = last_generation(run_id) or 0

    converged = False
    while not converged:
        print(('=======================================================\n'
               'GENERATION {0}\n'
               '=======================================================\n'
               ).format(gen))
        size_of_generation = config['children_per_generation']

        while materials_in_generation(run_id, gen) < size_of_generation:
            if gen == 0:
                print("writing new seed...")
                material, pseudo_material = generate_pseudo_material(
                    run_id, config['number_of_atom_types'])
                pseudo_material.dump()
            else:
                print(
                    "selecting a parent / running retests on parent / mutating / simulating"
                )
                parent_id = select_parent(
                    run_id,
                    max_generation=(gen - 1),
                    generation_limit=config['children_per_generation'])

                parent_material = session.query(Material).get(parent_id)

                # run retests until we've run enough
                while parent_material.retest_passed is None:
                    print("running retest...")
                    print("Date :\t%s" % datetime.now().date().isoformat())
                    print("Time :\t%s" % datetime.now().time().isoformat())
                    parent_pseudo_material_path = os.path.join(
                        os.path.dirname(os.path.dirname(htsohm.__file__)),
                        run_id, 'pseudo_materials',
                        '{0}.yaml'.format(parent_material.uuid))
                    with open(parent_pseudo_material_path) as parent_file:
                        parent_pseudo_material = yaml.load(parent_file)
                    retest(parent_material, config['retests']['number'],
                           config['retests']['tolerance'],
                           parent_pseudo_material)
                    session.refresh(parent_material)

                if not parent_material.retest_passed:
                    print(
                        "parent failed retest. restarting with parent selection."
                    )
                    continue

                mutation_strength = mutate(run_id, gen, parent_material)
                material, pseudo_material = mutate_pseudo_material(
                    parent_material, parent_pseudo_material, mutation_strength,
                    gen)
                pseudo_material.dump()
            run_all_simulations(material, pseudo_material)
            session.add(material)
            session.commit()

            material.generation_index = material.calculate_generation_index()
            if material.generation_index < config['children_per_generation']:
                session.add(material)
            else:
                # delete excess rows
                # session.delete(material)
                pass
            session.commit()
            sys.stdout.flush()
        gen += 1
        converged = evaluate_convergence(run_id, gen)
Beispiel #8
0
def count_number_of_materials(run_id):
    return session.query(func.count(Material.id)).filter(Material.run_id==run_id)[0][0]
Beispiel #9
0
def library_sizes():
    result = session.query(Material.run_id, func.count(Material.id)).group_by(Material.run_id)
    print("\nrun-id\t\t\t\t|\tlibrary size")
    print("{}+{}".format("-" * 32, "-" * 32))
    for row in result:
        print("{}\t|\t{}".format(row[0], row[1]))
Beispiel #10
0
def count_number_of_materials(run_id):
    return session.query(func.count(
        Material.id)).filter(Material.run_id == run_id)[0][0]