mineral-database
SQLite database of 96 mineral families (68 natural + 15 synthetic + 9 simulant + 4 composite) with 140 CDL expressions, crystal system data, and gemmological properties. Version 1.8.1. Now includes amorphous material support for opal, turquoise, pearl, and more.
pip install gemmology-mineral-database Core Query Functions
get_preset(name: str) → dict[str, Any] | None Get a mineral preset by name (case-insensitive). Returns a dictionary.
from mineral_database import get_preset
preset = get_preset("quartz")
if preset:
print(preset['name']) # "Quartz"
print(preset['cdl']) # CDL expression string
print(preset['system']) # "trigonal"
print(preset['hardness']) # "7"
print(preset['ri']) # "1.544-1.553" get_mineral(name: str) → Mineral | None Get a Mineral object by name. Returns a typed dataclass instead of a dict.
from mineral_database import get_mineral
mineral = get_mineral("diamond-octahedron")
if mineral:
print(mineral.name) # "Diamond"
print(mineral.cdl) # "cubic[m3m]:{111}@1.0 + {110}@0.2"
print(mineral.system) # "cubic"
print(mineral.origin) # "natural" list_presets(category: str | None = None) → list[str] List all available preset names, optionally filtered by crystal system or category.
from mineral_database import list_presets
names = list_presets()
print(len(names)) # 140
# Filter by crystal system
cubic = list_presets("cubic")
print(len(cubic)) # All cubic presets search_presets(query: str) → list[str] Search presets using full-text search across name, chemistry, and description.
from mineral_database import search_presets
results = search_presets("beryl")
print(results) # ['beryl-prismatic', 'emerald-prismatic', ...]
results = search_presets("SiO2")
print(results) # Quartz, Amethyst, etc. filter_minerals(system=None, min_hardness=None, max_hardness=None, has_twin=False) → list[str] Filter minerals by various criteria.
from mineral_database import filter_minerals
# Durable gems (hardness 7+)
durable = filter_minerals(min_hardness=7.0)
# Cubic minerals with twins
cubic_twins = filter_minerals(system="cubic", has_twin=True) RI/SG Lookup
find_by_ri(ri: float, tolerance: float = 0.01) → list[Mineral] Find minerals matching a measured refractive index, sorted by closest match.
from mineral_database import find_by_ri
matches = find_by_ri(1.544, tolerance=0.01)
for m in matches:
print(f"{m.name}: RI {m.ri}") find_by_sg(sg: float, tolerance: float = 0.05) → list[Mineral] Find minerals matching a specific gravity value, sorted by closest match.
Synthetic and Simulant Queries
list_synthetics(growth_method: str | None = None) → list[str] List all synthetic mineral family IDs, optionally filtered by growth method.
from mineral_database import list_synthetics
# All synthetics
synths = list_synthetics()
print(synths) # ['cvd-diamond', 'flame-fusion-ruby', ...]
# Filter by method
flux = list_synthetics(growth_method="flux")
print(flux) # Flux-grown synthetics only list_simulants(target: str | None = None) → list[str] List all simulant mineral family IDs, optionally filtered by what they imitate.
from mineral_database import list_simulants
# All simulants
sims = list_simulants()
print(sims) # ['cubic-zirconia', 'moissanite', ...]
# Diamond simulants specifically
diamond_sims = list_simulants(target="diamond")
print(diamond_sims) # ['cubic-zirconia', 'moissanite', ...] get_counterparts(name: str) → dict[str, list[str]] Get all synthetic and simulant counterparts for a natural mineral.
from mineral_database import get_counterparts
cp = get_counterparts("diamond")
print(cp['synthetics']) # ['cvd-diamond', 'hpht-diamond']
print(cp['simulants']) # ['cubic-zirconia', 'moissanite', ...] list_by_origin(origin: str) → list[str] List all mineral family IDs filtered by origin type.
from mineral_database import list_by_origin
naturals = list_by_origin("natural") # 68 families
synthetics = list_by_origin("synthetic") # 15 families
simulants = list_by_origin("simulant") # 9 families
composites = list_by_origin("composite") # 4 families get_family(name: str) → MineralFamily | None Get a MineralFamily object by ID, including synthetic-specific fields.
from mineral_database import get_family
family = get_family("cubic-zirconia")
if family:
print(family.name) # "Cubic Zirconia"
print(family.origin) # "simulant"
print(family.natural_counterpart_id) # "diamond"
print(family.growth_method) # "skull_melting" Calculator Utilities
classify(category: str, value: float) → str | None Classify a gemmological value based on standard thresholds.
from mineral_database import classify
# Birefringence classification
print(classify("birefringence", 0.009)) # "low"
print(classify("birefringence", 0.045)) # "high"
# Dispersion classification
print(classify("dispersion", 0.044)) # "very_high" (diamond)
# Critical angle classification
print(classify("critical_angle", 24.4)) # "very_small" (diamond) list_shape_factors() → list[dict] Get cut shape factors for carat weight estimation.
list_heat_treatable() → list[Mineral] Get minerals with heat treatment temperature data.
Database Configuration
set_database_path(path: Path) → None Override the default database path for all queries.
from pathlib import Path
from mineral_database import set_database_path
set_database_path(Path("/path/to/custom/minerals.db")) Classes
Mineral
Dataclass representing a mineral preset with all gemmological properties.
| Attribute | Type | Description |
|---|---|---|
id | str | Preset ID (e.g., "diamond-octahedron") |
name | str | Display name |
cdl | str | CDL expression |
system | str | Crystal system |
point_group | str | Point group symbol |
chemistry | str | Chemical formula |
hardness | int | float | str | Mohs hardness (may be range like "6-7") |
sg | float | str | None | Specific gravity |
ri | float | str | None | Refractive index |
birefringence | float | None | Maximum birefringence |
optical_character | str | None | Optical character |
dispersion | float | None | Dispersion value |
colors | list[str] | Common colours |
cleavage | str | None | Cleavage description |
twin_law | str | None | Twin law name |
origin | str | Origin: natural, synthetic, simulant, or composite |
MineralFamily
Dataclass representing a mineral family (normalized structure). Includes
synthetic-specific fields like growth_method, manufacturer,
and diagnostic_synthetic_features.
| Attribute | Type | Description |
|---|---|---|
id | str | Family ID (e.g., "diamond") |
name | str | Display name (e.g., "Diamond") |
crystal_system | str | Crystal system |
point_group | str | None | Point group symbol |
chemistry | str | None | Chemical formula |
origin | str | Origin: natural, synthetic, simulant, composite |
growth_method | str | None | Synthesis method (synthetics only) |
natural_counterpart_id | str | None | ID of natural equivalent |
Included Data
The database includes 96 mineral families with 140 CDL expressions:
Natural (68)
Diamond, Ruby, Emerald, Quartz, Garnet...
Synthetic (15)
CVD Diamond, Flux Ruby, Hydrothermal Emerald...
Simulant (9)
CZ, Moissanite, YAG, Glass...
Composite (4)
Garnet-Topped Doublet, Opal Triplet...
Amorphous material support
Materials previously without CDL expressions (opal, turquoise, pearl, obsidian, amber, chalcedony)
now use the CDL v2.0 amorphous system with shape descriptors.
These expressions use subtypes like opalescent,
waxy, and glassy
instead of crystal systems and point groups.