Instruction:
Can you generate the documentation for the following Python 3 function
def handle_request(self):
        try:
            request, client_address = self.get_request()
        except socket.error:
            return
        if self.verify_request(request, client_address):
            try:
                # we only serve once, and we want to free up the port
                # for future serves.
                self.socket.close()
                self.process_request(request, client_address)
            except SocketConnected as err:
                self._serve_process(err.slaveFd, err.serverPid)
                return
            except Exception as err:
                self.handle_error(request, client_address)
                self.close_request()

Response: Handle one request - serve current process to one connection.


Instruction:
Implement a Python 3 function for
serving a process by connecting its outputs and inputs to the pty slaveFd.

Response:
def _serve_process(self, slaveFd, serverPid):
        """
            Serves a process by connecting its outputs/inputs to the pty
            slaveFd.  serverPid is the process controlling the master fd
            that passes that output over the socket.
        """
        self.serverPid = serverPid
        if sys.stdin.isatty():
            self.oldTermios = termios.tcgetattr(sys.stdin.fileno())
        else:
            self.oldTermios = None
        self.oldStderr = SavedFile(2, sys, 'stderr')
        self.oldStdout = SavedFile(1, sys, 'stdout')
        self.oldStdin = SavedFile(0, sys, 'stdin')
        self.oldStderr.save(slaveFd, mode="w")
        self.oldStdout.save(slaveFd, mode="w")
        self.oldStdin.save(slaveFd, mode="r")
        os.close(slaveFd)
        self.closed = False


Instruction:
Can you create a Python 3 function that
asks a user for an integer between two values.

Response:
def int_input(message, low, high, show_range = True):
    '''
    Ask a user for a int input between two values

    args:
        message (str): Prompt for user
        low (int): Low value, user entered value must be > this value to be accepted
        high (int): High value, user entered value must be < this value to be accepted
        show_range (boolean, Default True): Print hint to user the range

    returns:
        int_in (int): Input integer
    '''

    int_in = low - 1
    while (int_in < low) or (int_in > high):
        if show_range:
            suffix = ' (integer between ' + str(low) + ' and ' + str(high) + ')'
        else:
            suffix = ''
        inp = input('Enter a ' + message + suffix + ': ')
        if re.match('^-?[0-9]+$', inp) is not None:
            int_in = int(inp)
        else:
            print(colored('Must be an integer, try again!', 'red'))
    return int_in


Instruction:
Can you write a function in Python 3 where it
asks a user for a float input between two values.

Response:
def float_input(message, low, high):
    '''
    Ask a user for a float input between two values

    args:
        message (str): Prompt for user
        low (float): Low value, user entered value must be > this value to be accepted
        high (float): High value, user entered value must be < this value to be accepted

    returns:
        float_in (int): Input float
    '''

    float_in = low - 1.0
    while (float_in < low) or (float_in > high):
        inp = input('Enter a ' + message + ' (float between ' + str(low) + ' and ' + str(high) + '): ')
        if re.match('^([0-9]*[.])?[0-9]+$', inp) is not None:
            float_in = float(inp)
        else:
            print(colored('Must be a float, try again!', 'red'))
    return float_in


Instruction:
Can you generate the documentation for the following Python 3 function
def bool_input(message):
    '''
    Ask a user for a boolean input

    args:
        message (str): Prompt for user

    returns:
        bool_in (boolean): Input boolean
    '''

    while True:
        suffix = ' (true or false): '
        inp = input(message + suffix)
        if inp.lower() == 'true':
            return True
        elif inp.lower() == 'false':
            return False
        else:
            print(colored('Must be either true or false, try again!', 'red'))

Response: Ask a user for a boolean input


Instruction:
Can you generate a brief explanation for the following Python 3 code
def main(args = None):
    '''
    Main entry point for transfer command line tool.

    This essentially will marshall the user to the functions they need.
    '''

    parser = argparse.ArgumentParser(description = 'Tool to perform transfer learning')

    parser.add_argument('-c','--configure',
                        action = 'store_true',
                        help = 'Configure transfer')

    parser.add_argument('-e','--export',
                        action = 'store_true',
                        dest = 'export_config',
                        help = 'Export configuration and models')

    parser.add_argument('-i','--import',
                        action = 'store',
                        type = str,
                        default = None,
                        dest = 'import_config',
                        help = 'Import configuration and models')

    parser.add_argument('-p','--project',
                        action = 'store',
                        type = str,
                        default = None,
                        dest = 'project',
                        help = 'Specify a project, if not supplied it will be picked from configured projects')

    parser.add_argument('-r','--run',
                        action = 'store_true',
                        help = 'Run all transfer learning operations')

    parser.add_argument('-f','--final',
                        action = 'store_true',
                        help = 'Run final training on all layers: Warning SLOW!')

    parser.add_argument('-l','--last-weights',
                        action = 'store_true',
                        dest = 'last',
                        help = 'Restart from the last weights, rather than the best intermediate weights')

    parser.add_argument('--predict',
                        action = 'store',
                        type = str,
                        default = None,
                        const = 'default',
                        dest = 'predict',
                        nargs='?',
                        help = 'Predict model on file or directory')

    parser.add_argument('--prediction-rest-api',
                        action = 'store_true',
                        dest = 'rest_api',
                        help = 'Start rest api to make predictions on files or directories')

    if len(sys.argv) == 1:
        parser.print_help()
        return

    args = parser.parse_args()

    if args.import_config is not None:
        import_config(args.import_config)
        return
    elif args.export_config:
        project = select_project(args.project)
        weights = model_input(project)
        ind = model_individual_input(project, weights)
        export_config(project, weights, ind)
        return
    elif args.configure:
        configure()
        return
    else:
        project = select_project(args.project)

    if args.run:

        if project['is_array'] == False:
            project = images_to_array(project)
            update_config(project)

        if project['is_augmented'] == False:
            project = augment_arrays(project)
            update_config(project)

        if project['is_pre_model'] == False:
            project = pre_model(project)
            update_config(project)

        project = train_model(project, final = args.final, last = args.last)
        update_config(project)

        print('')
        print(colored('Completed modeling round: ' + str(project['model_round']), 'cyan'))
        print('')
        print('Best current model: ', colored(project['best_weights'], 'yellow'))
        print('Last current model: ', colored(project['last_weights'], 'yellow'))
        print('')
        print('To further refine the model, run again with:')
        print('')
        print(colored('    transfer --run --project ' + project['name'], 'green'))
        print('')
        print('To make predictions:')
        print('')
        print(colored('    transfer --predict [optional dir or file] --project ' + project['name'], 'yellow'))
        print('')

    elif args.rest_api:
        if project['server_weights'] is not None:
            start_server(project, 'server_weights')

        elif project['best_weights'] is not None:
            weights = model_input(project)
            start_server(project, weights)

        else:
            print('Model is not trained.  Please first run your project:')
            print('')
            print(colored('    transfer --run', 'green'))
            print('')
    elif args.predict is not None:
        if args.predict == 'default':

            completer = Completer()
            readline.set_completer_delims('\t')
            readline.parse_and_bind('tab: complete')
            readline.set_completer(completer.path_completer)
            args.predict = str_input('Enter a path to file(s): ')
        if project['server_weights'] is not None:
            predict_model(project, 'server_weights', args.predict)

        elif project['best_weights'] is not None:
            weights = model_input(project)
            print('Predicting on image(s) in: ', colored(args.predict, 'yellow'))
            predict_model(project, weights, args.predict)

        else:
            print('Model is not trained.  Please first run your project:')
            print('')
            print(colored('    transfer --run', 'green'))
            print('')

Response: Entry point for the main function of the command line tool.


Instruction:
Explain what the following Python 3 code does
def configure():
    '''
    Configure the transfer environment and store
    '''
    completer = Completer()
    readline.set_completer_delims('\t')
    readline.parse_and_bind('tab: complete')
    readline.set_completer(completer.path_completer)

    home = os.path.expanduser('~')
    if os.path.isfile(os.path.join(home, '.transfer', 'config.yaml')):
        with open(os.path.join(home, '.transfer', 'config.yaml'), 'r') as fp:
            config = yaml.load(fp.read())
    else:
        config = []

    project_name = input('Name your project: ')
    existing_project = None
    for project in config:
        if project_name == project['name']:
            existing_project = project_name
    if existing_project is not None:
        print(colored('Project ' + project_name + ' already exists', 'red'))
        overwrite = str_input('Would you like to overwrite this project? (yes or no) ', ['yes', 'no'])
        if overwrite == 'no':
            return
        else:
            config = [project for project in config if project_name != project['name']]

    image_path = os.path.expanduser(input('Select parent directory for your images: '))
    path_unset = True
    while path_unset:
        project_path = os.path.expanduser(input('Select destination for your project: '))
        if (project_path.find(image_path) == 0):
            print('Project destination should not be same or within image directory!')
        else:
            path_unset = False

    print('Select architecture:')
    print('[0] resnet50')
    print('[1] xception')
    print('[2] inception_v3')
    architecture = int_input('choice', 0, 2, show_range = False)
    if architecture == 0:
        arch = 'resnet50'
        img_dim = 224
        conv_dim = 7
        final_cutoff = 80
    elif architecture == 1:
        arch = 'xception'
        img_dim = 299
        conv_dim = 10
        final_cutoff = 80
    else:
        arch = 'inception_v3'
        img_dim = 299
        conv_dim = 8
        final_cutoff = 80
    api_port = int_input('port for local prediction API (suggested: 5000)', 1024, 49151)
    kfold = int_input('number of folds to use (suggested: 5)', 3, 10)
    kfold_every = bool_input('Fit a model for every fold? (if false, just fit one)')
    print('Warning: if working on a remote computer, you may not be able to plot!')
    plot_cm = bool_input('Plot a confusion matrix after training?')
    batch_size = int_input('batch size (suggested: 8)', 1, 64)
    learning_rate = float_input('learning rate (suggested: 0.001)', 0, 1)
    learning_rate_decay = float_input('learning decay rate (suggested: 0.000001)', 0, 1)
    cycle = int_input('number of cycles before resetting the learning rate (suggested: 3)', 1, 10)
    num_rounds = int_input('number of rounds (suggested: 3)', 1, 100)
    print('Select image resolution:')
    print('[0] low (' + str(img_dim) + ' px)')
    print('[1] mid (' + str(img_dim * 2) + ' px)')
    print('[2] high (' + str(img_dim * 4) + ' px)')
    img_resolution_index = int_input('choice', 0, 2, show_range = False)
    if img_resolution_index == 0:
        img_size = 1
    elif img_resolution_index == 1:
        img_size = 2
    else:
        img_size = 4
    use_augmentation = str_input('Would you like to add image augmentation? (yes or no) ', ['yes', 'no'])
    if use_augmentation == 'yes':
        augmentations = select_augmentations()
    else:
        augmentations = None

    project = {'name': project_name,
               'img_path': image_path,
               'path': project_path,
               'plot': plot_cm,
               'api_port': api_port,
               'kfold': kfold,
               'kfold_every': kfold_every,
               'cycle': cycle,
               'seed': np.random.randint(9999),
               'batch_size': batch_size,
               'learning_rate': learning_rate,
               'learning_rate_decay': learning_rate_decay,
               'final_cutoff': final_cutoff,
               'rounds': num_rounds,
               'img_size': img_size,
               'augmentations': augmentations,
               'architecture': arch,
               'img_dim': img_dim,
               'conv_dim': conv_dim,
               'is_split': False,
               'is_array': False,
               'is_augmented': False,
               'is_pre_model': False,
               'is_final': False,
               'model_round': 0,
               'server_weights': None,
               'last_weights': None,
               'best_weights': None}

    config.append(project)
    store_config(config)
    print('')
    print(colored('Project configure saved!', 'cyan'))
    print('')
    print('To run project:')
    print('')
    print(colored('    transfer --run --project ' + project_name, 'green'))
    print('or')
    print(colored('    transfer -r -p ' + project_name, 'green'))

Response: Configure the transfer environment and store the result in a new file.


Instruction:
Make a summary of the following Python 3 code
def configure_server():
    '''
    Configure the transfer environment and store
    '''

    home = os.path.expanduser('~')
    if os.path.isfile(os.path.join(home, '.transfer', 'config.yaml')):
        with open(os.path.join(home, '.transfer', 'config.yaml'), 'r') as fp:
            config = yaml.load(fp.read())
    else:
        config = []

    project_name = input('Name your project: ')
    existing_project = None
    for project in config:
        if project_name == project['name']:
            existing_project = project_name
    if existing_project is not None:
        print(colored('Project ' + project_name + ' already exists', 'red'))
        overwrite = str_input('Would you like to overwrite this project? (yes or no) ', ['yes', 'no'])
        if overwrite == 'no':
            return
        else:
            config = [project for project in config if project_name != project['name']]

    api_port = int_input('port for local prediction API (suggested: 5000)', 1024, 49151)
    print('Select image resolution:')
    print('[0] low (224 px)')
    print('[1] mid (448 px)')
    print('[2] high (896 px)')
    img_resolution_index = int_input('choice', 0, 2, show_range = False)
    if img_resolution_index == 0:
        img_size = 1
    elif img_resolution_index == 1:
        img_size = 2
    else:
        img_size = 4
    num_categories = int_input('number of image categories in your model', 0, 10000000)

    weights = False
    while weights == False:
        server_weights = os.path.expanduser(input('Select weights file: '))
        if os.path.isfile(server_weights):
            weights = True
        else:
            print('Cannot find the weight file: ', server_weights)

    project = {'name': project_name,
               'api_port': api_port,
               'img_size': img_size,
               'number_categories': num_categories,
               'server_weights': server_weights}

    config.append(project)
    store_config(config)
    print('')
    print(colored('Project configure saved!', 'cyan'))
    print('')
    print('To start the server:')
    print('')
    print(colored('    transfer --prediction-rest-api --project ' + project_name, 'green'))
    print('or')
    print(colored('    transfer --prediction-rest-api -p ' + project_name, 'green'))

Response: Configure the server and store the current transfer environment and store the result in the store


Instruction:
Given the following Python 3 function, write the documentation
def select_project(user_provided_project):
    '''
    Select a project from configuration to run transfer on

    args:
        user_provided_project (str): Project name that should match a project in the config

    returns:
        project (dict): Configuration settings for a user selected project

    '''

    home = os.path.expanduser('~')
    if os.path.isfile(os.path.join(home, '.transfer', 'config.yaml')):
        with open(os.path.join(home, '.transfer', 'config.yaml'), 'r') as fp:
            projects = yaml.load(fp.read())
        if len(projects) == 1:
            project = projects[0]
        else:
            if user_provided_project in [project['name'] for project in projects]:
                for inner_project in projects:
                    if user_provided_project == inner_project['name']:
                        project = inner_project
            else:
                print('Select your project')
                for i, project in enumerate(projects):
                    print('[' + str(i) + ']: ' + project['name'])
                project_index = int_input('project', -1, len(projects), show_range = False)
                project = projects[project_index]
    else:
        print('Transfer is not configured.')
        print('Please run:')
        print('')
        print(colored('    transfer --configure', 'green'))
        return

    print(colored('Project selected: ' + project['name'], 'cyan'))
    return project

Response: Select a project from configuration to run transfer on


Instruction:
Explain what the following Python 3 code does
def store_config(config, suffix = None):
    '''
    Store configuration

    args:
        config (list[dict]): configurations for each project
    '''
    home = os.path.expanduser('~')
    if suffix is not None:
        config_path = os.path.join(home, '.transfer', suffix)
    else:
        config_path = os.path.join(home, '.transfer')

    os.makedirs(config_path, exist_ok = True)
    with open(os.path.join(config_path, 'config.yaml'), 'w') as fp:
        yaml.dump(config, fp)

Response: Store configuration for each project


Instruction:
Explain what the following Python 3 code does
def update_config(updated_project):
    '''
    Update project in configuration

    args:
        updated_project (dict): Updated project configuration values

    '''

    home = os.path.expanduser('~')
    if os.path.isfile(os.path.join(home, '.transfer', 'config.yaml')):
        with open(os.path.join(home, '.transfer', 'config.yaml'), 'r') as fp:
            projects = yaml.load(fp.read())
        replace_index = -1
        for i, project in enumerate(projects):
            if project['name'] == updated_project['name']:
                replace_index = i

        if replace_index > -1:
            projects[replace_index] = updated_project
            store_config(projects)
        else:
            print('Not saving configuration')
            print(colored('Project: ' + updated_project['name'] + ' was not found in configured projects!', 'red'))

    else:
        print('Transfer is not configured.')
        print('Please run:')
        print('')
        print(colored('    transfer --configure', 'cyan'))
        return

Response: Update project in configuration


Instruction:
Given the following Python 3 function, write the documentation
def _check_symbols(self, symbols):
        if len(symbols) != self.size:
            raise TypeError("The number of symbols in the graph does not "
                "match the length of the atomic numbers array.")
        for symbol in symbols:
            if not isinstance(symbol, str):
                raise TypeError("All symbols must be strings.")

Response: Checks that the given array of atomic numbers is a string.


Instruction:
Write a Python 3 script for
constructing a MolecularGraph object from a Molecule object.

Response:
def from_geometry(cls, molecule, do_orders=False, scaling=1.0):
        """Construct a MolecularGraph object based on interatomic distances

           All short distances are computed with the binning module and compared
           with a database of bond lengths. Based on this comparison, bonded
           atoms are detected.

           Before marking a pair of atoms A and B as bonded, it is also checked
           that there is no third atom C somewhat between A and B.
           When an atom C exists that is closer to B (than A) and the angle
           A-B-C is less than 45 degrees, atoms A and B are not bonded.
           Similarly if C is closer to A (than B) and the angle B-A-C is less
           then 45 degrees, A and B are not connected.

           Argument:
            | ``molecule``  --  The molecule to derive the graph from

           Optional arguments:
            | ``do_orders``  --  set to True to estimate the bond order
            | ``scaling``  --  scale the threshold for the connectivity. increase
                               this to 1.5 in case of transition states when a
                               fully connected topology is required.
        """
        from molmod.bonds import bonds

        unit_cell = molecule.unit_cell
        pair_search = PairSearchIntra(
            molecule.coordinates,
            bonds.max_length*bonds.bond_tolerance*scaling,
            unit_cell
        )

        orders = []
        lengths = []
        edges = []

        for i0, i1, delta, distance in pair_search:
            bond_order = bonds.bonded(molecule.numbers[i0], molecule.numbers[i1], distance/scaling)
            if bond_order is not None:
                if do_orders:
                    orders.append(bond_order)
                lengths.append(distance)
                edges.append((i0,i1))

        if do_orders:
            result = cls(edges, molecule.numbers, orders, symbols=molecule.symbols)
        else:
            result = cls(edges, molecule.numbers, symbols=molecule.symbols)

        # run a check on all neighbors. if two bonds point in a direction that
        # differs only by 45 deg. the longest of the two is discarded. the
        # double loop over the neighbors is done such that the longest bonds
        # are eliminated first
        slated_for_removal = set([])
        threshold = 0.5**0.5
        for c, ns in result.neighbors.items():
            lengths_ns = []
            for n in ns:
                delta = molecule.coordinates[n] - molecule.coordinates[c]
                if unit_cell is not None:
                    delta = unit_cell.shortest_vector(delta)
                length = np.linalg.norm(delta)
                lengths_ns.append([length, delta, n])
            lengths_ns.sort(reverse=True, key=(lambda r: r[0]))
            for i0, (length0, delta0, n0) in enumerate(lengths_ns):
                for i1, (length1, delta1, n1) in enumerate(lengths_ns[:i0]):
                    if length1 == 0.0:
                        continue
                    cosine = np.dot(delta0, delta1)/length0/length1
                    if cosine > threshold:
                        # length1 > length0
                        slated_for_removal.add((c,n1))
                        lengths_ns[i1][0] = 0.0
        # construct a mask
        mask = np.ones(len(edges), bool)
        for i0, i1 in slated_for_removal:
            edge_index = result.edge_index.get(frozenset([i0,i1]))
            if edge_index is None:
                raise ValueError('Could not find edge that has to be removed: %i %i' % (i0, i1))
            mask[edge_index] = False
        # actual removal
        edges = [edges[i] for i in range(len(edges)) if mask[i]]
        if do_orders:
            bond_order = [bond_order[i] for i in range(len(bond_order)) if mask[i]]
            result = cls(edges, molecule.numbers, orders)
        else:
            result = cls(edges, molecule.numbers)

        lengths = [lengths[i] for i in range(len(lengths)) if mask[i]]
        result.bond_lengths = np.array(lengths)

        return result


Instruction:
Can you implement a function in Python 3 that
constructs a molecular graph from the blob representation

Response:
def from_blob(cls, s):
        """Construct a molecular graph from the blob representation"""
        atom_str, edge_str = s.split()
        numbers = np.array([int(s) for s in atom_str.split(",")])
        edges = []
        orders = []
        for s in edge_str.split(","):
            i, j, o = (int(w) for w in s.split("_"))
            edges.append((i, j))
            orders.append(o)
        return cls(edges, numbers, np.array(orders))


Instruction:
Can you tell what is the following Python 3 function doing
def get_vertex_string(self, i):
        number = self.numbers[i]
        if number == 0:
            return Graph.get_vertex_string(self, i)
        else:
            # pad with zeros to make sure that string sort is identical to number sort
            return "%03i" % number

Response: Return a string based on the atom number


Instruction:
Can you tell what is the following Python 3 function doing
def get_edge_string(self, i):
        order = self.orders[i]
        if order == 0:
            return Graph.get_edge_string(self, i)
        else:
            # pad with zeros to make sure that string sort is identical to number sort
            return "%03i" % order

Response: Return a string based on the bond order


Instruction:
Create a Python 3 function to
create a subgraph of the current graph with the given subvertices.

Response:
def get_subgraph(self, subvertices, normalize=False):
        """Creates a subgraph of the current graph

           See :meth:`molmod.graphs.Graph.get_subgraph` for more information.
        """
        graph = Graph.get_subgraph(self, subvertices, normalize)
        if normalize:
            new_numbers = self.numbers[graph._old_vertex_indexes] # vertices do change
        else:
            new_numbers = self.numbers # vertices don't change!
        if self.symbols is None:
            new_symbols = None
        elif normalize:
            new_symbols = tuple(self.symbols[i] for i in graph._old_vertex_indexes)
        else:
            new_symbols = self.symbols
        new_orders = self.orders[graph._old_edge_indexes]
        result = MolecularGraph(graph.edges, new_numbers, new_orders, new_symbols)
        if normalize:
            result._old_vertex_indexes = graph._old_vertex_indexes
        result._old_edge_indexes = graph._old_edge_indexes
        return result


Instruction:
Write a Python 3 script for
returning a molecular graph where hydrogens are added explicitely.

Response:
def add_hydrogens(self, formal_charges=None):
        """Returns a molecular graph where hydrogens are added explicitely

           When the bond order is unknown, it assumes bond order one. If the
           graph  has an attribute formal_charges, this routine will take it
           into account when counting the number of hydrogens to be added. The
           returned graph will also have a formal_charges attribute.

           This routine only adds hydrogen atoms for a limited set of atoms from
           the periodic system: B, C, N, O, F, Al, Si, P, S, Cl, Br.
        """

        new_edges = list(self.edges)
        counter = self.num_vertices
        for i in range(self.num_vertices):
            num_elec = self.numbers[i]
            if formal_charges is not None:
                num_elec -= int(formal_charges[i])
            if num_elec >= 5 and num_elec <= 9:
                num_hydrogen = num_elec - 10 + 8
            elif num_elec >= 13 and num_elec <= 17:
                num_hydrogen = num_elec - 18 + 8
            elif num_elec == 35:
                num_hydrogen = 1
            else:
                continue
            if num_hydrogen > 4:
                num_hydrogen = 8 - num_hydrogen
            for n in self.neighbors[i]:
                bo = self.orders[self.edge_index[frozenset([i, n])]]
                if bo <= 0:
                    bo = 1
                num_hydrogen -= int(bo)
            for j in range(num_hydrogen):
                new_edges.append((i, counter))
                counter += 1
        new_numbers = np.zeros(counter, int)
        new_numbers[:self.num_vertices] = self.numbers
        new_numbers[self.num_vertices:] = 1
        new_orders = np.zeros(len(new_edges), int)
        new_orders[:self.num_edges] = self.orders
        new_orders[self.num_edges:] = 1
        result = MolecularGraph(new_edges, new_numbers, new_orders)
        return result


Instruction:
How would you implement a function in Python 3 that
checks if the next match can be a valid ( part of a ) ring.

Response:
def check_next_match(self, match, new_relations, subject_graph, one_match):
        """Check if the (onset for a) match can be a valid (part of a) ring"""
        if not CustomPattern.check_next_match(self, match, new_relations, subject_graph, one_match):
            return False
        if self.strong:
            # can this ever become a strong ring?
            vertex1_start = match.forward[self.pattern_graph.central_vertex]
            for vertex1 in new_relations.values():
                paths = list(subject_graph.iter_shortest_paths(vertex1, vertex1_start))
                if self.size % 2 == 0 and len(match) == self.size:
                    if len(paths) != 2:
                        #print "NRingPattern.check_next_match: not strong a.1"
                        return False
                    for path in paths:
                        if len(path) != len(match)//2+1:
                            #print "NRingPattern.check_next_match: not strong a.2"
                            return False
                else:
                    if len(paths) != 1:
                        #print "NRingPattern.check_next_match: not strong b.1"
                        return False
                    if len(paths[0]) != (len(match)+1)//2:
                        #print "NRingPattern.check_next_match: not strong b.2"
                        return False
            #print "RingPattern.check_next_match: no remarks"
        return True


Instruction:
Can you generate a brief explanation for the following Python 3 code
def complete(self, match, subject_graph):
        if not CustomPattern.complete(self, match, subject_graph):
            return False
        if self.strong:
            # If the ring is not strong, return False
            if self.size % 2 == 0:
                # even ring
                for i in range(self.size//2):
                    vertex1_start = match.forward[i]
                    vertex1_stop = match.forward[(i+self.size//2)%self.size]
                    paths = list(subject_graph.iter_shortest_paths(vertex1_start, vertex1_stop))
                    if len(paths) != 2:
                        #print "Even ring must have two paths between opposite vertices"
                        return False
                    for path in paths:
                        if len(path) != self.size//2+1:
                            #print "Paths between opposite vertices must half the size of the ring+1"
                            return False
            else:
                # odd ring
                for i in range(self.size//2+1):
                    vertex1_start = match.forward[i]
                    vertex1_stop = match.forward[(i+self.size//2)%self.size]
                    paths = list(subject_graph.iter_shortest_paths(vertex1_start, vertex1_stop))
                    if len(paths) > 1:
                        return False
                    if len(paths[0]) != self.size//2+1:
                        return False
                    vertex1_stop = match.forward[(i+self.size//2+1)%self.size]
                    paths = list(subject_graph.iter_shortest_paths(vertex1_start, vertex1_stop))
                    if len(paths) > 1:
                        return False
                    if len(paths[0]) != self.size//2+1:
                        return False
        return True

Response: Check the completeness of the ring match


Instruction:
Can you tell what is the following Python 3 function doing
def get_kind(self, value):
        if isinstance(value, float):
            return 'f'
        elif isinstance(value, int):
            return 'i'
        else:
            raise ValueError("Only integer or floating point values can be stored.")

Response: Return the kind of the attribute


Instruction:
Here you have a function in Python 3, explain what it does
def dump(self, f, name):
        # print the header line
        value = self.get()
        kind = self.get_kind(value)
        print("% 40s  kind=%s  value=%s" % (name, kind, value), file=f)

Response: Write the attribute to a file - like object


Instruction:
Can you write a function in Python 3 where it
returns the value of the attribute

Response:
def get(self, copy=False):
        """Return the value of the attribute"""
        array = getattr(self.owner, self.name)
        if copy:
            return array.copy()
        else:
            return array


Instruction:
Implement a function in Python 3 to
write the attribute to a file - like object

Response:
def dump(self, f, name):
        """Write the attribute to a file-like object"""
        array = self.get()
        # print the header line
        print("% 40s  kind=%s  shape=(%s)" % (
            name,
            array.dtype.kind,
            ",".join([str(int(size_axis)) for size_axis in array.shape]),
        ), file=f)
        # print the numbers
        counter = 0
        for value in array.flat:
            counter += 1
            print("% 20s" % value, end=' ', file=f)
            if counter % 4 == 0:
                print(file=f)
        if counter % 4 != 0:
            print(file=f)


Instruction:
Write a Python 3 function for
loading the array data from a file - like object

Response:
def load(self, f, skip):
        """Load the array data from a file-like object"""
        array = self.get()
        counter = 0
        counter_limit = array.size
        convert = array.dtype.type
        while counter < counter_limit:
            line = f.readline()
            words = line.split()
            for word in words:
                if counter >= counter_limit:
                    raise FileFormatError("Wrong array data: too many values.")
                if not skip:
                    array.flat[counter] = convert(word)
                counter += 1


Instruction:
Can you generate the documentation for the following Python 3 function
def _register(self, name, AttrCls):
        if not issubclass(AttrCls, StateAttr):
            raise TypeError("The second argument must a StateAttr instance.")
        if len(name) > 40:
            raise ValueError("Name can count at most 40 characters.")
        self._fields[name] = AttrCls(self._owner, name)

Response: Register a new attribute to take care of with dump and load


Instruction:
Can you implement a function in Python 3 that
returns a dictionary object with the registered fields and their values Optional rguments subset = list of names to restrict the number of fields in the result

Response:
def get(self, subset=None):
        """Return a dictionary object with the registered fields and their values

           Optional rgument:
            | ``subset``  --  a list of names to restrict the number of fields
                              in the result
        """
        if subset is None:
            return dict((name, attr.get(copy=True)) for name, attr in self._fields.items())
        else:
            return dict((name, attr.get(copy=True)) for name, attr in self._fields.items() if name in subset)


Instruction:
Write a Python 3 function that can
assign the data to the attributes of the current object based on a dictionary with the data to be assigned to .

Response:
def set(self, new_fields, subset=None):
        """Assign the registered fields based on a dictionary

           Argument:
            | ``new_fields``  --  the dictionary with the data to be assigned to
                                  the attributes

           Optional argument:
            | ``subset``  --  a list of names to restrict the fields that are
                              effectively overwritten
        """
        for name in new_fields:
            if name not in self._fields and (subset is None or name in subset):
                raise ValueError("new_fields contains an unknown field '%s'." % name)
        if subset is not None:
            for name in subset:
                if name not in self._fields:
                    raise ValueError("name '%s' in subset is not a known field in self._fields." % name)
                if name not in new_fields:
                    raise ValueError("name '%s' in subset is not a known field in new_fields." % name)
        if subset is None:
            if len(new_fields) != len(self._fields):
                raise ValueError("new_fields contains too many fields.")
        for name, attr in self._fields.items():
            if name in subset:
                attr.set(new_fields[name])


Instruction:
Write a Python 3 script for
dumping the registered fields to a file

Response:
def dump(self, filename):
        """Dump the registered fields to a file

           Argument:
            | ``filename``  --  the file to write to
        """
        with open(filename, "w") as f:
            for name in sorted(self._fields):
                self._fields[name].dump(f, name)


Instruction:
Can you generate the documentation for the following Python 3 function
def _load_bond_data(self):

        def read_units(unit_names):
            """convert unit_names into conversion factors"""
            tmp = {
                "A": units.angstrom,
                "pm": units.picometer,
                "nm": units.nanometer,
            }
            return [tmp[unit_name] for unit_name in unit_names]

        def read_length(BOND_TYPE, words, col):
            """Read the bondlengths from a single line in the data file"""
            nlow = int(words[2])
            nhigh = int(words[3])
            for i, conversion in zip(range((len(words) - 4) // 3), conversions):
                word = words[col + 3 + i*3]
                if word != 'NA':
                    self.lengths[BOND_TYPE][frozenset([nlow, nhigh])] = float(word)*conversion
                    return

        with pkg_resources.resource_stream(__name__, 'data/bonds.csv') as f:
            for line in f:
                words = line.decode('utf-8').split()
                if (len(words) > 0) and (words[0][0] != "#"):
                    if words[0] == "unit":
                        conversions = read_units(words[1:])
                    else:
                        read_length(BOND_SINGLE, words, 1)
                        read_length(BOND_DOUBLE, words, 2)
                        read_length(BOND_TRIPLE, words, 3)

Response: Load the bond data from the given file.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _approximate_unkown_bond_lengths(self):
        dataset = self.lengths[BOND_SINGLE]
        for n1 in periodic.iter_numbers():
            for n2 in periodic.iter_numbers():
                if n1 <= n2:
                    pair = frozenset([n1, n2])
                    atom1 = periodic[n1]
                    atom2 = periodic[n2]
                    #if (pair not in dataset) and hasattr(atom1, "covalent_radius") and hasattr(atom2, "covalent_radius"):
                    if (pair not in dataset) and (atom1.covalent_radius is not None) and (atom2.covalent_radius is not None):
                        dataset[pair] = (atom1.covalent_radius + atom2.covalent_radius)

Response: Completes the bond length database with approximations based on VDW radii


Instruction:
Can you write a function in Python 3 where it
returns the estimated bond type that is bonded between two atom numbers n1 and n2.

Response:
def bonded(self, n1, n2, distance):
        """Return the estimated bond type

           Arguments:
            | ``n1``  --  the atom number of the first atom in the bond
            | ``n2``  --  the atom number of the second atom the bond
            | ``distance``  --  the distance between the two atoms

           This method checks whether for the given pair of atom numbers, the
           given distance corresponds to a certain bond length. The best
           matching bond type will be returned. If the distance is a factor
           ``self.bond_tolerance`` larger than a tabulated distance, the
           algorithm will not relate them.
        """
        if distance > self.max_length * self.bond_tolerance:
            return None

        deviation = 0.0
        pair = frozenset([n1, n2])
        result = None
        for bond_type in bond_types:
            bond_length = self.lengths[bond_type].get(pair)
            if (bond_length is not None) and \
               (distance < bond_length * self.bond_tolerance):
                if result is None:
                    result = bond_type
                    deviation = abs(bond_length - distance)
                else:
                    new_deviation = abs(bond_length - distance)
                    if deviation > new_deviation:
                        result = bond_type
                        deviation = new_deviation
        return result


Instruction:
How would you code a function in Python 3 to
return the length of a bond between n1 and n2.

Response:
def get_length(self, n1, n2, bond_type=BOND_SINGLE):
        """Return the length of a bond between n1 and n2 of type bond_type

           Arguments:
            | ``n1``  --  the atom number of the first atom in the bond
            | ``n2``  --  the atom number of the second atom the bond

           Optional argument:
            | ``bond_type``  --  the type of bond [default=BOND_SINGLE]

           This is a safe method for querying a bond_length. If no answer can be
           found, this get_length returns None.
        """
        dataset = self.lengths.get(bond_type)
        if dataset == None:
            return None
        return dataset.get(frozenset([n1, n2]))


Instruction:
Write a Python 3 script for
constructing a 3D unit cell with the given parameters.

Response:
def from_parameters3(cls, lengths, angles):
        """Construct a 3D unit cell with the given parameters

           The a vector is always parallel with the x-axis and they point in the
           same direction. The b vector is always in the xy plane and points
           towards the positive y-direction. The c vector points towards the
           positive z-direction.
        """
        for length in lengths:
            if length <= 0:
                raise ValueError("The length parameters must be strictly positive.")
        for angle in angles:
            if angle <= 0 or angle >= np.pi:
                raise ValueError("The angle parameters must lie in the range ]0 deg, 180 deg[.")
        del length
        del angle

        matrix = np.zeros((3, 3), float)

        # first cell vector along x-axis
        matrix[0, 0] = lengths[0]

        # second cell vector in x-y plane
        matrix[0, 1] = np.cos(angles[2])*lengths[1]
        matrix[1, 1] = np.sin(angles[2])*lengths[1]

        # Finding the third cell vector is slightly more difficult. :-)
        # It works like this:
        # The dot products of a with c, b with c and c with c are known. the
        # vector a has only an x component, b has no z component. This results
        # in the following equations:
        u_a = lengths[0]*lengths[2]*np.cos(angles[1])
        u_b = lengths[1]*lengths[2]*np.cos(angles[0])
        matrix[0, 2] = u_a/matrix[0, 0]
        matrix[1, 2] = (u_b - matrix[0, 1]*matrix[0, 2])/matrix[1, 1]
        u_c = lengths[2]**2 - matrix[0, 2]**2 - matrix[1, 2]**2
        if u_c < 0:
            raise ValueError("The given cell parameters do not correspond to a unit cell.")
        matrix[2, 2] = np.sqrt(u_c)

        active = np.ones(3, bool)
        return cls(matrix, active)


Instruction:
Make a summary of the following Python 3 code
def active_inactive(self):
        active_indices = []
        inactive_indices = []
        for index, active in enumerate(self.active):
            if active:
                active_indices.append(index)
            else:
                inactive_indices.append(index)
        return active_indices, inactive_indices

Response: The indexes of the active and inactive cell vectors


Instruction:
Can you generate a brief explanation for the following Python 3 code
def reciprocal(self):
        U, S, Vt = np.linalg.svd(self.matrix*self.active)
        Sinv = np.zeros(S.shape, float)
        for i in range(3):
            if abs(S[i]) < self.eps:
                Sinv[i] = 0.0
            else:
                Sinv[i] = 1.0/S[i]
        return np.dot(U*Sinv, Vt)*self.active

Response: The reciprocal of the unit cell.


Instruction:
Implement a function in Python 3 to
compute the rotation matrix that aligns the unit cell with the the Cartesian axes starting with cell vector a.

Response:
def alignment_a(self):
        """Computes the rotation matrix that aligns the unit cell with the
           Cartesian axes, starting with cell vector a.

           * a parallel to x
           * b in xy-plane with b_y positive
           * c with c_z positive
        """
        from molmod.transformations import Rotation
        new_x = self.matrix[:, 0].copy()
        new_x /= np.linalg.norm(new_x)
        new_z = np.cross(new_x, self.matrix[:, 1])
        new_z /= np.linalg.norm(new_z)
        new_y = np.cross(new_z, new_x)
        new_y /= np.linalg.norm(new_y)
        return Rotation(np.array([new_x, new_y, new_z]))


Instruction:
Make a summary of the following Python 3 code
def spacings(self):
        result_invsq = (self.reciprocal**2).sum(axis=0)
        result = np.zeros(3, float)
        for i in range(3):
            if result_invsq[i] > 0:
                result[i] = result_invsq[i]**(-0.5)
        return result

Response: Computes the distances between neighboring crystal planes


Instruction:
Create a Python 3 function to
return a new unit cell with an additional cell vector.

Response:
def add_cell_vector(self, vector):
        """Returns a new unit cell with an additional cell vector"""
        act = self.active_inactive[0]
        if len(act) == 3:
            raise ValueError("The unit cell already has three active cell vectors.")
        matrix = np.zeros((3, 3), float)
        active = np.zeros(3, bool)
        if len(act) == 0:
            # Add the new vector
            matrix[:, 0] = vector
            active[0] = True
            return UnitCell(matrix, active)

        a = self.matrix[:, act[0]]
        matrix[:, 0] = a
        active[0] = True
        if len(act) == 1:
            # Add the new vector
            matrix[:, 1] = vector
            active[1] = True
            return UnitCell(matrix, active)

        b = self.matrix[:, act[1]]
        matrix[:, 1] = b
        active[1] = True
        if len(act) == 2:
            # Add the new vector
            matrix[:, 2] = vector
            active[2] = True
            return UnitCell(matrix, active)


Instruction:
Write a Python 3 script for
returning a list of indices of the interaction neighboring unit cells that have at least one point with a distance smaller than radius.

Response:
def get_radius_ranges(self, radius, mic=False):
        """Return ranges of indexes of the interacting neighboring unit cells

           Interacting neighboring unit cells have at least one point in their
           box volume that has a distance smaller or equal than radius to at
           least one point in the central cell. This concept is of importance
           when computing pair wise long-range interactions in periodic systems.

           The mic (stands for minimum image convention) option can be used to
           change the behavior of this routine such that only neighboring cells
           are considered that have at least one point withing a distance below
           `radius` from the center of the reference cell.
        """
        result = np.zeros(3, int)
        for i in range(3):
            if self.spacings[i] > 0:
                if mic:
                    result[i] = np.ceil(radius/self.spacings[i]-0.5)
                else:
                    result[i] = np.ceil(radius/self.spacings[i])
        return result


Instruction:
How would you code a function in Python 3 to
return the indexes of the interaction neighboring unit cells that have at least one point in the central cell that has a distance smaller than radius to the central cell.

Response:
def get_radius_indexes(self, radius, max_ranges=None):
        """Return the indexes of the interacting neighboring unit cells

           Interacting neighboring unit cells have at least one point in their
           box volume that has a distance smaller or equal than radius to at
           least one point in the central cell. This concept is of importance
           when computing pair wise long-range interactions in periodic systems.

           Argument:
            | ``radius``  --  the radius of the interaction sphere

           Optional argument:
            | ``max_ranges``  --  numpy array with three elements: The maximum
                                  ranges of indexes to consider. This is
                                  practical when working with the minimum image
                                  convention to reduce the generated bins to the
                                  minimum image. (see binning.py) Use -1 to
                                  avoid such limitations. The default is three
                                  times -1.

        """
        if max_ranges is None:
            max_ranges = np.array([-1, -1, -1])
        ranges = self.get_radius_ranges(radius)*2+1
        mask = (max_ranges != -1) & (max_ranges < ranges)
        ranges[mask] = max_ranges[mask]
        max_size = np.product(self.get_radius_ranges(radius)*2 + 1)
        indexes = np.zeros((max_size, 3), int)

        from molmod.ext import unit_cell_get_radius_indexes
        reciprocal = self.reciprocal*self.active
        matrix = self.matrix*self.active
        size = unit_cell_get_radius_indexes(
            matrix, reciprocal, radius, max_ranges, indexes
        )
        return indexes[:size]


Instruction:
Given the following Python 3 function, write the documentation
def guess_geometry(graph, unit_cell=None, verbose=False):

    N = len(graph.numbers)
    from molmod.minimizer import Minimizer, ConjugateGradient, \
        NewtonLineSearch, ConvergenceCondition, StopLossCondition

    search_direction = ConjugateGradient()
    line_search = NewtonLineSearch()
    convergence = ConvergenceCondition(grad_rms=1e-6, step_rms=1e-6)
    stop_loss = StopLossCondition(max_iter=500, fun_margin=0.1)

    ff = ToyFF(graph, unit_cell)
    x_init = np.random.normal(0, 1, N*3)

    #  level 1 geometry optimization: graph based
    ff.dm_quad = 1.0
    minimizer = Minimizer(x_init, ff, search_direction, line_search, convergence, stop_loss, anagrad=True, verbose=verbose)
    x_init = minimizer.x

    #  level 2 geometry optimization: graph based + pauli repulsion
    ff.dm_quad = 1.0
    ff.dm_reci = 1.0
    minimizer = Minimizer(x_init, ff, search_direction, line_search, convergence, stop_loss, anagrad=True, verbose=verbose)
    x_init = minimizer.x

    # Add a little noise to avoid saddle points
    x_init += np.random.uniform(-0.01, 0.01, len(x_init))

    #  level 3 geometry optimization: bond lengths + pauli
    ff.dm_quad = 0.0
    ff.dm_reci = 0.2
    ff.bond_quad = 1.0
    minimizer = Minimizer(x_init, ff, search_direction, line_search, convergence, stop_loss, anagrad=True, verbose=verbose)
    x_init = minimizer.x

    #  level 4 geometry optimization: bond lengths + bending angles + pauli
    ff.bond_quad = 0.0
    ff.bond_hyper = 1.0
    ff.span_quad = 1.0
    minimizer = Minimizer(x_init, ff, search_direction, line_search, convergence, stop_loss, anagrad=True, verbose=verbose)
    x_init = minimizer.x

    x_opt = x_init

    mol = Molecule(graph.numbers, x_opt.reshape((N, 3)))
    return mol

Response: This routine tries to guess the molecular geometry based on a molecular graph.


Instruction:
Explain what the following Python 3 code does
def tune_geometry(graph, mol, unit_cell=None, verbose=False):

    N = len(graph.numbers)
    from molmod.minimizer import Minimizer, ConjugateGradient, \
        NewtonLineSearch, ConvergenceCondition, StopLossCondition

    search_direction = ConjugateGradient()
    line_search = NewtonLineSearch()
    convergence = ConvergenceCondition(grad_rms=1e-6, step_rms=1e-6)
    stop_loss = StopLossCondition(max_iter=500, fun_margin=1.0)

    ff = ToyFF(graph, unit_cell)
    x_init = mol.coordinates.ravel()

    #  level 3 geometry optimization: bond lengths + pauli
    ff.dm_reci = 0.2
    ff.bond_quad = 1.0
    minimizer = Minimizer(x_init, ff, search_direction, line_search, convergence, stop_loss, anagrad=True, verbose=verbose)
    x_init = minimizer.x

    #  level 4 geometry optimization: bond lengths + bending angles + pauli
    ff.bond_quad = 0.0
    ff.bond_hyper = 1.0
    ff.span_quad = 1.0
    minimizer = Minimizer(x_init, ff, search_direction, line_search, convergence, stop_loss, anagrad=True, verbose=verbose)
    x_init = minimizer.x

    x_opt = x_init

    mol = Molecule(graph.numbers, x_opt.reshape((N, 3)))
    return mol

Response: Fine tune a molecular graph with a more accurate guess of the initial geometry.


Instruction:
Write a Python 3 script for
updating the coordinates and derived quantities of the system.

Response:
def update_coordinates(self, coordinates=None):
        """Update the coordinates (and derived quantities)

           Argument:
             coordinates  --  new Cartesian coordinates of the system
        """
        if coordinates is not None:
            self.coordinates = coordinates
        self.numc = len(self.coordinates)
        self.distances = np.zeros((self.numc, self.numc), float)
        self.deltas = np.zeros((self.numc, self.numc, 3), float)
        self.directions = np.zeros((self.numc, self.numc, 3), float)
        self.dirouters = np.zeros((self.numc, self.numc, 3, 3), float)
        for index1, coordinate1 in enumerate(self.coordinates):
            for index2, coordinate2 in enumerate(self.coordinates):
                delta = coordinate1 - coordinate2
                self.deltas[index1, index2] = delta
                distance = np.linalg.norm(delta)
                self.distances[index1, index2] = distance
                if index1 != index2:
                    tmp = delta/distance
                    self.directions[index1, index2] = tmp
                    self.dirouters[index1, index2] = np.outer(tmp, tmp)


Instruction:
How would you explain what the following Python 3 function does
def energy(self):
        result = 0.0
        for index1 in range(self.numc):
            for index2 in range(index1):
                if self.scaling[index1, index2] > 0:
                    for se, ve in self.yield_pair_energies(index1, index2):
                        result += se*ve*self.scaling[index1, index2]
        return result

Response: Compute the energy of the system


Instruction:
Given the following Python 3 function, write the documentation
def gradient_component(self, index1):
        result = np.zeros(3, float)
        for index2 in range(self.numc):
            if self.scaling[index1, index2] > 0:
                for (se, ve), (sg, vg) in zip(self.yield_pair_energies(index1, index2), self.yield_pair_gradients(index1, index2)):
                    result += (sg*self.directions[index1, index2]*ve + se*vg)*self.scaling[index1, index2]
        return result

Response: Compute the gradient of the energy for one atom


Instruction:
Can you write a function in Python 3 where it
computes the gradient of the energy for all atoms

Response:
def gradient(self):
        """Compute the gradient of the energy for all atoms"""
        result = np.zeros((self.numc, 3), float)
        for index1 in range(self.numc):
            result[index1] = self.gradient_component(index1)
        return result


Instruction:
Write a Python 3 script for
computing the hessian of the energy for one atom pair

Response:
def hessian_component(self, index1, index2):
        """Compute the hessian of the energy for one atom pair"""
        result = np.zeros((3, 3), float)
        if index1 == index2:
            for index3 in range(self.numc):
                if self.scaling[index1, index3] > 0:
                    d_1 = 1/self.distances[index1, index3]
                    for (se, ve), (sg, vg), (sh, vh) in zip(
                        self.yield_pair_energies(index1, index3),
                        self.yield_pair_gradients(index1, index3),
                        self.yield_pair_hessians(index1, index3)
                    ):
                        result += (
                            +sh*self.dirouters[index1, index3]*ve
                            +sg*(np.identity(3, float) - self.dirouters[index1, index3])*ve*d_1
                            +sg*np.outer(self.directions[index1, index3],  vg)
                            +sg*np.outer(vg, self.directions[index1, index3])
                            +se*vh
                        )*self.scaling[index1, index3]
        elif self.scaling[index1, index2] > 0:
            d_1 = 1/self.distances[index1, index2]
            for (se, ve), (sg, vg), (sh, vh) in zip(
                self.yield_pair_energies(index1, index2),
                self.yield_pair_gradients(index1, index2),
                self.yield_pair_hessians(index1, index2)
            ):
                result -= (
                    +sh*self.dirouters[index1, index2]*ve
                    +sg*(np.identity(3, float) - self.dirouters[index1, index2])*ve*d_1
                    +sg*np.outer(self.directions[index1, index2],  vg)
                    +sg*np.outer(vg, self.directions[index1, index2])
                    +se*vh
                )*self.scaling[index1, index2]
        return result


Instruction:
Make a summary of the following Python 3 code
def hessian(self):
        result = np.zeros((self.numc, 3, self.numc, 3), float)
        for index1 in range(self.numc):
            for index2 in range(self.numc):
                result[index1, :, index2, :] = self.hessian_component(index1, index2)
        return result

Response: Compute the hessian of the energy of the user


Instruction:
Create a Python 3 function for
yielding pairs of charges and dipoles.

Response:
def yield_pair_energies(self, index1, index2):
        """Yields pairs ((s(r_ij), v(bar{r}_ij))"""
        d_1 = 1/self.distances[index1, index2]
        if self.charges is not None:
            c1 = self.charges[index1]
            c2 = self.charges[index2]
            yield c1*c2*d_1, 1
        if self.dipoles is not None:
            d_3 = d_1**3
            d_5 = d_1**5
            delta = self.deltas[index1, index2]
            p1 = self.dipoles[index1]
            p2 = self.dipoles[index2]
            yield d_3*np.dot(p1, p2), 1
            yield -3*d_5, np.dot(p1, delta)*np.dot(delta, p2)
            if self.charges is not None:
                yield c1*d_3, np.dot(p2, delta)
                yield c2*d_3, np.dot(p1, -delta)


Instruction:
Create a Python 3 function to
yield pairs of gradients between two charges and dipoles.

Response:
def yield_pair_gradients(self, index1, index2):
        """Yields pairs ((s'(r_ij), grad_i v(bar{r}_ij))"""
        d_2 = 1/self.distances[index1, index2]**2
        if self.charges is not None:
            c1 = self.charges[index1]
            c2 = self.charges[index2]
            yield -c1*c2*d_2, np.zeros(3)
        if self.dipoles is not None:
            d_4 = d_2**2
            d_6 = d_2**3
            delta = self.deltas[index1, index2]
            p1 = self.dipoles[index1]
            p2 = self.dipoles[index2]
            yield -3*d_4*np.dot(p1, p2), np.zeros(3)
            yield 15*d_6, p1*np.dot(p2, delta) + p2*np.dot(p1, delta)
            if self.charges is not None:
                yield -3*c1*d_4, p2
                yield -3*c2*d_4, -p1


Instruction:
Implement a Python 3 function for
yielding pairs of hessians.

Response:
def yield_pair_hessians(self, index1, index2):
        """Yields pairs ((s''(r_ij), grad_i (x) grad_i v(bar{r}_ij))"""
        d_1 = 1/self.distances[index1, index2]
        d_3 = d_1**3
        if self.charges is not None:
            c1 = self.charges[index1]
            c2 = self.charges[index2]
            yield 2*c1*c2*d_3, np.zeros((3, 3))
        if self.dipoles is not None:
            d_5 = d_1**5
            d_7 = d_1**7
            p1 = self.dipoles[index1]
            p2 = self.dipoles[index2]
            yield 12*d_5*np.dot(p1, p2), np.zeros((3, 3))
            yield -90*d_7, np.outer(p1, p2) + np.outer(p2, p1)
            if self.charges is not None:
                yield 12*c1*d_5, np.zeros((3, 3))
                yield 12*c2*d_5, np.zeros((3, 3))


Instruction:
Given the following Python 3 function, write the documentation
def esp(self):
        result = np.zeros(self.numc, float)
        for index1 in range(self.numc):
            result[index1] = self.esp_component(index1)
        return result

Response: Compute the electrostatic potential at each atom due to other atoms


Instruction:
Create a Python 3 function to
compute the electrostatic potential at each atom due to other atoms

Response:
def efield(self):
        """Compute the electrostatic potential at each atom due to other atoms"""
        result = np.zeros((self.numc,3), float)
        for index1 in range(self.numc):
            result[index1] = self.efield_component(index1)
        return result


Instruction:
Can you generate a brief explanation for the following Python 3 code
def yield_pair_energies(self, index1, index2):
        strength = self.strengths[index1, index2]
        distance = self.distances[index1, index2]
        yield strength*distance**(-6), 1

Response: Yields pairs of strength and distance


Instruction:
Can you write a function in Python 3 where it
yields pairs of gradients

Response:
def yield_pair_gradients(self, index1, index2):
        """Yields pairs ((s'(r_ij), grad_i v(bar{r}_ij))"""
        strength = self.strengths[index1, index2]
        distance = self.distances[index1, index2]
        yield -6*strength*distance**(-7), np.zeros(3)


Instruction:
How would you code a function in Python 3 to
yield pairs of the energy between two sets of species.

Response:
def yield_pair_energies(self, index1, index2):
        """Yields pairs ((s(r_ij), v(bar{r}_ij))"""
        A = self.As[index1, index2]
        B = self.Bs[index1, index2]
        distance = self.distances[index1, index2]
        yield A*np.exp(-B*distance), 1


Instruction:
Can you tell what is the following Python 3 function doing
def yield_pair_gradients(self, index1, index2):
        A = self.As[index1, index2]
        B = self.Bs[index1, index2]
        distance = self.distances[index1, index2]
        yield -B*A*np.exp(-B*distance), np.zeros(3)

Response: Yields pairs of gradients


Instruction:
Can you implement a function in Python 3 that
loads the molecules from a CML file.

Response:
def load_cml(cml_filename):
    """Load the molecules from a CML file

       Argument:
        | ``cml_filename``  --  The filename of a CML file.

       Returns a list of molecule objects with optional molecular graph
       attribute and extra attributes.
    """
    parser = make_parser()
    parser.setFeature(feature_namespaces, 0)
    dh = CMLMoleculeLoader()
    parser.setContentHandler(dh)
    parser.parse(cml_filename)
    return dh.molecules


Instruction:
Explain what the following Python 3 code does
def _dump_cml_molecule(f, molecule):
    extra = getattr(molecule, "extra", {})
    attr_str = " ".join("%s='%s'" % (key, value) for key, value in extra.items())
    f.write(" <molecule id='%s' %s>\n" % (molecule.title, attr_str))
    f.write("  <atomArray>\n")
    atoms_extra = getattr(molecule, "atoms_extra", {})
    for counter, number, coordinate in zip(range(molecule.size), molecule.numbers, molecule.coordinates/angstrom):
        atom_extra = atoms_extra.get(counter, {})
        attr_str = " ".join("%s='%s'" % (key, value) for key, value in atom_extra.items())
        f.write("   <atom id='a%i' elementType='%s' x3='%s' y3='%s' z3='%s' %s />\n" % (
            counter, periodic[number].symbol, coordinate[0],  coordinate[1],
            coordinate[2], attr_str,
        ))
    f.write("  </atomArray>\n")
    if molecule.graph is not None:
        bonds_extra = getattr(molecule, "bonds_extra", {})
        f.write("  <bondArray>\n")
        for edge in molecule.graph.edges:
            bond_extra = bonds_extra.get(edge, {})
            attr_str = " ".join("%s='%s'" % (key, value) for key, value in bond_extra.items())
            i1, i2 = edge
            f.write("   <bond atomRefs2='a%i a%i' %s />\n" % (i1, i2, attr_str))
        f.write("  </bondArray>\n")
    f.write(" </molecule>\n")

Response: Dump a single molecule to a CML file


Instruction:
How would you explain what the following Python 3 function does
def dump_cml(f, molecules):
    if isinstance(f, str):
        f = open(f, "w")
        close = True
    else:
        close = False
    f.write("<?xml version='1.0'?>\n")
    f.write("<list xmlns='http://www.xml-cml.org/schema'>\n")
    for molecule in molecules:
        _dump_cml_molecule(f, molecule)
    f.write("</list>\n")
    if close:
        f.close()

Response: Dump a list of molecules to a CML file.


Instruction:
How would you code a function in Python 3 to
read the extra properties taking into account an exclude list

Response:
def _get_extra(self, attrs, exclude):
        """Read the extra properties, taking into account an exclude list"""
        result = {}
        for key in attrs.getNames():
            if key not in exclude:
                result[str(key)] = str(attrs[key])
        return result


Instruction:
How would you explain what the following Python 3 function does
def _read(self, filename, field_labels=None):
        # if fields is None, all fields are read
        def read_field(f):
            """Read a single field"""
            datatype = None
            while datatype is None:
                # find a sane header line
                line = f.readline()
                if line == "":
                    return False

                label = line[:43].strip()
                if field_labels is not None:
                    if len(field_labels) == 0:
                        return False
                    elif label not in field_labels:
                        return True
                    else:
                        field_labels.discard(label)
                line = line[43:]
                words = line.split()
                if len(words) == 0:
                    return True

                if words[0] == 'I':
                    datatype = int
                    unreadable = 0
                elif words[0] == 'R':
                    datatype = float
                    unreadable = np.nan

            if len(words) == 2:
                try:
                    value = datatype(words[1])
                except ValueError:
                    return True
            elif len(words) == 3:
                if words[1] != "N=":
                    raise FileFormatError("Unexpected line in formatted checkpoint file %s\n%s" % (filename, line[:-1]))
                length = int(words[2])
                value = np.zeros(length, datatype)
                counter = 0
                try:
                    while counter < length:
                        line = f.readline()
                        if line == "":
                            raise FileFormatError("Unexpected end of formatted checkpoint file %s" % filename)
                        for word in line.split():
                            try:
                                value[counter] = datatype(word)
                            except (ValueError, OverflowError) as e:
                                print('WARNING: could not interpret word while reading %s: %s' % (word, self.filename))
                                if self.ignore_errors:
                                    value[counter] = unreadable
                                else:
                                    raise
                            counter += 1
                except ValueError:
                    return True
            else:
                raise FileFormatError("Unexpected line in formatted checkpoint file %s\n%s" % (filename, line[:-1]))

            self.fields[label] = value
            return True

        self.fields = {}
        with open(filename, 'r') as f:
            self.title = f.readline()[:-1].strip()
            words = f.readline().split()
            if len(words) == 3:
                self.command, self.lot, self.basis = words
            elif len(words) == 2:
                self.command, self.lot = words
            else:
                raise FileFormatError('The second line of the FCHK file should contain two or three words.')

            while read_field(f):
                pass

Response: Read all the requested fields from a checkpoint file.


Instruction:
Write a Python 3 script for
converting a few elementary fields into a molecule object

Response:
def _analyze(self):
        """Convert a few elementary fields into a molecule object"""
        if ("Atomic numbers" in self.fields) and ("Current cartesian coordinates" in self.fields):
            self.molecule = Molecule(
                self.fields["Atomic numbers"],
                np.reshape(self.fields["Current cartesian coordinates"], (-1, 3)),
                self.title,
            )


Instruction:
Can you write a function in Python 3 where it
returns the coordinates of the geometries at each point in the optimization

Response:
def get_optimization_coordinates(self):
        """Return the coordinates of the geometries at each point in the optimization"""
        coor_array = self.fields.get("Opt point       1 Geometries")
        if coor_array is None:
            return []
        else:
            return np.reshape(coor_array, (-1, len(self.molecule.numbers), 3))


Instruction:
Can you tell what is the following Python 3 function doing
def get_optimized_molecule(self):
        opt_coor = self.get_optimization_coordinates()
        if len(opt_coor) == 0:
            return None
        else:
            return Molecule(
                self.molecule.numbers,
                opt_coor[-1],
            )

Response: Return a molecule object of the optimal geometry


Instruction:
Write a Python 3 function for
returning the energy gradients of all geometries during an optimization

Response:
def get_optimization_gradients(self):
        """Return the energy gradients of all geometries during an optimization"""
        grad_array = self.fields.get("Opt point       1 Gradient at each geome")
        if grad_array is None:
            return []
        else:
            return np.reshape(grad_array, (-1, len(self.molecule.numbers), 3))


Instruction:
How would you implement a function in Python 3 that
returns the hessian of the current molecule

Response:
def get_hessian(self):
        """Return the hessian"""
        force_const = self.fields.get("Cartesian Force Constants")
        if force_const is None:
            return None
        N = len(self.molecule.numbers)
        result = np.zeros((3*N, 3*N), float)
        counter = 0
        for row in range(3*N):
            result[row, :row+1] = force_const[counter:counter+row+1]
            result[:row+1, row] = force_const[counter:counter+row+1]
            counter += row + 1
        return result


Instruction:
Write a Python 3 script for
returning a copy of this object with the specified attributes changed.

Response:
def copy_with(self, **kwargs):
        """Return a copy with (a few) changed attributes

           The keyword arguments are the attributes to be replaced by new
           values. All other attributes are copied (or referenced) from the
           original object. This only works if the constructor takes all
           (read-only) attributes as arguments.
        """
        attrs = {}
        for key, descriptor in self.__class__.__dict__.items():
            if isinstance(descriptor, ReadOnlyAttribute):
                attrs[key] = descriptor.__get__(self)
        for key in kwargs:
            if key not in attrs:
                raise TypeError("Unknown attribute: %s" % key)
        attrs.update(kwargs)
        return self.__class__(**attrs)


Instruction:
Can you create a Python 3 function that
reads a single entry from the file.

Response:
def read(self, line, f, data):
        """See :meth:`PunchParser.read`"""
        self.used = True
        data["title"] = f.readline().strip()
        data["symmetry"] = f.readline().split()[0]
        if data["symmetry"] != "C1":
            raise NotImplementedError("Only C1 symmetry is supported.")
        symbols = []
        while line != " $END      \n":
            line = f.readline()
            if line[0] != " ":
                symbols.append(line.split()[0])
        data["symbols"] = symbols


Instruction:
Can you generate the documentation for the following Python 3 function
def read(self, line, f, data):
        f.readline()
        f.readline()
        N = len(data["symbols"])
        # if the data are already read before, just overwrite them
        numbers = data.get("numbers")
        if numbers is None:
            numbers = np.zeros(N, int)
            data["numbers"] = numbers
        coordinates = data.get("coordinates")
        if coordinates is None:
            coordinates = np.zeros((N,3), float)
            data["coordinates"] = coordinates
        for i in range(N):
            words = f.readline().split()
            numbers[i] = int(float(words[1]))
            coordinates[i,0] = float(words[2])*angstrom
            coordinates[i,1] = float(words[3])*angstrom
            coordinates[i,2] = float(words[4])*angstrom

Response: Read the untested version of the log file.


Instruction:
Create a Python 3 function to
read the energy and gradient from a Punch file.

Response:
def read(self, line, f, data):
        """See :meth:`PunchParser.read`"""
        data["energy"] = float(f.readline().split()[1])
        N = len(data["symbols"])
        # if the data are already read before, just overwrite them
        gradient = data.get("gradient")
        if gradient is None:
            gradient = np.zeros((N,3), float)
            data["gradient"] = gradient
        for i in range(N):
            words = f.readline().split()
            gradient[i,0] = float(words[2])
            gradient[i,1] = float(words[3])
            gradient[i,2] = float(words[4])


Instruction:
How would you implement a function in Python 3 that
reads a single HESS or ALM.

Response:
def read(self, line, f, data):
        """See :meth:`PunchParser.read`"""
        line = f.readline()
        assert(line == " $HESS\n")
        while line != " $END\n":
            line = f.readline()


Instruction:
Given the following Python 3 function, write the documentation
def read(self, line, f, data):
        assert("hessian" not in data)
        f.readline()
        N = len(data["symbols"])
        hessian = np.zeros((3*N, 3*N), float)
        tmp = hessian.ravel()
        counter = 0
        while True:
            line = f.readline()
            if line == " $END\n":
                break
            line = line[5:-1]
            for j in range(len(line)//15):
                tmp[counter] = float(line[j*15:(j+1)*15])
                counter += 1
        data["hessian"] = hessian

Response: Read a single entry from the Punch file.


Instruction:
How would you code a function in Python 3 to
read the masses from a Punch file.

Response:
def read(self, line, f, data):
        """See :meth:`PunchParser.read`"""
        N = len(data["symbols"])
        masses = np.zeros(N, float)
        counter = 0
        while counter < N:
            words = f.readline().split()
            for word in words:
                masses[counter] = float(word)*amu
                counter += 1
        data["masses"] = masses


Instruction:
Can you generate a brief explanation for the following Python 3 code
def setup_hydrocarbon_ff(graph):
    # A) Define parameters.
    # the bond parameters:
    bond_params = {
        (6, 1): 310*kcalmol/angstrom**2,
        (6, 6): 220*kcalmol/angstrom**2,
    }
    # for every (a, b), also add (b, a)
    for key, val in list(bond_params.items()):
        if key[0] != key[1]:
            bond_params[(key[1], key[0])] = val
    # the bend parameters
    bend_params = {
        (1, 6, 1): 35*kcalmol/rad**2,
        (1, 6, 6): 30*kcalmol/rad**2,
        (6, 6, 6): 60*kcalmol/rad**2,
    }
    # for every (a, b, c), also add (c, b, a)
    for key, val in list(bend_params.items()):
        if key[0] != key[2]:
            bend_params[(key[2], key[1], key[0])] = val

    # B) detect all internal coordinates and corresponding energy terms.
    terms = []
    # bonds
    for i0, i1 in graph.edges:
        K = bond_params[(graph.numbers[i0], graph.numbers[i1])]
        terms.append(BondStretchTerm(K, i0, i1))
    # bends (see b_bending_angles.py for the explanation)
    for i1 in range(graph.num_vertices):
        n = list(graph.neighbors[i1])
        for index, i0 in enumerate(n):
            for i2 in n[:index]:
                K = bend_params[(graph.numbers[i0], graph.numbers[i1], graph.numbers[i2])]
                terms.append(BendAngleTerm(K, i0, i1, i2))

    # C) Create and return the force field
    return ForceField(terms)

Response: Create a simple ForceField object for hydrocarbons based on the graph.


Instruction:
Write a Python 3 script to
add the contributions of this energy term to the Hessian.

Response:
def add_to_hessian(self, coordinates, hessian):
        """Add the contributions of this energy term to the Hessian

           Arguments:
            | ``coordinates`` -- A numpy array with 3N Cartesian coordinates.
            | ``hessian`` -- A matrix for the full Hessian to which this energy
                             term has to add its contribution.
        """
        # Compute the derivatives of the bond stretch towards the two cartesian
        # coordinates. The bond length is computed too, but not used.
        q, g = self.icfn(coordinates[list(self.indexes)], 1)
        # Add the contribution to the Hessian (an outer product)
        for ja, ia in enumerate(self.indexes):
            # ja is 0, 1, 2, ...
            # ia is i0, i1, i2, ...
            for jb, ib in enumerate(self.indexes):
                contrib = 2*self.force_constant*numpy.outer(g[ja], g[jb])
                hessian[3*ia:3*ia+3, 3*ib:3*ib+3] += contrib


Instruction:
Can you tell what is the following Python 3 function doing
def hessian(self, coordinates):
        # N3 is 3 times the number of atoms.
        N3 = coordinates.size
        # Start with a zero hessian.
        hessian = numpy.zeros((N3,N3), float)
        # Add the contribution of each term.
        for term in self.terms:
            term.add_to_hessian(coordinates, hessian)
        return hessian

Response: Compute the force - field Hessian for the given coordinates.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def compute_rotsym(molecule, graph, threshold=1e-3*angstrom):
    result = 0
    for match in graph.symmetries:
        permutation = list(j for i,j in sorted(match.forward.items()))
        new_coordinates = molecule.coordinates[permutation]
        rmsd = fit_rmsd(molecule.coordinates, new_coordinates)[2]
        if rmsd < threshold:
            result += 1
    return result

Response: Compute the rotational symmetry number of the given molecule and graph.


Instruction:
Can you tell what is the following Python 3 function doing
def quaternion_product(quat1, quat2):
    return np.array([
        quat1[0]*quat2[0] - np.dot(quat1[1:], quat2[1:]),
        quat1[0]*quat2[1] + quat2[0]*quat1[1] + quat1[2]*quat2[3] - quat1[3]*quat2[2],
        quat1[0]*quat2[2] + quat2[0]*quat1[2] + quat1[3]*quat2[1] - quat1[1]*quat2[3],
        quat1[0]*quat2[3] + quat2[0]*quat1[3] + quat1[1]*quat2[2] - quat1[2]*quat2[1]
    ], float)

Response: Return the quaternion product of the two arguments


Instruction:
Can you implement a function in Python 3 that
applies the rotation represented by the quaternion to the vector

Response:
def quaternion_rotation(quat, vector):
    """Apply the rotation represented by the quaternion to the vector

       Warning: This only works correctly for normalized quaternions.
    """
    dp = np.dot(quat[1:], vector)
    cos = (2*quat[0]*quat[0] - 1)
    return np.array([
        2 * (quat[0] * (quat[2] * vector[2] - quat[3] * vector[1]) + quat[1] * dp) + cos * vector[0],
        2 * (quat[0] * (quat[3] * vector[0] - quat[1] * vector[2]) + quat[2] * dp) + cos * vector[1],
        2 * (quat[0] * (quat[1] * vector[1] - quat[2] * vector[0]) + quat[3] * dp) + cos * vector[2]
    ], float)


Instruction:
Explain what the following Python 3 code does
def rotation_matrix_to_quaternion(rotation_matrix):
    invert = (np.linalg.det(rotation_matrix) < 0)
    if invert:
        factor = -1
    else:
        factor = 1
    c2 = 0.25*(factor*np.trace(rotation_matrix) + 1)
    if c2 < 0:
        #print c2
        c2 = 0.0
    c = np.sqrt(c2)
    r2 = 0.5*(1 + factor*np.diagonal(rotation_matrix)) - c2
    #print "check", r2.sum()+c2
    r = np.zeros(3, float)
    for index, r2_comp in enumerate(r2):
        if r2_comp < 0:
            continue
        else:
            row, col = off_diagonals[index]
            if (rotation_matrix[row, col] - rotation_matrix[col, row] < 0):
                r[index] = -np.sqrt(r2_comp)
            else:
                r[index] = +np.sqrt(r2_comp)
    return factor, np.array([c, r[0], r[1], r[2]], float)

Response: Compute the quaternion representing the rotation given by the matrix


Instruction:
How would you implement a function in Python 3 that
computes the rotation matrix representated by the quaternion

Response:
def quaternion_to_rotation_matrix(quaternion):
    """Compute the rotation matrix representated by the quaternion"""
    c, x, y, z = quaternion
    return np.array([
        [c*c + x*x - y*y - z*z, 2*x*y - 2*c*z,         2*x*z + 2*c*y        ],
        [2*x*y + 2*c*z,         c*c - x*x + y*y - z*z, 2*y*z - 2*c*x        ],
        [2*x*z - 2*c*y,         2*y*z + 2*c*x,         c*c - x*x - y*y + z*z]
    ], float)


Instruction:
Can you tell what is the following Python 3 function doing
def cosine(a, b):
    result = np.dot(a, b) / np.linalg.norm(a) / np.linalg.norm(b)
    return np.clip(result, -1, 1)

Response:
Compute the cosine between two vectors

uggers


Instruction:
Make a summary of the following Python 3 code
def random_unit(size=3):
    while True:
        result = np.random.normal(0, 1, size)
        length = np.linalg.norm(result)
        if length > 1e-3:
            return result/length

Response: Return a random unit vector of the given dimension


Instruction:
Create a Python 3 function for
returning a random normalized vector orthogonal to the given vector

Response:
def random_orthonormal(normal):
    """Return a random normalized vector orthogonal to the given vector"""
    u = normal_fns[np.argmin(np.fabs(normal))](normal)
    u /= np.linalg.norm(u)
    v = np.cross(normal, u)
    v /= np.linalg.norm(v)
    alpha = np.random.uniform(0.0, np.pi*2)
    return np.cos(alpha)*u + np.sin(alpha)*v


Instruction:
Make a summary of the following Python 3 code
def triangle_normal(a, b, c):
    normal = np.cross(a - c, b - c)
    norm = np.linalg.norm(normal)
    return normal/norm

Response: Return a vector orthogonal to the given triangle


Instruction:
Can you tell what is the following Python 3 function doing
def dot(r1, r2):
    if r1.size != r2.size:
        raise ValueError("Both arguments must have the same input size.")
    if r1.deriv != r2.deriv:
        raise ValueError("Both arguments must have the same deriv.")
    return r1.x*r2.x + r1.y*r2.y + r1.z*r2.z

Response: Compute the dot product of two Vector3 objects.


Instruction:
Can you write a function in Python 3 where it
computes the cross product of two Vector3 objects.

Response:
def cross(r1, r2):
    """Compute the cross product

       Arguments:
        | ``r1``, ``r2``  -- two :class:`Vector3` objects

       (Returns a Vector3)
    """
    if r1.size != r2.size:
        raise ValueError("Both arguments must have the same input size.")
    if r1.deriv != r2.deriv:
        raise ValueError("Both arguments must have the same deriv.")
    result = Vector3(r1.size, r1.deriv)
    result.x = r1.y*r2.z - r1.z*r2.y
    result.y = r1.z*r2.x - r1.x*r2.z
    result.z = r1.x*r2.y - r1.y*r2.x
    return result


Instruction:
Explain what the following Python 3 code does
def _opbend_transform_mean(rs, fn_low, deriv=0):
    v = 0.0
    d = np.zeros((4,3), float)
    dd = np.zeros((4,3,4,3), float)
    #loop over the 3 cyclic permutations
    for p in np.array([[0,1,2], [2,0,1], [1,2,0]]):
        opbend = _opbend_transform([rs[p[0]], rs[p[1]], rs[p[2]], rs[3]], fn_low, deriv)
        v += opbend[0]/3
        index0 = np.where(p==0)[0][0] #index0 is the index of the 0th atom (rs[0])
        index1 = np.where(p==1)[0][0]
        index2 = np.where(p==2)[0][0]
        index3 = 3
        if deriv>0:
            d[0] += opbend[1][index0]/3
            d[1] += opbend[1][index1]/3
            d[2] += opbend[1][index2]/3
            d[3] += opbend[1][index3]/3
        if deriv>1:
            dd[0, :, 0, :] += opbend[2][index0, :, index0, :]/3
            dd[0, :, 1, :] += opbend[2][index0, :, index1, :]/3
            dd[0, :, 2, :] += opbend[2][index0, :, index2, :]/3
            dd[0, :, 3, :] += opbend[2][index0, :, index3, :]/3

            dd[1, :, 0, :] += opbend[2][index1, :, index0, :]/3
            dd[1, :, 1, :] += opbend[2][index1, :, index1, :]/3
            dd[1, :, 2, :] += opbend[2][index1, :, index2, :]/3
            dd[1, :, 3, :] += opbend[2][index1, :, index3, :]/3

            dd[2, :, 0, :] += opbend[2][index2, :, index0, :]/3
            dd[2, :, 1, :] += opbend[2][index2, :, index1, :]/3
            dd[2, :, 2, :] += opbend[2][index2, :, index2, :]/3
            dd[2, :, 3, :] += opbend[2][index2, :, index3, :]/3

            dd[3, :, 0, :] += opbend[2][index3, :, index0, :]/3
            dd[3, :, 1, :] += opbend[2][index3, :, index1, :]/3
            dd[3, :, 2, :] += opbend[2][index3, :, index2, :]/3
            dd[3, :, 3, :] += opbend[2][index3, :, index3, :]/3
    if deriv==0:
        return v,
    elif deriv==1:
        return v, d
    elif deriv==2:
        return v, d, dd
    else:
        raise ValueError("deriv must be 0, 1 or 2.")

Response: Compute the mean of the 3 opbends


Instruction:
How would you explain what the following Python 3 function does
def _bond_length_low(r, deriv):
    r = Vector3(3, deriv, r, (0, 1, 2))
    d = r.norm()
    return d.results()

Response: Similar to bond_length but with a relative vector


Instruction:
How would you explain what the following Python 3 function does
def _bend_cos_low(a, b, deriv):
    a = Vector3(6, deriv, a, (0, 1, 2))
    b = Vector3(6, deriv, b, (3, 4, 5))
    a /= a.norm()
    b /= b.norm()
    return dot(a, b).results()

Response: Similar to bend_cos but with relative vectors


Instruction:
Here you have a function in Python 3, explain what it does
def _dihed_cos_low(a, b, c, deriv):
    a = Vector3(9, deriv, a, (0, 1, 2))
    b = Vector3(9, deriv, b, (3, 4, 5))
    c = Vector3(9, deriv, c, (6, 7, 8))
    b /= b.norm()
    tmp = b.copy()
    tmp *= dot(a, b)
    a -= tmp
    tmp = b.copy()
    tmp *= dot(c, b)
    c -= tmp
    a /= a.norm()
    c /= c.norm()
    return dot(a, c).results()

Response: Similar to dihed_cos but with relative vectors


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _dihed_angle_low(av, bv, cv, deriv):
    a = Vector3(9, deriv, av, (0, 1, 2))
    b = Vector3(9, deriv, bv, (3, 4, 5))
    c = Vector3(9, deriv, cv, (6, 7, 8))
    b /= b.norm()
    tmp = b.copy()
    tmp *= dot(a, b)
    a -= tmp
    tmp = b.copy()
    tmp *= dot(c, b)
    c -= tmp
    a /= a.norm()
    c /= c.norm()
    result = dot(a, c).results()
    # avoid trobles with the gradients by either using arccos or arcsin
    if abs(result[0]) < 0.5:
        # if the cosine is far away for -1 or +1, it is safe to take the arccos
        # and fix the sign of the angle.
        sign = 1-(np.linalg.det([av, bv, cv]) > 0)*2
        return _cos_to_angle(result, deriv, sign)
    else:
        # if the cosine is close to -1 or +1, it is better to compute the sine,
        # take the arcsin and fix the sign of the angle
        d = cross(b, a)
        side = (result[0] > 0)*2-1 # +1 means angle in range [-pi/2,pi/2]
        result = dot(d, c).results()
        return _sin_to_angle(result, deriv, side)

Response: Similar to dihed_cos but with relative vectors


Instruction:
Can you tell what is the following Python 3 function doing
def _opbend_cos_low(a, b, c, deriv):
    a = Vector3(9, deriv, a, (0, 1, 2))
    b = Vector3(9, deriv, b, (3, 4, 5))
    c = Vector3(9, deriv, c, (6, 7, 8))
    n  = cross(a,b)
    n /= n.norm()
    c /= c.norm()
    temp = dot(n,c)
    result = temp.copy()
    result.v = np.sqrt(1.0-temp.v**2)
    if result.deriv > 0:
        result.d *= -temp.v
        result.d /= result.v
    if result.deriv > 1:
        result.dd *= -temp.v
        result.dd /= result.v
        temp2 = np.array([temp.d]).transpose()*temp.d
        temp2 /= result.v**3
        result.dd -= temp2
    return result.results()

Response: Similar to opbend_cos but with relative vectors


Instruction:
Here you have a function in Python 3, explain what it does
def _opbend_angle_low(a, b, c, deriv=0):
    result = _opbend_cos_low(a, b, c, deriv)
    sign = np.sign(np.linalg.det([a, b, c]))
    return _cos_to_angle(result, deriv, sign)

Response: Similar to opbend_angle but with relative vectors


Instruction:
Write a Python 3 script for
converting a cosine and its derivatives to an angle and its derivatives

Response:
def _cos_to_angle(result, deriv, sign=1):
    """Convert a cosine and its derivatives to an angle and its derivatives"""
    v = np.arccos(np.clip(result[0], -1, 1))
    if deriv == 0:
        return v*sign,
    if abs(result[0]) >= 1:
        factor1 = 0
    else:
        factor1 = -1.0/np.sqrt(1-result[0]**2)
    d = factor1*result[1]
    if deriv == 1:
        return v*sign, d*sign
    factor2 = result[0]*factor1**3
    dd = factor2*np.outer(result[1], result[1]) + factor1*result[2]
    if deriv == 2:
        return v*sign, d*sign, dd*sign
    raise ValueError("deriv must be 0, 1 or 2.")


Instruction:
Implement a function in Python 3 to
convert a sine and its derivatives to an angle and its derivatives

Response:
def _sin_to_angle(result, deriv, side=1):
    """Convert a sine and its derivatives to an angle and its derivatives"""
    v = np.arcsin(np.clip(result[0], -1, 1))
    sign = side
    if sign == -1:
        if v < 0:
            offset = -np.pi
        else:
            offset = np.pi
    else:
        offset = 0.0
    if deriv == 0:
        return v*sign + offset,
    if abs(result[0]) >= 1:
        factor1 = 0
    else:
        factor1 = 1.0/np.sqrt(1-result[0]**2)
    d = factor1*result[1]
    if deriv == 1:
        return v*sign + offset, d*sign
    factor2 = result[0]*factor1**3
    dd = factor2*np.outer(result[1], result[1]) + factor1*result[2]
    if deriv == 2:
        return v*sign + offset, d*sign, dd*sign
    raise ValueError("deriv must be 0, 1 or 2.")


Instruction:
Create a Python 3 function for
returning a deep copy of the current Scalar object

Response:
def copy(self):
        """Return a deep copy"""
        result = Scalar(self.size, self.deriv)
        result.v = self.v
        if self.deriv > 0: result.d[:] = self.d[:]
        if self.deriv > 1: result.dd[:] = self.dd[:]
        return result


Instruction:
Implement a Python 3 function for
returning the value and optionally derivative and second order derivative

Response:
def results(self):
        """Return the value and optionally derivative and second order derivative"""
        if self.deriv == 0:
            return self.v,
        if self.deriv == 1:
            return self.v, self.d
        if self.deriv == 2:
            return self.v, self.d, self.dd


Instruction:
Can you generate the documentation for the following Python 3 function
def copy(self):
        result = Vector3(self.size, self.deriv)
        result.x.v = self.x.v
        result.y.v = self.y.v
        result.z.v = self.z.v
        if self.deriv > 0:
            result.x.d[:] = self.x.d
            result.y.d[:] = self.y.d
            result.z.d[:] = self.z.d
        if self.deriv > 1:
            result.x.dd[:] = self.x.dd
            result.y.dd[:] = self.y.dd
            result.z.dd[:] = self.z.dd
        return result

Response: Return a deep copy of the current Vector3.


Instruction:
How would you code a function in Python 3 to
return a Scalar object with the norm of this vector

Response:
def norm(self):
        """Return a Scalar object with the norm of this vector"""
        result = Scalar(self.size, self.deriv)
        result.v = np.sqrt(self.x.v**2 + self.y.v**2 + self.z.v**2)
        if self.deriv > 0:
            result.d += self.x.v*self.x.d
            result.d += self.y.v*self.y.d
            result.d += self.z.v*self.z.d
            result.d /= result.v
        if self.deriv > 1:
            result.dd += self.x.v*self.x.dd
            result.dd += self.y.v*self.y.dd
            result.dd += self.z.v*self.z.dd
            denom = result.v**2
            result.dd += (1 - self.x.v**2/denom)*np.outer(self.x.d, self.x.d)
            result.dd += (1 - self.y.v**2/denom)*np.outer(self.y.d, self.y.d)
            result.dd += (1 - self.z.v**2/denom)*np.outer(self.z.d, self.z.d)
            tmp = -self.x.v*self.y.v/denom*np.outer(self.x.d, self.y.d)
            result.dd += tmp+tmp.transpose()
            tmp = -self.y.v*self.z.v/denom*np.outer(self.y.d, self.z.d)
            result.dd += tmp+tmp.transpose()
            tmp = -self.z.v*self.x.v/denom*np.outer(self.z.d, self.x.d)
            result.dd += tmp+tmp.transpose()
            result.dd /= result.v
        return result


Instruction:
Implement a function in Python 3 to
get a line of data from the file and return it.

Response:
def _get_line(self):
        """Get a line or raise StopIteration"""
        line = self._f.readline()
        if len(line) == 0:
            raise StopIteration
        return line


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _read_frame(self):
        # Read the first line, ignore the title and try to get the time. The
        # time field is optional.
        line = self._get_line()
        pos = line.rfind("t=")
        if pos >= 0:
            time = float(line[pos+2:])*picosecond
        else:
            time = 0.0
        # Read the second line, the number of atoms must match with the first
        # frame.
        num_atoms = int(self._get_line())
        if self.num_atoms is not None and self.num_atoms != num_atoms:
            raise ValueError("The number of atoms must be the same over the entire file.")
        # Read the atom lines
        pos = np.zeros((num_atoms, 3), np.float32)
        vel = np.zeros((num_atoms, 3), np.float32)
        for i in range(num_atoms):
            words = self._get_line()[22:].split()
            pos[i, 0] = float(words[0])
            pos[i, 1] = float(words[1])
            pos[i, 2] = float(words[2])
            vel[i, 0] = float(words[3])
            vel[i, 1] = float(words[4])
            vel[i, 2] = float(words[5])
        pos *= nanometer
        vel *= nanometer/picosecond
        # Read the cell line
        cell = np.zeros((3, 3), np.float32)
        words = self._get_line().split()
        if len(words) >= 3:
            cell[0, 0] = float(words[0])
            cell[1, 1] = float(words[1])
            cell[2, 2] = float(words[2])
        if len(words) == 9:
            cell[1, 0] = float(words[3])
            cell[2, 0] = float(words[4])
            cell[0, 1] = float(words[5])
            cell[2, 1] = float(words[6])
            cell[0, 2] = float(words[7])
            cell[1, 2] = float(words[8])
        cell *= nanometer
        return time, pos, vel, cell

Response: Read one frame from the file.


Instruction:
Can you generate the documentation for the following Python 3 function
def setup_ics(graph):
    ics = []
    # A) Collect all bonds.
    for i0, i1 in graph.edges:
        ics.append(BondLength(i0, i1))
    # B) Collect all bends. (see b_bending_angles.py for the explanation)
    for i1 in range(graph.num_vertices):
        n = list(graph.neighbors[i1])
        for index, i0 in enumerate(n):
            for i2 in n[:index]:
                ics.append(BendingAngle(i0, i1, i2))
    # C) Collect all dihedrals.
    for i1, i2 in graph.edges:
        for i0 in graph.neighbors[i1]:
            if i0==i2:
                # All four indexes must be different.
                continue
            for i3 in graph.neighbors[i2]:
                if i3==i1 or i3==i0:
                    # All four indexes must be different.
                    continue
                ics.append(DihedralAngle(i0, i1, i2, i3))
    return ics

Response: This function creates a list of internal coordinates based on the graph.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def compute_jacobian(ics, coordinates):
    N3 = coordinates.size
    jacobian = numpy.zeros((N3, len(ics)), float)
    for j, ic in enumerate(ics):
        # Let the ic object fill in each column of the Jacobian.
        ic.fill_jacobian_column(jacobian[:,j], coordinates)
    return jacobian

Response: Construct a Jacobian matrix for the given internal and Cartesian coordinates.