Пример #1
0
    def connect_state_sets(self, states1, states2):
        '''
        This function goes through the process tables of all states in states1 checks if any of the unregistered
        processes connect to a state in state2. It thus tries to connect update the processtables of the states.
        '''
        # print "connect_state_sets: ",states1," ",states2
        for i in states1:
            proc_tab = i.get_process_table()
            for j in proc_tab:
                # print "checking state, process: ",i," ",j
                if proc_tab[j]['product'] != -1:
                    continue
                enew = proc_tab[j]['product_energy']
                energetically_close = []
                for state in states2:
                    if abs(state.get_energy() - enew) < self.epsilon_e:
                        energetically_close.append(state)

                # Perform distance checks on the energetically close configurations.
                if len(energetically_close) > 0:
                    # print "energetically close: ",energetically_close
                    pnew = i.get_process_product(j)
                    for state in energetically_close:
                        p = state.get_reactant()
                        # print "atoms.match between state, process, state: ",i," ",j," ",state
                        if atoms.match(p, pnew, config.comp_eps_r, config.comp_neighbor_cutoff, True):
                            # Update the reactant state to point at the new state id.
                            # print "structures match"
                            self.register_process(i.number, state.number, j)

        for i in states2:
            proc_tab = i.get_process_table()
            for j in proc_tab:
                # print "checking state, process: ",i," ",j
                if proc_tab[j]['product'] != -1:
                    continue
                enew = proc_tab[j]['product_energy']
                energetically_close = []
                for state in states1:
                    if abs(state.get_energy() - enew) < self.epsilon_e:
                        energetically_close.append(state)

                # Perform distance checks on the energetically close configurations.
                if len(energetically_close) > 0:
                    # print "energetically close: ",energetically_close
                    pnew = i.get_process_product(j)
                    for state in energetically_close:
                        p = state.get_reactant()
                        # print "atoms.match between state, process, state: ",i," ",j," ",state
                        if atoms.match(p, pnew, config.comp_eps_r, config.comp_neighbor_cutoff, True):
                            # Update the reactant state to point at the new state id.
                            # print "structures match"
                            self.register_process(i.number, state.number, j)
Пример #2
0
    def get_product_state(self, state_number, process_id):
        ''' Returns a State object referenced by state_number and process_id. '''
        #TODO: Compare configuration of product with existing states.

        # If the number of states in state_table is zero
        #we need to add the zero state and energy to the state table.
        if self.get_num_states() == 0:
            zst = self.get_state(0)
            self.append_state_table(zst.get_energy())

        # Load the state object containing the process we want the product for.
        st = self.get_state(state_number)
        st.load_process_table()

        # Get the state number for the product.
        newstnr = st.procs[process_id]['product']

        # If the product id is not initialized, make sure it is not a copy of an existing state.
        # Otherwise, create it, connect it to st, and return it.
        if newstnr == -1:

            # Make a list of states for which we need to compare configurations.
            enew = st.procs[process_id]['product_energy']
            energetically_close = []
            for id in range(self.get_num_states()):
                if abs(self.get_state(id).get_energy() - enew) < self.epsilon_e:
                    energetically_close.append(id)

            # Perform distance checks on the energetically close configurations.
            if len(energetically_close) > 0:
                pnew = st.get_process_product(process_id)
                for id in energetically_close:
                    p = self.get_state(id).get_reactant()
                    if atoms.match(p, pnew, config.comp_eps_r, config.comp_neighbor_cutoff, True):
                        if id == state_number:
                            logging.warning("State %i process %i leads back to initial state",
                                            state_number, process_id)
                        self.register_process(st.number, id, process_id)
                        return self.get_state(id)

            # The id for the new state is the number of states.
            newstnr = self.get_num_states()

            # Create the new state object.
            newst = self.StateClass(statepath = self.state_path(newstnr),
                                statenumber = newstnr,
                                statelist = self,
                                previous_state_num = state_number,
                                reactant_path = st.proc_product_path(process_id))
            self.register_process(st.number, newstnr, process_id)

            # Append the new state to the state table.
            self.append_state_table(st.procs[process_id]['product_energy'])

        # The product state already exists, so get it.
        else:
            newst = self.get_state(newstnr)

        # Return the product state.
        return newst
Пример #3
0
    def finish_minimization(self, result):
        result1 = self.load_result(self.finished_min1_name)
        result2 = result

        atoms1 = io.loadcon(result1['min.con'])
        atoms2 = io.loadcon(result2['min.con'])

        results_dat1 = io.parse_results(result1['results.dat'])
        results_dat2 = io.parse_results(result2['results.dat'])
        self.data['force_calls_minimization'] += results_dat1['total_force_calls']
        self.data['force_calls_minimization'] += results_dat2['total_force_calls']

        is_reactant = lambda a: atoms.match(a, self.reactant,
                                            config.comp_eps_r,
                                            config.comp_neighbor_cutoff, False)

        tc1 = io.parse_results(result1['results.dat'])['termination_reason']
        tc2 = io.parse_results(result2['results.dat'])['termination_reason']

        termination_reason1 = self.job_termination_reasons['minimization'][tc1]
        termination_reason2 = self.job_termination_reasons['minimization'][tc2]
        if termination_reason1 == 'max_iterations' or termination_reason2 == 'max_iterations':
            self.data['termination_reason'] = 9
            self.data['potential_energy_saddle'] = 0.0
            self.data['potential_energy_reactant'] = 0.0
            self.data['potential_energy_product'] = 0.0
            self.data['barrier_reactant_to_product'] = 0.0
            self.data['barrier_product_to_reactant'] = 0.0
            return

        # Check the connectivity of the process
        if (not is_reactant(atoms1) and not is_reactant(atoms2)) or \
           (is_reactant(atoms1) and is_reactant(atoms2)):
            # Not connected
            self.data['termination_reason'] = 6
            self.data['potential_energy_saddle'] = 0.0
            self.data['potential_energy_reactant'] = 0.0
            self.data['potential_energy_product'] = 0.0
            self.data['barrier_reactant_to_product'] = 0.0
            self.data['barrier_product_to_reactant'] = 0.0
            return
        elif is_reactant(atoms1):
            reactant_results_dat = results_dat1
            product_results_dat = results_dat2
            self.finished_reactant_name = self.finished_min1_name
            self.finished_product_name = self.finished_min2_name
        elif is_reactant(atoms2):
            reactant_results_dat = results_dat2
            product_results_dat = results_dat1
            self.finished_reactant_name = self.finished_min2_name
            self.finished_product_name = self.finished_min1_name

        self.data['potential_energy_reactant'] = reactant_results_dat['potential_energy']
        self.data['potential_energy_product'] = product_results_dat['potential_energy']

        self.data['barrier_reactant_to_product'] = self.data['potential_energy_saddle'] - \
                self.data['potential_energy_reactant'] 
        self.data['barrier_product_to_reactant'] = self.data['potential_energy_saddle'] - \
                self.data['potential_energy_product'] 
Пример #4
0
    def add_state(self, result_files, result_info):
        energy = result_info['minimum_energy']

        energetically_close = []
        added = True

        if len(self.energy_table) != 0:
            for row in self.energy_table:
                if abs(energy - row['energy']) < config.comp_eps_e:
                    energetically_close.append(row['state'])
            if len(energetically_close) != 0:
                a1 = io.loadcon(result_files['min.con'])
                for state_number in energetically_close:
                    state_con_path = os.path.join(config.path_states,
                                                  str(state_number),
                                                  'minimum.con')
                    a2 = io.loadcon(state_con_path)
                    if atoms.match(a1, a2, config.comp_eps_r,
                                   config.comp_neighbor_cutoff, True):
                        logger.info("Found a repeat of state %i", state_number)
                        added = False
                        for row in self.energy_table.rows:
                            if row['state'] == state_number:
                                row['repeats'] += 1
                                self.energy_table.write()
                                break

        if added:
            state_number = len(self.energy_table)

            row = {'state': state_number, 'energy': energy, 'repeats': 0}
            self.energy_table.add_row(row)
            self.energy_table.rows.sort(key=lambda r: -r['energy'])
            self.energy_table.write()

            state_path = os.path.join(config.path_states, str(state_number))
            os.mkdir(state_path)

            result_files['minimum.con'] = result_files['min.con']
            del result_files['min.con']

            for fn, fh in result_files.iteritems():
                if hasattr(fh, 'getvalue') == False:
                    continue
                p = os.path.join(state_path, fn)
                f = open(p, 'w')
                f.write(fh.getvalue())
                f.close()

        return added
Пример #5
0
    def add_state(self, result_files, result_info):
        energy = result_info['minimum_energy']

        energetically_close = []
        added = True

        if len(self.energy_table) != 0:
            for row in self.energy_table:
                if abs(energy-row['energy']) < config.comp_eps_e:
                    energetically_close.append(row['state'])
            if len(energetically_close) != 0:
                a1 = io.loadcon(result_files['min.con'])
                for state_number in energetically_close:
                    state_con_path = os.path.join(config.path_states, 
                                                  str(state_number),
                                                  'minimum.con')
                    a2 = io.loadcon(state_con_path)
                    if atoms.match(a1, a2, config.comp_eps_r, config.comp_neighbor_cutoff, True):
                        logger.info("Found a repeat of state %i", state_number)
                        added = False
                        for row in self.energy_table.rows:
                            if row['state'] == state_number:
                                row['repeats'] += 1
                                self.energy_table.write()
                                break

        if added:
            state_number = len(self.energy_table)

            row = { 'state':state_number, 'energy':energy, 'repeats':0 }
            self.energy_table.add_row(row)
            self.energy_table.rows.sort(key=lambda r:-r['energy'])
            self.energy_table.write()

            state_path = os.path.join(config.path_states, str(state_number))
            os.mkdir(state_path)

            result_files['minimum.con'] = result_files['min.con']
            del result_files['min.con']

            for fn, fh in result_files.iteritems():
                if hasattr(fh, 'getvalue') == False:
                    continue
                p = os.path.join(state_path, fn)
                f = open(p, 'w')
                f.write(fh.getvalue())
                f.close()

        return added 
Пример #6
0
    def find_repeat(self, saddle_file, barrier):
        self.load_process_table()
        energy_a = barrier
        p1 = io.loadcon(saddle_file)
        for id in self.procs.keys():
            energy_b = self.procs[id]['barrier']
            if abs(energy_a - energy_b) > config.comp_eps_e:
                continue

            if id in self.con_cache:
                p2 = self.con_cache[id]
            else:
                p2 = io.loadcon(self.proc_saddle_path(id))
                self.con_cache[id] = p2

            if atoms.match(p1, p2, config.comp_eps_r,
                           config.comp_neighbor_cutoff, False):
                return id
        return None
Пример #7
0
    def get_product_state(self, state_number, process_id):
        ''' Returns a State object referenced by state_number and process_id. '''
        #TODO: Compare configuration of product with existing states.

        # If the number of states in state_table is zero
        #we need to add the zero state and energy to the state table.
        if self.get_num_states() == 0:
            zst = self.get_state(0)
            self.append_state_table(zst.get_energy())

        # Load the state object containing the process we want the product for.
        st = self.get_state(state_number)
        st.load_process_table()

        # Get the state number for the product.
        newstnr = st.procs[process_id]['product']

        # If the product id is not initialized, make sure it is not a copy of an existing state.
        # Otherwise, create it, connect it to st, and return it.
        if newstnr == -1:

            # Make a list of states for which we need to compare configurations.
            enew = st.procs[process_id]['product_energy']
            energetically_close = []
            for id in range(self.get_num_states()):
                if abs(self.get_state(id).get_energy() -
                       enew) < self.epsilon_e:
                    energetically_close.append(id)

            # Perform distance checks on the energetically close configurations.
            if len(energetically_close) > 0:
                pnew = st.get_process_product(process_id)
                for id in energetically_close:
                    p = self.get_state(id).get_reactant()
                    if atoms.match(p, pnew, config.comp_eps_r,
                                   config.comp_neighbor_cutoff, True):
                        if id == state_number:
                            logging.warning(
                                "State %i process %i leads back to initial state",
                                state_number, process_id)
                        self.register_process(st.number, id, process_id)
                        return self.get_state(id)

            # The id for the new state is the number of states.
            newstnr = self.get_num_states()

            # Create the new state object.
            newst = self.StateClass(
                statepath=self.state_path(newstnr),
                statenumber=newstnr,
                statelist=self,
                previous_state_num=state_number,
                reactant_path=st.proc_product_path(process_id))
            self.register_process(st.number, newstnr, process_id)

            # Append the new state to the state table.
            self.append_state_table(st.procs[process_id]['product_energy'])

        # The product state already exists, so get it.
        else:
            newst = self.get_state(newstnr)

        # Return the product state.
        return newst
Пример #8
0
    def register_process(self, reactant_number, product_number, process_id):

        # Get the reactant and product state objects.
        reactant = self.get_state(reactant_number)
        product = self.get_state(product_number)
        reactant.load_process_table()

        # Forward process (reac->prod)
        # Make the reactant process point to the product state number.
        reactant.procs[process_id]['product'] = product_number
        reactant.save_process_table()

        # If the process is of type reac->reac no reverse process needs to be added and we can return.
        # This can be the case if for example a water molecule rotates to mirrored conf.
        if reactant_number == product_number:
            return

        # Loads 'reference' energy for the reactant state as defined in meta-data.
        reactant_energy = reactant.get_energy()
        saddle_energy = reactant.procs[process_id]['saddle_energy']

        # Reverse process (prod->reac).
        # Have any processes been determined for the product state.
        if product.get_num_procs() != 0:
            product.load_process_table()
            reverse_procs = product.get_process_table()
            candidates = []

            # An alike reverse process might already exist
            for id in reverse_procs.keys():
                proc = reverse_procs[id]
                if ( abs(proc['saddle_energy'] - saddle_energy) < self.epsilon_e ) and (proc['product']==-1):
                    candidates.append(id)

            if len(candidates):
                reactant_conf = reactant.get_reactant()
                for id in candidates:
                    conf = product.get_process_product(id)

                    # The process is known but has not been accepted yet.
                    if atoms.match(reactant_conf, conf, config.comp_eps_r, config.comp_neighbor_cutoff, False):

                        # Reverse process table should be updated to ensure that the two processes (reac->prod & proc->reac) are symmetric.
                        reactant.load_process_table()

                        # Remember we are now looking at the reverse processes 
                        reverse_procs[id]['product'] = reactant_number
                        reverse_procs[id]['saddle_energy'] = saddle_energy
                        reverse_procs[id]['prefactor'] = reactant.procs[process_id]['product_prefactor']
                        reverse_procs[id]['product_energy'] = reactant.get_energy()
                        reverse_procs[id]['product_prefactor'] = reactant.procs[process_id]['prefactor']
                        reverse_procs[id]['barrier'] = saddle_energy - product.get_energy()
                        reverse_procs[id]['rate'] = reactant.procs[process_id]['product_prefactor'] * math.exp( - ( saddle_energy - product.get_energy() ) /self.kT)
                        product.save_process_table()

                        # We are done.
                        return

            # The process is not in the list and must be added as a new process.
            reverse_process_id = product.get_num_procs()

        else:
            # This must be a new state.
            product.set_energy(reactant.procs[process_id]['product_energy'])
            reverse_process_id = 0

        # The product state does not know the reverse process yet.
        # Reverse id has been determined above. (0 if it is a new state, else the last element in the proc table + 1)
        shutil.copy(reactant.proc_saddle_path(process_id), product.proc_saddle_path(reverse_process_id))
        shutil.copy(reactant.proc_reactant_path(process_id), product.proc_product_path(reverse_process_id))
        shutil.copy(reactant.proc_product_path(process_id), product.proc_reactant_path(reverse_process_id))
        shutil.copy(reactant.proc_results_path(process_id), product.proc_results_path(reverse_process_id))
        shutil.copy(reactant.proc_mode_path(process_id), product.proc_mode_path(reverse_process_id))

        # Add the reverse process in the product state
        barrier = saddle_energy - product.get_energy()
        product.append_process_table(id = reverse_process_id,
                                     saddle_energy = saddle_energy,
                                     prefactor = reactant.procs[process_id]['product_prefactor'],
                                     product = reactant_number,
                                     product_energy = reactant_energy,
                                     product_prefactor = reactant.procs[process_id]['prefactor'],
                                     barrier = barrier,
                                     rate = reactant.procs[process_id]['product_prefactor'] * math.exp(-barrier / self.kT),
                                     repeats = 0)
        product.save_process_table()

        # Update the metadata.
        # If this the forward process was a random proc, increase the repeat count.
        if(process_id in reactant.get_proc_random_count() ):
            product.inc_proc_random_count(reverse_process_id)
        product.set_unique_saddle_count( product.get_unique_saddle_count() + 1 )
        product.update_lowest_barrier( barrier )

        # Register the process in the search result file.
        result_fake = {'barrier_reactant_to_product' : barrier,
                       'displacement_saddle_distance' : 0.0,
                       'force_calls_saddle' : 0,
                       'force_calls_minimization' : 0,
                       'force_calls_prefactors' : 0}
        if config.akmc_server_side_process_search:
            first_column = "search_id"
        else:
            first_column = "wuid"
        result = { first_column : 0,
                   'type' : 'reverse',
                   'results' : result_fake}
        product.append_search_result(result, 'reverse from '+str(reactant_number), None)
        return
Пример #9
0
def register_results(comm, current_state, states):
    logger.info("Registering results")
    if os.path.isdir(config.path_jobs_in):
        shutil.rmtree(config.path_jobs_in)
    os.makedirs(config.path_jobs_in)

    # Function used by communicator to determine whether to discard a result
    def keep_result(name):
        return True

    transition = None
    num_registered = 0
    speedup = 0
    number_state = []
    numres = 0
    for result in comm.get_results(config.path_jobs_in, keep_result):
        # The result dictionary contains the following key-value pairs:
        # reactant.con - an array of strings containing the reactant
        # product.con - an array of strings containing the product
        # results.dat - an array of strings containing the results
        # id - StateNumber_WUID
        #
        # The reactant, product, and mode are passed as lines of the files because
        # the information contained in them is not needed for registering results

        state_num = int(result['name'].split("_")[0])
        id = int(result['name'].split("_")[1]) + result['number']

        state = states.get_state(state_num)

        # read in the results
        result['results'] = io.parse_results(result['results.dat'])
        speedup += result['results']['speedup']
        if result['results']['transition_found'] == 1:
            result['results']['transition_time_s'] += state.get_time()
            a = result['results']['potential_energy_product']
            f = open("states/0/end_state_table", "a+")
            lines = f.readlines()
            f.close()
            proc = []
            number_state.append(0)
            count = 0
            state_match = 0
            flag = 0
            product = io.loadcon(result['product.con'])

            for i in range(0, numres):
                product2 = io.loadcon("states/0/procdata/product_%i.con" % i)
                if atoms.match(product, product2, config.comp_eps_r,
                               config.comp_neighbor_cutoff, True):
                    if flag == 0:
                        state_match = number_state[i]
                        number_state[numres] = state_match
                        flag = 1
                        break
            count = 0
            time_to_state = 0
            time_check = 0
            for line in lines[1:]:
                l = line.split()
                proc.append({
                    'state': l[0],
                    'views': l[1],
                    'rate': l[2],
                    'time': l[3]
                })
                if float(l[3]) > time_check:
                    time_check = float(l[3])
                if flag == 0:
                    number_state[numres] = int(l[0]) + 1
                else:
                    if state_match == int(l[0]):
                        proc[count]['views'] = str(int(l[1]) + 1)
                        time_to_state = float(
                            l[3]) + result['results']['transition_time_s']
                        proc[count]['time'] = str(time_to_state)
                        proc[count]['rate'] = str(
                            1 / (time_to_state / float(proc[count]['views'])))
                count += 1

            if flag == 0:
                proc.append({
                    'state':
                    number_state[numres],
                    'views':
                    1,
                    'rate':
                    1 / (float(time_check +
                               result['results']['transition_time_s'])),
                    'time':
                    time_check + result['results']['transition_time_s']
                })

            g = open("states/0/end_state_table", "w")
            g.write('state       views         rate        time \n')
            for j in range(0, len(proc)):
                g.write(str(proc[j]['state']))
                g.write("             ")
                g.write(str(proc[j]['views']))
                g.write("             ")
                g.write(str(proc[j]['rate']))
                g.write("             ")
                g.write(str(proc[j]['time']))
                g.write("\n")
            g.close()
            numres += 1
            time = result['results']['transition_time_s']
            process_id = state.add_process(result)
            logger.info("Found transition with time %.3e", time)
            if not transition and current_state.number == state.number:
                transition = {'process_id': process_id, 'time': time}
            state.zero_time()
        else:
            state.inc_time(result['results']['simulation_time_s'])
        num_registered += 1
    logger.info("Processed %i (result) searches", num_registered)
    if num_registered >= 1:
        logger.info("Average speedup is  %f", speedup / num_registered)
    return num_registered, transition, speedup
Пример #10
0
    def finish_minimization(self, result):
        result1 = self.load_result(self.finished_min1_name)
        result2 = result

        atoms1 = io.loadcon(result1['min.con'])
        atoms2 = io.loadcon(result2['min.con'])

        results_dat1 = io.parse_results(result1['results.dat'])
        results_dat2 = io.parse_results(result2['results.dat'])
        self.data['force_calls_minimization'] += results_dat1[
            'total_force_calls']
        self.data['force_calls_minimization'] += results_dat2[
            'total_force_calls']

        is_reactant = lambda a: atoms.match(
            a, self.reactant, config.comp_eps_r, config.comp_neighbor_cutoff,
            False)

        tc1 = io.parse_results(result1['results.dat'])['termination_reason']
        tc2 = io.parse_results(result2['results.dat'])['termination_reason']

        termination_reason1 = self.job_termination_reasons['minimization'][tc1]
        termination_reason2 = self.job_termination_reasons['minimization'][tc2]
        if termination_reason1 == 'max_iterations' or termination_reason2 == 'max_iterations':
            self.data['termination_reason'] = 9
            self.data['potential_energy_saddle'] = 0.0
            self.data['potential_energy_reactant'] = 0.0
            self.data['potential_energy_product'] = 0.0
            self.data['barrier_reactant_to_product'] = 0.0
            self.data['barrier_product_to_reactant'] = 0.0
            return

        # Check the connectivity of the process
        if (not is_reactant(atoms1) and not is_reactant(atoms2)) or \
           (is_reactant(atoms1) and is_reactant(atoms2)):
            # Not connected
            self.data['termination_reason'] = 6
            self.data['potential_energy_saddle'] = 0.0
            self.data['potential_energy_reactant'] = 0.0
            self.data['potential_energy_product'] = 0.0
            self.data['barrier_reactant_to_product'] = 0.0
            self.data['barrier_product_to_reactant'] = 0.0
            return
        elif is_reactant(atoms1):
            reactant_results_dat = results_dat1
            product_results_dat = results_dat2
            self.finished_reactant_name = self.finished_min1_name
            self.finished_product_name = self.finished_min2_name
        elif is_reactant(atoms2):
            reactant_results_dat = results_dat2
            product_results_dat = results_dat1
            self.finished_reactant_name = self.finished_min2_name
            self.finished_product_name = self.finished_min1_name

        self.data['potential_energy_reactant'] = reactant_results_dat[
            'potential_energy']
        self.data['potential_energy_product'] = product_results_dat[
            'potential_energy']

        self.data['barrier_reactant_to_product'] = self.data['potential_energy_saddle'] - \
                self.data['potential_energy_reactant']
        self.data['barrier_product_to_reactant'] = self.data['potential_energy_saddle'] - \
                self.data['potential_energy_product']
Пример #11
0
def register_results(comm, current_state, states):
    logger.info("Registering results")
    if os.path.isdir(config.path_jobs_in):
        shutil.rmtree(config.path_jobs_in)
    os.makedirs(config.path_jobs_in)
    # Function used by communicator to determine whether to discard a result
    def keep_result(name):
        return True
    transition = None
    num_registered = 0
    speedup = 0
    number_state = []
    numres = 0
    for result in comm.get_results(config.path_jobs_in, keep_result):
        # The result dictionary contains the following key-value pairs:
        # reactant.con - an array of strings containing the reactant
        # product.con - an array of strings containing the product
        # results.dat - an array of strings containing the results
        # id - StateNumber_WUID
        #
        # The reactant, product, and mode are passed as lines of the files because
        # the information contained in them is not needed for registering results
        
        
        state_num = int(result['name'].split("_")[0])
        id = int(result['name'].split("_")[1]) + result['number']

        state = states.get_state(state_num)

        # read in the results
        result['results'] = io.parse_results(result['results.dat'])
        speedup += result['results']['speedup']
        if result['results']['transition_found'] == 1:
            result['results']['transition_time_s'] += state.get_time()
            a = result['results']['potential_energy_product']
            f = open ("states/0/end_state_table","a+")
            lines = f.readlines()
            f.close()
            proc = []
            number_state.append(0)                                      
            count = 0 
            state_match = 0
            flag = 0
            product = io.loadcon (result['product.con'])                            


            for i in range(0, numres):                                                                        
                product2 = io.loadcon ("states/0/procdata/product_%i.con" % i )                                 
                if atoms.match(product, product2,config.comp_eps_r,config.comp_neighbor_cutoff,True):          
                    if flag == 0:                                                                                
                        state_match = number_state[i]
                        number_state[numres] = state_match
                        flag = 1            
                        break
            count = 0 
            time_to_state = 0
            time_check = 0
            for line in lines[1:]:                                                                         
                l = line.split()                                      
                proc.append({'state': l[0], 'views': l[1], 'rate': l[2], 'time': l[3]})  
                if float(l[3]) > time_check:
                    time_check = float(l[3])
                if flag == 0:
                    number_state[numres] = int(l[0])+1
                else:
                    if state_match == int(l[0]):
                        proc[count]['views'] = str(int(l[1]) + 1)
                        time_to_state = float(l[3]) + result['results']['transition_time_s']
                        proc[count]['time'] = str(time_to_state)
                        proc[count]['rate'] = str(1/(time_to_state/float(proc[count]['views'])))
                count += 1


            if flag == 0:
                proc.append({'state': number_state[numres],  'views': 1, 'rate': 1/(float(time_check+result['results']['transition_time_s'])) , 'time': time_check + result['results']['transition_time_s']}) 


            g = open ("states/0/end_state_table","w")
            g.write('state       views         rate        time \n')
            for j in range(0,len(proc)):
                g.write(str(proc[j]['state']))
                g.write("             ")
                g.write(str(proc[j]['views']))
                g.write("             ")
                g.write(str(proc[j]['rate']))
                g.write("             ")
                g.write(str(proc[j]['time']))
                g.write("\n")
            g.close() 
            numres += 1
            time = result['results']['transition_time_s']
            process_id = state.add_process(result)
            logger.info("Found transition with time %.3e", time)
            if not transition and current_state.number==state.number:
                transition = {'process_id':process_id, 'time':time}
            state.zero_time()
        else:
            state.inc_time(result['results']['simulation_time_s'])
        num_registered += 1
    logger.info("Processed %i (result) searches", num_registered)
    if num_registered >=1:
        logger.info("Average speedup is  %f", speedup/num_registered)
    return num_registered, transition, speedup