Metadata-Version: 2.1
Name: fibos
Version: 2.1.1
Summary: Package to calculate Occluded Surfaces
Author: Herson Hebert Mendes Soares
Requires-Python: >=3.8
Requires-Dist: numpy>=1.22.4
Requires-Dist: biopython>=1.84
Requires-Dist: testresources>=2.0.1
Requires-Dist: pandas>=2.2.3
Description-Content-Type: text/markdown

---
editor_options: 
  markdown: 
    wrap: sentence
---

# FIBOS

The Occluded Surface (OS) algorithm is a widely used approach for analyzing atomic packing in biomolecules. 
Here, we introduce **fibos**, an R and Python package that extends the OS methodology with enhancements. 
It integrates efficient Fortran code from the original OS implementation and introduces an innovation: 
the use of Fibonacci spirals for surface point distribution. This modification reduces anisotropy and 
ensures a more uniform and even distribution of surface dots, improving the accuracy
of the algorithm.

R fibos version is available to install by [CRAN](https://cran.r-project.org/web/packages/fibos/index.html).

## Operating Systems

FIBOS was designed to be multiplatform and run on Linux, Windows and Mac.\
Tested on:

- **Linux**: Ubuntu ($\geq$ 20.04)
- **Windows**: Windows 11
- **Mac**: MacOS 15.0.1

## Compilers

- gfortran
- gcc

## Python versions

Tested on: 3.10, 3.11, 3.12

## Main functions:

1.  **`occluded_surface(pdb, method = "FIBOS")`**: Implements the Occluded Surface 
algorithm, generating points, areas, and normals for each atom. As parameters it 
accepts a PDB id (or the path to a local PDB file) and a method selection — either 
the classic 'OS' or the default 'FIBOS'. The function returns the results as a table 
and creates a file named `prot_PDBid.srf` in the `fibos_file` directory.

2.  **`osp(file)`**: Implements the Occluded Surface Packing (OSP) metric for 
each residue. Accepts a path to an .srf file generated by `occluded_surface` as a 
parameter and returns the results as a table summarized by residue.

3.  **`get_radii()`**: Returns the Van der Waals radii values employed in the 
surface occlusion calculations. These are the values used in each computation.

4.  **`set_radii(radii_values)`**: Enables customization of the radii values used
in surface occlusion calculations. To specify new values, the function accepts a 
DataFrame as its parameter.

5.  **`reset_radii()`**: Reverts all modifications made to the radii values,
resetting them to their default settings.

### Quickstart:

```Python
import fibos
import os

# Calculate FIBOS per atom and create .srf files in fibos_files folder
pdb_fibos = fibos.occluded_surface("1fib", method="FIBOS")

# Show first 3 rows of pdb_fibos table
print(pdb_fibos.head(3))

#                     ATOM NUMBER_POINTS   AREA RAYLENGTH DISTANCE
# 0  GLN 1@N___>HIS 3@NE2_             6  1.287     0.791     5.49
# 1  GLN 1@N___>HIS 3@CE1_             1  0.200     0.894     6.06
# 2  GLN 1@N___>HIS 3@CG__             1  0.160     0.991     6.27

# Calculate OSP metric per residue from .srf file in fibos_files folder
pdb_osp = fibos.osp(os.path.join("fibos_files","prot_1fib.srf"))

# Show first 3 rows of pdb_osp table
print(pdb_osp.head(3))

#    Resnum Resname     OS  os*[1-raylen]    OSP
# 0       1     GLN  36.81          21.94  0.157
# 1       2     ILE  49.33          36.13  0.317
# 2       3     HIS  64.14          43.17  0.335
```

### A more complex example:

```Python
import fibos
import os
from Bio.PDB import PDBList
from concurrent.futures import ProcessPoolExecutor
from functools import partial

# Auxiliary function to calculate occluded surface
def occluded_surface_worker(pdb_path, method):
    return fibos.occluded_surface(pdb_path, method=method)

# Get PDB file from RCSB and put it into the PDB folder  
# Rename the file appropriately and return path to it 
# (i.e., PDB/prot_8rxn.ent -> PDB/8rxn.pdb)
def get_pdb(id, path="."):
    pdbl = PDBList()
    new_path = os.path.join(path, f"{id.lower()}.pdb")
    if not os.path.exists(new_path):
        original_path = pdbl.retrieve_pdb_file(id.lower(), pdir=path, file_format='pdb')
        os.rename(original_path, new_path)
    return new_path

if __name__ == "__main__":

    # source of PDB files
    pdb_folder = "PDB"

    # fibos folder output
    fibos_folder = "fibos_files"

    # Create PDB folder if it does not exist
    os.makedirs(pdb_folder, exist_ok=True)
    
    # PDB ids list
    pdb_ids = ["8RXN", "1ROP"]

    # Get PDB files from RCSB and put them into the PDB folder  
    pdb_paths = list(map(lambda pdb_id: get_pdb(pdb_id, path=pdb_folder), pdb_ids))
    print(pdb_paths)
    
    # Detect number of physical cores and update cores according to pdb_ids size
    ideal_cores = min(os.cpu_count(), len(pdb_ids))

    # Calculate in parallel FIBOS per PDBid 
    # Create .srf files in fibos_files folder
    # Return FIBOS tables in pdb_fibos list
    worker_with_params = partial(occluded_surface_worker, method="FIBOS")
    with ProcessPoolExecutor(max_workers=ideal_cores) as executor:
        pdb_fibos = list(executor.map(worker_with_params, pdb_paths))

    # Show first 3 rows of first pdb_fibos table
    print(pdb_fibos[0].head(3))
    
    # Prepare paths for the generated .srf files in folder fibos_files
    srf_paths = list(map(lambda pdb_id: os.path.join(fibos_folder, f"prot_{pdb_id.lower()}.srf"), pdb_ids))
    print(srf_paths)
    
    # Calculate OSP metric by residue
    # Return OSP tables in pdb_osp list
    pdb_osp = list(map(lambda srf_path: fibos.osp(srf_path), srf_paths))
    
    # Show first 3 rows of the first pdb_osp table
    print(pdb_osp[0].head(3))
    
# OBS: If you need to run this example in a Jupyter Notebook, move the 
# occluded_surface_worker function to a "fun.py" file and import it as 
# "from fun import occluded_surface_worker"
```

### Case Study:
[Here](https://github.com/insilico-unifei/fibos-R-case-study-supp.git) we show a 
case study (currently only in R), aiming to compare the packing density between experimentally 
determined structures and the same structures predicted by AlphaFold (AF).

## Authors

-   Carlos Silveira ([carlos.silveira\@unifei.edu.br](mailto:carlos.silveira@unifei.edu.br))\
    Herson Soares ([d2020102075\@unifei.edu.br](mailto:d2020102075@unifei.edu.br))\
    Institute of Technological Sciences,\
    Federal University of Itajubá,\
    Campus Itabira, Brazil.

-   João Romanelli ([joaoromanelli\@unifei.edu.br](mailto:joaoromanelli@unifei.edu.br)) \
    Institute of Applied and Pure Sciences, \
    Federal University of Itajubá, \
    Campus Itabira, Brazil.

-   Patrick Fleming ([Pat.Fleming\@jhu.edu](mailto:Pat.Fleming@jhu.edu)) \
    Thomas C. Jenkins Department of Biophysics, \
    Johns Hopkins University, \
    Baltimore, MD, USA

## References

Fleming PJ, Richards FM. Protein packing: Dependence on protein size, secondary structure and amino acid composition. J Mol Biol 2000;299:487–98.

Pattabiraman N, Ward KB, Fleming PJ. Occluded molecular surface: Analysis of protein packing. J Mol Recognit 1995;8:334–44.