---
title: Property Filters
description: There is no ZINC filter panel. Ask Ivy to filter a ZINC lookup's results by molecular weight, LogP, hydrogen-bond and rotatable-bond caps, similarity and structural alerts.
---

This page shows how to narrow a [ZINC](/docs/zinc) query with physicochemical property filters — molecular weight, LogP, hydrogen-bonding, and flexibility — plus vendor and structural-alert options. Choosing the filter set is what most affects the outcome, since it shrinks the result set to a drug-like, fragment-like, or lead-like subset.

## Where the filters run

There is no ZINC filter panel in .bloom*. The ZINC lookup Ivy runs in chat searches by SMILES (exact match or close analogs by edit distance) or by ZINC ID, and returns up to 1,000 compounds with ZINC ID, SMILES, tranche, molecular weight and logP. Every filter on this page is applied afterward, by Ivy, in the chat's [code workspace](/docs/sandbox) with RDKit. Describe the filters you want in chat:

```
Find close ZINC analogs of gefitinib, keep MW 150-500 and logP -1 to 5, and drop PAINS hits
From these ZINC compounds, keep fragment-like ones (MW under 300, at most 3 rotatable bonds)
```

## Filters Ivy can apply

### Molecular weight (Da)
- **Min Molecular Weight**: Minimum weight in Daltons (default: 150)
- **Max Molecular Weight**: Maximum weight in Daltons (default: 500)

### Lipophilicity (LogP)
- **Min LogP**: Minimum partition coefficient (default: -2)
- **Max LogP**: Maximum partition coefficient (default: 5)
- LogP measures how well a compound partitions between water and octanol

### Hydrogen bonding
- **Max H-Bond Donors**: Maximum donor count (Lipinski rule: ≤5)
- **Max H-Bond Acceptors**: Maximum acceptor count (Lipinski rule: ≤10)

### Molecular flexibility
- **Max Rotatable Bonds**: Controls molecular flexibility (fewer = more rigid, drug-like)

## Vendor information

- ZINC ID and catalog-code lookups return vendor codes and catalog names, so Ivy can keep only compounds listed by the vendors you name.
- The lookup can return a purchasability field on request; ask Ivy to include it if in-stock versus make-on-demand matters.
- Prices are not in ZINC. Ivy gets indicative prices from a separate vendor price search ([compound procurement](/docs/workflows/compound-procurement)).

## Common filter presets

| Use Case | MW Range | LogP Range | Rotatable Bonds | Notes |
|----------|----------|------------|-----------------|-------|
| Drug-like | 150-500 | -1 to 5 | ≤8 | Lipinski Rule-of-5 compliant |
| Fragment-like | 100-300 | -2 to 3 | ≤3 | Rule-of-3 for FBDD |
| Lead-like | 200-450 | -2 to 4.5 | ≤7 | Optimal for optimization |
| CNS drugs | 200-450 | 1 to 4 | ≤6 | Blood-brain barrier penetrant |

## Example with RDKit post-filter

This is the kind of RDKit filter Ivy runs in the code workspace. You can also run it on your own machine:

```python
import pandas as pd
from rdkit import Chem
from rdkit.Chem import Descriptors, Lipinski

df = pd.read_csv("zinc.csv")
rows = []
for _, row in df.iterrows():
    mol = Chem.MolFromSmiles(row["smiles"])
    if mol is None:
        continue
    mw = Descriptors.MolWt(mol)
    logp = Descriptors.MolLogP(mol)
    rb = Lipinski.NumRotatableBonds(mol)
    if not (150 <= mw <= 500):
        continue
    if not (-1 <= logp <= 5):
        continue
    if rb > 8:
        continue
    rows.append(row)

pd.DataFrame(rows).to_csv("/workspace/scratch/zinc_filtered.csv", index=False)
```

## PAINS and structural alerts

For PAINS filtering after download:

```python
from rdkit.Chem import FilterCatalog
from rdkit.Chem.FilterCatalog import FilterCatalogParams

params = FilterCatalogParams()
params.AddCatalog(FilterCatalogParams.FilterCatalogs.PAINS)
catalog = FilterCatalog.FilterCatalog(params)

# Filter compounds
filtered = [mol for mol in mols if not catalog.HasMatch(mol)]
```

## Tips

- Ask Ivy to report how many records each criterion removed
- Keep both raw and filtered files for reproducibility
