<jupyter_start><jupyter_text>`prolintpy`:  loading data and topology description `prolintpy` relies on `MDTraj` to read input data files, as such, it is the only module that has to be imported alongside `prolintpy`:<jupyter_code>import mdtraj as md
import prolintpy as pl<jupyter_output><empty_output><jupyter_text>Load the data using MDTraj<jupyter_code>t = md.load('./data/test_data_1.xtc', top='./data/test_data_1.gro')
t<jupyter_output><empty_output><jupyter_text>Load the data to prolintpy and define the protein and lipid topology We first specify the resolution of the input data and indicate if we want to combine the proteins (only applicable if there are more than one protein in the system). Combining proteins will result in the calculated metrics being averages of all copies.<jupyter_code>resolution = "martini"
combine_proteins = False
lipids = pl.Lipids(t.topology, resolution=resolution)
proteins = pl.Proteins(t.topology, resolution=resolution).system_proteins(merge=combine_proteins)<jupyter_output><empty_output><jupyter_text>Extract information about the input system Get all the lipid residues in the system<jupyter_code>lipids.lipid_names()<jupyter_output><empty_output><jupyter_text>Get the names of the different lipids as well as their count<jupyter_code>lipids.lipid_count()<jupyter_output><empty_output><jupyter_text>Get a pandas DataFrame for the defined systems<jupyter_code>lipids.ldf.head()<jupyter_output><empty_output><jupyter_text>Retrieve the residue IDs of all cholesterol lipids<jupyter_code>lipids.ldf[lipids.ldf.resName == "CHOL"].resSeq.unique()<jupyter_output><empty_output><jupyter_text>List the proteins found in the system and store the first one (the only one here) in a variable. `prolintpy` derives topology information for proteins from the input coordinate file. Two proteins will be considered the same if they are entirely identical (same number of residues, completely identical order and type of atoms/beads).<jupyter_code>proteins
protein = proteins[0]<jupyter_output><empty_output><jupyter_text>Get various protein information. Note that to get a dataframe<jupyter_code>protein.name = "GIRK" # Give the protein a better name
protein.n_residues
print (protein.first_residue, protein.last_residue)
protein.counter<jupyter_output><empty_output><jupyter_text>Get the indices for residues 50, 60, and 70<jupyter_code>protein.get_indices([50, 60, 70])<jupyter_output>Using the available dataframe<jupyter_text>Why `prolintpy` is easy to scale-up  If the input system contains only one copy of only one protein type (as in this example) then `proteins` will be a list of only one element. This entails a little bit extra work to get the protein out of the list, but provides much more flexibility in handling more complex system setups. You can use the `counter` option alongside the length of the `proteins` list to extract information about proteins in the system dynamically.For instance, to get a DataFrame representation for each protein in the system dynamically (that is without knowing anything about the composition of the input system), we can do that very easilyOne way of doing that is the following syntax:<jupyter_code>def get_dataframes(proteins):
    """
    Takes as input a prolintpy.Protein object and returns a list of DataFrame elements 
    for each copy of each protein in the system. 
    """
    dataframe_list = [protein.dataframe[protein_copy] for protein in proteins for protein_copy in range(protein.counter)]
    return dataframe_list
# returns a list of DataFrame elements 
get_dataframes(proteins)<jupyter_output><empty_output><jupyter_text>Exercise Test the above commands using a system that contains multiple proteins in different number of copies/replicates. In particular, test the function `get_dataframes()` and how it works for such systems. The test files `test_data_2.xtc`  and `test_data_2.gro` contain a system that has four copies/replicates of one protein type. Note how a very simple function that we wrote allows us to have complete access to the protein topology of system.<jupyter_code>t = md.load('./data/test_data_2.xtc', top='./data/test_data_2.gro')
t<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.06907265774378585, 'fraction_numerical': 0.004541108986615679, 'mean_word_length': 6.355008787346222, 'pattern_counts': {'":': 0, '<': 48, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '139817', 'license': 'MIT', 'n_tokens_mistral': 1268, 'n_tokens_neox': 1191, 'n_words': 464, 'path': '01-topology-description.ipynb', 'repo_name': 'ProLint/tutorials', 'size': '4184'}