Spaces:
Running
Running
add: demo app code and deps.
Browse files- .gitignore +1 -0
- Dockerfile +20 -0
- redis.conf +2 -0
- requirements.txt +11 -0
- src/app.py +218 -0
- src/constants.py +33 -0
- src/data.py +13 -0
- src/data/dataset_smiles.csv +22 -0
- src/data/isomer_design_subset.csv +415 -0
- src/data/sample_smiles.csv +13 -0
- src/main.js +322 -0
- src/main.min.js +1 -0
- src/service.py +213 -0
- src/src/app.py +218 -0
- src/src/constants.py +33 -0
- src/src/data.py +13 -0
- src/src/data/dataset_smiles.csv +22 -0
- src/src/data/isomer_design_subset.csv +415 -0
- src/src/data/sample_smiles.csv +13 -0
- src/src/main.js +322 -0
- src/src/main.min.js +1 -0
- src/src/service.py +213 -0
.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
__pycache__/
|
Dockerfile
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM redis/redis-stack:latest
|
| 2 |
+
|
| 3 |
+
RUN apt-get update && apt-get install -y \
|
| 4 |
+
pip \
|
| 5 |
+
libxrender1 libxext6 \
|
| 6 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 7 |
+
|
| 8 |
+
WORKDIR /app
|
| 9 |
+
|
| 10 |
+
COPY requirements.txt .
|
| 11 |
+
RUN pip install --no-cache-dir torch==2.6.0+cpu --index-url https://download.pytorch.org/whl/cpu
|
| 12 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
| 13 |
+
|
| 14 |
+
COPY redis.conf .
|
| 15 |
+
ENV REDIS_HOST=localhost
|
| 16 |
+
ENV REDIS_PORT=6379
|
| 17 |
+
|
| 18 |
+
COPY ./src ./src
|
| 19 |
+
|
| 20 |
+
CMD ["sh", "-c", "redis-server redis.conf & python3 src/app.py"]
|
redis.conf
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
loadmodule /opt/redis-stack/lib/redisearch.so
|
| 2 |
+
maxmemory 768mb
|
requirements.txt
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
chem-mrl>=0.5.8
|
| 2 |
+
gradio[mcp]>=4.0.0
|
| 3 |
+
transformers>=4.30.0
|
| 4 |
+
torch>=2.0.0
|
| 5 |
+
redis>=4.5.0
|
| 6 |
+
redis-om>=0.2.0
|
| 7 |
+
numpy>=1.24.0
|
| 8 |
+
python-dotenv>=1.0.0
|
| 9 |
+
scikit-learn>=1.3.0
|
| 10 |
+
rdkit>=2025.3.2
|
| 11 |
+
sentence-transformers==4.0.1
|
src/app.py
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import numpy as np
|
| 3 |
+
import pandas as pd
|
| 4 |
+
from rdkit import Chem
|
| 5 |
+
from rdkit.Chem import Draw
|
| 6 |
+
from rdkit.Chem.Draw import rdMolDraw2D
|
| 7 |
+
|
| 8 |
+
from constants import EMBEDDING_DIMENSION, LAUNCH_PARAMETERS, SUPPORTED_EMBEDDING_DIMENSIONS
|
| 9 |
+
from data import SAMPLE_SMILES
|
| 10 |
+
from service import MolecularEmbeddingService, SimilarMolecule, setup_logger
|
| 11 |
+
|
| 12 |
+
logger = setup_logger()
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class App:
|
| 16 |
+
def __init__(self):
|
| 17 |
+
self.embedding_service = MolecularEmbeddingService()
|
| 18 |
+
self.demo = self.create_gradio_interface()
|
| 19 |
+
|
| 20 |
+
def molecule_similarity_search_pipeline(
|
| 21 |
+
self, smiles: str, embed_dim: int
|
| 22 |
+
) -> tuple[list[float], list[SimilarMolecule], str]:
|
| 23 |
+
"""Complete pipeline: SMILES -> Canonical SMILES -> Embedding -> Similar molecules"""
|
| 24 |
+
try:
|
| 25 |
+
if not smiles or smiles.strip() == "":
|
| 26 |
+
return [], [], "Please provide a valid SMILES string"
|
| 27 |
+
|
| 28 |
+
logger.info(f"Running similarity search: {smiles} - ({embed_dim})")
|
| 29 |
+
embedding = self.embedding_service.get_molecular_embedding(smiles, embed_dim)
|
| 30 |
+
neighbors = self.embedding_service.find_similar_molecules(embedding, embed_dim)
|
| 31 |
+
|
| 32 |
+
return embedding.tolist(), neighbors, "Search completed successfully"
|
| 33 |
+
|
| 34 |
+
except Exception as e:
|
| 35 |
+
error_msg = f"Search failed: {str(e)}"
|
| 36 |
+
logger.error(error_msg)
|
| 37 |
+
return [], [], error_msg
|
| 38 |
+
|
| 39 |
+
@staticmethod
|
| 40 |
+
def _truncated_attribute(obj, attr, max_len=45):
|
| 41 |
+
return f"{obj[attr][:max_len]}{'...' if len(obj[attr]) > max_len else ''}"
|
| 42 |
+
|
| 43 |
+
@classmethod
|
| 44 |
+
def _draw_molecule_grid(cls, similar: list[SimilarMolecule]) -> np.ndarray:
|
| 45 |
+
mols = [Chem.MolFromSmiles(m["smiles"]) for m in similar]
|
| 46 |
+
legends = [
|
| 47 |
+
f"{cls._truncated_attribute(m, 'name')}\n{m['category']}\n"
|
| 48 |
+
f"{cls._truncated_attribute(m, 'smiles')}\n({m['score']:.2E})"
|
| 49 |
+
for m in similar
|
| 50 |
+
]
|
| 51 |
+
|
| 52 |
+
draw_options = rdMolDraw2D.MolDrawOptions()
|
| 53 |
+
draw_options.legendFontSize = 17
|
| 54 |
+
draw_options.legendFraction = 0.29
|
| 55 |
+
draw_options.drawMolsSameScale = False
|
| 56 |
+
|
| 57 |
+
img = Draw.MolsToGridImage(
|
| 58 |
+
mols,
|
| 59 |
+
legends=legends,
|
| 60 |
+
molsPerRow=2,
|
| 61 |
+
subImgSize=(250, 250),
|
| 62 |
+
drawOptions=draw_options,
|
| 63 |
+
)
|
| 64 |
+
return img
|
| 65 |
+
|
| 66 |
+
@staticmethod
|
| 67 |
+
def _display_sample_molecules(mols: pd.DataFrame):
|
| 68 |
+
for _, row in mols.iterrows():
|
| 69 |
+
with gr.Group():
|
| 70 |
+
gr.Textbox(value=row["smiles"], label=f"{row['name']} ({row['category']})", interactive=False, scale=3)
|
| 71 |
+
sample_btn = gr.Button(
|
| 72 |
+
f"Load {row['name']}",
|
| 73 |
+
scale=1,
|
| 74 |
+
size="sm",
|
| 75 |
+
variant="primary",
|
| 76 |
+
)
|
| 77 |
+
sample_btn.click(
|
| 78 |
+
fn=None,
|
| 79 |
+
js=f"() => {{window.setJSMESmiles('{row['smiles']}');}}",
|
| 80 |
+
)
|
| 81 |
+
|
| 82 |
+
@staticmethod
|
| 83 |
+
def clear_all():
|
| 84 |
+
return "", [], [], None, "Cleared - Draw a new molecule or enter SMILES"
|
| 85 |
+
|
| 86 |
+
def handle_search(self, smiles: str, embed_dim: int):
|
| 87 |
+
if not smiles.strip():
|
| 88 |
+
return (
|
| 89 |
+
[],
|
| 90 |
+
[],
|
| 91 |
+
None,
|
| 92 |
+
"Please draw a molecule or enter a SMILES string",
|
| 93 |
+
)
|
| 94 |
+
embedding, similar, status = self.molecule_similarity_search_pipeline(smiles, embed_dim)
|
| 95 |
+
img = self._draw_molecule_grid(similar)
|
| 96 |
+
return embedding, similar, img, status
|
| 97 |
+
|
| 98 |
+
def create_gradio_interface(self):
|
| 99 |
+
"""Create the Gradio interface optimized for JavaScript client usage"""
|
| 100 |
+
head_scripts = """
|
| 101 |
+
<link rel="preconnect" href="https://jsme-editor.github.io">
|
| 102 |
+
<link rel="preload" href="https://jsme-editor.github.io/dist/jsme/jsme.nocache.js" as="script" crossorigin="anonymous">
|
| 103 |
+
<link rel="preload" href="gradio_api/file=src/main.min.js" as="script">
|
| 104 |
+
<script type="text/javascript" src="https://jsme-editor.github.io/dist/jsme/jsme.nocache.js" crossorigin="anonymous" defer></script>
|
| 105 |
+
<script type="text/javascript" src="gradio_api/file=src/main.min.js" defer></script>
|
| 106 |
+
"""
|
| 107 |
+
|
| 108 |
+
with gr.Blocks(
|
| 109 |
+
title="Chem-MRL: Molecular Similarity Search Demo",
|
| 110 |
+
theme=gr.themes.Soft(),
|
| 111 |
+
head=head_scripts,
|
| 112 |
+
) as demo:
|
| 113 |
+
gr.Markdown("""
|
| 114 |
+
# 🧪 Chem-MRL: Molecular Similarity Search Demo
|
| 115 |
+
|
| 116 |
+
Use the JSME editor to draw a molecule or input a SMILES string.
|
| 117 |
+
The backend encodes the molecule using the Chem-MRL model to produce a vector embedding.
|
| 118 |
+
Similarity search is performed via an HNSW-indexed Redis vector store to retrieve closest matches.<br/>
|
| 119 |
+
|
| 120 |
+
[Model Repo](https://github.com/emapco/chem-mrl) | [Demo Repo](https://github.com/emapco/chem-mrl-demo)
|
| 121 |
+
""")
|
| 122 |
+
with gr.Tab("🔬 Molecular Search"), gr.Row():
|
| 123 |
+
with gr.Column(scale=1):
|
| 124 |
+
gr.Markdown("### Molecule Input")
|
| 125 |
+
gr.HTML("<div id='jsme_container'></div>")
|
| 126 |
+
|
| 127 |
+
smiles_input = gr.Textbox(
|
| 128 |
+
label="SMILES String",
|
| 129 |
+
placeholder="Draw a molecule above or enter SMILES here (e.g., CCO for ethanol)",
|
| 130 |
+
lines=2,
|
| 131 |
+
elem_id="smiles_input",
|
| 132 |
+
)
|
| 133 |
+
|
| 134 |
+
embedding_dimension = gr.Dropdown(
|
| 135 |
+
choices=SUPPORTED_EMBEDDING_DIMENSIONS,
|
| 136 |
+
value=EMBEDDING_DIMENSION,
|
| 137 |
+
label="Embedding Dimension",
|
| 138 |
+
elem_id="embedding_dimension",
|
| 139 |
+
)
|
| 140 |
+
|
| 141 |
+
with gr.Row():
|
| 142 |
+
search_btn = gr.Button(
|
| 143 |
+
"🔍 Search Molecule Database",
|
| 144 |
+
variant="primary",
|
| 145 |
+
elem_id="search_btn",
|
| 146 |
+
)
|
| 147 |
+
clear_btn = gr.Button("🗑️ Clear All", variant="secondary")
|
| 148 |
+
|
| 149 |
+
with gr.Column(scale=1):
|
| 150 |
+
gr.Markdown("### Search Results")
|
| 151 |
+
status_output = gr.Textbox(
|
| 152 |
+
label="Status",
|
| 153 |
+
interactive=False,
|
| 154 |
+
elem_id="status_output",
|
| 155 |
+
value="Ready - Draw a molecule or enter SMILES",
|
| 156 |
+
)
|
| 157 |
+
|
| 158 |
+
with gr.Accordion("Molecular Embedding Vector", open=False):
|
| 159 |
+
embedding_output = gr.JSON(
|
| 160 |
+
label="Molecular Embedding",
|
| 161 |
+
elem_id="embedding_output",
|
| 162 |
+
)
|
| 163 |
+
|
| 164 |
+
with gr.Accordion("Similar Molecules Response", open=False):
|
| 165 |
+
similar_molecules_output = gr.JSON(
|
| 166 |
+
label="API Response",
|
| 167 |
+
elem_id="similar_molecules_output",
|
| 168 |
+
)
|
| 169 |
+
|
| 170 |
+
molecule_image = gr.Image(label="Similiar Molecules Grid", type="pil")
|
| 171 |
+
|
| 172 |
+
with gr.Tab("📊 Sample Molecules"):
|
| 173 |
+
gr.Markdown("""
|
| 174 |
+
### Sample Molecules in Database
|
| 175 |
+
Click any button below to load the molecule into the JSME editor:
|
| 176 |
+
""")
|
| 177 |
+
|
| 178 |
+
with gr.Row():
|
| 179 |
+
with gr.Column(scale=1):
|
| 180 |
+
self._display_sample_molecules(SAMPLE_SMILES[::3])
|
| 181 |
+
with gr.Column(scale=1):
|
| 182 |
+
self._display_sample_molecules(SAMPLE_SMILES[1::3])
|
| 183 |
+
with gr.Column(scale=1):
|
| 184 |
+
self._display_sample_molecules(SAMPLE_SMILES[2::3])
|
| 185 |
+
|
| 186 |
+
search_btn.click(
|
| 187 |
+
fn=self.handle_search,
|
| 188 |
+
inputs=[smiles_input, embedding_dimension],
|
| 189 |
+
outputs=[
|
| 190 |
+
embedding_output,
|
| 191 |
+
similar_molecules_output,
|
| 192 |
+
molecule_image,
|
| 193 |
+
status_output,
|
| 194 |
+
],
|
| 195 |
+
api_name="molecule_similarity_search_pipeline",
|
| 196 |
+
)
|
| 197 |
+
|
| 198 |
+
# Clear UI state
|
| 199 |
+
clear_btn.click(
|
| 200 |
+
fn=self.clear_all,
|
| 201 |
+
js="window.clearJSME",
|
| 202 |
+
outputs=[
|
| 203 |
+
smiles_input,
|
| 204 |
+
embedding_output,
|
| 205 |
+
similar_molecules_output,
|
| 206 |
+
molecule_image,
|
| 207 |
+
status_output,
|
| 208 |
+
],
|
| 209 |
+
)
|
| 210 |
+
|
| 211 |
+
gr.set_static_paths(paths=["src/"])
|
| 212 |
+
|
| 213 |
+
return demo
|
| 214 |
+
|
| 215 |
+
|
| 216 |
+
if __name__ == "__main__":
|
| 217 |
+
app = App()
|
| 218 |
+
app.demo.launch(**LAUNCH_PARAMETERS)
|
src/constants.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Model config
|
| 2 |
+
MODEL_NAME = "Derify/ChemMRL-alpha"
|
| 3 |
+
SUPPORTED_EMBEDDING_DIMENSIONS = [1024, 768, 512, 256, 128, 64, 32, 16, 8, 4, 2]
|
| 4 |
+
EMBEDDING_DIMENSION = max(SUPPORTED_EMBEDDING_DIMENSIONS)
|
| 5 |
+
|
| 6 |
+
# HNSW index parameters
|
| 7 |
+
HNSW_K = 6
|
| 8 |
+
HNSW_PARAMETERS = {
|
| 9 |
+
# Embedding vector dtype
|
| 10 |
+
"TYPE": "FLOAT32",
|
| 11 |
+
# Embedding vectors are normalized so COSINE and IP are equivalent
|
| 12 |
+
"DISTANCE_METRIC": "IP",
|
| 13 |
+
# Defines the initial capacity of the vector index. It helps in pre-allocating space for the index.
|
| 14 |
+
"INITIAL_CAP": 440,
|
| 15 |
+
# Max number of outgoing edges (connections) for each node in a graph layer.
|
| 16 |
+
"M": 32,
|
| 17 |
+
# Max number of connected neighbors to consider during graph building.
|
| 18 |
+
# Higher values increase accuracy, but also increase index build time.
|
| 19 |
+
"EF_CONSTRUCTION": 512,
|
| 20 |
+
# Max top candidates during KNN search. Higher values increase accuracy, but also increase search latency.
|
| 21 |
+
"EF_RUNTIME": 10,
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
# Gradio launch parameters
|
| 25 |
+
LAUNCH_PARAMETERS = {
|
| 26 |
+
"server_name": "0.0.0.0",
|
| 27 |
+
"server_port": 7860,
|
| 28 |
+
"share": True,
|
| 29 |
+
"debug": False,
|
| 30 |
+
"show_api": False,
|
| 31 |
+
"pwa": True,
|
| 32 |
+
"mcp_server": False,
|
| 33 |
+
}
|
src/data.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
|
| 3 |
+
import pandas as pd
|
| 4 |
+
|
| 5 |
+
__data_dir = os.path.join(os.path.dirname(__file__), "data")
|
| 6 |
+
|
| 7 |
+
__dataset_smiles_file = os.path.join(__data_dir, "dataset_smiles.csv")
|
| 8 |
+
__sample_smiles_file = os.path.join(__data_dir, "sample_smiles.csv")
|
| 9 |
+
__isomer_design_subset_file = os.path.join(__data_dir, "isomer_design_subset.csv")
|
| 10 |
+
|
| 11 |
+
DATASET_SMILES = pd.read_csv(__dataset_smiles_file)
|
| 12 |
+
SAMPLE_SMILES = pd.read_csv(__sample_smiles_file)
|
| 13 |
+
ISOMER_DESIGN_SUBSET = pd.read_csv(__isomer_design_subset_file)
|
src/data/dataset_smiles.csv
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
smiles,name,category
|
| 2 |
+
CCO,Ethanol,Alcohol
|
| 3 |
+
CC(=O)O,Acetic acid,Carboxylic acid
|
| 4 |
+
c1ccccc1,Benzene,Aromatic hydrocarbon
|
| 5 |
+
CC(C)O,Isopropanol,Alcohol
|
| 6 |
+
CCN(CC)CC,Triethylamine,Amine
|
| 7 |
+
c1ccc(cc1)O,Phenol,Aromatic alcohol
|
| 8 |
+
CC(=O)OC1=CC=CC=C1C(=O)O,Aspirin,Carboxylic acid ester
|
| 9 |
+
CN1C=NC2=C1C(=O)N(C(=O)N2C)C,Caffeine,Alkaloid
|
| 10 |
+
CC(C)(C)OC(=O)NC1CCC(CC1)O,Boc-protected cyclohexanol,Protected alcohol
|
| 11 |
+
CCCCCCCCCCCCCCC(=O)O,Palmitic acid,Fatty acid
|
| 12 |
+
c1ccc2c(c1)cccn2,Quinoline,Aromatic heterocycle
|
| 13 |
+
CC1=CC=C(C=C1)C,p-Xylene,Aromatic hydrocarbon
|
| 14 |
+
CCCCO,Butanol,Alcohol
|
| 15 |
+
CC(C)C,Isobutane,Alkane
|
| 16 |
+
c1ccc(cc1)N,Aniline,Aromatic amine
|
| 17 |
+
CC(=O)N,Acetamide,Amide
|
| 18 |
+
CCCCCCCCCCCCCCCCCC(=O)O,Stearic acid,Fatty acid
|
| 19 |
+
c1ccc(cc1)C(=O)O,Benzoic acid,Aromatic carboxylic acid
|
| 20 |
+
CCc1ccccc1,Ethylbenzene,Aromatic hydrocarbon
|
| 21 |
+
CC(C)CC(C)(C)C,"2,2,4-Trimethylpentane",Branched alkane
|
| 22 |
+
O=C1c2ccccc2C(=O)N1C3CCC(=O)NC3=O,Thalidomide,Phthalimides
|
src/data/isomer_design_subset.csv
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
smiles,name,category
|
| 2 |
+
O=C1CCCCC1(c1ccccc1Cl)N1CCCCC1,2-Cl-2'-Oxo-PCP,arylcycloalkylamine
|
| 3 |
+
CCCCNC1(c2ccccc2)CCCCC1,PCB,arylcycloalkylamine
|
| 4 |
+
COc1ccccc1C1(N2CCCCC2)CCCCC1,2-MeO-PCP,arylcycloalkylamine
|
| 5 |
+
c1ccc(C2(n3cccc3)CCCCC2)cc1,PCPyrrole,arylcycloalkylamine
|
| 6 |
+
Fc1cccc(C2(N3CCCC3)CC3CCC2C3)c1,3F-PBCHPy,arylcycloalkylamine
|
| 7 |
+
COc1ccc(C2(NCC3CCCO3)CCCCC2)cc1,1-(4-Methoxyphenyl)-N-[(oxolan-2-yl)methyl]cyclohexan-1-amine,arylcycloalkylamine
|
| 8 |
+
COc1ccc(C2(N3CCCC3)CC3CCC2C3)cc1,4-MeO-PBCHPy,arylcycloalkylamine
|
| 9 |
+
C=CCN(CC)C1(c2ccccc2)CCCCC1,N-Allyl-PCE,arylcycloalkylamine
|
| 10 |
+
CCCCCNC1(c2ccccc2)CCCCC1,PCPe,arylcycloalkylamine
|
| 11 |
+
OC1CCCCC1(c1ccccc1)N1CCCCC1,2'-HO-PCP,arylcycloalkylamine
|
| 12 |
+
Cc1ccccc1C1(N2CCCC(O)C2)CCCCC1,3″-HO-2-Me-PCP,arylcycloalkylamine
|
| 13 |
+
c1ccc(C2(N3CCCCC3)CCCC2)cc1,PCPEP,arylcycloalkylamine
|
| 14 |
+
CCN(C)C1(c2ccccc2C)CCCCC1,2-Me-PCEM,arylcycloalkylamine
|
| 15 |
+
Fc1ccccc1C1(N2CCCC2)CC2CCC1C2,2F-PBCHPy,arylcycloalkylamine
|
| 16 |
+
CC(C)OCCCNC1(c2ccccc2)CCCCC1,1-Phenyl-N-{3-[(propan-2-yl)oxy]propyl}cyclohexan-1-amine,arylcycloalkylamine
|
| 17 |
+
CCNC1(c2ccc(C)cc2)CCCCC1,4-Me-PCE,arylcycloalkylamine
|
| 18 |
+
CCNC1(c2cccc(OC)c2)CCCCC1=O,MXE,arylcycloalkylamine
|
| 19 |
+
CCOC(=O)CCCN(C)C1(c2ccccc2Cl)CCCCC1=O,Et-KE-Bu,arylcycloalkylamine
|
| 20 |
+
CCNC1(c2ccccc2)CCCCC1,PCE,arylcycloalkylamine
|
| 21 |
+
c1cc2c(cc1C1(N3CCOCC3)CCCCC1)OCO2,"3,4-MD-PCMo",arylcycloalkylamine
|
| 22 |
+
OCCNC1(c2ccccc2)CCCCC1,PCEOH,arylcycloalkylamine
|
| 23 |
+
c1ccc(C2(N3CCCCC3)CCCCCCC2)cc1,PCOP,arylcycloalkylamine
|
| 24 |
+
COc1ccc(C2(N3CCCCC3)CC3CCC2C3)cc1,4-MeO-PBCHP,arylcycloalkylamine
|
| 25 |
+
COc1cccc(C2(N3CCCCC3)CCCc3ccccc32)c1,"1-[1-(3-Methoxyphenyl)-1,2,3,4-tetrahydronaphthalen-1-yl]piperidine",arylcycloalkylamine
|
| 26 |
+
CCNC12CCCCC1CCc1ccccc12,"N-Ethyl-1,3,4,9,10,10a-hexahydrophenanthren-4a(2H)-amine",arylcycloalkylamine
|
| 27 |
+
c1ccc([C@]2(N3CCCCC3)C[C@H]3C[C@H]3C2)cc1,"1-[(1R,3r,5S)-3-Phenylbicyclo[3.1.0]hexan-3-yl]piperidine",arylcycloalkylamine
|
| 28 |
+
c1ccc(C2(N3CCCCC3)CN3CCC2CC3)cc1,P3QP,arylcycloalkylamine
|
| 29 |
+
COc1cccc(C2(N3CCCC3)CCCCC2=O)c1,3-MeO-2'-Oxo-PCPy,arylcycloalkylamine
|
| 30 |
+
c1cc2c(cc1C1(N3CCCCC3)CCCCC1)OCCO2,"3,4-ED-PCP",arylcycloalkylamine
|
| 31 |
+
NC1(c2ccccc2Cl)CCCNC1=O,3-Amino-3-(2-chlorophenyl)piperidin-2-one,arylcycloalkylamine
|
| 32 |
+
CC[C@]1(c2ccccc2)OC[C@H]([C@@H]2CCCCN2)O1,CL-1848C,arylcycloalkylamine
|
| 33 |
+
O=[N+]([O-])c1cccc(C2(N3CCCCC3)CCCCC2)c1,3-NO2-PCP,arylcycloalkylamine
|
| 34 |
+
Fc1cccc(C2(N3CCCCC3)CCCCCC2)c1,3F-PCHEP,arylcycloalkylamine
|
| 35 |
+
CCNC1(c2cccc(OC(C)C)c2)CCCCC1=O,iPXE,arylcycloalkylamine
|
| 36 |
+
COc1cc(C2(N3CCCCC3)CCCCC2)ccc1C,3-MeO-4-Me-PCP,arylcycloalkylamine
|
| 37 |
+
O=C1CCC(c2ccccc2)(N2CCCCC2)CC1,4'-Oxo-PCP,arylcycloalkylamine
|
| 38 |
+
CCNC1(c2ccc3c(c2)OCO3)CCCCC1,"3,4-MD-PCE",arylcycloalkylamine
|
| 39 |
+
CNC1(c2ccccc2OC)CCCCC1=O,2-MDCK,arylcycloalkylamine
|
| 40 |
+
CCOc1cccc(C2(N3CCCCC3)CCCCC2)c1,3-EtO-PCP,arylcycloalkylamine
|
| 41 |
+
CNC1(c2ccccc2C)CCCCC1=O,o-MDCK,arylcycloalkylamine
|
| 42 |
+
CNC1(c2cccc(Cl)c2)CCCCC1=O,meta-Ketamine,arylcycloalkylamine
|
| 43 |
+
CCNC1(c2cc(OC)ccc2Br)CCCCC1=O,Bromo-methoxetamine,arylcycloalkylamine
|
| 44 |
+
CNC1(c2cccc(OC)c2)CCCCC1=O,MXM,arylcycloalkylamine
|
| 45 |
+
CCCOC(=O)CCNC1(c2ccccc2Cl)CCCCC1=O,nPr-NKE-Et,arylcycloalkylamine
|
| 46 |
+
CC1CCCCC1(c1ccccc1)N1CCCCC1,2'-Me-PCP,arylcycloalkylamine
|
| 47 |
+
Cc1ccc(C2(N3CCC(O)CC3)CCCCC2O)cc1,"2',4″-HO-4-Me-PCP",arylcycloalkylamine
|
| 48 |
+
NC1(c2ccccc2Cl)CCC(O)CC1=O,"(2,5)-HNK",arylcycloalkylamine
|
| 49 |
+
Fc1cccc(C2(N3CCCCC3)CC3CCC2C3)c1,3F-PBCHP,arylcycloalkylamine
|
| 50 |
+
CC(C)NC1(c2ccccc2)CCCCC1,PCiP,arylcycloalkylamine
|
| 51 |
+
Fc1ccc(C2(N3CCCCC3)CCCCCC2)cc1,4F-PCHEP,arylcycloalkylamine
|
| 52 |
+
CCCNC1(c2ccccc2)CCCC1,PCPEPr,arylcycloalkylamine
|
| 53 |
+
CC(C)Oc1cccc(C2(N)CCCCC2)c1,3-IpO-PCA,arylcycloalkylamine
|
| 54 |
+
CC(O)CNC1(c2ccccc2)CCCCC1,1-[(1-Phenylcyclohexyl)amino]propan-2-ol,arylcycloalkylamine
|
| 55 |
+
Cc1ccc(C2(N(C)C)CCC(O)(CCc3ccccc3)CC2)cc1,MDPC,arylcycloalkylamine
|
| 56 |
+
Cc1cc(O)ccc1C1(N2CCOCC2)CCCCC1,4-HO-2-Me-PCMo,arylcycloalkylamine
|
| 57 |
+
O=C1CCCCC1(c1ccccc1)N1CCCC1,2-Phenyl-2-(pyrrolidin-1-yl)cyclohexan-1-one,arylcycloalkylamine
|
| 58 |
+
CNC1(c2ccccc2Cl)CCCCCC1=O,2-(2-Chlorophenyl)-2-(methylamino)cycloheptan-1-one,arylcycloalkylamine
|
| 59 |
+
CCN(CC)C1(c2ccccc2)CCCCC1,PCDE,arylcycloalkylamine
|
| 60 |
+
COc1cccc([C@@]2(O)CCN(C3(c4ccccc4)CCCCC3)C[C@@H]2CN(C)C)c1,US 7049327 #6,arylcycloalkylamine
|
| 61 |
+
Cc1cccc(C2(N3CCCC3)CC3CCC2C3)c1,3-Me-PBCHPy,arylcycloalkylamine
|
| 62 |
+
C#Cc1ccc2c(c1)C(c1ccccc1F)=N[C@@H](C)c1c(C(=O)N(C)C)ncn1-2,GL-i-54,aryldiazepine
|
| 63 |
+
O=C1CN=C(c2c(F)cccc2F)c2cc(Cl)ccc2N1,Ro-07-3953,aryldiazepine
|
| 64 |
+
O=C1CN=C(c2ccn[nH]2)c2cc(Cl)ccc2N1,SCHEMBL9684958,aryldiazepine
|
| 65 |
+
C#Cc1ccc2c(c1)C(c1ccccn1)=NCc1c(C(N)=O)ncn1-2,MP-ii-065,aryldiazepine
|
| 66 |
+
CN1C(=O)CN=C(c2ccccc2F)c2c(Cl)cccc21,Ro-13-0699,aryldiazepine
|
| 67 |
+
C#Cc1ccc2c(c1)C(c1ccccc1)=NCc1c(C(=O)OCC(F)(F)F)ncn1-2,DM-ii-20,aryldiazepine
|
| 68 |
+
O=C1OCCC2N=C(c3ccccc3)c3ccccc3-n3cnc1c32,"8-Phenyl-6,6a-dihydro-4-oxa-2,7,12b-triazabenzo[b]cyclopenta[kl]heptalen-3(5H)-one",aryldiazepine
|
| 69 |
+
CCC1C(C)=NN=C(c2ccc(OC)c(OC)c2)c2cc(OC)c(OC)cc21,Tofisopam,aryldiazepine
|
| 70 |
+
CN1C(=O)CN=C(c2ccc(F)cc2)c2cc(Cl)ccc21,4F-Diazepam,aryldiazepine
|
| 71 |
+
CC(C)COC(=O)c1ncn2c1C1CCCN1C(=O)c1c(Cl)cccc1-2,Ro-16-7082,aryldiazepine
|
| 72 |
+
CN1C(=O)CN=C(c2cccs2)c2cc(Cl)ccc21,WZ-113,aryldiazepine
|
| 73 |
+
CC(=O)c1ccc2c(c1)C(c1ccccc1)=NCC(=O)N2,Ro-20-3053,aryldiazepine
|
| 74 |
+
C#Cc1ccc2c(c1)C(=O)N(C)Cc1c(C(=O)OC(C)(C)C)ncn1-2,RY-24,aryldiazepine
|
| 75 |
+
CC(C)(C)OC(=O)c1ncn2c1C1CCCN1C(=O)c1c(F)cccc1-2,Ro-16-8912,aryldiazepine
|
| 76 |
+
O=C1CN=C(c2ccccc2F)c2cc(Cl)ccc2N1CCO,Ro-07-2750,aryldiazepine
|
| 77 |
+
CN1C(=O)CN=C(c2ccccc2Cl)c2cc([N+](=O)[O-])ccc21,Ro-05-4082,aryldiazepine
|
| 78 |
+
Cc1nnc2n1-c1sc(Cl)cc1C(c1ccccc1)=NC2,Deschloroclotizolam,aryldiazepine
|
| 79 |
+
CCOC(=O)c1ncn2c1C(C)N=C(c1ccc(F)cc1)c1cc(F)ccc1-2,"Ethyl 8-fluoro-6-(4-fluorophenyl)-4-methyl-4H-imidazo[1,5-a][1,4]benzodiazepine-3-carboxylate",aryldiazepine
|
| 80 |
+
O=C1CN=C(c2ccccc2F)c2cc(Cl)c(Cl)cc2N1,Ro-20-8065,aryldiazepine
|
| 81 |
+
CN1C(=O)CN=C(c2c(F)cccc2F)c2cc(Br)ccc21,Ro-13-3780,aryldiazepine
|
| 82 |
+
CN1C(=O)CC(=O)N(c2ccccc2)c2cc(Cl)ccc21,Clobazam,aryldiazepine
|
| 83 |
+
OCc1nnc2n1-c1ccc(Cl)cc1C(c1ccccc1)=NC2,alpha-Hydroxyalprazolam,aryldiazepine
|
| 84 |
+
O=C1Nc2ccc(Cl)cc2C(c2ccccc2)=NC1O,Oxazepam,aryldiazepine
|
| 85 |
+
CCOC(=O)c1ncn2c1CN=C(c1ccc([N+](=O)[O-])cc1)c1ccccc1-2,Ro-23-2896,aryldiazepine
|
| 86 |
+
CN1C(=O)CN=C(c2ccccc2F)c2cc(Br)ccc21,Flubrometazepam,aryldiazepine
|
| 87 |
+
CN(C)C(=O)c1nc2n(n1)-c1ccc(Cl)cc1C(c1ccccc1Cl)=NC2,Rilmazolam,aryldiazepine
|
| 88 |
+
CC1N=C(c2ccccc2F)c2cc(Cl)ccc2NC1=O,Ro-11-4878,aryldiazepine
|
| 89 |
+
CCOC(=O)c1ncn2c1C1CCCN1C(=O)c1cc(Br)ccc1-2,RY-054,aryldiazepine
|
| 90 |
+
CCOC(=O)c1ncn2c1C1CCN1C(=O)c1c(Cl)cccc1-2,Ro-16-0858,aryldiazepine
|
| 91 |
+
CN1C(=O)CN=C(c2ccc(Cl)cc2)c2cc(Cl)ccc21,Ro-05-4864,aryldiazepine
|
| 92 |
+
CN(C)CCc1nnc2n1-c1ccc(Cl)cc1C(c1ccccc1)=NC2,U-43465F,aryldiazepine
|
| 93 |
+
CN1C(=O)CN=C(c2ccccc2F)c2c(Cl)cc(Cl)cc21,Ro-13-0882,aryldiazepine
|
| 94 |
+
CCc1ccc2c(c1)C(c1ccccc1)=NCC(=O)N2,Ro-20-2533,aryldiazepine
|
| 95 |
+
CCOC(=O)c1ncn2c1CC=C(c1ccccc1F)c1ccccc1-2,Ro-15-2200,aryldiazepine
|
| 96 |
+
O=C1CC=C(c2ccccc2Cl)c2cc([N+](=O)[O-])ccc2N1,Ro-15-8867,aryldiazepine
|
| 97 |
+
Cc1cc2c(cc1Cl)NC(=O)CN=C2c1ccccc1F,Ro-20-8552,aryldiazepine
|
| 98 |
+
N#Cc1ncn2c1CN=C(c1ccc(Cl)cc1)c1cc(Cl)ccc1-2,"8-Chloro-6-(4-chlorophenyl)-4H-imidazo[1,5-a][1,4]benzodiazepine-3-carbonitrile",aryldiazepine
|
| 99 |
+
CC(C)c1nc(-c2ncn3c2CN(C)C(=O)c2c(Cl)cccc2-3)no1,FG-8205,aryldiazepine
|
| 100 |
+
Cc1nnc2n1-c1ccc([N+](=O)[O-])cc1C(c1ccccc1Cl)=NC2,Clonazolam,aryldiazepine
|
| 101 |
+
O=C1CN=C(c2ccccc2[N+](=O)[O-])c2cc(Br)ccc2N1,QH-II-067a,aryldiazepine
|
| 102 |
+
NC(=O)c1ncn2c1CC=C(c1ccccc1F)c1cc(Cl)ccc1-2,Ro-14-3930,aryldiazepine
|
| 103 |
+
COC(=O)CC[C@@H]1N=C(c2ccccn2)c2cc(Br)ccc2-n2c(C)cnc21,CNS-7056,aryldiazepine
|
| 104 |
+
CN1C(=O)CN=C(C2CCC2)c2cc(F)ccc21,"5-Cyclobutyl-7-fluoro-1-methyl-1,3-dihydro-2H-1,4-benzodiazepin-2-one",aryldiazepine
|
| 105 |
+
O=C1CN=C(c2c(F)cccc2Cl)c2cc(Cl)ccc2N1,Ro-07-5193,aryldiazepine
|
| 106 |
+
CN1C(=O)CN=C(c2ccccc2F)c2cc(I)ccc21,Ro-07-9957,aryldiazepine
|
| 107 |
+
O=C1CN=C(c2ccccc2)c2cc(Cl)ccc2N1CC1CC1,Prazepam,aryldiazepine
|
| 108 |
+
CCOC(=O)c1ncn2c1CN=C(c1cccc([N+](=O)[O-])c1)c1cc(F)ccc1-2,"Ethyl 8-fluoro-6-(3-nitrophenyl)-4H-imidazo[1,5-a][1,4]benzodiazepine-3-carboxylate",aryldiazepine
|
| 109 |
+
Clc1ccc2c(c1)-c1ncnn1Cc1c(Cl)ncn1-2,Ro4882224,aryldiazepine
|
| 110 |
+
[N-]=[N+]=Nc1ccc2c(c1)C(c1ccccc1F)=NCC(=O)N2,Ro-14-3074,aryldiazepine
|
| 111 |
+
Fc1ccccc1C1=NCC=Cc2ccc(Cl)cc21,Ro-22-1274,aryldiazepine
|
| 112 |
+
Nc1ncc2c(n1)-c1ccc(Cl)cc1C(c1ccccc1F)=NC2,Ro-22-2038,aryldiazepine
|
| 113 |
+
Clc1ccc2c(c1)C(c1ccccc1)=NCc1nncn1-2,Estazolam,aryldiazepine
|
| 114 |
+
Cc1nn(C)c2c1C(c1ccccc1F)=NCC(=O)N2C,Zolazepam,aryldiazepine
|
| 115 |
+
Cc1nnc2n1-c1ccc(Cl)cc1C(c1ccccn1)=NC2,Pyclazolam,aryldiazepine
|
| 116 |
+
S=C1CN=C(c2ccccc2)c2cc(Cl)ccc2N1,Thionordazepam,aryldiazepine
|
| 117 |
+
O=C1CN=C(c2ccccc2)c2cc(Cl)ccc2N1CC(F)(F)F,Halazepam,aryldiazepine
|
| 118 |
+
C#Cc1ccc2c(c1)C(c1ccccc1)=NCC1=N/C(=C\N3CCN(C)CC3)C(=O)N12,PS-i-37,aryldiazepine
|
| 119 |
+
C#Cc1ccc2c(c1)C(c1ccccc1F)=NCc1c(C(=O)OCC(F)(F)F)ncn1-2,JY-i-59,aryldiazepine
|
| 120 |
+
O=C1CN=C(c2ccccc2F)c2cc([N+](=O)[O-])ccc2N1,Fonazepam,aryldiazepine
|
| 121 |
+
CN1CCN(/C=C2\N=C3CN=C(c4ccccc4)c4cc(Br)ccc4N3C2=O)CC1,PS-1-35,aryldiazepine
|
| 122 |
+
CCCCCCC(C)(C)c1ccc([C@@H]2CCC[C@H](O)C2)c(O)c1,"(1R,3S) CP 47,497",cannabinoid
|
| 123 |
+
CCCc1ccc(C(=O)c2cn(CCCCCF)c3ccccc23)c2ccccc12,SGT-62,cannabinoid
|
| 124 |
+
CC(C)[C@H](NC(=O)c1cn(Cc2ccc(F)cc2)c2ccccc12)C(N)=O,AB-FUBICA,cannabinoid
|
| 125 |
+
CCCCCn1nc(C(=O)N[C@@H](Cc2ccccc2)C(=O)OC)c2ccccc21,MPP-PINACA,cannabinoid
|
| 126 |
+
O=C(Cc1cn(Cc2ccc(F)cc2)c2ccccc12)NC1C2CC3CC(C2)CC1C3,AFUBIATA,cannabinoid
|
| 127 |
+
CC(C)(C)c1nc(N2CCC(F)(F)C2)c2nnn(Cc3ccccc3S(C)(=O)=O)c2n1,"5-tert-Butyl-7-(3,3-difluoropyrrolidin-1-yl)-3-{[2-(methanesulfonyl)phenyl]methyl}-3H-[1,2,3]triazolo[4,5-d]pyrimidine",cannabinoid
|
| 128 |
+
CCC(C(N)=O)N(C)C(=O)c1nn(Cc2ccc(F)cc2)c2ccccc12,AB-FUBINACA isomer 5,cannabinoid
|
| 129 |
+
COc1cccc2c3c(=O)n([C@@H]4C(C)(C)[C@@H]5CC[C@@]4(C)C5)ccc3n(Cc3ccncc3)c12,WO 2001/058869 #190,cannabinoid
|
| 130 |
+
CCCC(F)Cn1cc(C(=O)C2C(C)(C)C2(C)C)c2ccccc21,(2-Fluoropentyl) XLR-11,cannabinoid
|
| 131 |
+
O=C(Nc1ccccc1)c1cn(CCCCCF)c2ccccc12,LTI-701,cannabinoid
|
| 132 |
+
C=CCCCn1nc(C(=O)N[C@H](C(=O)OC)C(C)C)c2ccccc21,MMB-4en-PINACA,cannabinoid
|
| 133 |
+
O=C(Nc1ccccc1)c1nn(CC2CCOCC2)c2ccccc12,SGT-224,cannabinoid
|
| 134 |
+
Cc1ccc(C(=O)NC(C)(C)c2ccccc2)cc1S(=O)(=O)N1CCC(F)(F)CC1,SGT-233,cannabinoid
|
| 135 |
+
CCCCCn1nc(C(=O)c2ccc(OC)c3ccccc23)c2ccccc21,SGT-35,cannabinoid
|
| 136 |
+
CC1(C)C(C(=O)c2cn(CC3CCCCC3)c3ccccc23)C1(C)C,(CHM) UR-144,cannabinoid
|
| 137 |
+
CN1CCCCC1Cn1cc(C(=O)c2ccc(N=C=S)c3ccccc23)c2ccc(N=C=S)cc21,AM-2215,cannabinoid
|
| 138 |
+
CCCCCCC1(c2ccc(-c3cc(C)cc(C)c3)c(O)c2)CC1,"4-(1-Hexylcyclopropyl)-3',5'-dimethyl[1,1'-biphenyl]-2-ol",cannabinoid
|
| 139 |
+
COC(=O)[C@@H](NC(=O)c1cn(Cc2ccc(F)cc2)c2ncccc12)C(C)(C)C,MDMB-FUB7AICA,cannabinoid
|
| 140 |
+
CN1CCCCC1Cn1cc(C(=O)c2ccccc2I)c2ccccc21,AM-2233,cannabinoid
|
| 141 |
+
O=C(c1cccc2ccccc12)n1c(-c2ccncc2)nc2ccccc21,(Naphthalen-1-yl)[2-(pyridin-4-yl)-1H-benzimidazol-1-yl]methanone,cannabinoid
|
| 142 |
+
C=CCCCn1nc(C(=O)N[C@H](C(=O)OC)C(C)(C)C)c2ccccc21,MDMB-4en-PINACA,cannabinoid
|
| 143 |
+
Oc1ccc(/C=C2\C=C(CCN3CCOCC3)c3ccccc32)c2ccccc12,US 5292736 #19,cannabinoid
|
| 144 |
+
CCc1c(C(=O)NN2CCCCC2)nn(-c2ccc(Cl)cc2Cl)c1-c1ccc(C#Cc2ccc(C(F)(F)F)cc2)s1,TM-38837,cannabinoid
|
| 145 |
+
COC(=O)[C@H](Cc1ccccc1)NC(=O)c1cn(CCCCCF)c2ccccc12,MPHP-2201,cannabinoid
|
| 146 |
+
Cc1ccc2c(C(C[N+](=O)[O-])c3ccccc3)c(-c3ccccc3)[nH]c2c1,GAT211,cannabinoid
|
| 147 |
+
CCCCCn1nc(C(=O)NC2CCCCC2)c2ccccc21,SGT-85,cannabinoid
|
| 148 |
+
CN1CCCCC1Cn1cc(C(=O)c2ccc([N+](=O)[O-])c3ccccc23)c2ccccc21,AM-1299,cannabinoid
|
| 149 |
+
CCc1c(C)cc(C(=O)NC2(C(=O)O)CCCCC2)c(=O)n1Cc1ccc(F)cc1,S-777469,cannabinoid
|
| 150 |
+
CCCCCC(C)NC(=O)c1nn(CCCCC)c2ccccc12,SGT-71,cannabinoid
|
| 151 |
+
CC1(C)Oc2cc(C34CC5CC(CC(C5)C3)C4)cc(O)c2[C@@H]2CC(O)CC[C@H]21,"(6aR,10aR)-3-(Adamantan-1-yl)-6,6-dimethyl-6a,7,8,9,10,10a-hexahydro-6H-dibenzo[b,d]pyran-1,9-diol",cannabinoid
|
| 152 |
+
C=C(C)[C@H]1CCC(CO)=C[C@@H]1c1c(O)cc(C(C)(C)CCCCN2CCOCC2)cc1O,"(1'S,2'S)-5'-(Hydroxymethyl)-4-[2-methyl-6-(morpholin-4-yl)hexan-2-yl]-2'-(prop-1-en-2-yl)-1',2',3',4'-tetrahydro[1,1'-biphenyl]-2,6-diol",cannabinoid
|
| 153 |
+
O=C(N/N=C1\C(=O)N(CCCCCF)c2ccccc21)c1ccccc1,BZO-5F-POXIZID,cannabinoid
|
| 154 |
+
CCCCCOc1c(OC)ccc2cc(C(=O)NCc3ccc4c(c3)OCO4)c(=O)[nH]c12,JTE-907,cannabinoid
|
| 155 |
+
CCCCn1nc(C(=O)N[C@@H](Cc2ccccc2)C(=O)OC)c2ccccc21,MPP(N)-073,cannabinoid
|
| 156 |
+
CCCCCCC(C)(C)c1ccc([C@@H]2CCC[C@@H](O)C2)c(O)c1,"(R,R)-epi-CP 47,497",cannabinoid
|
| 157 |
+
CCCCCOc1ccc(C(=O)c2cccc3ccccc23)c2ccccc12,CB-13,cannabinoid
|
| 158 |
+
COc1ccccc1OC(=O)c1ccc(C)c(S(=O)(=O)N2CCOCC2)c1,2-Methoxyphenyl 4-methyl-3-(morpholine-4-sulfonyl)benzoate,cannabinoid
|
| 159 |
+
CCCCCC#Cc1cc(O)c2c(c1)OC(C)(C)[C@@H]1CC=C(C)C[C@@H]21,AMG-1,cannabinoid
|
| 160 |
+
CC(C)[C@H](NC(=O)c1cn(CCCCCF)c2ccccc12)C(N)=O,5F-ABICA,cannabinoid
|
| 161 |
+
CCCCCn1cc(C(=O)NC23CC4CC(CC(C4)C2)C3)c(=O)c2ccc(F)cc21,"N-(Adamantan-1-yl)-7-fluoro-4-oxo-1-pentyl-1,4-dihydroquinoline-3-carboxamide",cannabinoid
|
| 162 |
+
CC1=CC[C@@H]2[C@@H](C1)c1c(O)cc(C(C)(C)CCCCCC#N)cc1OC2(C)C,O-774,cannabinoid
|
| 163 |
+
CC(C)(C)[C@H](NC(=O)n1c(=O)n(CCN2CCOCC2)c2ccccc21)C(N)=O,WO 2008/032164 #4,cannabinoid
|
| 164 |
+
COC(=O)[C@H](Cc1ccccc1)NC(=O)c1cn(CC2CCCCC2)c2ccccc12,MPP-CHMICA,cannabinoid
|
| 165 |
+
Fc1ccc2nc(-c3ccccn3)n(Cc3cccc4ccccc34)c2c1,6-Fluoro-1-[(naphthalen-1-yl)methyl]-2-(pyridin-2-yl)-1H-benzimidazole,cannabinoid
|
| 166 |
+
CCCCCn1cc(C(=O)N[C@@H](C)c2ccccc2)c2ccccc21,1-Pentyl-N-[(1S)-1-phenylethyl]-1H-indole-3-carboxamide,cannabinoid
|
| 167 |
+
CCCCCCCC(C)c1cc(OC(=O)CCCN(CC)CC)c2c(c1)OC(C)(C)C1=C2CC(C)CC1,SP-325,cannabinoid
|
| 168 |
+
CCCCCn1cc(C(=O)c2cccc3ccccc23)cc1-c1cccc(C)c1,JWH-346,cannabinoid
|
| 169 |
+
O=C(Cc1ccccc1)N/N=C1\C(=O)N(CC2CCCCC2)c2cc(OCCN3CCOCC3)ccc21,"N'-{1-(Cyclohexylmethyl)-6-[2-(morpholin-4-yl)ethoxy]-2-oxo-1,2-dihydro-3H-indol-3-ylidene}-2-phenylacetohydrazide",cannabinoid
|
| 170 |
+
Cc1c(C(=O)C2C(C)(C)C2(C)C)c2ccccc2n1CCCCCF,2-Me-XLR-11,cannabinoid
|
| 171 |
+
COc1ccc2c(c1)CCC2CNC(=O)c1cn(CCCCCF)c2ccccc12,SGT-105,cannabinoid
|
| 172 |
+
CCCCCc1cc(O)c2c(c1)OC(C)(C)C(CCC(C)=O)C2=O,CBCN,cannabinoid
|
| 173 |
+
CCCCCn1nc(C(=O)NC(C)(C)c2ccc(F)cc2)c2ccccc21,SGT-60,cannabinoid
|
| 174 |
+
CC(C)(C)[C@H](NC(=O)c1nn(CC2CCCCCC2)c2ccccc12)C(=O)NCCO,WO 2009/106980 #433,cannabinoid
|
| 175 |
+
CC(C)(NC(=O)c1cn(Cc2ccc(F)cc2)c2ccccc12)c1ccccc1,CUMYL-FUBICA,cannabinoid
|
| 176 |
+
COC(=O)[C@@H](NC(=O)c1nn(CC2CCCCC2)c2ccccc12)C(C)(C)C,MDMB(N)-CHM,cannabinoid
|
| 177 |
+
CCCCCn1nc(C(=O)c2cccc3ccccc23)c2ccccc21,SGT-17,cannabinoid
|
| 178 |
+
CCCCCn1cc(C(=O)N[C@H](C(N)=O)C(C)(C)C)c2ccccc21,ADBICA,cannabinoid
|
| 179 |
+
CN1CCCCC1Cn1cc(C(=O)c2cc(N=C=S)ccc2I)c2ccc(N=C=S)cc21,AM-2223,cannabinoid
|
| 180 |
+
CCCCCCCCCn1cc(C(=O)c2cccc3ccccc23)c2ccccc21,(Nonyl) JWH-018,cannabinoid
|
| 181 |
+
CCCCCCC(C)(C)c1cc(OC)c([C@@H]2C=C(CO)C3CC2C3(C)C)c(OC)c1,HU-433,cannabinoid
|
| 182 |
+
C=CCc1cc(OC)c(OC)c(OC)c1OC,"2,3,4,5-Tetramethoxyphenylprop-2-ene",essential oil
|
| 183 |
+
C/C=C\c1ccc(O)c(OC)c1,cis-4-Hydroxy-3-methoxyphenylprop-1-ene,essential oil
|
| 184 |
+
C/C=C/c1ccc2c(c1OC)OCO2,Isocroweacin,essential oil
|
| 185 |
+
C/C=C\c1cc(OC)c(O)c(OC)c1,"cis-4-Hydroxy-3,5-dimethoxyphenylprop-1-ene",essential oil
|
| 186 |
+
C=CCc1ccc2c(c1OC)OCO2,Croweacin,essential oil
|
| 187 |
+
C/C=C\c1cc2c(cc1OC)OCO2,"cis-2-Methoxy-4,5-methylenedioxyphenylprop-1-ene",essential oil
|
| 188 |
+
C=CCc1ccc2c(c1)OCO2,Safrole,essential oil
|
| 189 |
+
C/C=C\c1cc(OC)c2c(c1)OCO2,cis-Isomyristicin,essential oil
|
| 190 |
+
C/C=C\c1ccc(OC)cc1OC,"cis-2,4-Dimethoxyphenylprop-1-ene",essential oil
|
| 191 |
+
C/C=C\c1ccc2c(c1OC)OCO2,"cis-2-Methoxy-3,4-methylenedioxyphenylprop-1-ene",essential oil
|
| 192 |
+
C/C=C/c1ccc(OC)c(OC)c1,Methylisoeugenol,essential oil
|
| 193 |
+
C=CCc1ccc(OC)cc1OC,Osmorrhizole,essential oil
|
| 194 |
+
C=CCc1ccc(OC)c(OC)c1,Methyleugenol,essential oil
|
| 195 |
+
C=CCc1ccc(O)c(OC)c1,Eugenol,essential oil
|
| 196 |
+
C=CCc1cc2c(c(OC)c1OC)OCO2,Dillapiole,essential oil
|
| 197 |
+
C/C=C\c1ccc2c(c1)OCO2,alpha-Isosafrole,essential oil
|
| 198 |
+
C/C=C/c1cc(OC)c(OC)c(OC)c1,Isoelemicin,essential oil
|
| 199 |
+
C=CCc1ccc(OC)c(O)c1,Chavibetol,essential oil
|
| 200 |
+
C=CCc1cc(OC)c(OC)c(OC)c1,Elemicin,essential oil
|
| 201 |
+
C=CCc1cc(OC)cc(OC)c1,"3,5-Dimethoxyphenylprop-2-ene",essential oil
|
| 202 |
+
C/C=C\c1cc(OC)c(OC)c(OC)c1,cis-Isoelemicin,essential oil
|
| 203 |
+
C/C=C/c1cc(OC)c(OC)c(OC)c1OC,"trans-2,3,4,5-Tetramethoxyphenylprop-1-ene",essential oil
|
| 204 |
+
C/C=C/c1cc(OC)c2c(c1OC)OCO2,Isoapiole,essential oil
|
| 205 |
+
C/C=C\c1ccc(OC)c(O)c1,cis-3-Hydroxy-4-methoxyphenylprop-1-ene,essential oil
|
| 206 |
+
C=CCc1ccc(OC)cc1,Estragole,essential oil
|
| 207 |
+
C/C=C\c1cc(OC)c2c(c1OC)OCO2,"cis-2,5-Dimethoxy-3,4-methylenedioxyphenylprop-1-ene",essential oil
|
| 208 |
+
C=CCc1cc(OC)c2c(c1OC)OCO2,Apiole,essential oil
|
| 209 |
+
C/C=C/c1ccc(OC)cc1OC,Nothosmyrnol,essential oil
|
| 210 |
+
C/C=C/c1cc(OC)cc(OC)c1,"trans-3,5-Dimethoxyphenylprop-1-ene",essential oil
|
| 211 |
+
C/C=C\c1cc2c(c(OC)c1OC)OCO2,"cis-2,3-Dimethoxy-4,5-methylenedioxyphenylprop-1-ene",essential oil
|
| 212 |
+
C/C=C\c1ccc(OC)cc1,cis-4-Methoxyphenylprop-1-ene,essential oil
|
| 213 |
+
C/C=C/c1cc(OC)c(O)c(OC)c1,"2,6-Dimethoxy-4-[(1E)-prop-1-en-1-yl]phenol",essential oil
|
| 214 |
+
C=CCc1cc(OC)c(OC)cc1OC,γ-Asarone,essential oil
|
| 215 |
+
C/C=C/c1ccc(OC)cc1,Anethole,essential oil
|
| 216 |
+
C=CCc1cc2c(cc1OC)OCO2,Asaricin,essential oil
|
| 217 |
+
C/C=C/c1cc2c(c(OC)c1OC)OCO2,Isodillapiole,essential oil
|
| 218 |
+
C/C=C/c1cc(OC)c(OC)cc1OC,Asarone,essential oil
|
| 219 |
+
C/C=C/c1ccc(O)c(OC)c1,Isoeugenol,essential oil
|
| 220 |
+
C/C=C\c1cc(OC)cc(OC)c1,"cis-3,5-Dimethoxyphenylprop-1-ene",essential oil
|
| 221 |
+
C/C=C\c1cc(OC)c(OC)cc1OC,beta-Asarone,essential oil
|
| 222 |
+
C=CCc1cc(OC)c2c(c1)OCO2,Myristicin,essential oil
|
| 223 |
+
C/C=C/c1ccc(OC)c(O)c1,2-Methoxy-5-[(1E)-prop-1-en-1-yl]phenol,essential oil
|
| 224 |
+
C/C=C/c1cc(OC)c2c(c1)OCO2,Isomyristicin,essential oil
|
| 225 |
+
C/C=C\c1ccc(OC)c(OC)c1,"cis-3,4-Dimethoxyphenylprop-1-ene",essential oil
|
| 226 |
+
C=CCc1cc(OC)c(O)c(OC)c1,5-Methoxyeugenol,essential oil
|
| 227 |
+
C/C=C/c1ccc2c(c1)OCO2,beta-Isosafrole,essential oil
|
| 228 |
+
C/C=C\c1cc(OC)c(OC)c(OC)c1OC,"cis-2,3,4,5-Tetramethoxyphenylprop-1-ene",essential oil
|
| 229 |
+
C/C=C/c1cc2c(cc1OC)OCO2,Carpacin,essential oil
|
| 230 |
+
CCC(=O)N(c1ccccc1)C1(COC)CCN(CC(O)c2cccs2)CC1,beta-Hydroxy-sufentanil,fentanyl
|
| 231 |
+
CCC(=O)N(CCc1ccccc1)C1CCN(CCc2ccccc2)CC1,(ethylene) Fentanyl,fentanyl
|
| 232 |
+
CCC(=O)N(c1ccccc1F)C1(c2ccccc2)CCN(CCn2cccn2)CC1,N-(2-Fluorophenyl)-N-{4-phenyl-1-[2-(1H-pyrazol-1-yl)ethyl]piperidin-4-yl}propanamide,fentanyl
|
| 233 |
+
CCC(=O)N(c1ccccc1)C1CCN(C(C)Cc2cc(OC)c(I)cc2OC)CC1,N-(DOI) fentanyl,fentanyl
|
| 234 |
+
CCC(=O)N(c1ccccc1)C1(COC(=O)C(C)(C)C)CCN(CCN2C(=O)c3ccccc3C2=O)CC1,"{1-[2-(1,3-Dioxo-1,3-dihydro-2H-isoindol-2-yl)ethyl]-4-[phenyl(propanoyl)amino]piperidin-4-yl}methyl 2,2-dimethylpropanoate",fentanyl
|
| 235 |
+
CC(C)C(=O)N(c1cccc(F)c1)C1CCN(CCc2ccccc2)CC1,m-Fluoro-isobutyrylfentanyl,fentanyl
|
| 236 |
+
CCCC(=O)N(c1ccc(OC)cc1)C1CCN(CCc2ccccc2)CC1,p-MeO-BF,fentanyl
|
| 237 |
+
CCC(=O)N(c1ccccc1)C1(C(=O)OC)CCN(Cc2ccccc2)CC1,Benzylcarfentanil,fentanyl
|
| 238 |
+
CCC(=O)N(c1ccccc1)C1(C(=O)OC)CCN(CCc2ccsc2)CC1,Methyl 4-[phenyl(propanoyl)amino]-1-[2-(thiophen-3-yl)ethyl]piperidine-4-carboxylate,fentanyl
|
| 239 |
+
COCC(=O)N(c1ccc(C)cc1)C1CCN(CCc2ccccc2)CC1,p-Methyl-methoxyacetylfentanyl,fentanyl
|
| 240 |
+
CCCCC(=O)N(c1ccc(OC)cc1)C1CCN(CCc2ccccc2)CC1,p-Methoxy-valerylfentanyl,fentanyl
|
| 241 |
+
CCC(=O)N(c1ccccc1)C1CCN(CCc2ccccc2)CC1F,NFEPP,fentanyl
|
| 242 |
+
CCC(=O)N(c1ccccc1)C1CCN(C(C)Cc2cc(OC)c(Br)cc2OC)CC1,N-(DOB) fentanyl,fentanyl
|
| 243 |
+
CCCC(=O)N(c1ccccc1)C1CCN(C)CC1,N-Methyl-butyrylfentanyl,fentanyl
|
| 244 |
+
O=C(c1ccco1)N(c1ccccc1)C1CCN(CCc2ccc(O)cc2)CC1,4'-Hydroxy-furanylfentanyl,fentanyl
|
| 245 |
+
CCC(=O)OCC1(N(C(=O)CC)c2ccccc2)CCN(CCN2C(=O)c3ccccc3C2=O)CC1,"{1-[2-(1,3-Dioxo-1,3-dihydro-2H-isoindol-2-yl)ethyl]-4-[phenyl(propanoyl)amino]piperidin-4-yl}methyl propanoate",fentanyl
|
| 246 |
+
CCC(=O)N(c1ccccc1)C1CCN(CCc2ccccc2)C(C)C1,2-Methylfentanyl,fentanyl
|
| 247 |
+
CC(=O)N(c1ccccc1)C1CCN(CCCc2ccccc2)CC1,Phenylpropyl-acetyl-norfentanyl,fentanyl
|
| 248 |
+
CCC(=O)N(c1ccccc1)C1CCN(CCOc2ccccc2)CC1,POE-F,fentanyl
|
| 249 |
+
O=C(c1ccco1)N(c1ccccc1)C1CCNCC1,Furanyl-norfentanyl,fentanyl
|
| 250 |
+
CCC(=O)N(c1ccccc1)C1CCN(Cc2ccccc2)CC1,R-4129,fentanyl
|
| 251 |
+
Cc1ccc(NC2CCN(CCc3ccccc3)CC2)cc1,p-Me-4-ANPP,fentanyl
|
| 252 |
+
CCC(=O)N(c1ccccc1)C1(C(=O)O)CCN(CCc2ccccc2)C(O)C1,2-Hydroxycarfentanil acid,fentanyl
|
| 253 |
+
COCC(=O)N(c1ccc(F)cc1)C1CCN(CCc2ccccc2)CC1,p-Fluoro-methoxyacetylfentanyl,fentanyl
|
| 254 |
+
Cc1cccc(N(C(=O)c2ccco2)C2CCN(CCc3ccccc3)CC2)c1,m-Methyl-furanylfentanyl,fentanyl
|
| 255 |
+
CCC(=O)N(c1ccccc1)C1CCN(CCc2ccccc2F)CC1,2″-Fluorofentanyl,fentanyl
|
| 256 |
+
COc1ccccc1N(C(=O)c1ccco1)C1CCN(CCc2ccccc2)CC1,o-Methoxy-furanylfentanyl,fentanyl
|
| 257 |
+
CCC(=O)N(c1ccccc1)C1CCN(CC(O)c2ccc(F)cc2)CC1,N-{1-[2-(4-Fluorophenyl)-2-hydroxyethyl]piperidin-4-yl}-N-phenylpropanamide,fentanyl
|
| 258 |
+
CC(=O)N(c1ccccc1)C1CCN(CCc2cccs2)CC1,Acetylthiofentanyl,fentanyl
|
| 259 |
+
COCC(=O)N(c1cccc(F)c1)C1CCN(CCc2ccccc2)CC1,m-Fluoro-methoxyacetylfentanyl,fentanyl
|
| 260 |
+
COc1cc(CCN2CCC(N(C(=O)C(=O)CCC(=O)O)c3ccccc3)CC2)ccc1O,N-Phenyl-N-[1-(2-phenylethyl)piperidin-4-yl]-2-oxo-4-carboxybutanamide,fentanyl
|
| 261 |
+
CCC(=O)N(c1ccccc1)C1(COC)CCN(CCn2nnn(CC)c2=O)CC1,R-39209,fentanyl
|
| 262 |
+
CCC(=O)N(c1ccc(Cl)cc1)C1CCN(CCc2ccccc2)CC1,p-CF,fentanyl
|
| 263 |
+
CCC(=O)N(c1ccccc1)C1CCNCC1,Norfentanyl,fentanyl
|
| 264 |
+
COC(=O)CCN1CCC(Nc2ccccc2)(C(=O)OC)CC1,Despropionyl remifentanil,fentanyl
|
| 265 |
+
CCC(=O)N(c1ccccc1)C1(c2nc(C)cs2)CCN(CCc2ccccc2)CC1,"N-[4-(4-Methyl-1,3-thiazol-2-yl)-1-(2-phenylethyl)piperidin-4-yl]-N-phenylpropanamide",fentanyl
|
| 266 |
+
CCC(=O)N(c1ccccc1)C1(c2ccccc2)CCN(CCc2ccccc2)CC1,4-Phenylfentanyl,fentanyl
|
| 267 |
+
CCC(=O)N(c1ccccc1C)C1CCN(CCc2ccccc2)CC1,o-Methylfentanyl,fentanyl
|
| 268 |
+
CCC(=O)N(c1ccccc1)C1(C(=O)OC)CCN(CCCCCF)CC1,Fluoropentyl-norcarfentanil,fentanyl
|
| 269 |
+
O=C(c1ccco1)N(c1ccccc1)C1CCN(Cc2ccccc2)CC1,Furanylbenzylfentanyl,fentanyl
|
| 270 |
+
CCC(=O)N(c1ccc2ncoc2c1)C1CCN(CCc2ccccc2)CC1,N-Benzoxazolyl-fentanyl,fentanyl
|
| 271 |
+
COCC(=O)N(c1cccc(C)c1)C1CCN(CCc2ccccc2)CC1,m-Methyl-methoxyacetylfentanyl,fentanyl
|
| 272 |
+
CC(C)C(=O)OCC1(N(C(=O)C(C)C)c2ccccc2)CCN(CCN2C(=O)c3ccccc3C2=O)CC1,"{1-[2-(1,3-Dioxo-1,3-dihydro-2H-isoindol-2-yl)ethyl]-4-[(2-methylpropanoyl)(phenyl)amino]piperidin-4-yl}methyl 2-methylpropanoate",fentanyl
|
| 273 |
+
CCC(=O)N(c1ccccc1)C1(C(=O)OC)CCN(CCc2ccccn2)CC1,Methyl 4-[phenyl(propanoyl)amino]-1-[2-(pyridin-2-yl)ethyl]piperidine-4-carboxylate,fentanyl
|
| 274 |
+
c1ccc(CCN2CCC(Nc3ccccc3)CC2)cc1,ANPP,fentanyl
|
| 275 |
+
CCCc1cc(OC)c(CCN2CCC(N(C(=O)CC)c3ccccc3)CC2)cc1OC,N-(2C-P) fentanyl,fentanyl
|
| 276 |
+
CCC(=O)N(c1ccccc1)C1CCN(CC(O)c2ccncc2)CC1C,N-{1-[2-Hydroxy-2-(pyridin-4-yl)ethyl]-3-methylpiperidin-4-yl}-N-phenylpropanamide,fentanyl
|
| 277 |
+
CCC(=O)N(c1ccccc1)C1CCN(CC(=O)c2cccc(F)c2)CC1,N-{1-[2-(3-Fluorophenyl)-2-oxoethyl]piperidin-4-yl}-N-phenylpropanamide,fentanyl
|
| 278 |
+
CCCCc1cc(OC)c(CC(C)N2CCC(N(C(=O)CC)c3ccccc3)CC2)cc1OC,N-(DOBU) fentanyl,fentanyl
|
| 279 |
+
COCC(=O)N(c1ccccc1)C1C(C)CN(CCn2cccn2)CC1C,"N-{3,5-Dimethyl-1-[2-(1H-pyrazol-1-yl)ethyl]piperidin-4-yl}-2-methoxy-N-phenylacetamide",fentanyl
|
| 280 |
+
Cc1ccc(N(C(=O)C2CCCO2)C2CCN(CCc3ccccc3)CC2)cc1,p-Methyl-tetrahydrofuranylfentanyl,fentanyl
|
| 281 |
+
CCC(=O)N(c1ccccc1)C1CCN(CCc2cc(OC)cc(OC)c2)CC1,"3″,5″-DiMeO-F",fentanyl
|
| 282 |
+
CC(=O)N(c1ccccc1)C1CCN(CCc2ccccc2)CC1,Acetylfentanyl,fentanyl
|
| 283 |
+
CCC(=O)N(c1ccccc1)C1CCN(CCc2ccc(F)cc2)CC1,4″-Fluorofentanyl,fentanyl
|
| 284 |
+
CCC(=O)N(c1ccccc1)C1(COC(=O)OC)CCN(CCc2cccs2)CC1,Methyl {4-[phenyl(propanoyl)amino]-1-[2-(thiophen-2-yl)ethyl]piperidin-4-yl}methyl carbonate,fentanyl
|
| 285 |
+
CCC(=O)[N+]([O-])(c1ccccc1)C1(C(=O)OC)CCN(CCc2ccccc2)CC1,Carfentanil N-oxide,fentanyl
|
| 286 |
+
CCC(=O)N(c1ccccc1)C1(C(=O)OC)CCN(CCc2cccc(O)c2)CC1,3″-Hydroxycarfentanil,fentanyl
|
| 287 |
+
CCC(=O)N(c1ccccc1)C1CCN(C(C)C(=O)OC(C)C)CC1,Propan-2-yl 2-{4-[phenyl(propanoyl)amino]piperidin-1-yl}propanoate,fentanyl
|
| 288 |
+
O=C(C1CCC1)N(c1ccc(Cl)cc1)C1CCN(CCc2ccccc2)CC1,p-Chloro-cyclobutylfentanyl,fentanyl
|
| 289 |
+
CCC(C)C(=O)N(c1ccccc1)C1CCN(CCc2ccccc2)CC1,alpha'-Methyl-butyrylfentanyl,fentanyl
|
| 290 |
+
Oc1cc2c(cc1O)CNCC2,Norsalsolinol,neurotoxin
|
| 291 |
+
CC(N)Cc1ccc(Cl)cc1,PCA,neurotoxin
|
| 292 |
+
CC1NCCc2cc(O)c(O)cc21,Salsolinol,neurotoxin
|
| 293 |
+
CC(N)Cc1ccc(Br)cc1,PBA,neurotoxin
|
| 294 |
+
NCCc1cc(O)c(O)cc1O,6-OHDA,neurotoxin
|
| 295 |
+
COc1ccc(CCN)cc1OC,DMPEA,peyote alkaloid
|
| 296 |
+
CNCCc1cc(OC)c(OC)c(OC)c1,M-M,peyote alkaloid
|
| 297 |
+
COc1cc2c(c(OC)c1OC)C(C)N(C=O)CC2,N-Formyl-O-methylanhalonidine,peyote alkaloid
|
| 298 |
+
COc1cc2c(c3c1OCO3)C(C)[N+](C)(C)CC2,Lophotine,peyote alkaloid
|
| 299 |
+
COc1cc(CCN)ccc1O,GEA,peyote alkaloid
|
| 300 |
+
COc1cc(CCNCC(=O)O)cc(OC)c1OC,Mescaloxylic acid,peyote alkaloid
|
| 301 |
+
COc1cc2c(c(O)c1OC)C(C)N(C=O)CC2,N-Formylanhalonidine,peyote alkaloid
|
| 302 |
+
COc1cc(CCN2C(=O)CC(O)C2=O)cc(OC)c1OC,Mescaline malimide,peyote alkaloid
|
| 303 |
+
CNCCc1ccc(O)c(O)c1,Epinine,peyote alkaloid
|
| 304 |
+
COc1cc2c(c(O)c1OC)C(C)(C(=O)O)NCC2,Peyoruvic acid,peyote alkaloid
|
| 305 |
+
CCN1CCc2cc(OC)c3c(c2C1C)OCO3,Peyophorine,peyote alkaloid
|
| 306 |
+
COc1cc(CCN2C(=O)C=CC2=O)cc(OC)c1OC,Mescaline maleimide,peyote alkaloid
|
| 307 |
+
COc1c(O)cc2c(c1OC)CN(C)CC2,Isoanhalidine,peyote alkaloid
|
| 308 |
+
NCCc1ccc2c(c1)OCO2,MDPEA,peyote alkaloid
|
| 309 |
+
COc1cc2c(c(O)c1OC)C1CCC(=O)N1CC2,Peyoglutam,peyote alkaloid
|
| 310 |
+
COc1cc(CCN)cc(O)c1OC,3-DESMETHYL,peyote alkaloid
|
| 311 |
+
CCOc1ccc(CC(C)N(C)C)c(OCC)c1,"2,4-Diethoxy-N,N-dimethylamphetamine",peyote alkaloid
|
| 312 |
+
CN(C)CCc1ccc2c(c1)OCO2,Lobivine,peyote alkaloid
|
| 313 |
+
COc1c(O)cc2c(c1OC)C(C)N(C)CC2,Isopellotine,peyote alkaloid
|
| 314 |
+
COc1cc(CCNC(C)=O)cc(OC)c1OC,N-Acetylmescaline,peyote alkaloid
|
| 315 |
+
COc1cc2c(c3c1OCO3)C(C)N(C(C)=O)CC2,N-Acetylanhalonine,peyote alkaloid
|
| 316 |
+
COc1cc(CCN(C)C)cc(O)c1OC,"N,N-Me-3-DESMETHYL",peyote alkaloid
|
| 317 |
+
COc1c(O)cc2c(c1OC)C(C)NCC2,Isoanhalonidine,peyote alkaloid
|
| 318 |
+
COc1cc(CCn2cccc2C(=O)O)cc(OC)c1OC,Peyonine,peyote alkaloid
|
| 319 |
+
COc1cc2c(c(O)c1OC)CN(C(C)=O)CC2,N-Acetylanhalamine,peyote alkaloid
|
| 320 |
+
COc1cc2c(c(O)c1OC)C(C(=O)O)NCC2,Peyoxylic acid,peyote alkaloid
|
| 321 |
+
COc1cc(CCN(C)C)ccc1O,MM-GEA,peyote alkaloid
|
| 322 |
+
COc1cc2c(c(OC)c1OC)CNCC2,Anhalinine,peyote alkaloid
|
| 323 |
+
CNCCc1ccc(O)cc1,HMePEA,peyote alkaloid
|
| 324 |
+
COc1cc2c(c(O)c1OC)C[N+](C)(C)CC2,Anhalotine,peyote alkaloid
|
| 325 |
+
COc1c(O)cc2c(c1OC)CNCC2,Isoanhalamine,peyote alkaloid
|
| 326 |
+
COc1cc(CCN)cc(O)c1O,"3,4-DESMETHYL",peyote alkaloid
|
| 327 |
+
COc1cc2c(c(O)c1OC)CN(C=O)CC2,N-Formylanhalamine,peyote alkaloid
|
| 328 |
+
COc1cc(CCNC(C)C(=O)O)cc(OC)c1OC,Mescaloruvic acid,peyote alkaloid
|
| 329 |
+
C[N+](C)(C)CCc1ccc(O)cc1,Candicine,peyote alkaloid
|
| 330 |
+
COc1cc2c(c(O)c1OC)C(C)NCC2,Anhalonidine,peyote alkaloid
|
| 331 |
+
COc1cc2c(c(OC)c1OC)C1CCC(=O)N1CC2,Mescalotam,peyote alkaloid
|
| 332 |
+
COc1cc2c(c3c1OCO3)C(C)NCC2,Anhalonine,peyote alkaloid
|
| 333 |
+
COc1cc2c(c(O)c1OC)C(C)N(C)CC2,Pellotine,peyote alkaloid
|
| 334 |
+
COc1cc2c(c(O)c1OC)CN(C)CC2,Anhalidine,peyote alkaloid
|
| 335 |
+
COc1cc2c(c3c1OCO3)C(C)N(C)CC2,Lophophorine,peyote alkaloid
|
| 336 |
+
COc1cc(CCN)cc2c1OCO2,LOPHOPHINE,peyote alkaloid
|
| 337 |
+
COc1cc(CCNC(C)=O)cc(O)c1OC,N-Acetyl-3-demethymescaline,peyote alkaloid
|
| 338 |
+
COc1cc(CCN)cc(OC)c1OC,M,peyote alkaloid
|
| 339 |
+
COc1cc(CCN2C(=O)CCC2=O)cc(OC)c1OC,Mescaline succinimide,peyote alkaloid
|
| 340 |
+
COc1cc2c(c(O)c1OC)C(C)[N+](C)(C)CC2,Peyotine,peyote alkaloid
|
| 341 |
+
COc1cc2c(c(OC)c1OC)C(C)NCC2,O-Methylanhalonidine,peyote alkaloid
|
| 342 |
+
COc1cc2c(c(O)c1OC)CNCC2,Anhalamine,peyote alkaloid
|
| 343 |
+
COc1cc(CCN2C(=O)CC(O)(CC(=O)O)C2=O)cc(OC)c1OC,Mescaline citrimide,peyote alkaloid
|
| 344 |
+
CN(C)CCc1ccc(O)cc1,Hordenine,peyote alkaloid
|
| 345 |
+
COc1cc(CCNC=O)cc(OC)c1OC,N-Formylmescaline,peyote alkaloid
|
| 346 |
+
CNCCc1cc(O)c(OC)c(OC)c1,N-Me-3-DESMETHYL,peyote alkaloid
|
| 347 |
+
COc1cc(CCn2c(C=O)ccc2CO)cc(OC)c1OC,Peyoglunal,peyote alkaloid
|
| 348 |
+
COc1cc(CCNC=O)cc(O)c1OC,N-Formyl-3-demethylmescaline,peyote alkaloid
|
| 349 |
+
NCCc1ccc(O)c(O)c1,Dopamine,peyote alkaloid
|
| 350 |
+
COc1cc2c(c3c1OCO3)C(C)N(C=O)CC2,N-Formylanhalonine,peyote alkaloid
|
| 351 |
+
CNCCc1ccc(O)c(OC)c1,N-Me-GEA,peyote alkaloid
|
| 352 |
+
COc1cc2c(c(OC)c1OC)CN(C=O)CC2,N-Formylanhalinine,peyote alkaloid
|
| 353 |
+
COc1cc(CCN2C(=O)C3CC(=O)OC3C2=O)cc(OC)c1OC,Mescaline isocitrimide lactone,peyote alkaloid
|
| 354 |
+
COc1cc2c(c(OC)c1OC)C(C)N(C)CC2,O-Methylpellotine,peyote alkaloid
|
| 355 |
+
CCC(C)N(CCc1c[nH]c2ccc(F)cc12)C(C)C,5-Fluoro-IPSBT,tryptamine
|
| 356 |
+
CC(C)N(CCc1c[nH]c2ccc(F)cc12)CC1CC1,5-Fluoro-N-cyclopropylmethyl-NIPT,tryptamine
|
| 357 |
+
CCCCCCN(C)CCc1c[nH]c2ccc(OC)cc12,N-[2-(5-Methoxy-1H-indol-3-yl)ethyl]-N-methylhexan-1-amine,tryptamine
|
| 358 |
+
CN(C)CCc1c[nH]c2c(Br)ccc(O)c12,7-Bromopsilocin,tryptamine
|
| 359 |
+
CCCCN(CCCC)CCc1c[nH]c2cc(OC)c(OC)cc12,"5,6-MeO-DBT",tryptamine
|
| 360 |
+
CN(C/C=C/c1ccccc1)CCc1c[nH]c2ccccc12,N-Phenylpropenyl-NMT,tryptamine
|
| 361 |
+
COc1cc2[nH]cc(CCN3CCCC3)c2cc1OC,"5,6-MeO-pyr-T",tryptamine
|
| 362 |
+
Cn1cc(CCN)c2c3c(ccc21)OCCC3,"CP 132,484",tryptamine
|
| 363 |
+
C=CCN(CCc1c(C)[nH]c2ccc(OC)cc12)C1CCCCC1,2-Methyl-5-methoxy-N-allyl-N-cyclohexyltryptamine,tryptamine
|
| 364 |
+
Cc1cc(OP(=O)(O)O)c2c(CCN)c[nH]c2c1,6-Methyl-4-PO-T,tryptamine
|
| 365 |
+
CCCCCN(CCCCC)CCc1c[nH]c2ccccc12,"N,N-Dipentyltryptamine",tryptamine
|
| 366 |
+
COc1ccc2[nH]cc(CC3CCCN3C)c2c1,CP-108509,tryptamine
|
| 367 |
+
COc1ccc(OC)c(CCCN(C)CCc2c[nH]c3ccc(OC)cc23)c1,"3-(2,5-Dimethoxyphenyl)-N-[2-(5-methoxy-1H-indol-3-yl)ethyl]-N-methylpropan-1-amine",tryptamine
|
| 368 |
+
C=CCN(CCc1c[nH]c2ccc(F)cc12)C(C)C,5-Fluoro-ALIPT,tryptamine
|
| 369 |
+
NCCc1c[nH]c2ccc(OC3CCCC3)cc12,5-Cyclopentyloxy-T,tryptamine
|
| 370 |
+
COc1ccc(OC)c(CCN(C)CCc2c[nH]c3ccc(OC)cc23)c1,"N-(2,5-Dimethoxyphenylethyl)-5-MeO-NMT",tryptamine
|
| 371 |
+
Oc1cccc2[nH]cc(CCN3CCCCC3)c12,4-HO-pip-T,tryptamine
|
| 372 |
+
CN(C)CCc1c[nH]c2cccc(OCc3ccccc3)c12,4-Benzyloxy-DMT,tryptamine
|
| 373 |
+
CN(C)CCc1c[nH]c2cccc(OC(=O)SCc3ccccc3)c12,S-Benzyl O-{3-[2-(dimethylamino)ethyl]-1H-indol-4-yl} carbonothioate,tryptamine
|
| 374 |
+
COc1cc(OC)c2[nH]cc(CCNCc3ccccc3)c2c1,"5,7-MeO-T-NB",tryptamine
|
| 375 |
+
CNC(C)Cc1c[nH]c2ccc(OCc3ccccc3)cc12,5-Benzyloxy-alpha-methyl-NMT,tryptamine
|
| 376 |
+
CC(C)(C)CCCCCCCOc1ccc2[nH]cc(CCN)c2c1,"5-(8,8-Dimethylnonyloxy)-T",tryptamine
|
| 377 |
+
CCCOc1ccc2[nH]cc(CCN(CC)CC)c2c1,5-PrO-DET,tryptamine
|
| 378 |
+
COc1ccc2[nH]cc(CCN(C)CCCc3cc(OC)c(OC)c(OC)c3)c2c1,"N-(3,4,5-Trimethoxyphenylpropyl)-5-MeO-NMT",tryptamine
|
| 379 |
+
c1ccc2c(CCN3CCN(CCc4c[nH]c5ccccc45)CC3)c[nH]c2c1,"3,3'-[Piperazine-1,4-diyldi(ethane-2,1-diyl)]di(1H-indole)",tryptamine
|
| 380 |
+
CC(C)N(CCc1c[nH]c2cccc(OCc3ccccc3)c12)C(C)C,4-Benzyloxy-DIPT,tryptamine
|
| 381 |
+
CC(C)N(CCc1c[nH]c2ccc(F)cc12)C1CCC1,5-Fluoro-IPCBT,tryptamine
|
| 382 |
+
CCOc1ccc(CNCCc2c[nH]c3ccccc23)cc1,T-NB4OEt,tryptamine
|
| 383 |
+
O=C(O)CCNCCc1c[nH]c2cc([N+](=O)[O-])ccc12,6-Nitro-N-(2-carboxyethyl)tryptamine,tryptamine
|
| 384 |
+
CN1CCN(CCc2c[nH]c3cccc(O)c23)CC1,4'-Methyl-4-HO-piperazine-T,tryptamine
|
| 385 |
+
CN(CCC#N)CCc1c[nH]c2ccccc12,N-Cyanoethyl-NMT,tryptamine
|
| 386 |
+
COc1cc(F)c2[nH]cc(CCN(C)C)c2c1,7-Fluoro-5-MeO-DMT,tryptamine
|
| 387 |
+
CN(CCc1c[nH]c2ccc(F)cc12)C1CCC1,5-Fluoro-MCBT,tryptamine
|
| 388 |
+
CNCCc1c[nH]c2c(OC)cccc12,7-MeO-NMT,tryptamine
|
| 389 |
+
Cc1c(O)c(O)cc2c(CCN)c[nH]c12,"7-Methyl-5,6-HO-T",tryptamine
|
| 390 |
+
Oc1ccc(CNCCc2c[nH]c3ccccc23)cc1,T-NB4OH,tryptamine
|
| 391 |
+
COc1c(Br)cc(Br)cc1CNCCc1c[nH]c2ccccc12,T-NBOMe35Br,tryptamine
|
| 392 |
+
CCn1cc(CCN(C)C)c2c(OCc3ccccc3)cc(F)cc21,1-Ethyl-6-fluoro-4-benzyloxy-DMT,tryptamine
|
| 393 |
+
CN(C)CCc1c[nH]c2cccc(OC(=O)c3cccc(C(=O)Oc4cccc5[nH]cc(CCN(C)C)c45)c3)c12,"Bis{3-[2-(dimethylamino)ethyl]-1H-indol-4-yl} benzene-1,3-dicarboxylate",tryptamine
|
| 394 |
+
CCN(CC)C(=O)CCN(C)CCc1c[nH]c2ccc(OC)cc12,"N,N-Diethyl-N3-[2-(5-methoxy-1H-indol-3-yl)ethyl]-N3-methyl-beta-alaninamide",tryptamine
|
| 395 |
+
COc1ccc(CNCCc2c[nH]c3c(Br)cc(OC)cc23)cc1,7-Bromo-5-MeO-T-NB4OMe,tryptamine
|
| 396 |
+
CCCN(C)CCc1c[nH]c2ccc(F)cc12,5-Fluoro-MPT,tryptamine
|
| 397 |
+
CN(CCc1c[nH]c2cc3c(cc12)OCO3)Cc1ccccc1,"5,6-MDO-NMT-NB",tryptamine
|
| 398 |
+
Cc1c(OC(=O)CCC(=O)O)ccc2[nH]cc(CCN(C)C)c12,Psilocin-4-methyl-5-succinate,tryptamine
|
| 399 |
+
COc1ccc2[nH]cc(CC(C)N)c2c1Br,4-Bromo-5-MeO-AMT,tryptamine
|
| 400 |
+
CN(C)CC(=O)c1c[nH]c2cc(F)ccc12,beta-Oxo-6-fluoro-DMT,tryptamine
|
| 401 |
+
COc1ccc2[nH]cc(C(O)CN(C)C)c2c1,beta-HO-5-MeO-DMT,tryptamine
|
| 402 |
+
COc1cccc2c(CCN)c[nH]c12,7-MeO-T,tryptamine
|
| 403 |
+
COc1cc(I)c2[nH]cc(CCN(C)C)c2c1,7-Iodo-5-MeO-DMT,tryptamine
|
| 404 |
+
C[C@@H]1CC[C@H](C)N1CCc1c[nH]c2ccccc12,"(R,S)-Dimethyl-pyr-T",tryptamine
|
| 405 |
+
COc1ccc(Sn2cc(CCN(C)C)c3c(OC)cccc32)cc1,1-(4-Methoxyphenylthio)-4-MeO-DMT,tryptamine
|
| 406 |
+
CCCN(CCc1c[nH]c2c(F)cccc12)C1CCC1,7-Fluoro-PCBT,tryptamine
|
| 407 |
+
CC(=O)NCCc1c[nH]c2cc(F)cc(NC(C)=O)c12,6-Fluoro-4-acetamido-N-acetyltryptamine,tryptamine
|
| 408 |
+
CCCCS(=O)(=O)n1cc(CCN(C)C)c2c(OC)cccc21,1-Butylsulfonyl-4-MeO-DMT,tryptamine
|
| 409 |
+
CCCN(CCC)CCc1c[nH]c2ccc(OC(C)=O)cc12,5-AcO-DPT,tryptamine
|
| 410 |
+
CN(C)CCc1cn(C)c2ccccc12,1-TMT,tryptamine
|
| 411 |
+
CCN(CCc1c[nH]c2cc(F)c(F)cc12)C(C)C,"5,6-Difluoro-EIPT",tryptamine
|
| 412 |
+
CN(C)CC(=O)c1c[nH]c2c(F)cc(F)cc12,"beta-Oxo-5,7-difluoro-DMT",tryptamine
|
| 413 |
+
CN(C)CCc1cn(C)c2cc(F)cc(OCc3ccccc3)c12,1-Methyl-6-fluoro-4-benzyloxy-DMT,tryptamine
|
| 414 |
+
CCCc1[nH]c2ccc(OC)cc2c1CCN(C)C,2-Propyl-5-MeO-DMT,tryptamine
|
| 415 |
+
CC(=O)Oc2cccc1[nH]cc(CCN(C)C)c12,4-AcO-DMT,tryptamine
|
src/data/sample_smiles.csv
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
smiles,name,category
|
| 2 |
+
CCO,Ethanol,Alcohol
|
| 3 |
+
CC(=O)O,Acetic acid,Carboxylic acid
|
| 4 |
+
c1ccccc1,Benzene,Aromatic hydrocarbon
|
| 5 |
+
CC(C)O,Isopropanol,Alcohol
|
| 6 |
+
c1ccc(cc1)O,Phenol,Aromatic alcohol
|
| 7 |
+
CC(=O)OC1=CC=CC=C1C(=O)O,Aspirin,Carboxylic acid ester
|
| 8 |
+
CN1C=NC2=C1C(=O)N(C(=O)N2C)C,Caffeine,Alkaloid
|
| 9 |
+
CCN(CC)CC,Triethylamine,Amine
|
| 10 |
+
c1ccc2c(c1)cccn2,Quinoline,Aromatic heterocycle
|
| 11 |
+
c1ccc(cc1)N,Aniline,Aromatic amine
|
| 12 |
+
O=P(O)(O)OP(=O)(O)OP(=O)(O)OC[C@H]3O[C@@H](n2cnc1c(ncnc12)N)[C@H](O)[C@@H]3O,ATP,Nucleotide
|
| 13 |
+
CN(C)CCC1=CNC2=C1C(=CC=C2)OP(=O)(O)O,Psilocybin,Tryptamine
|
src/main.js
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview JSME (JavaScript Molecule Editor) integration with Gradio interface
|
| 3 |
+
* Handles bidirectional synchronization between JSME applet and Gradio textbox
|
| 4 |
+
* @author Manny Cortes ('[email protected]')
|
| 5 |
+
* @version 0.2.0
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
// ============================================================================
|
| 9 |
+
// GLOBAL VARIABLES
|
| 10 |
+
// ============================================================================
|
| 11 |
+
|
| 12 |
+
/** @type {Object|null} The JSME applet instance */
|
| 13 |
+
let jsmeApplet = null;
|
| 14 |
+
|
| 15 |
+
/** @type {string} Last known value of the textbox to prevent infinite loops */
|
| 16 |
+
let lastTextboxValue = "";
|
| 17 |
+
|
| 18 |
+
// ============================================================================
|
| 19 |
+
// CONSTANTS
|
| 20 |
+
// ============================================================================
|
| 21 |
+
|
| 22 |
+
/** @const {string} Default SMILES for initial molecule (ethanol) */
|
| 23 |
+
const DEFAULT_SMILES = "CCO";
|
| 24 |
+
|
| 25 |
+
/** @const {string} Container height for JSME applet */
|
| 26 |
+
const CONTAINER_HEIGHT = "450px";
|
| 27 |
+
|
| 28 |
+
/** @const {string} CSS selector for the Gradio SMILES input element */
|
| 29 |
+
const SMILES_INPUT_SELECTOR = "#smiles_input textarea, #smiles_input input";
|
| 30 |
+
|
| 31 |
+
/** @const {number} Delay for paste event handling (ms) */
|
| 32 |
+
const PASTE_DELAY = 50;
|
| 33 |
+
|
| 34 |
+
/** @const {number} Delay for initialization retry (ms) */
|
| 35 |
+
const INIT_RETRY_DELAY = 2000;
|
| 36 |
+
|
| 37 |
+
/** @const {string[]} Events to trigger for Gradio change detection */
|
| 38 |
+
const GRADIO_CHANGE_EVENTS = ["input", "change", "keyup"];
|
| 39 |
+
|
| 40 |
+
// ============================================================================
|
| 41 |
+
// CORE INITIALIZATION
|
| 42 |
+
// ============================================================================
|
| 43 |
+
|
| 44 |
+
/**
|
| 45 |
+
* Initializes the JSME applet after the library has been loaded
|
| 46 |
+
* Sets up the molecular editor with default options and callbacks
|
| 47 |
+
* @throws {Error} When JSME initialization fails
|
| 48 |
+
*/
|
| 49 |
+
function initializeJSME() {
|
| 50 |
+
try {
|
| 51 |
+
console.log("Initializing JSME...");
|
| 52 |
+
// https://github.com/jsme-editor/jsme-editor.github.io
|
| 53 |
+
// https://jsme-editor.github.io/dist/api_javadoc/index.html
|
| 54 |
+
// http://wiki.jmol.org/index.php/Jmol_JavaScript_Object/JME/Options
|
| 55 |
+
jsmeApplet = new JSApplet.JSME(
|
| 56 |
+
"jsme_container",
|
| 57 |
+
getJsmeContainerWidthPx(),
|
| 58 |
+
CONTAINER_HEIGHT,
|
| 59 |
+
{
|
| 60 |
+
options:
|
| 61 |
+
"rButton,zoom,zoomgui,newLook,star,multipart,polarnitro,NOexportInChI,NOexportInChIkey,NOsearchInChIkey,NOexportSVG,NOpaste",
|
| 62 |
+
}
|
| 63 |
+
);
|
| 64 |
+
|
| 65 |
+
jsmeApplet.setCallBack("AfterStructureModified", handleJSMEStructureChange);
|
| 66 |
+
jsmeApplet.setMenuScale(getJsmeGuiScale());
|
| 67 |
+
jsmeApplet.setUserInterfaceBackgroundColor("#adadad");
|
| 68 |
+
|
| 69 |
+
// Set initial molecule and sync state
|
| 70 |
+
jsmeApplet.readGenericMolecularInput(DEFAULT_SMILES);
|
| 71 |
+
lastTextboxValue = DEFAULT_SMILES;
|
| 72 |
+
|
| 73 |
+
setupTextboxEventListeners();
|
| 74 |
+
window.addEventListener("resize", handleResize);
|
| 75 |
+
|
| 76 |
+
console.log("JSME initialized successfully");
|
| 77 |
+
} catch (error) {
|
| 78 |
+
console.error("Error initializing JSME:", error);
|
| 79 |
+
throw error;
|
| 80 |
+
}
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
/**
|
| 84 |
+
* Handles structure changes in the JSME applet
|
| 85 |
+
* Converts the structure to SMILES and updates the Gradio textbox
|
| 86 |
+
* @param {Event} event - The JSME structure modification event
|
| 87 |
+
*/
|
| 88 |
+
function handleJSMEStructureChange(event) {
|
| 89 |
+
try {
|
| 90 |
+
const smiles = jsmeApplet.smiles();
|
| 91 |
+
updateGradioTextbox(smiles);
|
| 92 |
+
} catch (error) {
|
| 93 |
+
console.error("Error getting SMILES from JSME:", error);
|
| 94 |
+
}
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
/**
|
| 98 |
+
* Calculates the appropriate GUI scale for the JSME applet based on container width
|
| 99 |
+
* Uses breakpoints to determine optimal scaling for different screen sizes
|
| 100 |
+
* @returns {number} The scale factor for the JSME GUI (0.88 to 2.0)
|
| 101 |
+
*/
|
| 102 |
+
function getJsmeGuiScale() {
|
| 103 |
+
const width = getJsmeContainerWidthNumber();
|
| 104 |
+
let menuScale;
|
| 105 |
+
if (width > 460) {
|
| 106 |
+
menuScale = 1.3;
|
| 107 |
+
} else if (width > 420) {
|
| 108 |
+
menuScale = 1.1;
|
| 109 |
+
} else if (width > 370) {
|
| 110 |
+
menuScale = 1.05;
|
| 111 |
+
} else if (width > 300) {
|
| 112 |
+
menuScale = 0.88;
|
| 113 |
+
} else {
|
| 114 |
+
menuScale = 2;
|
| 115 |
+
}
|
| 116 |
+
return menuScale;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
/**
|
| 120 |
+
* Gets the JSME container width as a CSS-compatible string value
|
| 121 |
+
* Returns either a pixel value or percentage based on available width
|
| 122 |
+
* @returns {string} Width as "100%" or "{width}px" format
|
| 123 |
+
*/
|
| 124 |
+
function getJsmeContainerWidthPx() {
|
| 125 |
+
const parentWidth = getJsmeContainerWidthNumber();
|
| 126 |
+
if (parentWidth == null || parentWidth <= 0) {
|
| 127 |
+
return "100%";
|
| 128 |
+
}
|
| 129 |
+
return `${parentWidth}px`;
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
/**
|
| 133 |
+
* Gets the numeric width of the JSME container's parent element
|
| 134 |
+
* Used for responsive scaling calculations
|
| 135 |
+
* @returns {number|null} Width in pixels, or null if container not found
|
| 136 |
+
*/
|
| 137 |
+
function getJsmeContainerWidthNumber() {
|
| 138 |
+
const container = document.getElementById("jsme_container");
|
| 139 |
+
if (!container) {
|
| 140 |
+
return null;
|
| 141 |
+
}
|
| 142 |
+
return container.parentNode.offsetWidth;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
// ============================================================================
|
| 146 |
+
// GRADIO INTEGRATION
|
| 147 |
+
// ============================================================================
|
| 148 |
+
|
| 149 |
+
/**
|
| 150 |
+
* Updates the Gradio textbox with a SMILES string
|
| 151 |
+
* Triggers appropriate events to ensure Gradio detects the change
|
| 152 |
+
* @param {string} smiles - The SMILES string to set in the textbox
|
| 153 |
+
*/
|
| 154 |
+
function updateGradioTextbox(smiles) {
|
| 155 |
+
try {
|
| 156 |
+
const textbox = document.querySelector(SMILES_INPUT_SELECTOR);
|
| 157 |
+
|
| 158 |
+
if (!textbox || textbox.value === smiles) {
|
| 159 |
+
return;
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
textbox.value = smiles;
|
| 163 |
+
lastTextboxValue = smiles;
|
| 164 |
+
|
| 165 |
+
// Trigger events to ensure Gradio detects the change
|
| 166 |
+
GRADIO_CHANGE_EVENTS.forEach((eventType) => {
|
| 167 |
+
const event = new Event(eventType, {
|
| 168 |
+
bubbles: true,
|
| 169 |
+
cancelable: true,
|
| 170 |
+
});
|
| 171 |
+
textbox.dispatchEvent(event);
|
| 172 |
+
});
|
| 173 |
+
} catch (error) {
|
| 174 |
+
console.error("Error updating Gradio textbox:", error);
|
| 175 |
+
}
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
// ============================================================================
|
| 179 |
+
// JSME UPDATE FUNCTIONS
|
| 180 |
+
// ============================================================================
|
| 181 |
+
|
| 182 |
+
/**
|
| 183 |
+
* Updates the JSME applet with a SMILES string from the textbox
|
| 184 |
+
* @param {string} smiles - The SMILES string to display in JSME
|
| 185 |
+
*/
|
| 186 |
+
function updateJSMEFromTextbox(smiles) {
|
| 187 |
+
if (!jsmeApplet) {
|
| 188 |
+
return;
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
try {
|
| 192 |
+
if (smiles && smiles.trim() !== "") {
|
| 193 |
+
jsmeApplet.readGenericMolecularInput(smiles.trim());
|
| 194 |
+
} else {
|
| 195 |
+
jsmeApplet.reset();
|
| 196 |
+
}
|
| 197 |
+
lastTextboxValue = smiles;
|
| 198 |
+
} catch (error) {
|
| 199 |
+
console.error("Error updating JSME from textbox:", error);
|
| 200 |
+
}
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
// ============================================================================
|
| 204 |
+
// UI MONITORING
|
| 205 |
+
// ============================================================================
|
| 206 |
+
|
| 207 |
+
/**
|
| 208 |
+
* Finds the textbox element and sets up event listeners
|
| 209 |
+
*/
|
| 210 |
+
function setupTextboxEventListeners() {
|
| 211 |
+
const textbox = document.querySelector(SMILES_INPUT_SELECTOR);
|
| 212 |
+
if (!textbox) {
|
| 213 |
+
return;
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
textbox.addEventListener("input", handleTextboxChange);
|
| 217 |
+
textbox.addEventListener("change", handleTextboxChange);
|
| 218 |
+
textbox.addEventListener("paste", handleTextboxPaste);
|
| 219 |
+
textbox.addEventListener("keyup", handleTextboxChange);
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
/**
|
| 223 |
+
* Handles textbox change events
|
| 224 |
+
* @param {Event} event - The change event
|
| 225 |
+
*/
|
| 226 |
+
function handleTextboxChange(event) {
|
| 227 |
+
if (event.target.value !== lastTextboxValue) {
|
| 228 |
+
updateJSMEFromTextbox(event.target.value);
|
| 229 |
+
}
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
/**
|
| 233 |
+
* Handles textbox paste events with a delay to ensure content is available
|
| 234 |
+
* @param {Event} event - The paste event
|
| 235 |
+
*/
|
| 236 |
+
function handleTextboxPaste(event) {
|
| 237 |
+
setTimeout(() => {
|
| 238 |
+
updateJSMEFromTextbox(event.target.value);
|
| 239 |
+
}, PASTE_DELAY);
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
/**
|
| 243 |
+
* Handles window resize events and updates JSME applet width
|
| 244 |
+
*/
|
| 245 |
+
function handleResize() {
|
| 246 |
+
if (!jsmeApplet) {
|
| 247 |
+
return;
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
try {
|
| 251 |
+
jsmeApplet.setMenuScale(getJsmeGuiScale());
|
| 252 |
+
jsmeApplet.setWidth(getJsmeContainerWidthPx());
|
| 253 |
+
} catch (error) {
|
| 254 |
+
console.error("Error resizing JSME applet:", error);
|
| 255 |
+
}
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
// ============================================================================
|
| 259 |
+
// PUBLIC API
|
| 260 |
+
// ============================================================================
|
| 261 |
+
|
| 262 |
+
/**
|
| 263 |
+
* Sets a SMILES string in both JSME and Gradio textbox
|
| 264 |
+
* @param {string} smiles - The SMILES string to set
|
| 265 |
+
* @returns {string} The SMILES string that was set
|
| 266 |
+
* @public
|
| 267 |
+
*/
|
| 268 |
+
window.setJSMESmiles = function (smiles) {
|
| 269 |
+
if (jsmeApplet) {
|
| 270 |
+
updateJSMEFromTextbox(smiles);
|
| 271 |
+
}
|
| 272 |
+
|
| 273 |
+
updateGradioTextbox(smiles);
|
| 274 |
+
return smiles;
|
| 275 |
+
};
|
| 276 |
+
|
| 277 |
+
/**
|
| 278 |
+
* Clears both JSME and Gradio textbox
|
| 279 |
+
* @returns {Array} Array containing cleared state for Gradio components
|
| 280 |
+
* @public
|
| 281 |
+
*/
|
| 282 |
+
window.clearJSME = function () {
|
| 283 |
+
if (jsmeApplet) {
|
| 284 |
+
jsmeApplet.reset();
|
| 285 |
+
}
|
| 286 |
+
|
| 287 |
+
updateGradioTextbox("");
|
| 288 |
+
return ["", [], [], "Cleared - Draw a new molecule or enter SMILES"];
|
| 289 |
+
};
|
| 290 |
+
|
| 291 |
+
// ============================================================================
|
| 292 |
+
// INITIALIZATION LOGIC
|
| 293 |
+
// ============================================================================
|
| 294 |
+
|
| 295 |
+
/**
|
| 296 |
+
* Checks if JSME library is loaded and initializes JSME applet
|
| 297 |
+
* Retries until the library becomes available
|
| 298 |
+
*/
|
| 299 |
+
function initializeWhenReady() {
|
| 300 |
+
if (typeof JSApplet !== "undefined" && JSApplet.JSME) {
|
| 301 |
+
console.log("JSME library loaded, initializing...");
|
| 302 |
+
initializeJSME();
|
| 303 |
+
} else {
|
| 304 |
+
console.log("JSME library not ready, retrying...");
|
| 305 |
+
setTimeout(initializeWhenReady, INIT_RETRY_DELAY);
|
| 306 |
+
}
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
/**
|
| 310 |
+
* Starts the initialization process based on document ready state
|
| 311 |
+
*/
|
| 312 |
+
function startInitialization() {
|
| 313 |
+
if (document.readyState === "loading") {
|
| 314 |
+
document.addEventListener("DOMContentLoaded", () => {
|
| 315 |
+
setTimeout(initializeWhenReady, INIT_RETRY_DELAY);
|
| 316 |
+
});
|
| 317 |
+
} else {
|
| 318 |
+
setTimeout(initializeWhenReady, INIT_RETRY_DELAY);
|
| 319 |
+
}
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
startInitialization();
|
src/main.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
function initializeJSME(){try{(jsmeApplet=new JSApplet.JSME("jsme_container",getJsmeContainerWidthPx(),CONTAINER_HEIGHT,{options:"rButton,zoom,zoomgui,newLook,star,multipart,polarnitro,NOexportInChI,NOexportInChIkey,NOsearchInChIkey,NOexportSVG,NOpaste"})).setCallBack("AfterStructureModified",handleJSMEStructureChange),jsmeApplet.setMenuScale(getJsmeGuiScale()),jsmeApplet.setUserInterfaceBackgroundColor("#adadad"),jsmeApplet.readGenericMolecularInput(DEFAULT_SMILES),lastTextboxValue=DEFAULT_SMILES,setupTextboxEventListeners(),window.addEventListener("resize",handleResize)}catch(e){throw e}}function handleJSMEStructureChange(){try{updateGradioTextbox(jsmeApplet.smiles())}catch(e){}}function getJsmeGuiScale(){const e=getJsmeContainerWidthNumber();return e>460?1.3:e>420?1.1:e>370?1.05:e>300?.88:2}function getJsmeContainerWidthPx(){const e=getJsmeContainerWidthNumber();return null==e||e<=0?"100%":`${e}px`}function getJsmeContainerWidthNumber(){const e=document.getElementById("jsme_container");return e?e.parentNode.offsetWidth:null}function updateGradioTextbox(e){try{const t=document.querySelector(SMILES_INPUT_SELECTOR);if(!t||t.value===e)return;t.value=e,lastTextboxValue=e,GRADIO_CHANGE_EVENTS.forEach(e=>{const n=new Event(e,{bubbles:!0,cancelable:!0});t.dispatchEvent(n)})}catch(e){}}function updateJSMEFromTextbox(e){if(jsmeApplet)try{e&&""!==e.trim()?jsmeApplet.readGenericMolecularInput(e.trim()):jsmeApplet.reset(),lastTextboxValue=e}catch(e){}}function setupTextboxEventListeners(){const e=document.querySelector(SMILES_INPUT_SELECTOR);e&&(e.addEventListener("input",handleTextboxChange),e.addEventListener("change",handleTextboxChange),e.addEventListener("paste",handleTextboxPaste),e.addEventListener("keyup",handleTextboxChange))}function handleTextboxChange(e){e.target.value!==lastTextboxValue&&updateJSMEFromTextbox(e.target.value)}function handleTextboxPaste(e){setTimeout(()=>{updateJSMEFromTextbox(e.target.value)},PASTE_DELAY)}function handleResize(){if(jsmeApplet)try{jsmeApplet.setMenuScale(getJsmeGuiScale()),jsmeApplet.setWidth(getJsmeContainerWidthPx())}catch(e){}}function initializeWhenReady(){"undefined"!=typeof JSApplet&&JSApplet.JSME?initializeJSME():setTimeout(initializeWhenReady,INIT_RETRY_DELAY)}function startInitialization(){"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{setTimeout(initializeWhenReady,INIT_RETRY_DELAY)}):setTimeout(initializeWhenReady,INIT_RETRY_DELAY)}let jsmeApplet=null,lastTextboxValue="";const DEFAULT_SMILES="CCO",CONTAINER_HEIGHT="450px",SMILES_INPUT_SELECTOR="#smiles_input textarea, #smiles_input input",PASTE_DELAY=50,INIT_RETRY_DELAY=2e3,GRADIO_CHANGE_EVENTS=["input","change","keyup"];window.setJSMESmiles=function(e){return jsmeApplet&&updateJSMEFromTextbox(e),updateGradioTextbox(e),e},window.clearJSME=function(){return jsmeApplet&&jsmeApplet.reset(),updateGradioTextbox(""),["",[],[],"Cleared - Draw a new molecule or enter SMILES"]},startInitialization();
|
src/service.py
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import logging
|
| 2 |
+
import os
|
| 3 |
+
from typing import TypedDict
|
| 4 |
+
|
| 5 |
+
import numpy as np
|
| 6 |
+
import pandas as pd
|
| 7 |
+
import redis
|
| 8 |
+
from chem_mrl.molecular_fingerprinter import MorganFingerprinter
|
| 9 |
+
from dotenv import load_dotenv
|
| 10 |
+
from redis.commands.search.field import TextField, VectorField
|
| 11 |
+
from redis.commands.search.indexDefinition import IndexDefinition, IndexType
|
| 12 |
+
from redis.commands.search.query import Query
|
| 13 |
+
from sentence_transformers import SentenceTransformer
|
| 14 |
+
|
| 15 |
+
from constants import (
|
| 16 |
+
EMBEDDING_DIMENSION,
|
| 17 |
+
HNSW_K,
|
| 18 |
+
HNSW_PARAMETERS,
|
| 19 |
+
MODEL_NAME,
|
| 20 |
+
SUPPORTED_EMBEDDING_DIMENSIONS,
|
| 21 |
+
)
|
| 22 |
+
from data import DATASET_SMILES, ISOMER_DESIGN_SUBSET
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def setup_logger(clear_handler=False):
|
| 26 |
+
if clear_handler:
|
| 27 |
+
for handler in logging.root.handlers[:]:
|
| 28 |
+
logging.root.removeHandler(handler) # issue with sentence-transformer's logging handler
|
| 29 |
+
logging.basicConfig(format="%(asctime)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S", level=logging.INFO)
|
| 30 |
+
logger = logging.getLogger(__name__)
|
| 31 |
+
return logger
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
load_dotenv("../.env")
|
| 35 |
+
logger = setup_logger(clear_handler=True)
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
class SimilarMolecule(TypedDict):
|
| 39 |
+
smiles: str
|
| 40 |
+
name: str
|
| 41 |
+
category: str
|
| 42 |
+
score: float
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
class MolecularEmbeddingService:
|
| 46 |
+
def __init__(self):
|
| 47 |
+
self.model_name = MODEL_NAME
|
| 48 |
+
self.index_name = "molecule_embeddings"
|
| 49 |
+
self.model_embed_dim = EMBEDDING_DIMENSION
|
| 50 |
+
|
| 51 |
+
self.model = self._initialize_model()
|
| 52 |
+
self.redis_client = self._initialize_redis()
|
| 53 |
+
self._initialize_datastore()
|
| 54 |
+
|
| 55 |
+
def _initialize_model(self):
|
| 56 |
+
"""Initialize the Hugging Face transformers model"""
|
| 57 |
+
try:
|
| 58 |
+
model = SentenceTransformer(self.model_name) # type: ignore
|
| 59 |
+
model.eval()
|
| 60 |
+
return model
|
| 61 |
+
except Exception as e:
|
| 62 |
+
logger.error(f"Failed to load model: {e}")
|
| 63 |
+
raise
|
| 64 |
+
|
| 65 |
+
def _initialize_redis(self):
|
| 66 |
+
"""Initialize Redis connection"""
|
| 67 |
+
try:
|
| 68 |
+
redis_host = os.getenv("REDIS_HOST", "localhost")
|
| 69 |
+
redis_port = int(os.getenv("REDIS_PORT", 6379))
|
| 70 |
+
redis_password = os.getenv("REDIS_PASSWORD", None)
|
| 71 |
+
logger.info(
|
| 72 |
+
f"Connecting to Redis at {redis_host}:{redis_port} with password: {'***' if redis_password else 'None'}"
|
| 73 |
+
)
|
| 74 |
+
redis_client = redis.Redis(
|
| 75 |
+
host=redis_host,
|
| 76 |
+
port=redis_port,
|
| 77 |
+
password=redis_password,
|
| 78 |
+
decode_responses=True,
|
| 79 |
+
)
|
| 80 |
+
redis_client.ping()
|
| 81 |
+
return redis_client
|
| 82 |
+
except Exception as e:
|
| 83 |
+
logger.error(f"Failed to connect to Redis: {e}")
|
| 84 |
+
raise
|
| 85 |
+
|
| 86 |
+
def _initialize_datastore(self):
|
| 87 |
+
self.__create_hnsw_index()
|
| 88 |
+
self.__populate_sample_data(DATASET_SMILES)
|
| 89 |
+
self.__populate_sample_data(ISOMER_DESIGN_SUBSET)
|
| 90 |
+
|
| 91 |
+
def __create_hnsw_index(self):
|
| 92 |
+
"""Create HNSW index for molecular embeddings"""
|
| 93 |
+
try:
|
| 94 |
+
self.redis_client.ft(self.index_name).info()
|
| 95 |
+
logger.info(f"Index {self.index_name} already exists")
|
| 96 |
+
return
|
| 97 |
+
except redis.exceptions.ResponseError:
|
| 98 |
+
pass
|
| 99 |
+
|
| 100 |
+
try:
|
| 101 |
+
schema: list[TextField | VectorField] = [
|
| 102 |
+
VectorField(
|
| 103 |
+
self.embedding_field_name(dim),
|
| 104 |
+
"HNSW",
|
| 105 |
+
{
|
| 106 |
+
**HNSW_PARAMETERS,
|
| 107 |
+
"DIM": dim,
|
| 108 |
+
},
|
| 109 |
+
)
|
| 110 |
+
for dim in SUPPORTED_EMBEDDING_DIMENSIONS
|
| 111 |
+
]
|
| 112 |
+
schema.insert(0, TextField("smiles"))
|
| 113 |
+
|
| 114 |
+
self.redis_client.ft(self.index_name).create_index(
|
| 115 |
+
schema,
|
| 116 |
+
definition=IndexDefinition(prefix=[self.molecule_index_prefix("")], index_type=IndexType.HASH),
|
| 117 |
+
)
|
| 118 |
+
|
| 119 |
+
logger.info(f"Created HNSW index: {self.index_name}")
|
| 120 |
+
|
| 121 |
+
except Exception as e:
|
| 122 |
+
logger.error(f"Failed to create HNSW index: {e}")
|
| 123 |
+
raise
|
| 124 |
+
|
| 125 |
+
def __populate_sample_data(self, df: pd.DataFrame):
|
| 126 |
+
"""Populate Redis with sample molecular data"""
|
| 127 |
+
logger.info("Populating Redis with sample molecular data...")
|
| 128 |
+
for _, row in df.iterrows():
|
| 129 |
+
try:
|
| 130 |
+
key = self.molecule_index_prefix(row["smiles"])
|
| 131 |
+
if self.redis_client.exists(key):
|
| 132 |
+
continue
|
| 133 |
+
|
| 134 |
+
mapping: dict[str, bytes | str] = {
|
| 135 |
+
self.embedding_field_name(embed_dim): self.get_molecular_embedding(
|
| 136 |
+
row["smiles"], embed_dim
|
| 137 |
+
).tobytes()
|
| 138 |
+
for embed_dim in SUPPORTED_EMBEDDING_DIMENSIONS
|
| 139 |
+
}
|
| 140 |
+
mapping = {**mapping, **row.to_dict()}
|
| 141 |
+
|
| 142 |
+
self.redis_client.hset(
|
| 143 |
+
key,
|
| 144 |
+
mapping=mapping,
|
| 145 |
+
)
|
| 146 |
+
|
| 147 |
+
except Exception as e:
|
| 148 |
+
logger.error(f"Failed to process molecule {row}: {e}")
|
| 149 |
+
continue
|
| 150 |
+
|
| 151 |
+
logger.info(f"Populated {len(df)} sample molecules")
|
| 152 |
+
|
| 153 |
+
def get_molecular_embedding(self, smiles: str, embed_dim: int) -> np.ndarray:
|
| 154 |
+
"""Generate molecular embedding using ChemMRL"""
|
| 155 |
+
try:
|
| 156 |
+
if embed_dim <= 0:
|
| 157 |
+
raise ValueError("embed_dim must be positive")
|
| 158 |
+
|
| 159 |
+
# Preprocess smiles similarly as training data for optimal performance
|
| 160 |
+
smiles = MorganFingerprinter.canonicalize_smiles(smiles) or smiles
|
| 161 |
+
|
| 162 |
+
embedding: np.ndarray = self.model.encode(
|
| 163 |
+
[smiles],
|
| 164 |
+
show_progress_bar=False,
|
| 165 |
+
convert_to_numpy=True,
|
| 166 |
+
)[0]
|
| 167 |
+
|
| 168 |
+
return self._truncate_and_normalize_embedding(embedding, embed_dim)
|
| 169 |
+
|
| 170 |
+
except Exception as e:
|
| 171 |
+
logger.error(f"Failed to generate embedding for {smiles}: {e}")
|
| 172 |
+
raise
|
| 173 |
+
|
| 174 |
+
def _truncate_and_normalize_embedding(self, embedding: np.ndarray, embed_dim: int) -> np.ndarray:
|
| 175 |
+
"""Truncate and normalize embedding"""
|
| 176 |
+
if embed_dim < len(embedding):
|
| 177 |
+
embedding = embedding[:embed_dim]
|
| 178 |
+
norms = np.linalg.norm(embedding, ord=2, keepdims=True)
|
| 179 |
+
return embedding / np.where(norms == 0, 1, norms)
|
| 180 |
+
|
| 181 |
+
def find_similar_molecules(
|
| 182 |
+
self, query_embedding: np.ndarray, embed_dim: int, k: int = HNSW_K
|
| 183 |
+
) -> list[SimilarMolecule]:
|
| 184 |
+
"""Find k most similar molecules using HNSW"""
|
| 185 |
+
try:
|
| 186 |
+
query_vector = query_embedding.astype(np.float32).tobytes()
|
| 187 |
+
query = (
|
| 188 |
+
Query(f"*=>[KNN {k} @{self.embedding_field_name(embed_dim)} $vec AS score]")
|
| 189 |
+
.sort_by("score")
|
| 190 |
+
.return_fields("smiles", "name", "category", "score")
|
| 191 |
+
.dialect(2)
|
| 192 |
+
)
|
| 193 |
+
|
| 194 |
+
results = self.redis_client.ft(self.index_name).search(query, query_params={"vec": query_vector})
|
| 195 |
+
|
| 196 |
+
neighbors: list[SimilarMolecule] = [
|
| 197 |
+
{"smiles": doc.smiles, "name": doc.name, "category": doc.category, "score": float(doc.score)}
|
| 198 |
+
for doc in results.docs
|
| 199 |
+
]
|
| 200 |
+
|
| 201 |
+
return neighbors
|
| 202 |
+
|
| 203 |
+
except Exception as e:
|
| 204 |
+
logger.error(f"Failed to find similar molecules: {e}")
|
| 205 |
+
return []
|
| 206 |
+
|
| 207 |
+
@staticmethod
|
| 208 |
+
def embedding_field_name(dim: int) -> str:
|
| 209 |
+
return f"embedding_{dim}"
|
| 210 |
+
|
| 211 |
+
@staticmethod
|
| 212 |
+
def molecule_index_prefix(smiles: str) -> str:
|
| 213 |
+
return f"mol:{smiles}"
|
src/src/app.py
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import numpy as np
|
| 3 |
+
import pandas as pd
|
| 4 |
+
from rdkit import Chem
|
| 5 |
+
from rdkit.Chem import Draw
|
| 6 |
+
from rdkit.Chem.Draw import rdMolDraw2D
|
| 7 |
+
|
| 8 |
+
from constants import EMBEDDING_DIMENSION, LAUNCH_PARAMETERS, SUPPORTED_EMBEDDING_DIMENSIONS
|
| 9 |
+
from data import SAMPLE_SMILES
|
| 10 |
+
from service import MolecularEmbeddingService, SimilarMolecule, setup_logger
|
| 11 |
+
|
| 12 |
+
logger = setup_logger()
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class App:
|
| 16 |
+
def __init__(self):
|
| 17 |
+
self.embedding_service = MolecularEmbeddingService()
|
| 18 |
+
self.demo = self.create_gradio_interface()
|
| 19 |
+
|
| 20 |
+
def molecule_similarity_search_pipeline(
|
| 21 |
+
self, smiles: str, embed_dim: int
|
| 22 |
+
) -> tuple[list[float], list[SimilarMolecule], str]:
|
| 23 |
+
"""Complete pipeline: SMILES -> Canonical SMILES -> Embedding -> Similar molecules"""
|
| 24 |
+
try:
|
| 25 |
+
if not smiles or smiles.strip() == "":
|
| 26 |
+
return [], [], "Please provide a valid SMILES string"
|
| 27 |
+
|
| 28 |
+
logger.info(f"Running similarity search: {smiles} - ({embed_dim})")
|
| 29 |
+
embedding = self.embedding_service.get_molecular_embedding(smiles, embed_dim)
|
| 30 |
+
neighbors = self.embedding_service.find_similar_molecules(embedding, embed_dim)
|
| 31 |
+
|
| 32 |
+
return embedding.tolist(), neighbors, "Search completed successfully"
|
| 33 |
+
|
| 34 |
+
except Exception as e:
|
| 35 |
+
error_msg = f"Search failed: {str(e)}"
|
| 36 |
+
logger.error(error_msg)
|
| 37 |
+
return [], [], error_msg
|
| 38 |
+
|
| 39 |
+
@staticmethod
|
| 40 |
+
def _truncated_attribute(obj, attr, max_len=45):
|
| 41 |
+
return f"{obj[attr][:max_len]}{'...' if len(obj[attr]) > max_len else ''}"
|
| 42 |
+
|
| 43 |
+
@classmethod
|
| 44 |
+
def _draw_molecule_grid(cls, similar: list[SimilarMolecule]) -> np.ndarray:
|
| 45 |
+
mols = [Chem.MolFromSmiles(m["smiles"]) for m in similar]
|
| 46 |
+
legends = [
|
| 47 |
+
f"{cls._truncated_attribute(m, 'name')}\n{m['category']}\n"
|
| 48 |
+
f"{cls._truncated_attribute(m, 'smiles')}\n({m['score']:.2E})"
|
| 49 |
+
for m in similar
|
| 50 |
+
]
|
| 51 |
+
|
| 52 |
+
draw_options = rdMolDraw2D.MolDrawOptions()
|
| 53 |
+
draw_options.legendFontSize = 17
|
| 54 |
+
draw_options.legendFraction = 0.29
|
| 55 |
+
draw_options.drawMolsSameScale = False
|
| 56 |
+
|
| 57 |
+
img = Draw.MolsToGridImage(
|
| 58 |
+
mols,
|
| 59 |
+
legends=legends,
|
| 60 |
+
molsPerRow=2,
|
| 61 |
+
subImgSize=(250, 250),
|
| 62 |
+
drawOptions=draw_options,
|
| 63 |
+
)
|
| 64 |
+
return img
|
| 65 |
+
|
| 66 |
+
@staticmethod
|
| 67 |
+
def _display_sample_molecules(mols: pd.DataFrame):
|
| 68 |
+
for _, row in mols.iterrows():
|
| 69 |
+
with gr.Group():
|
| 70 |
+
gr.Textbox(value=row["smiles"], label=f"{row['name']} ({row['category']})", interactive=False, scale=3)
|
| 71 |
+
sample_btn = gr.Button(
|
| 72 |
+
f"Load {row['name']}",
|
| 73 |
+
scale=1,
|
| 74 |
+
size="sm",
|
| 75 |
+
variant="primary",
|
| 76 |
+
)
|
| 77 |
+
sample_btn.click(
|
| 78 |
+
fn=None,
|
| 79 |
+
js=f"() => {{window.setJSMESmiles('{row['smiles']}');}}",
|
| 80 |
+
)
|
| 81 |
+
|
| 82 |
+
@staticmethod
|
| 83 |
+
def clear_all():
|
| 84 |
+
return "", [], [], None, "Cleared - Draw a new molecule or enter SMILES"
|
| 85 |
+
|
| 86 |
+
def handle_search(self, smiles: str, embed_dim: int):
|
| 87 |
+
if not smiles.strip():
|
| 88 |
+
return (
|
| 89 |
+
[],
|
| 90 |
+
[],
|
| 91 |
+
None,
|
| 92 |
+
"Please draw a molecule or enter a SMILES string",
|
| 93 |
+
)
|
| 94 |
+
embedding, similar, status = self.molecule_similarity_search_pipeline(smiles, embed_dim)
|
| 95 |
+
img = self._draw_molecule_grid(similar)
|
| 96 |
+
return embedding, similar, img, status
|
| 97 |
+
|
| 98 |
+
def create_gradio_interface(self):
|
| 99 |
+
"""Create the Gradio interface optimized for JavaScript client usage"""
|
| 100 |
+
head_scripts = """
|
| 101 |
+
<link rel="preconnect" href="https://jsme-editor.github.io">
|
| 102 |
+
<link rel="preload" href="https://jsme-editor.github.io/dist/jsme/jsme.nocache.js" as="script" crossorigin="anonymous">
|
| 103 |
+
<link rel="preload" href="gradio_api/file=src/main.min.js" as="script">
|
| 104 |
+
<script type="text/javascript" src="https://jsme-editor.github.io/dist/jsme/jsme.nocache.js" crossorigin="anonymous" defer></script>
|
| 105 |
+
<script type="text/javascript" src="gradio_api/file=src/main.min.js" defer></script>
|
| 106 |
+
"""
|
| 107 |
+
|
| 108 |
+
with gr.Blocks(
|
| 109 |
+
title="Chem-MRL: Molecular Similarity Search Demo",
|
| 110 |
+
theme=gr.themes.Soft(),
|
| 111 |
+
head=head_scripts,
|
| 112 |
+
) as demo:
|
| 113 |
+
gr.Markdown("""
|
| 114 |
+
# 🧪 Chem-MRL: Molecular Similarity Search Demo
|
| 115 |
+
|
| 116 |
+
Use the JSME editor to draw a molecule or input a SMILES string.
|
| 117 |
+
The backend encodes the molecule using the Chem-MRL model to produce a vector embedding.
|
| 118 |
+
Similarity search is performed via an HNSW-indexed Redis vector store to retrieve closest matches.<br/>
|
| 119 |
+
|
| 120 |
+
[Model Repo](https://github.com/emapco/chem-mrl) | [Demo Repo](https://github.com/emapco/chem-mrl-demo)
|
| 121 |
+
""")
|
| 122 |
+
with gr.Tab("🔬 Molecular Search"), gr.Row():
|
| 123 |
+
with gr.Column(scale=1):
|
| 124 |
+
gr.Markdown("### Molecule Input")
|
| 125 |
+
gr.HTML("<div id='jsme_container'></div>")
|
| 126 |
+
|
| 127 |
+
smiles_input = gr.Textbox(
|
| 128 |
+
label="SMILES String",
|
| 129 |
+
placeholder="Draw a molecule above or enter SMILES here (e.g., CCO for ethanol)",
|
| 130 |
+
lines=2,
|
| 131 |
+
elem_id="smiles_input",
|
| 132 |
+
)
|
| 133 |
+
|
| 134 |
+
embedding_dimension = gr.Dropdown(
|
| 135 |
+
choices=SUPPORTED_EMBEDDING_DIMENSIONS,
|
| 136 |
+
value=EMBEDDING_DIMENSION,
|
| 137 |
+
label="Embedding Dimension",
|
| 138 |
+
elem_id="embedding_dimension",
|
| 139 |
+
)
|
| 140 |
+
|
| 141 |
+
with gr.Row():
|
| 142 |
+
search_btn = gr.Button(
|
| 143 |
+
"🔍 Search Molecule Database",
|
| 144 |
+
variant="primary",
|
| 145 |
+
elem_id="search_btn",
|
| 146 |
+
)
|
| 147 |
+
clear_btn = gr.Button("🗑️ Clear All", variant="secondary")
|
| 148 |
+
|
| 149 |
+
with gr.Column(scale=1):
|
| 150 |
+
gr.Markdown("### Search Results")
|
| 151 |
+
status_output = gr.Textbox(
|
| 152 |
+
label="Status",
|
| 153 |
+
interactive=False,
|
| 154 |
+
elem_id="status_output",
|
| 155 |
+
value="Ready - Draw a molecule or enter SMILES",
|
| 156 |
+
)
|
| 157 |
+
|
| 158 |
+
with gr.Accordion("Molecular Embedding Vector", open=False):
|
| 159 |
+
embedding_output = gr.JSON(
|
| 160 |
+
label="Molecular Embedding",
|
| 161 |
+
elem_id="embedding_output",
|
| 162 |
+
)
|
| 163 |
+
|
| 164 |
+
with gr.Accordion("Similar Molecules Response", open=False):
|
| 165 |
+
similar_molecules_output = gr.JSON(
|
| 166 |
+
label="API Response",
|
| 167 |
+
elem_id="similar_molecules_output",
|
| 168 |
+
)
|
| 169 |
+
|
| 170 |
+
molecule_image = gr.Image(label="Similiar Molecules Grid", type="pil")
|
| 171 |
+
|
| 172 |
+
with gr.Tab("📊 Sample Molecules"):
|
| 173 |
+
gr.Markdown("""
|
| 174 |
+
### Sample Molecules in Database
|
| 175 |
+
Click any button below to load the molecule into the JSME editor:
|
| 176 |
+
""")
|
| 177 |
+
|
| 178 |
+
with gr.Row():
|
| 179 |
+
with gr.Column(scale=1):
|
| 180 |
+
self._display_sample_molecules(SAMPLE_SMILES[::3])
|
| 181 |
+
with gr.Column(scale=1):
|
| 182 |
+
self._display_sample_molecules(SAMPLE_SMILES[1::3])
|
| 183 |
+
with gr.Column(scale=1):
|
| 184 |
+
self._display_sample_molecules(SAMPLE_SMILES[2::3])
|
| 185 |
+
|
| 186 |
+
search_btn.click(
|
| 187 |
+
fn=self.handle_search,
|
| 188 |
+
inputs=[smiles_input, embedding_dimension],
|
| 189 |
+
outputs=[
|
| 190 |
+
embedding_output,
|
| 191 |
+
similar_molecules_output,
|
| 192 |
+
molecule_image,
|
| 193 |
+
status_output,
|
| 194 |
+
],
|
| 195 |
+
api_name="molecule_similarity_search_pipeline",
|
| 196 |
+
)
|
| 197 |
+
|
| 198 |
+
# Clear UI state
|
| 199 |
+
clear_btn.click(
|
| 200 |
+
fn=self.clear_all,
|
| 201 |
+
js="window.clearJSME",
|
| 202 |
+
outputs=[
|
| 203 |
+
smiles_input,
|
| 204 |
+
embedding_output,
|
| 205 |
+
similar_molecules_output,
|
| 206 |
+
molecule_image,
|
| 207 |
+
status_output,
|
| 208 |
+
],
|
| 209 |
+
)
|
| 210 |
+
|
| 211 |
+
gr.set_static_paths(paths=["src/"])
|
| 212 |
+
|
| 213 |
+
return demo
|
| 214 |
+
|
| 215 |
+
|
| 216 |
+
if __name__ == "__main__":
|
| 217 |
+
app = App()
|
| 218 |
+
app.demo.launch(**LAUNCH_PARAMETERS)
|
src/src/constants.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Model config
|
| 2 |
+
MODEL_NAME = "Derify/ChemMRL-alpha"
|
| 3 |
+
SUPPORTED_EMBEDDING_DIMENSIONS = [1024, 768, 512, 256, 128, 64, 32, 16, 8, 4, 2]
|
| 4 |
+
EMBEDDING_DIMENSION = max(SUPPORTED_EMBEDDING_DIMENSIONS)
|
| 5 |
+
|
| 6 |
+
# HNSW index parameters
|
| 7 |
+
HNSW_K = 6
|
| 8 |
+
HNSW_PARAMETERS = {
|
| 9 |
+
# Embedding vector dtype
|
| 10 |
+
"TYPE": "FLOAT32",
|
| 11 |
+
# Embedding vectors are normalized so COSINE and IP are equivalent
|
| 12 |
+
"DISTANCE_METRIC": "IP",
|
| 13 |
+
# Defines the initial capacity of the vector index. It helps in pre-allocating space for the index.
|
| 14 |
+
"INITIAL_CAP": 440,
|
| 15 |
+
# Max number of outgoing edges (connections) for each node in a graph layer.
|
| 16 |
+
"M": 32,
|
| 17 |
+
# Max number of connected neighbors to consider during graph building.
|
| 18 |
+
# Higher values increase accuracy, but also increase index build time.
|
| 19 |
+
"EF_CONSTRUCTION": 512,
|
| 20 |
+
# Max top candidates during KNN search. Higher values increase accuracy, but also increase search latency.
|
| 21 |
+
"EF_RUNTIME": 10,
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
# Gradio launch parameters
|
| 25 |
+
LAUNCH_PARAMETERS = {
|
| 26 |
+
"server_name": "0.0.0.0",
|
| 27 |
+
"server_port": 7860,
|
| 28 |
+
"share": True,
|
| 29 |
+
"debug": False,
|
| 30 |
+
"show_api": False,
|
| 31 |
+
"pwa": True,
|
| 32 |
+
"mcp_server": False,
|
| 33 |
+
}
|
src/src/data.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
|
| 3 |
+
import pandas as pd
|
| 4 |
+
|
| 5 |
+
__data_dir = os.path.join(os.path.dirname(__file__), "data")
|
| 6 |
+
|
| 7 |
+
__dataset_smiles_file = os.path.join(__data_dir, "dataset_smiles.csv")
|
| 8 |
+
__sample_smiles_file = os.path.join(__data_dir, "sample_smiles.csv")
|
| 9 |
+
__isomer_design_subset_file = os.path.join(__data_dir, "isomer_design_subset.csv")
|
| 10 |
+
|
| 11 |
+
DATASET_SMILES = pd.read_csv(__dataset_smiles_file)
|
| 12 |
+
SAMPLE_SMILES = pd.read_csv(__sample_smiles_file)
|
| 13 |
+
ISOMER_DESIGN_SUBSET = pd.read_csv(__isomer_design_subset_file)
|
src/src/data/dataset_smiles.csv
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
smiles,name,category
|
| 2 |
+
CCO,Ethanol,Alcohol
|
| 3 |
+
CC(=O)O,Acetic acid,Carboxylic acid
|
| 4 |
+
c1ccccc1,Benzene,Aromatic hydrocarbon
|
| 5 |
+
CC(C)O,Isopropanol,Alcohol
|
| 6 |
+
CCN(CC)CC,Triethylamine,Amine
|
| 7 |
+
c1ccc(cc1)O,Phenol,Aromatic alcohol
|
| 8 |
+
CC(=O)OC1=CC=CC=C1C(=O)O,Aspirin,Carboxylic acid ester
|
| 9 |
+
CN1C=NC2=C1C(=O)N(C(=O)N2C)C,Caffeine,Alkaloid
|
| 10 |
+
CC(C)(C)OC(=O)NC1CCC(CC1)O,Boc-protected cyclohexanol,Protected alcohol
|
| 11 |
+
CCCCCCCCCCCCCCC(=O)O,Palmitic acid,Fatty acid
|
| 12 |
+
c1ccc2c(c1)cccn2,Quinoline,Aromatic heterocycle
|
| 13 |
+
CC1=CC=C(C=C1)C,p-Xylene,Aromatic hydrocarbon
|
| 14 |
+
CCCCO,Butanol,Alcohol
|
| 15 |
+
CC(C)C,Isobutane,Alkane
|
| 16 |
+
c1ccc(cc1)N,Aniline,Aromatic amine
|
| 17 |
+
CC(=O)N,Acetamide,Amide
|
| 18 |
+
CCCCCCCCCCCCCCCCCC(=O)O,Stearic acid,Fatty acid
|
| 19 |
+
c1ccc(cc1)C(=O)O,Benzoic acid,Aromatic carboxylic acid
|
| 20 |
+
CCc1ccccc1,Ethylbenzene,Aromatic hydrocarbon
|
| 21 |
+
CC(C)CC(C)(C)C,"2,2,4-Trimethylpentane",Branched alkane
|
| 22 |
+
O=C1c2ccccc2C(=O)N1C3CCC(=O)NC3=O,Thalidomide,Phthalimides
|
src/src/data/isomer_design_subset.csv
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
smiles,name,category
|
| 2 |
+
O=C1CCCCC1(c1ccccc1Cl)N1CCCCC1,2-Cl-2'-Oxo-PCP,arylcycloalkylamine
|
| 3 |
+
CCCCNC1(c2ccccc2)CCCCC1,PCB,arylcycloalkylamine
|
| 4 |
+
COc1ccccc1C1(N2CCCCC2)CCCCC1,2-MeO-PCP,arylcycloalkylamine
|
| 5 |
+
c1ccc(C2(n3cccc3)CCCCC2)cc1,PCPyrrole,arylcycloalkylamine
|
| 6 |
+
Fc1cccc(C2(N3CCCC3)CC3CCC2C3)c1,3F-PBCHPy,arylcycloalkylamine
|
| 7 |
+
COc1ccc(C2(NCC3CCCO3)CCCCC2)cc1,1-(4-Methoxyphenyl)-N-[(oxolan-2-yl)methyl]cyclohexan-1-amine,arylcycloalkylamine
|
| 8 |
+
COc1ccc(C2(N3CCCC3)CC3CCC2C3)cc1,4-MeO-PBCHPy,arylcycloalkylamine
|
| 9 |
+
C=CCN(CC)C1(c2ccccc2)CCCCC1,N-Allyl-PCE,arylcycloalkylamine
|
| 10 |
+
CCCCCNC1(c2ccccc2)CCCCC1,PCPe,arylcycloalkylamine
|
| 11 |
+
OC1CCCCC1(c1ccccc1)N1CCCCC1,2'-HO-PCP,arylcycloalkylamine
|
| 12 |
+
Cc1ccccc1C1(N2CCCC(O)C2)CCCCC1,3″-HO-2-Me-PCP,arylcycloalkylamine
|
| 13 |
+
c1ccc(C2(N3CCCCC3)CCCC2)cc1,PCPEP,arylcycloalkylamine
|
| 14 |
+
CCN(C)C1(c2ccccc2C)CCCCC1,2-Me-PCEM,arylcycloalkylamine
|
| 15 |
+
Fc1ccccc1C1(N2CCCC2)CC2CCC1C2,2F-PBCHPy,arylcycloalkylamine
|
| 16 |
+
CC(C)OCCCNC1(c2ccccc2)CCCCC1,1-Phenyl-N-{3-[(propan-2-yl)oxy]propyl}cyclohexan-1-amine,arylcycloalkylamine
|
| 17 |
+
CCNC1(c2ccc(C)cc2)CCCCC1,4-Me-PCE,arylcycloalkylamine
|
| 18 |
+
CCNC1(c2cccc(OC)c2)CCCCC1=O,MXE,arylcycloalkylamine
|
| 19 |
+
CCOC(=O)CCCN(C)C1(c2ccccc2Cl)CCCCC1=O,Et-KE-Bu,arylcycloalkylamine
|
| 20 |
+
CCNC1(c2ccccc2)CCCCC1,PCE,arylcycloalkylamine
|
| 21 |
+
c1cc2c(cc1C1(N3CCOCC3)CCCCC1)OCO2,"3,4-MD-PCMo",arylcycloalkylamine
|
| 22 |
+
OCCNC1(c2ccccc2)CCCCC1,PCEOH,arylcycloalkylamine
|
| 23 |
+
c1ccc(C2(N3CCCCC3)CCCCCCC2)cc1,PCOP,arylcycloalkylamine
|
| 24 |
+
COc1ccc(C2(N3CCCCC3)CC3CCC2C3)cc1,4-MeO-PBCHP,arylcycloalkylamine
|
| 25 |
+
COc1cccc(C2(N3CCCCC3)CCCc3ccccc32)c1,"1-[1-(3-Methoxyphenyl)-1,2,3,4-tetrahydronaphthalen-1-yl]piperidine",arylcycloalkylamine
|
| 26 |
+
CCNC12CCCCC1CCc1ccccc12,"N-Ethyl-1,3,4,9,10,10a-hexahydrophenanthren-4a(2H)-amine",arylcycloalkylamine
|
| 27 |
+
c1ccc([C@]2(N3CCCCC3)C[C@H]3C[C@H]3C2)cc1,"1-[(1R,3r,5S)-3-Phenylbicyclo[3.1.0]hexan-3-yl]piperidine",arylcycloalkylamine
|
| 28 |
+
c1ccc(C2(N3CCCCC3)CN3CCC2CC3)cc1,P3QP,arylcycloalkylamine
|
| 29 |
+
COc1cccc(C2(N3CCCC3)CCCCC2=O)c1,3-MeO-2'-Oxo-PCPy,arylcycloalkylamine
|
| 30 |
+
c1cc2c(cc1C1(N3CCCCC3)CCCCC1)OCCO2,"3,4-ED-PCP",arylcycloalkylamine
|
| 31 |
+
NC1(c2ccccc2Cl)CCCNC1=O,3-Amino-3-(2-chlorophenyl)piperidin-2-one,arylcycloalkylamine
|
| 32 |
+
CC[C@]1(c2ccccc2)OC[C@H]([C@@H]2CCCCN2)O1,CL-1848C,arylcycloalkylamine
|
| 33 |
+
O=[N+]([O-])c1cccc(C2(N3CCCCC3)CCCCC2)c1,3-NO2-PCP,arylcycloalkylamine
|
| 34 |
+
Fc1cccc(C2(N3CCCCC3)CCCCCC2)c1,3F-PCHEP,arylcycloalkylamine
|
| 35 |
+
CCNC1(c2cccc(OC(C)C)c2)CCCCC1=O,iPXE,arylcycloalkylamine
|
| 36 |
+
COc1cc(C2(N3CCCCC3)CCCCC2)ccc1C,3-MeO-4-Me-PCP,arylcycloalkylamine
|
| 37 |
+
O=C1CCC(c2ccccc2)(N2CCCCC2)CC1,4'-Oxo-PCP,arylcycloalkylamine
|
| 38 |
+
CCNC1(c2ccc3c(c2)OCO3)CCCCC1,"3,4-MD-PCE",arylcycloalkylamine
|
| 39 |
+
CNC1(c2ccccc2OC)CCCCC1=O,2-MDCK,arylcycloalkylamine
|
| 40 |
+
CCOc1cccc(C2(N3CCCCC3)CCCCC2)c1,3-EtO-PCP,arylcycloalkylamine
|
| 41 |
+
CNC1(c2ccccc2C)CCCCC1=O,o-MDCK,arylcycloalkylamine
|
| 42 |
+
CNC1(c2cccc(Cl)c2)CCCCC1=O,meta-Ketamine,arylcycloalkylamine
|
| 43 |
+
CCNC1(c2cc(OC)ccc2Br)CCCCC1=O,Bromo-methoxetamine,arylcycloalkylamine
|
| 44 |
+
CNC1(c2cccc(OC)c2)CCCCC1=O,MXM,arylcycloalkylamine
|
| 45 |
+
CCCOC(=O)CCNC1(c2ccccc2Cl)CCCCC1=O,nPr-NKE-Et,arylcycloalkylamine
|
| 46 |
+
CC1CCCCC1(c1ccccc1)N1CCCCC1,2'-Me-PCP,arylcycloalkylamine
|
| 47 |
+
Cc1ccc(C2(N3CCC(O)CC3)CCCCC2O)cc1,"2',4″-HO-4-Me-PCP",arylcycloalkylamine
|
| 48 |
+
NC1(c2ccccc2Cl)CCC(O)CC1=O,"(2,5)-HNK",arylcycloalkylamine
|
| 49 |
+
Fc1cccc(C2(N3CCCCC3)CC3CCC2C3)c1,3F-PBCHP,arylcycloalkylamine
|
| 50 |
+
CC(C)NC1(c2ccccc2)CCCCC1,PCiP,arylcycloalkylamine
|
| 51 |
+
Fc1ccc(C2(N3CCCCC3)CCCCCC2)cc1,4F-PCHEP,arylcycloalkylamine
|
| 52 |
+
CCCNC1(c2ccccc2)CCCC1,PCPEPr,arylcycloalkylamine
|
| 53 |
+
CC(C)Oc1cccc(C2(N)CCCCC2)c1,3-IpO-PCA,arylcycloalkylamine
|
| 54 |
+
CC(O)CNC1(c2ccccc2)CCCCC1,1-[(1-Phenylcyclohexyl)amino]propan-2-ol,arylcycloalkylamine
|
| 55 |
+
Cc1ccc(C2(N(C)C)CCC(O)(CCc3ccccc3)CC2)cc1,MDPC,arylcycloalkylamine
|
| 56 |
+
Cc1cc(O)ccc1C1(N2CCOCC2)CCCCC1,4-HO-2-Me-PCMo,arylcycloalkylamine
|
| 57 |
+
O=C1CCCCC1(c1ccccc1)N1CCCC1,2-Phenyl-2-(pyrrolidin-1-yl)cyclohexan-1-one,arylcycloalkylamine
|
| 58 |
+
CNC1(c2ccccc2Cl)CCCCCC1=O,2-(2-Chlorophenyl)-2-(methylamino)cycloheptan-1-one,arylcycloalkylamine
|
| 59 |
+
CCN(CC)C1(c2ccccc2)CCCCC1,PCDE,arylcycloalkylamine
|
| 60 |
+
COc1cccc([C@@]2(O)CCN(C3(c4ccccc4)CCCCC3)C[C@@H]2CN(C)C)c1,US 7049327 #6,arylcycloalkylamine
|
| 61 |
+
Cc1cccc(C2(N3CCCC3)CC3CCC2C3)c1,3-Me-PBCHPy,arylcycloalkylamine
|
| 62 |
+
C#Cc1ccc2c(c1)C(c1ccccc1F)=N[C@@H](C)c1c(C(=O)N(C)C)ncn1-2,GL-i-54,aryldiazepine
|
| 63 |
+
O=C1CN=C(c2c(F)cccc2F)c2cc(Cl)ccc2N1,Ro-07-3953,aryldiazepine
|
| 64 |
+
O=C1CN=C(c2ccn[nH]2)c2cc(Cl)ccc2N1,SCHEMBL9684958,aryldiazepine
|
| 65 |
+
C#Cc1ccc2c(c1)C(c1ccccn1)=NCc1c(C(N)=O)ncn1-2,MP-ii-065,aryldiazepine
|
| 66 |
+
CN1C(=O)CN=C(c2ccccc2F)c2c(Cl)cccc21,Ro-13-0699,aryldiazepine
|
| 67 |
+
C#Cc1ccc2c(c1)C(c1ccccc1)=NCc1c(C(=O)OCC(F)(F)F)ncn1-2,DM-ii-20,aryldiazepine
|
| 68 |
+
O=C1OCCC2N=C(c3ccccc3)c3ccccc3-n3cnc1c32,"8-Phenyl-6,6a-dihydro-4-oxa-2,7,12b-triazabenzo[b]cyclopenta[kl]heptalen-3(5H)-one",aryldiazepine
|
| 69 |
+
CCC1C(C)=NN=C(c2ccc(OC)c(OC)c2)c2cc(OC)c(OC)cc21,Tofisopam,aryldiazepine
|
| 70 |
+
CN1C(=O)CN=C(c2ccc(F)cc2)c2cc(Cl)ccc21,4F-Diazepam,aryldiazepine
|
| 71 |
+
CC(C)COC(=O)c1ncn2c1C1CCCN1C(=O)c1c(Cl)cccc1-2,Ro-16-7082,aryldiazepine
|
| 72 |
+
CN1C(=O)CN=C(c2cccs2)c2cc(Cl)ccc21,WZ-113,aryldiazepine
|
| 73 |
+
CC(=O)c1ccc2c(c1)C(c1ccccc1)=NCC(=O)N2,Ro-20-3053,aryldiazepine
|
| 74 |
+
C#Cc1ccc2c(c1)C(=O)N(C)Cc1c(C(=O)OC(C)(C)C)ncn1-2,RY-24,aryldiazepine
|
| 75 |
+
CC(C)(C)OC(=O)c1ncn2c1C1CCCN1C(=O)c1c(F)cccc1-2,Ro-16-8912,aryldiazepine
|
| 76 |
+
O=C1CN=C(c2ccccc2F)c2cc(Cl)ccc2N1CCO,Ro-07-2750,aryldiazepine
|
| 77 |
+
CN1C(=O)CN=C(c2ccccc2Cl)c2cc([N+](=O)[O-])ccc21,Ro-05-4082,aryldiazepine
|
| 78 |
+
Cc1nnc2n1-c1sc(Cl)cc1C(c1ccccc1)=NC2,Deschloroclotizolam,aryldiazepine
|
| 79 |
+
CCOC(=O)c1ncn2c1C(C)N=C(c1ccc(F)cc1)c1cc(F)ccc1-2,"Ethyl 8-fluoro-6-(4-fluorophenyl)-4-methyl-4H-imidazo[1,5-a][1,4]benzodiazepine-3-carboxylate",aryldiazepine
|
| 80 |
+
O=C1CN=C(c2ccccc2F)c2cc(Cl)c(Cl)cc2N1,Ro-20-8065,aryldiazepine
|
| 81 |
+
CN1C(=O)CN=C(c2c(F)cccc2F)c2cc(Br)ccc21,Ro-13-3780,aryldiazepine
|
| 82 |
+
CN1C(=O)CC(=O)N(c2ccccc2)c2cc(Cl)ccc21,Clobazam,aryldiazepine
|
| 83 |
+
OCc1nnc2n1-c1ccc(Cl)cc1C(c1ccccc1)=NC2,alpha-Hydroxyalprazolam,aryldiazepine
|
| 84 |
+
O=C1Nc2ccc(Cl)cc2C(c2ccccc2)=NC1O,Oxazepam,aryldiazepine
|
| 85 |
+
CCOC(=O)c1ncn2c1CN=C(c1ccc([N+](=O)[O-])cc1)c1ccccc1-2,Ro-23-2896,aryldiazepine
|
| 86 |
+
CN1C(=O)CN=C(c2ccccc2F)c2cc(Br)ccc21,Flubrometazepam,aryldiazepine
|
| 87 |
+
CN(C)C(=O)c1nc2n(n1)-c1ccc(Cl)cc1C(c1ccccc1Cl)=NC2,Rilmazolam,aryldiazepine
|
| 88 |
+
CC1N=C(c2ccccc2F)c2cc(Cl)ccc2NC1=O,Ro-11-4878,aryldiazepine
|
| 89 |
+
CCOC(=O)c1ncn2c1C1CCCN1C(=O)c1cc(Br)ccc1-2,RY-054,aryldiazepine
|
| 90 |
+
CCOC(=O)c1ncn2c1C1CCN1C(=O)c1c(Cl)cccc1-2,Ro-16-0858,aryldiazepine
|
| 91 |
+
CN1C(=O)CN=C(c2ccc(Cl)cc2)c2cc(Cl)ccc21,Ro-05-4864,aryldiazepine
|
| 92 |
+
CN(C)CCc1nnc2n1-c1ccc(Cl)cc1C(c1ccccc1)=NC2,U-43465F,aryldiazepine
|
| 93 |
+
CN1C(=O)CN=C(c2ccccc2F)c2c(Cl)cc(Cl)cc21,Ro-13-0882,aryldiazepine
|
| 94 |
+
CCc1ccc2c(c1)C(c1ccccc1)=NCC(=O)N2,Ro-20-2533,aryldiazepine
|
| 95 |
+
CCOC(=O)c1ncn2c1CC=C(c1ccccc1F)c1ccccc1-2,Ro-15-2200,aryldiazepine
|
| 96 |
+
O=C1CC=C(c2ccccc2Cl)c2cc([N+](=O)[O-])ccc2N1,Ro-15-8867,aryldiazepine
|
| 97 |
+
Cc1cc2c(cc1Cl)NC(=O)CN=C2c1ccccc1F,Ro-20-8552,aryldiazepine
|
| 98 |
+
N#Cc1ncn2c1CN=C(c1ccc(Cl)cc1)c1cc(Cl)ccc1-2,"8-Chloro-6-(4-chlorophenyl)-4H-imidazo[1,5-a][1,4]benzodiazepine-3-carbonitrile",aryldiazepine
|
| 99 |
+
CC(C)c1nc(-c2ncn3c2CN(C)C(=O)c2c(Cl)cccc2-3)no1,FG-8205,aryldiazepine
|
| 100 |
+
Cc1nnc2n1-c1ccc([N+](=O)[O-])cc1C(c1ccccc1Cl)=NC2,Clonazolam,aryldiazepine
|
| 101 |
+
O=C1CN=C(c2ccccc2[N+](=O)[O-])c2cc(Br)ccc2N1,QH-II-067a,aryldiazepine
|
| 102 |
+
NC(=O)c1ncn2c1CC=C(c1ccccc1F)c1cc(Cl)ccc1-2,Ro-14-3930,aryldiazepine
|
| 103 |
+
COC(=O)CC[C@@H]1N=C(c2ccccn2)c2cc(Br)ccc2-n2c(C)cnc21,CNS-7056,aryldiazepine
|
| 104 |
+
CN1C(=O)CN=C(C2CCC2)c2cc(F)ccc21,"5-Cyclobutyl-7-fluoro-1-methyl-1,3-dihydro-2H-1,4-benzodiazepin-2-one",aryldiazepine
|
| 105 |
+
O=C1CN=C(c2c(F)cccc2Cl)c2cc(Cl)ccc2N1,Ro-07-5193,aryldiazepine
|
| 106 |
+
CN1C(=O)CN=C(c2ccccc2F)c2cc(I)ccc21,Ro-07-9957,aryldiazepine
|
| 107 |
+
O=C1CN=C(c2ccccc2)c2cc(Cl)ccc2N1CC1CC1,Prazepam,aryldiazepine
|
| 108 |
+
CCOC(=O)c1ncn2c1CN=C(c1cccc([N+](=O)[O-])c1)c1cc(F)ccc1-2,"Ethyl 8-fluoro-6-(3-nitrophenyl)-4H-imidazo[1,5-a][1,4]benzodiazepine-3-carboxylate",aryldiazepine
|
| 109 |
+
Clc1ccc2c(c1)-c1ncnn1Cc1c(Cl)ncn1-2,Ro4882224,aryldiazepine
|
| 110 |
+
[N-]=[N+]=Nc1ccc2c(c1)C(c1ccccc1F)=NCC(=O)N2,Ro-14-3074,aryldiazepine
|
| 111 |
+
Fc1ccccc1C1=NCC=Cc2ccc(Cl)cc21,Ro-22-1274,aryldiazepine
|
| 112 |
+
Nc1ncc2c(n1)-c1ccc(Cl)cc1C(c1ccccc1F)=NC2,Ro-22-2038,aryldiazepine
|
| 113 |
+
Clc1ccc2c(c1)C(c1ccccc1)=NCc1nncn1-2,Estazolam,aryldiazepine
|
| 114 |
+
Cc1nn(C)c2c1C(c1ccccc1F)=NCC(=O)N2C,Zolazepam,aryldiazepine
|
| 115 |
+
Cc1nnc2n1-c1ccc(Cl)cc1C(c1ccccn1)=NC2,Pyclazolam,aryldiazepine
|
| 116 |
+
S=C1CN=C(c2ccccc2)c2cc(Cl)ccc2N1,Thionordazepam,aryldiazepine
|
| 117 |
+
O=C1CN=C(c2ccccc2)c2cc(Cl)ccc2N1CC(F)(F)F,Halazepam,aryldiazepine
|
| 118 |
+
C#Cc1ccc2c(c1)C(c1ccccc1)=NCC1=N/C(=C\N3CCN(C)CC3)C(=O)N12,PS-i-37,aryldiazepine
|
| 119 |
+
C#Cc1ccc2c(c1)C(c1ccccc1F)=NCc1c(C(=O)OCC(F)(F)F)ncn1-2,JY-i-59,aryldiazepine
|
| 120 |
+
O=C1CN=C(c2ccccc2F)c2cc([N+](=O)[O-])ccc2N1,Fonazepam,aryldiazepine
|
| 121 |
+
CN1CCN(/C=C2\N=C3CN=C(c4ccccc4)c4cc(Br)ccc4N3C2=O)CC1,PS-1-35,aryldiazepine
|
| 122 |
+
CCCCCCC(C)(C)c1ccc([C@@H]2CCC[C@H](O)C2)c(O)c1,"(1R,3S) CP 47,497",cannabinoid
|
| 123 |
+
CCCc1ccc(C(=O)c2cn(CCCCCF)c3ccccc23)c2ccccc12,SGT-62,cannabinoid
|
| 124 |
+
CC(C)[C@H](NC(=O)c1cn(Cc2ccc(F)cc2)c2ccccc12)C(N)=O,AB-FUBICA,cannabinoid
|
| 125 |
+
CCCCCn1nc(C(=O)N[C@@H](Cc2ccccc2)C(=O)OC)c2ccccc21,MPP-PINACA,cannabinoid
|
| 126 |
+
O=C(Cc1cn(Cc2ccc(F)cc2)c2ccccc12)NC1C2CC3CC(C2)CC1C3,AFUBIATA,cannabinoid
|
| 127 |
+
CC(C)(C)c1nc(N2CCC(F)(F)C2)c2nnn(Cc3ccccc3S(C)(=O)=O)c2n1,"5-tert-Butyl-7-(3,3-difluoropyrrolidin-1-yl)-3-{[2-(methanesulfonyl)phenyl]methyl}-3H-[1,2,3]triazolo[4,5-d]pyrimidine",cannabinoid
|
| 128 |
+
CCC(C(N)=O)N(C)C(=O)c1nn(Cc2ccc(F)cc2)c2ccccc12,AB-FUBINACA isomer 5,cannabinoid
|
| 129 |
+
COc1cccc2c3c(=O)n([C@@H]4C(C)(C)[C@@H]5CC[C@@]4(C)C5)ccc3n(Cc3ccncc3)c12,WO 2001/058869 #190,cannabinoid
|
| 130 |
+
CCCC(F)Cn1cc(C(=O)C2C(C)(C)C2(C)C)c2ccccc21,(2-Fluoropentyl) XLR-11,cannabinoid
|
| 131 |
+
O=C(Nc1ccccc1)c1cn(CCCCCF)c2ccccc12,LTI-701,cannabinoid
|
| 132 |
+
C=CCCCn1nc(C(=O)N[C@H](C(=O)OC)C(C)C)c2ccccc21,MMB-4en-PINACA,cannabinoid
|
| 133 |
+
O=C(Nc1ccccc1)c1nn(CC2CCOCC2)c2ccccc12,SGT-224,cannabinoid
|
| 134 |
+
Cc1ccc(C(=O)NC(C)(C)c2ccccc2)cc1S(=O)(=O)N1CCC(F)(F)CC1,SGT-233,cannabinoid
|
| 135 |
+
CCCCCn1nc(C(=O)c2ccc(OC)c3ccccc23)c2ccccc21,SGT-35,cannabinoid
|
| 136 |
+
CC1(C)C(C(=O)c2cn(CC3CCCCC3)c3ccccc23)C1(C)C,(CHM) UR-144,cannabinoid
|
| 137 |
+
CN1CCCCC1Cn1cc(C(=O)c2ccc(N=C=S)c3ccccc23)c2ccc(N=C=S)cc21,AM-2215,cannabinoid
|
| 138 |
+
CCCCCCC1(c2ccc(-c3cc(C)cc(C)c3)c(O)c2)CC1,"4-(1-Hexylcyclopropyl)-3',5'-dimethyl[1,1'-biphenyl]-2-ol",cannabinoid
|
| 139 |
+
COC(=O)[C@@H](NC(=O)c1cn(Cc2ccc(F)cc2)c2ncccc12)C(C)(C)C,MDMB-FUB7AICA,cannabinoid
|
| 140 |
+
CN1CCCCC1Cn1cc(C(=O)c2ccccc2I)c2ccccc21,AM-2233,cannabinoid
|
| 141 |
+
O=C(c1cccc2ccccc12)n1c(-c2ccncc2)nc2ccccc21,(Naphthalen-1-yl)[2-(pyridin-4-yl)-1H-benzimidazol-1-yl]methanone,cannabinoid
|
| 142 |
+
C=CCCCn1nc(C(=O)N[C@H](C(=O)OC)C(C)(C)C)c2ccccc21,MDMB-4en-PINACA,cannabinoid
|
| 143 |
+
Oc1ccc(/C=C2\C=C(CCN3CCOCC3)c3ccccc32)c2ccccc12,US 5292736 #19,cannabinoid
|
| 144 |
+
CCc1c(C(=O)NN2CCCCC2)nn(-c2ccc(Cl)cc2Cl)c1-c1ccc(C#Cc2ccc(C(F)(F)F)cc2)s1,TM-38837,cannabinoid
|
| 145 |
+
COC(=O)[C@H](Cc1ccccc1)NC(=O)c1cn(CCCCCF)c2ccccc12,MPHP-2201,cannabinoid
|
| 146 |
+
Cc1ccc2c(C(C[N+](=O)[O-])c3ccccc3)c(-c3ccccc3)[nH]c2c1,GAT211,cannabinoid
|
| 147 |
+
CCCCCn1nc(C(=O)NC2CCCCC2)c2ccccc21,SGT-85,cannabinoid
|
| 148 |
+
CN1CCCCC1Cn1cc(C(=O)c2ccc([N+](=O)[O-])c3ccccc23)c2ccccc21,AM-1299,cannabinoid
|
| 149 |
+
CCc1c(C)cc(C(=O)NC2(C(=O)O)CCCCC2)c(=O)n1Cc1ccc(F)cc1,S-777469,cannabinoid
|
| 150 |
+
CCCCCC(C)NC(=O)c1nn(CCCCC)c2ccccc12,SGT-71,cannabinoid
|
| 151 |
+
CC1(C)Oc2cc(C34CC5CC(CC(C5)C3)C4)cc(O)c2[C@@H]2CC(O)CC[C@H]21,"(6aR,10aR)-3-(Adamantan-1-yl)-6,6-dimethyl-6a,7,8,9,10,10a-hexahydro-6H-dibenzo[b,d]pyran-1,9-diol",cannabinoid
|
| 152 |
+
C=C(C)[C@H]1CCC(CO)=C[C@@H]1c1c(O)cc(C(C)(C)CCCCN2CCOCC2)cc1O,"(1'S,2'S)-5'-(Hydroxymethyl)-4-[2-methyl-6-(morpholin-4-yl)hexan-2-yl]-2'-(prop-1-en-2-yl)-1',2',3',4'-tetrahydro[1,1'-biphenyl]-2,6-diol",cannabinoid
|
| 153 |
+
O=C(N/N=C1\C(=O)N(CCCCCF)c2ccccc21)c1ccccc1,BZO-5F-POXIZID,cannabinoid
|
| 154 |
+
CCCCCOc1c(OC)ccc2cc(C(=O)NCc3ccc4c(c3)OCO4)c(=O)[nH]c12,JTE-907,cannabinoid
|
| 155 |
+
CCCCn1nc(C(=O)N[C@@H](Cc2ccccc2)C(=O)OC)c2ccccc21,MPP(N)-073,cannabinoid
|
| 156 |
+
CCCCCCC(C)(C)c1ccc([C@@H]2CCC[C@@H](O)C2)c(O)c1,"(R,R)-epi-CP 47,497",cannabinoid
|
| 157 |
+
CCCCCOc1ccc(C(=O)c2cccc3ccccc23)c2ccccc12,CB-13,cannabinoid
|
| 158 |
+
COc1ccccc1OC(=O)c1ccc(C)c(S(=O)(=O)N2CCOCC2)c1,2-Methoxyphenyl 4-methyl-3-(morpholine-4-sulfonyl)benzoate,cannabinoid
|
| 159 |
+
CCCCCC#Cc1cc(O)c2c(c1)OC(C)(C)[C@@H]1CC=C(C)C[C@@H]21,AMG-1,cannabinoid
|
| 160 |
+
CC(C)[C@H](NC(=O)c1cn(CCCCCF)c2ccccc12)C(N)=O,5F-ABICA,cannabinoid
|
| 161 |
+
CCCCCn1cc(C(=O)NC23CC4CC(CC(C4)C2)C3)c(=O)c2ccc(F)cc21,"N-(Adamantan-1-yl)-7-fluoro-4-oxo-1-pentyl-1,4-dihydroquinoline-3-carboxamide",cannabinoid
|
| 162 |
+
CC1=CC[C@@H]2[C@@H](C1)c1c(O)cc(C(C)(C)CCCCCC#N)cc1OC2(C)C,O-774,cannabinoid
|
| 163 |
+
CC(C)(C)[C@H](NC(=O)n1c(=O)n(CCN2CCOCC2)c2ccccc21)C(N)=O,WO 2008/032164 #4,cannabinoid
|
| 164 |
+
COC(=O)[C@H](Cc1ccccc1)NC(=O)c1cn(CC2CCCCC2)c2ccccc12,MPP-CHMICA,cannabinoid
|
| 165 |
+
Fc1ccc2nc(-c3ccccn3)n(Cc3cccc4ccccc34)c2c1,6-Fluoro-1-[(naphthalen-1-yl)methyl]-2-(pyridin-2-yl)-1H-benzimidazole,cannabinoid
|
| 166 |
+
CCCCCn1cc(C(=O)N[C@@H](C)c2ccccc2)c2ccccc21,1-Pentyl-N-[(1S)-1-phenylethyl]-1H-indole-3-carboxamide,cannabinoid
|
| 167 |
+
CCCCCCCC(C)c1cc(OC(=O)CCCN(CC)CC)c2c(c1)OC(C)(C)C1=C2CC(C)CC1,SP-325,cannabinoid
|
| 168 |
+
CCCCCn1cc(C(=O)c2cccc3ccccc23)cc1-c1cccc(C)c1,JWH-346,cannabinoid
|
| 169 |
+
O=C(Cc1ccccc1)N/N=C1\C(=O)N(CC2CCCCC2)c2cc(OCCN3CCOCC3)ccc21,"N'-{1-(Cyclohexylmethyl)-6-[2-(morpholin-4-yl)ethoxy]-2-oxo-1,2-dihydro-3H-indol-3-ylidene}-2-phenylacetohydrazide",cannabinoid
|
| 170 |
+
Cc1c(C(=O)C2C(C)(C)C2(C)C)c2ccccc2n1CCCCCF,2-Me-XLR-11,cannabinoid
|
| 171 |
+
COc1ccc2c(c1)CCC2CNC(=O)c1cn(CCCCCF)c2ccccc12,SGT-105,cannabinoid
|
| 172 |
+
CCCCCc1cc(O)c2c(c1)OC(C)(C)C(CCC(C)=O)C2=O,CBCN,cannabinoid
|
| 173 |
+
CCCCCn1nc(C(=O)NC(C)(C)c2ccc(F)cc2)c2ccccc21,SGT-60,cannabinoid
|
| 174 |
+
CC(C)(C)[C@H](NC(=O)c1nn(CC2CCCCCC2)c2ccccc12)C(=O)NCCO,WO 2009/106980 #433,cannabinoid
|
| 175 |
+
CC(C)(NC(=O)c1cn(Cc2ccc(F)cc2)c2ccccc12)c1ccccc1,CUMYL-FUBICA,cannabinoid
|
| 176 |
+
COC(=O)[C@@H](NC(=O)c1nn(CC2CCCCC2)c2ccccc12)C(C)(C)C,MDMB(N)-CHM,cannabinoid
|
| 177 |
+
CCCCCn1nc(C(=O)c2cccc3ccccc23)c2ccccc21,SGT-17,cannabinoid
|
| 178 |
+
CCCCCn1cc(C(=O)N[C@H](C(N)=O)C(C)(C)C)c2ccccc21,ADBICA,cannabinoid
|
| 179 |
+
CN1CCCCC1Cn1cc(C(=O)c2cc(N=C=S)ccc2I)c2ccc(N=C=S)cc21,AM-2223,cannabinoid
|
| 180 |
+
CCCCCCCCCn1cc(C(=O)c2cccc3ccccc23)c2ccccc21,(Nonyl) JWH-018,cannabinoid
|
| 181 |
+
CCCCCCC(C)(C)c1cc(OC)c([C@@H]2C=C(CO)C3CC2C3(C)C)c(OC)c1,HU-433,cannabinoid
|
| 182 |
+
C=CCc1cc(OC)c(OC)c(OC)c1OC,"2,3,4,5-Tetramethoxyphenylprop-2-ene",essential oil
|
| 183 |
+
C/C=C\c1ccc(O)c(OC)c1,cis-4-Hydroxy-3-methoxyphenylprop-1-ene,essential oil
|
| 184 |
+
C/C=C/c1ccc2c(c1OC)OCO2,Isocroweacin,essential oil
|
| 185 |
+
C/C=C\c1cc(OC)c(O)c(OC)c1,"cis-4-Hydroxy-3,5-dimethoxyphenylprop-1-ene",essential oil
|
| 186 |
+
C=CCc1ccc2c(c1OC)OCO2,Croweacin,essential oil
|
| 187 |
+
C/C=C\c1cc2c(cc1OC)OCO2,"cis-2-Methoxy-4,5-methylenedioxyphenylprop-1-ene",essential oil
|
| 188 |
+
C=CCc1ccc2c(c1)OCO2,Safrole,essential oil
|
| 189 |
+
C/C=C\c1cc(OC)c2c(c1)OCO2,cis-Isomyristicin,essential oil
|
| 190 |
+
C/C=C\c1ccc(OC)cc1OC,"cis-2,4-Dimethoxyphenylprop-1-ene",essential oil
|
| 191 |
+
C/C=C\c1ccc2c(c1OC)OCO2,"cis-2-Methoxy-3,4-methylenedioxyphenylprop-1-ene",essential oil
|
| 192 |
+
C/C=C/c1ccc(OC)c(OC)c1,Methylisoeugenol,essential oil
|
| 193 |
+
C=CCc1ccc(OC)cc1OC,Osmorrhizole,essential oil
|
| 194 |
+
C=CCc1ccc(OC)c(OC)c1,Methyleugenol,essential oil
|
| 195 |
+
C=CCc1ccc(O)c(OC)c1,Eugenol,essential oil
|
| 196 |
+
C=CCc1cc2c(c(OC)c1OC)OCO2,Dillapiole,essential oil
|
| 197 |
+
C/C=C\c1ccc2c(c1)OCO2,alpha-Isosafrole,essential oil
|
| 198 |
+
C/C=C/c1cc(OC)c(OC)c(OC)c1,Isoelemicin,essential oil
|
| 199 |
+
C=CCc1ccc(OC)c(O)c1,Chavibetol,essential oil
|
| 200 |
+
C=CCc1cc(OC)c(OC)c(OC)c1,Elemicin,essential oil
|
| 201 |
+
C=CCc1cc(OC)cc(OC)c1,"3,5-Dimethoxyphenylprop-2-ene",essential oil
|
| 202 |
+
C/C=C\c1cc(OC)c(OC)c(OC)c1,cis-Isoelemicin,essential oil
|
| 203 |
+
C/C=C/c1cc(OC)c(OC)c(OC)c1OC,"trans-2,3,4,5-Tetramethoxyphenylprop-1-ene",essential oil
|
| 204 |
+
C/C=C/c1cc(OC)c2c(c1OC)OCO2,Isoapiole,essential oil
|
| 205 |
+
C/C=C\c1ccc(OC)c(O)c1,cis-3-Hydroxy-4-methoxyphenylprop-1-ene,essential oil
|
| 206 |
+
C=CCc1ccc(OC)cc1,Estragole,essential oil
|
| 207 |
+
C/C=C\c1cc(OC)c2c(c1OC)OCO2,"cis-2,5-Dimethoxy-3,4-methylenedioxyphenylprop-1-ene",essential oil
|
| 208 |
+
C=CCc1cc(OC)c2c(c1OC)OCO2,Apiole,essential oil
|
| 209 |
+
C/C=C/c1ccc(OC)cc1OC,Nothosmyrnol,essential oil
|
| 210 |
+
C/C=C/c1cc(OC)cc(OC)c1,"trans-3,5-Dimethoxyphenylprop-1-ene",essential oil
|
| 211 |
+
C/C=C\c1cc2c(c(OC)c1OC)OCO2,"cis-2,3-Dimethoxy-4,5-methylenedioxyphenylprop-1-ene",essential oil
|
| 212 |
+
C/C=C\c1ccc(OC)cc1,cis-4-Methoxyphenylprop-1-ene,essential oil
|
| 213 |
+
C/C=C/c1cc(OC)c(O)c(OC)c1,"2,6-Dimethoxy-4-[(1E)-prop-1-en-1-yl]phenol",essential oil
|
| 214 |
+
C=CCc1cc(OC)c(OC)cc1OC,γ-Asarone,essential oil
|
| 215 |
+
C/C=C/c1ccc(OC)cc1,Anethole,essential oil
|
| 216 |
+
C=CCc1cc2c(cc1OC)OCO2,Asaricin,essential oil
|
| 217 |
+
C/C=C/c1cc2c(c(OC)c1OC)OCO2,Isodillapiole,essential oil
|
| 218 |
+
C/C=C/c1cc(OC)c(OC)cc1OC,Asarone,essential oil
|
| 219 |
+
C/C=C/c1ccc(O)c(OC)c1,Isoeugenol,essential oil
|
| 220 |
+
C/C=C\c1cc(OC)cc(OC)c1,"cis-3,5-Dimethoxyphenylprop-1-ene",essential oil
|
| 221 |
+
C/C=C\c1cc(OC)c(OC)cc1OC,beta-Asarone,essential oil
|
| 222 |
+
C=CCc1cc(OC)c2c(c1)OCO2,Myristicin,essential oil
|
| 223 |
+
C/C=C/c1ccc(OC)c(O)c1,2-Methoxy-5-[(1E)-prop-1-en-1-yl]phenol,essential oil
|
| 224 |
+
C/C=C/c1cc(OC)c2c(c1)OCO2,Isomyristicin,essential oil
|
| 225 |
+
C/C=C\c1ccc(OC)c(OC)c1,"cis-3,4-Dimethoxyphenylprop-1-ene",essential oil
|
| 226 |
+
C=CCc1cc(OC)c(O)c(OC)c1,5-Methoxyeugenol,essential oil
|
| 227 |
+
C/C=C/c1ccc2c(c1)OCO2,beta-Isosafrole,essential oil
|
| 228 |
+
C/C=C\c1cc(OC)c(OC)c(OC)c1OC,"cis-2,3,4,5-Tetramethoxyphenylprop-1-ene",essential oil
|
| 229 |
+
C/C=C/c1cc2c(cc1OC)OCO2,Carpacin,essential oil
|
| 230 |
+
CCC(=O)N(c1ccccc1)C1(COC)CCN(CC(O)c2cccs2)CC1,beta-Hydroxy-sufentanil,fentanyl
|
| 231 |
+
CCC(=O)N(CCc1ccccc1)C1CCN(CCc2ccccc2)CC1,(ethylene) Fentanyl,fentanyl
|
| 232 |
+
CCC(=O)N(c1ccccc1F)C1(c2ccccc2)CCN(CCn2cccn2)CC1,N-(2-Fluorophenyl)-N-{4-phenyl-1-[2-(1H-pyrazol-1-yl)ethyl]piperidin-4-yl}propanamide,fentanyl
|
| 233 |
+
CCC(=O)N(c1ccccc1)C1CCN(C(C)Cc2cc(OC)c(I)cc2OC)CC1,N-(DOI) fentanyl,fentanyl
|
| 234 |
+
CCC(=O)N(c1ccccc1)C1(COC(=O)C(C)(C)C)CCN(CCN2C(=O)c3ccccc3C2=O)CC1,"{1-[2-(1,3-Dioxo-1,3-dihydro-2H-isoindol-2-yl)ethyl]-4-[phenyl(propanoyl)amino]piperidin-4-yl}methyl 2,2-dimethylpropanoate",fentanyl
|
| 235 |
+
CC(C)C(=O)N(c1cccc(F)c1)C1CCN(CCc2ccccc2)CC1,m-Fluoro-isobutyrylfentanyl,fentanyl
|
| 236 |
+
CCCC(=O)N(c1ccc(OC)cc1)C1CCN(CCc2ccccc2)CC1,p-MeO-BF,fentanyl
|
| 237 |
+
CCC(=O)N(c1ccccc1)C1(C(=O)OC)CCN(Cc2ccccc2)CC1,Benzylcarfentanil,fentanyl
|
| 238 |
+
CCC(=O)N(c1ccccc1)C1(C(=O)OC)CCN(CCc2ccsc2)CC1,Methyl 4-[phenyl(propanoyl)amino]-1-[2-(thiophen-3-yl)ethyl]piperidine-4-carboxylate,fentanyl
|
| 239 |
+
COCC(=O)N(c1ccc(C)cc1)C1CCN(CCc2ccccc2)CC1,p-Methyl-methoxyacetylfentanyl,fentanyl
|
| 240 |
+
CCCCC(=O)N(c1ccc(OC)cc1)C1CCN(CCc2ccccc2)CC1,p-Methoxy-valerylfentanyl,fentanyl
|
| 241 |
+
CCC(=O)N(c1ccccc1)C1CCN(CCc2ccccc2)CC1F,NFEPP,fentanyl
|
| 242 |
+
CCC(=O)N(c1ccccc1)C1CCN(C(C)Cc2cc(OC)c(Br)cc2OC)CC1,N-(DOB) fentanyl,fentanyl
|
| 243 |
+
CCCC(=O)N(c1ccccc1)C1CCN(C)CC1,N-Methyl-butyrylfentanyl,fentanyl
|
| 244 |
+
O=C(c1ccco1)N(c1ccccc1)C1CCN(CCc2ccc(O)cc2)CC1,4'-Hydroxy-furanylfentanyl,fentanyl
|
| 245 |
+
CCC(=O)OCC1(N(C(=O)CC)c2ccccc2)CCN(CCN2C(=O)c3ccccc3C2=O)CC1,"{1-[2-(1,3-Dioxo-1,3-dihydro-2H-isoindol-2-yl)ethyl]-4-[phenyl(propanoyl)amino]piperidin-4-yl}methyl propanoate",fentanyl
|
| 246 |
+
CCC(=O)N(c1ccccc1)C1CCN(CCc2ccccc2)C(C)C1,2-Methylfentanyl,fentanyl
|
| 247 |
+
CC(=O)N(c1ccccc1)C1CCN(CCCc2ccccc2)CC1,Phenylpropyl-acetyl-norfentanyl,fentanyl
|
| 248 |
+
CCC(=O)N(c1ccccc1)C1CCN(CCOc2ccccc2)CC1,POE-F,fentanyl
|
| 249 |
+
O=C(c1ccco1)N(c1ccccc1)C1CCNCC1,Furanyl-norfentanyl,fentanyl
|
| 250 |
+
CCC(=O)N(c1ccccc1)C1CCN(Cc2ccccc2)CC1,R-4129,fentanyl
|
| 251 |
+
Cc1ccc(NC2CCN(CCc3ccccc3)CC2)cc1,p-Me-4-ANPP,fentanyl
|
| 252 |
+
CCC(=O)N(c1ccccc1)C1(C(=O)O)CCN(CCc2ccccc2)C(O)C1,2-Hydroxycarfentanil acid,fentanyl
|
| 253 |
+
COCC(=O)N(c1ccc(F)cc1)C1CCN(CCc2ccccc2)CC1,p-Fluoro-methoxyacetylfentanyl,fentanyl
|
| 254 |
+
Cc1cccc(N(C(=O)c2ccco2)C2CCN(CCc3ccccc3)CC2)c1,m-Methyl-furanylfentanyl,fentanyl
|
| 255 |
+
CCC(=O)N(c1ccccc1)C1CCN(CCc2ccccc2F)CC1,2″-Fluorofentanyl,fentanyl
|
| 256 |
+
COc1ccccc1N(C(=O)c1ccco1)C1CCN(CCc2ccccc2)CC1,o-Methoxy-furanylfentanyl,fentanyl
|
| 257 |
+
CCC(=O)N(c1ccccc1)C1CCN(CC(O)c2ccc(F)cc2)CC1,N-{1-[2-(4-Fluorophenyl)-2-hydroxyethyl]piperidin-4-yl}-N-phenylpropanamide,fentanyl
|
| 258 |
+
CC(=O)N(c1ccccc1)C1CCN(CCc2cccs2)CC1,Acetylthiofentanyl,fentanyl
|
| 259 |
+
COCC(=O)N(c1cccc(F)c1)C1CCN(CCc2ccccc2)CC1,m-Fluoro-methoxyacetylfentanyl,fentanyl
|
| 260 |
+
COc1cc(CCN2CCC(N(C(=O)C(=O)CCC(=O)O)c3ccccc3)CC2)ccc1O,N-Phenyl-N-[1-(2-phenylethyl)piperidin-4-yl]-2-oxo-4-carboxybutanamide,fentanyl
|
| 261 |
+
CCC(=O)N(c1ccccc1)C1(COC)CCN(CCn2nnn(CC)c2=O)CC1,R-39209,fentanyl
|
| 262 |
+
CCC(=O)N(c1ccc(Cl)cc1)C1CCN(CCc2ccccc2)CC1,p-CF,fentanyl
|
| 263 |
+
CCC(=O)N(c1ccccc1)C1CCNCC1,Norfentanyl,fentanyl
|
| 264 |
+
COC(=O)CCN1CCC(Nc2ccccc2)(C(=O)OC)CC1,Despropionyl remifentanil,fentanyl
|
| 265 |
+
CCC(=O)N(c1ccccc1)C1(c2nc(C)cs2)CCN(CCc2ccccc2)CC1,"N-[4-(4-Methyl-1,3-thiazol-2-yl)-1-(2-phenylethyl)piperidin-4-yl]-N-phenylpropanamide",fentanyl
|
| 266 |
+
CCC(=O)N(c1ccccc1)C1(c2ccccc2)CCN(CCc2ccccc2)CC1,4-Phenylfentanyl,fentanyl
|
| 267 |
+
CCC(=O)N(c1ccccc1C)C1CCN(CCc2ccccc2)CC1,o-Methylfentanyl,fentanyl
|
| 268 |
+
CCC(=O)N(c1ccccc1)C1(C(=O)OC)CCN(CCCCCF)CC1,Fluoropentyl-norcarfentanil,fentanyl
|
| 269 |
+
O=C(c1ccco1)N(c1ccccc1)C1CCN(Cc2ccccc2)CC1,Furanylbenzylfentanyl,fentanyl
|
| 270 |
+
CCC(=O)N(c1ccc2ncoc2c1)C1CCN(CCc2ccccc2)CC1,N-Benzoxazolyl-fentanyl,fentanyl
|
| 271 |
+
COCC(=O)N(c1cccc(C)c1)C1CCN(CCc2ccccc2)CC1,m-Methyl-methoxyacetylfentanyl,fentanyl
|
| 272 |
+
CC(C)C(=O)OCC1(N(C(=O)C(C)C)c2ccccc2)CCN(CCN2C(=O)c3ccccc3C2=O)CC1,"{1-[2-(1,3-Dioxo-1,3-dihydro-2H-isoindol-2-yl)ethyl]-4-[(2-methylpropanoyl)(phenyl)amino]piperidin-4-yl}methyl 2-methylpropanoate",fentanyl
|
| 273 |
+
CCC(=O)N(c1ccccc1)C1(C(=O)OC)CCN(CCc2ccccn2)CC1,Methyl 4-[phenyl(propanoyl)amino]-1-[2-(pyridin-2-yl)ethyl]piperidine-4-carboxylate,fentanyl
|
| 274 |
+
c1ccc(CCN2CCC(Nc3ccccc3)CC2)cc1,ANPP,fentanyl
|
| 275 |
+
CCCc1cc(OC)c(CCN2CCC(N(C(=O)CC)c3ccccc3)CC2)cc1OC,N-(2C-P) fentanyl,fentanyl
|
| 276 |
+
CCC(=O)N(c1ccccc1)C1CCN(CC(O)c2ccncc2)CC1C,N-{1-[2-Hydroxy-2-(pyridin-4-yl)ethyl]-3-methylpiperidin-4-yl}-N-phenylpropanamide,fentanyl
|
| 277 |
+
CCC(=O)N(c1ccccc1)C1CCN(CC(=O)c2cccc(F)c2)CC1,N-{1-[2-(3-Fluorophenyl)-2-oxoethyl]piperidin-4-yl}-N-phenylpropanamide,fentanyl
|
| 278 |
+
CCCCc1cc(OC)c(CC(C)N2CCC(N(C(=O)CC)c3ccccc3)CC2)cc1OC,N-(DOBU) fentanyl,fentanyl
|
| 279 |
+
COCC(=O)N(c1ccccc1)C1C(C)CN(CCn2cccn2)CC1C,"N-{3,5-Dimethyl-1-[2-(1H-pyrazol-1-yl)ethyl]piperidin-4-yl}-2-methoxy-N-phenylacetamide",fentanyl
|
| 280 |
+
Cc1ccc(N(C(=O)C2CCCO2)C2CCN(CCc3ccccc3)CC2)cc1,p-Methyl-tetrahydrofuranylfentanyl,fentanyl
|
| 281 |
+
CCC(=O)N(c1ccccc1)C1CCN(CCc2cc(OC)cc(OC)c2)CC1,"3″,5″-DiMeO-F",fentanyl
|
| 282 |
+
CC(=O)N(c1ccccc1)C1CCN(CCc2ccccc2)CC1,Acetylfentanyl,fentanyl
|
| 283 |
+
CCC(=O)N(c1ccccc1)C1CCN(CCc2ccc(F)cc2)CC1,4″-Fluorofentanyl,fentanyl
|
| 284 |
+
CCC(=O)N(c1ccccc1)C1(COC(=O)OC)CCN(CCc2cccs2)CC1,Methyl {4-[phenyl(propanoyl)amino]-1-[2-(thiophen-2-yl)ethyl]piperidin-4-yl}methyl carbonate,fentanyl
|
| 285 |
+
CCC(=O)[N+]([O-])(c1ccccc1)C1(C(=O)OC)CCN(CCc2ccccc2)CC1,Carfentanil N-oxide,fentanyl
|
| 286 |
+
CCC(=O)N(c1ccccc1)C1(C(=O)OC)CCN(CCc2cccc(O)c2)CC1,3″-Hydroxycarfentanil,fentanyl
|
| 287 |
+
CCC(=O)N(c1ccccc1)C1CCN(C(C)C(=O)OC(C)C)CC1,Propan-2-yl 2-{4-[phenyl(propanoyl)amino]piperidin-1-yl}propanoate,fentanyl
|
| 288 |
+
O=C(C1CCC1)N(c1ccc(Cl)cc1)C1CCN(CCc2ccccc2)CC1,p-Chloro-cyclobutylfentanyl,fentanyl
|
| 289 |
+
CCC(C)C(=O)N(c1ccccc1)C1CCN(CCc2ccccc2)CC1,alpha'-Methyl-butyrylfentanyl,fentanyl
|
| 290 |
+
Oc1cc2c(cc1O)CNCC2,Norsalsolinol,neurotoxin
|
| 291 |
+
CC(N)Cc1ccc(Cl)cc1,PCA,neurotoxin
|
| 292 |
+
CC1NCCc2cc(O)c(O)cc21,Salsolinol,neurotoxin
|
| 293 |
+
CC(N)Cc1ccc(Br)cc1,PBA,neurotoxin
|
| 294 |
+
NCCc1cc(O)c(O)cc1O,6-OHDA,neurotoxin
|
| 295 |
+
COc1ccc(CCN)cc1OC,DMPEA,peyote alkaloid
|
| 296 |
+
CNCCc1cc(OC)c(OC)c(OC)c1,M-M,peyote alkaloid
|
| 297 |
+
COc1cc2c(c(OC)c1OC)C(C)N(C=O)CC2,N-Formyl-O-methylanhalonidine,peyote alkaloid
|
| 298 |
+
COc1cc2c(c3c1OCO3)C(C)[N+](C)(C)CC2,Lophotine,peyote alkaloid
|
| 299 |
+
COc1cc(CCN)ccc1O,GEA,peyote alkaloid
|
| 300 |
+
COc1cc(CCNCC(=O)O)cc(OC)c1OC,Mescaloxylic acid,peyote alkaloid
|
| 301 |
+
COc1cc2c(c(O)c1OC)C(C)N(C=O)CC2,N-Formylanhalonidine,peyote alkaloid
|
| 302 |
+
COc1cc(CCN2C(=O)CC(O)C2=O)cc(OC)c1OC,Mescaline malimide,peyote alkaloid
|
| 303 |
+
CNCCc1ccc(O)c(O)c1,Epinine,peyote alkaloid
|
| 304 |
+
COc1cc2c(c(O)c1OC)C(C)(C(=O)O)NCC2,Peyoruvic acid,peyote alkaloid
|
| 305 |
+
CCN1CCc2cc(OC)c3c(c2C1C)OCO3,Peyophorine,peyote alkaloid
|
| 306 |
+
COc1cc(CCN2C(=O)C=CC2=O)cc(OC)c1OC,Mescaline maleimide,peyote alkaloid
|
| 307 |
+
COc1c(O)cc2c(c1OC)CN(C)CC2,Isoanhalidine,peyote alkaloid
|
| 308 |
+
NCCc1ccc2c(c1)OCO2,MDPEA,peyote alkaloid
|
| 309 |
+
COc1cc2c(c(O)c1OC)C1CCC(=O)N1CC2,Peyoglutam,peyote alkaloid
|
| 310 |
+
COc1cc(CCN)cc(O)c1OC,3-DESMETHYL,peyote alkaloid
|
| 311 |
+
CCOc1ccc(CC(C)N(C)C)c(OCC)c1,"2,4-Diethoxy-N,N-dimethylamphetamine",peyote alkaloid
|
| 312 |
+
CN(C)CCc1ccc2c(c1)OCO2,Lobivine,peyote alkaloid
|
| 313 |
+
COc1c(O)cc2c(c1OC)C(C)N(C)CC2,Isopellotine,peyote alkaloid
|
| 314 |
+
COc1cc(CCNC(C)=O)cc(OC)c1OC,N-Acetylmescaline,peyote alkaloid
|
| 315 |
+
COc1cc2c(c3c1OCO3)C(C)N(C(C)=O)CC2,N-Acetylanhalonine,peyote alkaloid
|
| 316 |
+
COc1cc(CCN(C)C)cc(O)c1OC,"N,N-Me-3-DESMETHYL",peyote alkaloid
|
| 317 |
+
COc1c(O)cc2c(c1OC)C(C)NCC2,Isoanhalonidine,peyote alkaloid
|
| 318 |
+
COc1cc(CCn2cccc2C(=O)O)cc(OC)c1OC,Peyonine,peyote alkaloid
|
| 319 |
+
COc1cc2c(c(O)c1OC)CN(C(C)=O)CC2,N-Acetylanhalamine,peyote alkaloid
|
| 320 |
+
COc1cc2c(c(O)c1OC)C(C(=O)O)NCC2,Peyoxylic acid,peyote alkaloid
|
| 321 |
+
COc1cc(CCN(C)C)ccc1O,MM-GEA,peyote alkaloid
|
| 322 |
+
COc1cc2c(c(OC)c1OC)CNCC2,Anhalinine,peyote alkaloid
|
| 323 |
+
CNCCc1ccc(O)cc1,HMePEA,peyote alkaloid
|
| 324 |
+
COc1cc2c(c(O)c1OC)C[N+](C)(C)CC2,Anhalotine,peyote alkaloid
|
| 325 |
+
COc1c(O)cc2c(c1OC)CNCC2,Isoanhalamine,peyote alkaloid
|
| 326 |
+
COc1cc(CCN)cc(O)c1O,"3,4-DESMETHYL",peyote alkaloid
|
| 327 |
+
COc1cc2c(c(O)c1OC)CN(C=O)CC2,N-Formylanhalamine,peyote alkaloid
|
| 328 |
+
COc1cc(CCNC(C)C(=O)O)cc(OC)c1OC,Mescaloruvic acid,peyote alkaloid
|
| 329 |
+
C[N+](C)(C)CCc1ccc(O)cc1,Candicine,peyote alkaloid
|
| 330 |
+
COc1cc2c(c(O)c1OC)C(C)NCC2,Anhalonidine,peyote alkaloid
|
| 331 |
+
COc1cc2c(c(OC)c1OC)C1CCC(=O)N1CC2,Mescalotam,peyote alkaloid
|
| 332 |
+
COc1cc2c(c3c1OCO3)C(C)NCC2,Anhalonine,peyote alkaloid
|
| 333 |
+
COc1cc2c(c(O)c1OC)C(C)N(C)CC2,Pellotine,peyote alkaloid
|
| 334 |
+
COc1cc2c(c(O)c1OC)CN(C)CC2,Anhalidine,peyote alkaloid
|
| 335 |
+
COc1cc2c(c3c1OCO3)C(C)N(C)CC2,Lophophorine,peyote alkaloid
|
| 336 |
+
COc1cc(CCN)cc2c1OCO2,LOPHOPHINE,peyote alkaloid
|
| 337 |
+
COc1cc(CCNC(C)=O)cc(O)c1OC,N-Acetyl-3-demethymescaline,peyote alkaloid
|
| 338 |
+
COc1cc(CCN)cc(OC)c1OC,M,peyote alkaloid
|
| 339 |
+
COc1cc(CCN2C(=O)CCC2=O)cc(OC)c1OC,Mescaline succinimide,peyote alkaloid
|
| 340 |
+
COc1cc2c(c(O)c1OC)C(C)[N+](C)(C)CC2,Peyotine,peyote alkaloid
|
| 341 |
+
COc1cc2c(c(OC)c1OC)C(C)NCC2,O-Methylanhalonidine,peyote alkaloid
|
| 342 |
+
COc1cc2c(c(O)c1OC)CNCC2,Anhalamine,peyote alkaloid
|
| 343 |
+
COc1cc(CCN2C(=O)CC(O)(CC(=O)O)C2=O)cc(OC)c1OC,Mescaline citrimide,peyote alkaloid
|
| 344 |
+
CN(C)CCc1ccc(O)cc1,Hordenine,peyote alkaloid
|
| 345 |
+
COc1cc(CCNC=O)cc(OC)c1OC,N-Formylmescaline,peyote alkaloid
|
| 346 |
+
CNCCc1cc(O)c(OC)c(OC)c1,N-Me-3-DESMETHYL,peyote alkaloid
|
| 347 |
+
COc1cc(CCn2c(C=O)ccc2CO)cc(OC)c1OC,Peyoglunal,peyote alkaloid
|
| 348 |
+
COc1cc(CCNC=O)cc(O)c1OC,N-Formyl-3-demethylmescaline,peyote alkaloid
|
| 349 |
+
NCCc1ccc(O)c(O)c1,Dopamine,peyote alkaloid
|
| 350 |
+
COc1cc2c(c3c1OCO3)C(C)N(C=O)CC2,N-Formylanhalonine,peyote alkaloid
|
| 351 |
+
CNCCc1ccc(O)c(OC)c1,N-Me-GEA,peyote alkaloid
|
| 352 |
+
COc1cc2c(c(OC)c1OC)CN(C=O)CC2,N-Formylanhalinine,peyote alkaloid
|
| 353 |
+
COc1cc(CCN2C(=O)C3CC(=O)OC3C2=O)cc(OC)c1OC,Mescaline isocitrimide lactone,peyote alkaloid
|
| 354 |
+
COc1cc2c(c(OC)c1OC)C(C)N(C)CC2,O-Methylpellotine,peyote alkaloid
|
| 355 |
+
CCC(C)N(CCc1c[nH]c2ccc(F)cc12)C(C)C,5-Fluoro-IPSBT,tryptamine
|
| 356 |
+
CC(C)N(CCc1c[nH]c2ccc(F)cc12)CC1CC1,5-Fluoro-N-cyclopropylmethyl-NIPT,tryptamine
|
| 357 |
+
CCCCCCN(C)CCc1c[nH]c2ccc(OC)cc12,N-[2-(5-Methoxy-1H-indol-3-yl)ethyl]-N-methylhexan-1-amine,tryptamine
|
| 358 |
+
CN(C)CCc1c[nH]c2c(Br)ccc(O)c12,7-Bromopsilocin,tryptamine
|
| 359 |
+
CCCCN(CCCC)CCc1c[nH]c2cc(OC)c(OC)cc12,"5,6-MeO-DBT",tryptamine
|
| 360 |
+
CN(C/C=C/c1ccccc1)CCc1c[nH]c2ccccc12,N-Phenylpropenyl-NMT,tryptamine
|
| 361 |
+
COc1cc2[nH]cc(CCN3CCCC3)c2cc1OC,"5,6-MeO-pyr-T",tryptamine
|
| 362 |
+
Cn1cc(CCN)c2c3c(ccc21)OCCC3,"CP 132,484",tryptamine
|
| 363 |
+
C=CCN(CCc1c(C)[nH]c2ccc(OC)cc12)C1CCCCC1,2-Methyl-5-methoxy-N-allyl-N-cyclohexyltryptamine,tryptamine
|
| 364 |
+
Cc1cc(OP(=O)(O)O)c2c(CCN)c[nH]c2c1,6-Methyl-4-PO-T,tryptamine
|
| 365 |
+
CCCCCN(CCCCC)CCc1c[nH]c2ccccc12,"N,N-Dipentyltryptamine",tryptamine
|
| 366 |
+
COc1ccc2[nH]cc(CC3CCCN3C)c2c1,CP-108509,tryptamine
|
| 367 |
+
COc1ccc(OC)c(CCCN(C)CCc2c[nH]c3ccc(OC)cc23)c1,"3-(2,5-Dimethoxyphenyl)-N-[2-(5-methoxy-1H-indol-3-yl)ethyl]-N-methylpropan-1-amine",tryptamine
|
| 368 |
+
C=CCN(CCc1c[nH]c2ccc(F)cc12)C(C)C,5-Fluoro-ALIPT,tryptamine
|
| 369 |
+
NCCc1c[nH]c2ccc(OC3CCCC3)cc12,5-Cyclopentyloxy-T,tryptamine
|
| 370 |
+
COc1ccc(OC)c(CCN(C)CCc2c[nH]c3ccc(OC)cc23)c1,"N-(2,5-Dimethoxyphenylethyl)-5-MeO-NMT",tryptamine
|
| 371 |
+
Oc1cccc2[nH]cc(CCN3CCCCC3)c12,4-HO-pip-T,tryptamine
|
| 372 |
+
CN(C)CCc1c[nH]c2cccc(OCc3ccccc3)c12,4-Benzyloxy-DMT,tryptamine
|
| 373 |
+
CN(C)CCc1c[nH]c2cccc(OC(=O)SCc3ccccc3)c12,S-Benzyl O-{3-[2-(dimethylamino)ethyl]-1H-indol-4-yl} carbonothioate,tryptamine
|
| 374 |
+
COc1cc(OC)c2[nH]cc(CCNCc3ccccc3)c2c1,"5,7-MeO-T-NB",tryptamine
|
| 375 |
+
CNC(C)Cc1c[nH]c2ccc(OCc3ccccc3)cc12,5-Benzyloxy-alpha-methyl-NMT,tryptamine
|
| 376 |
+
CC(C)(C)CCCCCCCOc1ccc2[nH]cc(CCN)c2c1,"5-(8,8-Dimethylnonyloxy)-T",tryptamine
|
| 377 |
+
CCCOc1ccc2[nH]cc(CCN(CC)CC)c2c1,5-PrO-DET,tryptamine
|
| 378 |
+
COc1ccc2[nH]cc(CCN(C)CCCc3cc(OC)c(OC)c(OC)c3)c2c1,"N-(3,4,5-Trimethoxyphenylpropyl)-5-MeO-NMT",tryptamine
|
| 379 |
+
c1ccc2c(CCN3CCN(CCc4c[nH]c5ccccc45)CC3)c[nH]c2c1,"3,3'-[Piperazine-1,4-diyldi(ethane-2,1-diyl)]di(1H-indole)",tryptamine
|
| 380 |
+
CC(C)N(CCc1c[nH]c2cccc(OCc3ccccc3)c12)C(C)C,4-Benzyloxy-DIPT,tryptamine
|
| 381 |
+
CC(C)N(CCc1c[nH]c2ccc(F)cc12)C1CCC1,5-Fluoro-IPCBT,tryptamine
|
| 382 |
+
CCOc1ccc(CNCCc2c[nH]c3ccccc23)cc1,T-NB4OEt,tryptamine
|
| 383 |
+
O=C(O)CCNCCc1c[nH]c2cc([N+](=O)[O-])ccc12,6-Nitro-N-(2-carboxyethyl)tryptamine,tryptamine
|
| 384 |
+
CN1CCN(CCc2c[nH]c3cccc(O)c23)CC1,4'-Methyl-4-HO-piperazine-T,tryptamine
|
| 385 |
+
CN(CCC#N)CCc1c[nH]c2ccccc12,N-Cyanoethyl-NMT,tryptamine
|
| 386 |
+
COc1cc(F)c2[nH]cc(CCN(C)C)c2c1,7-Fluoro-5-MeO-DMT,tryptamine
|
| 387 |
+
CN(CCc1c[nH]c2ccc(F)cc12)C1CCC1,5-Fluoro-MCBT,tryptamine
|
| 388 |
+
CNCCc1c[nH]c2c(OC)cccc12,7-MeO-NMT,tryptamine
|
| 389 |
+
Cc1c(O)c(O)cc2c(CCN)c[nH]c12,"7-Methyl-5,6-HO-T",tryptamine
|
| 390 |
+
Oc1ccc(CNCCc2c[nH]c3ccccc23)cc1,T-NB4OH,tryptamine
|
| 391 |
+
COc1c(Br)cc(Br)cc1CNCCc1c[nH]c2ccccc12,T-NBOMe35Br,tryptamine
|
| 392 |
+
CCn1cc(CCN(C)C)c2c(OCc3ccccc3)cc(F)cc21,1-Ethyl-6-fluoro-4-benzyloxy-DMT,tryptamine
|
| 393 |
+
CN(C)CCc1c[nH]c2cccc(OC(=O)c3cccc(C(=O)Oc4cccc5[nH]cc(CCN(C)C)c45)c3)c12,"Bis{3-[2-(dimethylamino)ethyl]-1H-indol-4-yl} benzene-1,3-dicarboxylate",tryptamine
|
| 394 |
+
CCN(CC)C(=O)CCN(C)CCc1c[nH]c2ccc(OC)cc12,"N,N-Diethyl-N3-[2-(5-methoxy-1H-indol-3-yl)ethyl]-N3-methyl-beta-alaninamide",tryptamine
|
| 395 |
+
COc1ccc(CNCCc2c[nH]c3c(Br)cc(OC)cc23)cc1,7-Bromo-5-MeO-T-NB4OMe,tryptamine
|
| 396 |
+
CCCN(C)CCc1c[nH]c2ccc(F)cc12,5-Fluoro-MPT,tryptamine
|
| 397 |
+
CN(CCc1c[nH]c2cc3c(cc12)OCO3)Cc1ccccc1,"5,6-MDO-NMT-NB",tryptamine
|
| 398 |
+
Cc1c(OC(=O)CCC(=O)O)ccc2[nH]cc(CCN(C)C)c12,Psilocin-4-methyl-5-succinate,tryptamine
|
| 399 |
+
COc1ccc2[nH]cc(CC(C)N)c2c1Br,4-Bromo-5-MeO-AMT,tryptamine
|
| 400 |
+
CN(C)CC(=O)c1c[nH]c2cc(F)ccc12,beta-Oxo-6-fluoro-DMT,tryptamine
|
| 401 |
+
COc1ccc2[nH]cc(C(O)CN(C)C)c2c1,beta-HO-5-MeO-DMT,tryptamine
|
| 402 |
+
COc1cccc2c(CCN)c[nH]c12,7-MeO-T,tryptamine
|
| 403 |
+
COc1cc(I)c2[nH]cc(CCN(C)C)c2c1,7-Iodo-5-MeO-DMT,tryptamine
|
| 404 |
+
C[C@@H]1CC[C@H](C)N1CCc1c[nH]c2ccccc12,"(R,S)-Dimethyl-pyr-T",tryptamine
|
| 405 |
+
COc1ccc(Sn2cc(CCN(C)C)c3c(OC)cccc32)cc1,1-(4-Methoxyphenylthio)-4-MeO-DMT,tryptamine
|
| 406 |
+
CCCN(CCc1c[nH]c2c(F)cccc12)C1CCC1,7-Fluoro-PCBT,tryptamine
|
| 407 |
+
CC(=O)NCCc1c[nH]c2cc(F)cc(NC(C)=O)c12,6-Fluoro-4-acetamido-N-acetyltryptamine,tryptamine
|
| 408 |
+
CCCCS(=O)(=O)n1cc(CCN(C)C)c2c(OC)cccc21,1-Butylsulfonyl-4-MeO-DMT,tryptamine
|
| 409 |
+
CCCN(CCC)CCc1c[nH]c2ccc(OC(C)=O)cc12,5-AcO-DPT,tryptamine
|
| 410 |
+
CN(C)CCc1cn(C)c2ccccc12,1-TMT,tryptamine
|
| 411 |
+
CCN(CCc1c[nH]c2cc(F)c(F)cc12)C(C)C,"5,6-Difluoro-EIPT",tryptamine
|
| 412 |
+
CN(C)CC(=O)c1c[nH]c2c(F)cc(F)cc12,"beta-Oxo-5,7-difluoro-DMT",tryptamine
|
| 413 |
+
CN(C)CCc1cn(C)c2cc(F)cc(OCc3ccccc3)c12,1-Methyl-6-fluoro-4-benzyloxy-DMT,tryptamine
|
| 414 |
+
CCCc1[nH]c2ccc(OC)cc2c1CCN(C)C,2-Propyl-5-MeO-DMT,tryptamine
|
| 415 |
+
CC(=O)Oc2cccc1[nH]cc(CCN(C)C)c12,4-AcO-DMT,tryptamine
|
src/src/data/sample_smiles.csv
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
smiles,name,category
|
| 2 |
+
CCO,Ethanol,Alcohol
|
| 3 |
+
CC(=O)O,Acetic acid,Carboxylic acid
|
| 4 |
+
c1ccccc1,Benzene,Aromatic hydrocarbon
|
| 5 |
+
CC(C)O,Isopropanol,Alcohol
|
| 6 |
+
c1ccc(cc1)O,Phenol,Aromatic alcohol
|
| 7 |
+
CC(=O)OC1=CC=CC=C1C(=O)O,Aspirin,Carboxylic acid ester
|
| 8 |
+
CN1C=NC2=C1C(=O)N(C(=O)N2C)C,Caffeine,Alkaloid
|
| 9 |
+
CCN(CC)CC,Triethylamine,Amine
|
| 10 |
+
c1ccc2c(c1)cccn2,Quinoline,Aromatic heterocycle
|
| 11 |
+
c1ccc(cc1)N,Aniline,Aromatic amine
|
| 12 |
+
O=P(O)(O)OP(=O)(O)OP(=O)(O)OC[C@H]3O[C@@H](n2cnc1c(ncnc12)N)[C@H](O)[C@@H]3O,ATP,Nucleotide
|
| 13 |
+
CN(C)CCC1=CNC2=C1C(=CC=C2)OP(=O)(O)O,Psilocybin,Tryptamine
|
src/src/main.js
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview JSME (JavaScript Molecule Editor) integration with Gradio interface
|
| 3 |
+
* Handles bidirectional synchronization between JSME applet and Gradio textbox
|
| 4 |
+
* @author Manny Cortes ('[email protected]')
|
| 5 |
+
* @version 0.2.0
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
// ============================================================================
|
| 9 |
+
// GLOBAL VARIABLES
|
| 10 |
+
// ============================================================================
|
| 11 |
+
|
| 12 |
+
/** @type {Object|null} The JSME applet instance */
|
| 13 |
+
let jsmeApplet = null;
|
| 14 |
+
|
| 15 |
+
/** @type {string} Last known value of the textbox to prevent infinite loops */
|
| 16 |
+
let lastTextboxValue = "";
|
| 17 |
+
|
| 18 |
+
// ============================================================================
|
| 19 |
+
// CONSTANTS
|
| 20 |
+
// ============================================================================
|
| 21 |
+
|
| 22 |
+
/** @const {string} Default SMILES for initial molecule (ethanol) */
|
| 23 |
+
const DEFAULT_SMILES = "CCO";
|
| 24 |
+
|
| 25 |
+
/** @const {string} Container height for JSME applet */
|
| 26 |
+
const CONTAINER_HEIGHT = "450px";
|
| 27 |
+
|
| 28 |
+
/** @const {string} CSS selector for the Gradio SMILES input element */
|
| 29 |
+
const SMILES_INPUT_SELECTOR = "#smiles_input textarea, #smiles_input input";
|
| 30 |
+
|
| 31 |
+
/** @const {number} Delay for paste event handling (ms) */
|
| 32 |
+
const PASTE_DELAY = 50;
|
| 33 |
+
|
| 34 |
+
/** @const {number} Delay for initialization retry (ms) */
|
| 35 |
+
const INIT_RETRY_DELAY = 2000;
|
| 36 |
+
|
| 37 |
+
/** @const {string[]} Events to trigger for Gradio change detection */
|
| 38 |
+
const GRADIO_CHANGE_EVENTS = ["input", "change", "keyup"];
|
| 39 |
+
|
| 40 |
+
// ============================================================================
|
| 41 |
+
// CORE INITIALIZATION
|
| 42 |
+
// ============================================================================
|
| 43 |
+
|
| 44 |
+
/**
|
| 45 |
+
* Initializes the JSME applet after the library has been loaded
|
| 46 |
+
* Sets up the molecular editor with default options and callbacks
|
| 47 |
+
* @throws {Error} When JSME initialization fails
|
| 48 |
+
*/
|
| 49 |
+
function initializeJSME() {
|
| 50 |
+
try {
|
| 51 |
+
console.log("Initializing JSME...");
|
| 52 |
+
// https://github.com/jsme-editor/jsme-editor.github.io
|
| 53 |
+
// https://jsme-editor.github.io/dist/api_javadoc/index.html
|
| 54 |
+
// http://wiki.jmol.org/index.php/Jmol_JavaScript_Object/JME/Options
|
| 55 |
+
jsmeApplet = new JSApplet.JSME(
|
| 56 |
+
"jsme_container",
|
| 57 |
+
getJsmeContainerWidthPx(),
|
| 58 |
+
CONTAINER_HEIGHT,
|
| 59 |
+
{
|
| 60 |
+
options:
|
| 61 |
+
"rButton,zoom,zoomgui,newLook,star,multipart,polarnitro,NOexportInChI,NOexportInChIkey,NOsearchInChIkey,NOexportSVG,NOpaste",
|
| 62 |
+
}
|
| 63 |
+
);
|
| 64 |
+
|
| 65 |
+
jsmeApplet.setCallBack("AfterStructureModified", handleJSMEStructureChange);
|
| 66 |
+
jsmeApplet.setMenuScale(getJsmeGuiScale());
|
| 67 |
+
jsmeApplet.setUserInterfaceBackgroundColor("#adadad");
|
| 68 |
+
|
| 69 |
+
// Set initial molecule and sync state
|
| 70 |
+
jsmeApplet.readGenericMolecularInput(DEFAULT_SMILES);
|
| 71 |
+
lastTextboxValue = DEFAULT_SMILES;
|
| 72 |
+
|
| 73 |
+
setupTextboxEventListeners();
|
| 74 |
+
window.addEventListener("resize", handleResize);
|
| 75 |
+
|
| 76 |
+
console.log("JSME initialized successfully");
|
| 77 |
+
} catch (error) {
|
| 78 |
+
console.error("Error initializing JSME:", error);
|
| 79 |
+
throw error;
|
| 80 |
+
}
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
/**
|
| 84 |
+
* Handles structure changes in the JSME applet
|
| 85 |
+
* Converts the structure to SMILES and updates the Gradio textbox
|
| 86 |
+
* @param {Event} event - The JSME structure modification event
|
| 87 |
+
*/
|
| 88 |
+
function handleJSMEStructureChange(event) {
|
| 89 |
+
try {
|
| 90 |
+
const smiles = jsmeApplet.smiles();
|
| 91 |
+
updateGradioTextbox(smiles);
|
| 92 |
+
} catch (error) {
|
| 93 |
+
console.error("Error getting SMILES from JSME:", error);
|
| 94 |
+
}
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
/**
|
| 98 |
+
* Calculates the appropriate GUI scale for the JSME applet based on container width
|
| 99 |
+
* Uses breakpoints to determine optimal scaling for different screen sizes
|
| 100 |
+
* @returns {number} The scale factor for the JSME GUI (0.88 to 2.0)
|
| 101 |
+
*/
|
| 102 |
+
function getJsmeGuiScale() {
|
| 103 |
+
const width = getJsmeContainerWidthNumber();
|
| 104 |
+
let menuScale;
|
| 105 |
+
if (width > 460) {
|
| 106 |
+
menuScale = 1.3;
|
| 107 |
+
} else if (width > 420) {
|
| 108 |
+
menuScale = 1.1;
|
| 109 |
+
} else if (width > 370) {
|
| 110 |
+
menuScale = 1.05;
|
| 111 |
+
} else if (width > 300) {
|
| 112 |
+
menuScale = 0.88;
|
| 113 |
+
} else {
|
| 114 |
+
menuScale = 2;
|
| 115 |
+
}
|
| 116 |
+
return menuScale;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
/**
|
| 120 |
+
* Gets the JSME container width as a CSS-compatible string value
|
| 121 |
+
* Returns either a pixel value or percentage based on available width
|
| 122 |
+
* @returns {string} Width as "100%" or "{width}px" format
|
| 123 |
+
*/
|
| 124 |
+
function getJsmeContainerWidthPx() {
|
| 125 |
+
const parentWidth = getJsmeContainerWidthNumber();
|
| 126 |
+
if (parentWidth == null || parentWidth <= 0) {
|
| 127 |
+
return "100%";
|
| 128 |
+
}
|
| 129 |
+
return `${parentWidth}px`;
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
/**
|
| 133 |
+
* Gets the numeric width of the JSME container's parent element
|
| 134 |
+
* Used for responsive scaling calculations
|
| 135 |
+
* @returns {number|null} Width in pixels, or null if container not found
|
| 136 |
+
*/
|
| 137 |
+
function getJsmeContainerWidthNumber() {
|
| 138 |
+
const container = document.getElementById("jsme_container");
|
| 139 |
+
if (!container) {
|
| 140 |
+
return null;
|
| 141 |
+
}
|
| 142 |
+
return container.parentNode.offsetWidth;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
// ============================================================================
|
| 146 |
+
// GRADIO INTEGRATION
|
| 147 |
+
// ============================================================================
|
| 148 |
+
|
| 149 |
+
/**
|
| 150 |
+
* Updates the Gradio textbox with a SMILES string
|
| 151 |
+
* Triggers appropriate events to ensure Gradio detects the change
|
| 152 |
+
* @param {string} smiles - The SMILES string to set in the textbox
|
| 153 |
+
*/
|
| 154 |
+
function updateGradioTextbox(smiles) {
|
| 155 |
+
try {
|
| 156 |
+
const textbox = document.querySelector(SMILES_INPUT_SELECTOR);
|
| 157 |
+
|
| 158 |
+
if (!textbox || textbox.value === smiles) {
|
| 159 |
+
return;
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
textbox.value = smiles;
|
| 163 |
+
lastTextboxValue = smiles;
|
| 164 |
+
|
| 165 |
+
// Trigger events to ensure Gradio detects the change
|
| 166 |
+
GRADIO_CHANGE_EVENTS.forEach((eventType) => {
|
| 167 |
+
const event = new Event(eventType, {
|
| 168 |
+
bubbles: true,
|
| 169 |
+
cancelable: true,
|
| 170 |
+
});
|
| 171 |
+
textbox.dispatchEvent(event);
|
| 172 |
+
});
|
| 173 |
+
} catch (error) {
|
| 174 |
+
console.error("Error updating Gradio textbox:", error);
|
| 175 |
+
}
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
// ============================================================================
|
| 179 |
+
// JSME UPDATE FUNCTIONS
|
| 180 |
+
// ============================================================================
|
| 181 |
+
|
| 182 |
+
/**
|
| 183 |
+
* Updates the JSME applet with a SMILES string from the textbox
|
| 184 |
+
* @param {string} smiles - The SMILES string to display in JSME
|
| 185 |
+
*/
|
| 186 |
+
function updateJSMEFromTextbox(smiles) {
|
| 187 |
+
if (!jsmeApplet) {
|
| 188 |
+
return;
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
try {
|
| 192 |
+
if (smiles && smiles.trim() !== "") {
|
| 193 |
+
jsmeApplet.readGenericMolecularInput(smiles.trim());
|
| 194 |
+
} else {
|
| 195 |
+
jsmeApplet.reset();
|
| 196 |
+
}
|
| 197 |
+
lastTextboxValue = smiles;
|
| 198 |
+
} catch (error) {
|
| 199 |
+
console.error("Error updating JSME from textbox:", error);
|
| 200 |
+
}
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
// ============================================================================
|
| 204 |
+
// UI MONITORING
|
| 205 |
+
// ============================================================================
|
| 206 |
+
|
| 207 |
+
/**
|
| 208 |
+
* Finds the textbox element and sets up event listeners
|
| 209 |
+
*/
|
| 210 |
+
function setupTextboxEventListeners() {
|
| 211 |
+
const textbox = document.querySelector(SMILES_INPUT_SELECTOR);
|
| 212 |
+
if (!textbox) {
|
| 213 |
+
return;
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
textbox.addEventListener("input", handleTextboxChange);
|
| 217 |
+
textbox.addEventListener("change", handleTextboxChange);
|
| 218 |
+
textbox.addEventListener("paste", handleTextboxPaste);
|
| 219 |
+
textbox.addEventListener("keyup", handleTextboxChange);
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
/**
|
| 223 |
+
* Handles textbox change events
|
| 224 |
+
* @param {Event} event - The change event
|
| 225 |
+
*/
|
| 226 |
+
function handleTextboxChange(event) {
|
| 227 |
+
if (event.target.value !== lastTextboxValue) {
|
| 228 |
+
updateJSMEFromTextbox(event.target.value);
|
| 229 |
+
}
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
/**
|
| 233 |
+
* Handles textbox paste events with a delay to ensure content is available
|
| 234 |
+
* @param {Event} event - The paste event
|
| 235 |
+
*/
|
| 236 |
+
function handleTextboxPaste(event) {
|
| 237 |
+
setTimeout(() => {
|
| 238 |
+
updateJSMEFromTextbox(event.target.value);
|
| 239 |
+
}, PASTE_DELAY);
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
/**
|
| 243 |
+
* Handles window resize events and updates JSME applet width
|
| 244 |
+
*/
|
| 245 |
+
function handleResize() {
|
| 246 |
+
if (!jsmeApplet) {
|
| 247 |
+
return;
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
try {
|
| 251 |
+
jsmeApplet.setMenuScale(getJsmeGuiScale());
|
| 252 |
+
jsmeApplet.setWidth(getJsmeContainerWidthPx());
|
| 253 |
+
} catch (error) {
|
| 254 |
+
console.error("Error resizing JSME applet:", error);
|
| 255 |
+
}
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
// ============================================================================
|
| 259 |
+
// PUBLIC API
|
| 260 |
+
// ============================================================================
|
| 261 |
+
|
| 262 |
+
/**
|
| 263 |
+
* Sets a SMILES string in both JSME and Gradio textbox
|
| 264 |
+
* @param {string} smiles - The SMILES string to set
|
| 265 |
+
* @returns {string} The SMILES string that was set
|
| 266 |
+
* @public
|
| 267 |
+
*/
|
| 268 |
+
window.setJSMESmiles = function (smiles) {
|
| 269 |
+
if (jsmeApplet) {
|
| 270 |
+
updateJSMEFromTextbox(smiles);
|
| 271 |
+
}
|
| 272 |
+
|
| 273 |
+
updateGradioTextbox(smiles);
|
| 274 |
+
return smiles;
|
| 275 |
+
};
|
| 276 |
+
|
| 277 |
+
/**
|
| 278 |
+
* Clears both JSME and Gradio textbox
|
| 279 |
+
* @returns {Array} Array containing cleared state for Gradio components
|
| 280 |
+
* @public
|
| 281 |
+
*/
|
| 282 |
+
window.clearJSME = function () {
|
| 283 |
+
if (jsmeApplet) {
|
| 284 |
+
jsmeApplet.reset();
|
| 285 |
+
}
|
| 286 |
+
|
| 287 |
+
updateGradioTextbox("");
|
| 288 |
+
return ["", [], [], "Cleared - Draw a new molecule or enter SMILES"];
|
| 289 |
+
};
|
| 290 |
+
|
| 291 |
+
// ============================================================================
|
| 292 |
+
// INITIALIZATION LOGIC
|
| 293 |
+
// ============================================================================
|
| 294 |
+
|
| 295 |
+
/**
|
| 296 |
+
* Checks if JSME library is loaded and initializes JSME applet
|
| 297 |
+
* Retries until the library becomes available
|
| 298 |
+
*/
|
| 299 |
+
function initializeWhenReady() {
|
| 300 |
+
if (typeof JSApplet !== "undefined" && JSApplet.JSME) {
|
| 301 |
+
console.log("JSME library loaded, initializing...");
|
| 302 |
+
initializeJSME();
|
| 303 |
+
} else {
|
| 304 |
+
console.log("JSME library not ready, retrying...");
|
| 305 |
+
setTimeout(initializeWhenReady, INIT_RETRY_DELAY);
|
| 306 |
+
}
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
/**
|
| 310 |
+
* Starts the initialization process based on document ready state
|
| 311 |
+
*/
|
| 312 |
+
function startInitialization() {
|
| 313 |
+
if (document.readyState === "loading") {
|
| 314 |
+
document.addEventListener("DOMContentLoaded", () => {
|
| 315 |
+
setTimeout(initializeWhenReady, INIT_RETRY_DELAY);
|
| 316 |
+
});
|
| 317 |
+
} else {
|
| 318 |
+
setTimeout(initializeWhenReady, INIT_RETRY_DELAY);
|
| 319 |
+
}
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
startInitialization();
|
src/src/main.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
function initializeJSME(){try{(jsmeApplet=new JSApplet.JSME("jsme_container",getJsmeContainerWidthPx(),CONTAINER_HEIGHT,{options:"rButton,zoom,zoomgui,newLook,star,multipart,polarnitro,NOexportInChI,NOexportInChIkey,NOsearchInChIkey,NOexportSVG,NOpaste"})).setCallBack("AfterStructureModified",handleJSMEStructureChange),jsmeApplet.setMenuScale(getJsmeGuiScale()),jsmeApplet.setUserInterfaceBackgroundColor("#adadad"),jsmeApplet.readGenericMolecularInput(DEFAULT_SMILES),lastTextboxValue=DEFAULT_SMILES,setupTextboxEventListeners(),window.addEventListener("resize",handleResize)}catch(e){throw e}}function handleJSMEStructureChange(){try{updateGradioTextbox(jsmeApplet.smiles())}catch(e){}}function getJsmeGuiScale(){const e=getJsmeContainerWidthNumber();return e>460?1.3:e>420?1.1:e>370?1.05:e>300?.88:2}function getJsmeContainerWidthPx(){const e=getJsmeContainerWidthNumber();return null==e||e<=0?"100%":`${e}px`}function getJsmeContainerWidthNumber(){const e=document.getElementById("jsme_container");return e?e.parentNode.offsetWidth:null}function updateGradioTextbox(e){try{const t=document.querySelector(SMILES_INPUT_SELECTOR);if(!t||t.value===e)return;t.value=e,lastTextboxValue=e,GRADIO_CHANGE_EVENTS.forEach(e=>{const n=new Event(e,{bubbles:!0,cancelable:!0});t.dispatchEvent(n)})}catch(e){}}function updateJSMEFromTextbox(e){if(jsmeApplet)try{e&&""!==e.trim()?jsmeApplet.readGenericMolecularInput(e.trim()):jsmeApplet.reset(),lastTextboxValue=e}catch(e){}}function setupTextboxEventListeners(){const e=document.querySelector(SMILES_INPUT_SELECTOR);e&&(e.addEventListener("input",handleTextboxChange),e.addEventListener("change",handleTextboxChange),e.addEventListener("paste",handleTextboxPaste),e.addEventListener("keyup",handleTextboxChange))}function handleTextboxChange(e){e.target.value!==lastTextboxValue&&updateJSMEFromTextbox(e.target.value)}function handleTextboxPaste(e){setTimeout(()=>{updateJSMEFromTextbox(e.target.value)},PASTE_DELAY)}function handleResize(){if(jsmeApplet)try{jsmeApplet.setMenuScale(getJsmeGuiScale()),jsmeApplet.setWidth(getJsmeContainerWidthPx())}catch(e){}}function initializeWhenReady(){"undefined"!=typeof JSApplet&&JSApplet.JSME?initializeJSME():setTimeout(initializeWhenReady,INIT_RETRY_DELAY)}function startInitialization(){"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{setTimeout(initializeWhenReady,INIT_RETRY_DELAY)}):setTimeout(initializeWhenReady,INIT_RETRY_DELAY)}let jsmeApplet=null,lastTextboxValue="";const DEFAULT_SMILES="CCO",CONTAINER_HEIGHT="450px",SMILES_INPUT_SELECTOR="#smiles_input textarea, #smiles_input input",PASTE_DELAY=50,INIT_RETRY_DELAY=2e3,GRADIO_CHANGE_EVENTS=["input","change","keyup"];window.setJSMESmiles=function(e){return jsmeApplet&&updateJSMEFromTextbox(e),updateGradioTextbox(e),e},window.clearJSME=function(){return jsmeApplet&&jsmeApplet.reset(),updateGradioTextbox(""),["",[],[],"Cleared - Draw a new molecule or enter SMILES"]},startInitialization();
|
src/src/service.py
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import logging
|
| 2 |
+
import os
|
| 3 |
+
from typing import TypedDict
|
| 4 |
+
|
| 5 |
+
import numpy as np
|
| 6 |
+
import pandas as pd
|
| 7 |
+
import redis
|
| 8 |
+
from chem_mrl.molecular_fingerprinter import MorganFingerprinter
|
| 9 |
+
from dotenv import load_dotenv
|
| 10 |
+
from redis.commands.search.field import TextField, VectorField
|
| 11 |
+
from redis.commands.search.indexDefinition import IndexDefinition, IndexType
|
| 12 |
+
from redis.commands.search.query import Query
|
| 13 |
+
from sentence_transformers import SentenceTransformer
|
| 14 |
+
|
| 15 |
+
from constants import (
|
| 16 |
+
EMBEDDING_DIMENSION,
|
| 17 |
+
HNSW_K,
|
| 18 |
+
HNSW_PARAMETERS,
|
| 19 |
+
MODEL_NAME,
|
| 20 |
+
SUPPORTED_EMBEDDING_DIMENSIONS,
|
| 21 |
+
)
|
| 22 |
+
from data import DATASET_SMILES, ISOMER_DESIGN_SUBSET
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def setup_logger(clear_handler=False):
|
| 26 |
+
if clear_handler:
|
| 27 |
+
for handler in logging.root.handlers[:]:
|
| 28 |
+
logging.root.removeHandler(handler) # issue with sentence-transformer's logging handler
|
| 29 |
+
logging.basicConfig(format="%(asctime)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S", level=logging.INFO)
|
| 30 |
+
logger = logging.getLogger(__name__)
|
| 31 |
+
return logger
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
load_dotenv("../.env")
|
| 35 |
+
logger = setup_logger(clear_handler=True)
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
class SimilarMolecule(TypedDict):
|
| 39 |
+
smiles: str
|
| 40 |
+
name: str
|
| 41 |
+
category: str
|
| 42 |
+
score: float
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
class MolecularEmbeddingService:
|
| 46 |
+
def __init__(self):
|
| 47 |
+
self.model_name = MODEL_NAME
|
| 48 |
+
self.index_name = "molecule_embeddings"
|
| 49 |
+
self.model_embed_dim = EMBEDDING_DIMENSION
|
| 50 |
+
|
| 51 |
+
self.model = self._initialize_model()
|
| 52 |
+
self.redis_client = self._initialize_redis()
|
| 53 |
+
self._initialize_datastore()
|
| 54 |
+
|
| 55 |
+
def _initialize_model(self):
|
| 56 |
+
"""Initialize the Hugging Face transformers model"""
|
| 57 |
+
try:
|
| 58 |
+
model = SentenceTransformer(self.model_name) # type: ignore
|
| 59 |
+
model.eval()
|
| 60 |
+
return model
|
| 61 |
+
except Exception as e:
|
| 62 |
+
logger.error(f"Failed to load model: {e}")
|
| 63 |
+
raise
|
| 64 |
+
|
| 65 |
+
def _initialize_redis(self):
|
| 66 |
+
"""Initialize Redis connection"""
|
| 67 |
+
try:
|
| 68 |
+
redis_host = os.getenv("REDIS_HOST", "localhost")
|
| 69 |
+
redis_port = int(os.getenv("REDIS_PORT", 6379))
|
| 70 |
+
redis_password = os.getenv("REDIS_PASSWORD", None)
|
| 71 |
+
logger.info(
|
| 72 |
+
f"Connecting to Redis at {redis_host}:{redis_port} with password: {'***' if redis_password else 'None'}"
|
| 73 |
+
)
|
| 74 |
+
redis_client = redis.Redis(
|
| 75 |
+
host=redis_host,
|
| 76 |
+
port=redis_port,
|
| 77 |
+
password=redis_password,
|
| 78 |
+
decode_responses=True,
|
| 79 |
+
)
|
| 80 |
+
redis_client.ping()
|
| 81 |
+
return redis_client
|
| 82 |
+
except Exception as e:
|
| 83 |
+
logger.error(f"Failed to connect to Redis: {e}")
|
| 84 |
+
raise
|
| 85 |
+
|
| 86 |
+
def _initialize_datastore(self):
|
| 87 |
+
self.__create_hnsw_index()
|
| 88 |
+
self.__populate_sample_data(DATASET_SMILES)
|
| 89 |
+
self.__populate_sample_data(ISOMER_DESIGN_SUBSET)
|
| 90 |
+
|
| 91 |
+
def __create_hnsw_index(self):
|
| 92 |
+
"""Create HNSW index for molecular embeddings"""
|
| 93 |
+
try:
|
| 94 |
+
self.redis_client.ft(self.index_name).info()
|
| 95 |
+
logger.info(f"Index {self.index_name} already exists")
|
| 96 |
+
return
|
| 97 |
+
except redis.exceptions.ResponseError:
|
| 98 |
+
pass
|
| 99 |
+
|
| 100 |
+
try:
|
| 101 |
+
schema: list[TextField | VectorField] = [
|
| 102 |
+
VectorField(
|
| 103 |
+
self.embedding_field_name(dim),
|
| 104 |
+
"HNSW",
|
| 105 |
+
{
|
| 106 |
+
**HNSW_PARAMETERS,
|
| 107 |
+
"DIM": dim,
|
| 108 |
+
},
|
| 109 |
+
)
|
| 110 |
+
for dim in SUPPORTED_EMBEDDING_DIMENSIONS
|
| 111 |
+
]
|
| 112 |
+
schema.insert(0, TextField("smiles"))
|
| 113 |
+
|
| 114 |
+
self.redis_client.ft(self.index_name).create_index(
|
| 115 |
+
schema,
|
| 116 |
+
definition=IndexDefinition(prefix=[self.molecule_index_prefix("")], index_type=IndexType.HASH),
|
| 117 |
+
)
|
| 118 |
+
|
| 119 |
+
logger.info(f"Created HNSW index: {self.index_name}")
|
| 120 |
+
|
| 121 |
+
except Exception as e:
|
| 122 |
+
logger.error(f"Failed to create HNSW index: {e}")
|
| 123 |
+
raise
|
| 124 |
+
|
| 125 |
+
def __populate_sample_data(self, df: pd.DataFrame):
|
| 126 |
+
"""Populate Redis with sample molecular data"""
|
| 127 |
+
logger.info("Populating Redis with sample molecular data...")
|
| 128 |
+
for _, row in df.iterrows():
|
| 129 |
+
try:
|
| 130 |
+
key = self.molecule_index_prefix(row["smiles"])
|
| 131 |
+
if self.redis_client.exists(key):
|
| 132 |
+
continue
|
| 133 |
+
|
| 134 |
+
mapping: dict[str, bytes | str] = {
|
| 135 |
+
self.embedding_field_name(embed_dim): self.get_molecular_embedding(
|
| 136 |
+
row["smiles"], embed_dim
|
| 137 |
+
).tobytes()
|
| 138 |
+
for embed_dim in SUPPORTED_EMBEDDING_DIMENSIONS
|
| 139 |
+
}
|
| 140 |
+
mapping = {**mapping, **row.to_dict()}
|
| 141 |
+
|
| 142 |
+
self.redis_client.hset(
|
| 143 |
+
key,
|
| 144 |
+
mapping=mapping,
|
| 145 |
+
)
|
| 146 |
+
|
| 147 |
+
except Exception as e:
|
| 148 |
+
logger.error(f"Failed to process molecule {row}: {e}")
|
| 149 |
+
continue
|
| 150 |
+
|
| 151 |
+
logger.info(f"Populated {len(df)} sample molecules")
|
| 152 |
+
|
| 153 |
+
def get_molecular_embedding(self, smiles: str, embed_dim: int) -> np.ndarray:
|
| 154 |
+
"""Generate molecular embedding using ChemMRL"""
|
| 155 |
+
try:
|
| 156 |
+
if embed_dim <= 0:
|
| 157 |
+
raise ValueError("embed_dim must be positive")
|
| 158 |
+
|
| 159 |
+
# Preprocess smiles similarly as training data for optimal performance
|
| 160 |
+
smiles = MorganFingerprinter.canonicalize_smiles(smiles) or smiles
|
| 161 |
+
|
| 162 |
+
embedding: np.ndarray = self.model.encode(
|
| 163 |
+
[smiles],
|
| 164 |
+
show_progress_bar=False,
|
| 165 |
+
convert_to_numpy=True,
|
| 166 |
+
)[0]
|
| 167 |
+
|
| 168 |
+
return self._truncate_and_normalize_embedding(embedding, embed_dim)
|
| 169 |
+
|
| 170 |
+
except Exception as e:
|
| 171 |
+
logger.error(f"Failed to generate embedding for {smiles}: {e}")
|
| 172 |
+
raise
|
| 173 |
+
|
| 174 |
+
def _truncate_and_normalize_embedding(self, embedding: np.ndarray, embed_dim: int) -> np.ndarray:
|
| 175 |
+
"""Truncate and normalize embedding"""
|
| 176 |
+
if embed_dim < len(embedding):
|
| 177 |
+
embedding = embedding[:embed_dim]
|
| 178 |
+
norms = np.linalg.norm(embedding, ord=2, keepdims=True)
|
| 179 |
+
return embedding / np.where(norms == 0, 1, norms)
|
| 180 |
+
|
| 181 |
+
def find_similar_molecules(
|
| 182 |
+
self, query_embedding: np.ndarray, embed_dim: int, k: int = HNSW_K
|
| 183 |
+
) -> list[SimilarMolecule]:
|
| 184 |
+
"""Find k most similar molecules using HNSW"""
|
| 185 |
+
try:
|
| 186 |
+
query_vector = query_embedding.astype(np.float32).tobytes()
|
| 187 |
+
query = (
|
| 188 |
+
Query(f"*=>[KNN {k} @{self.embedding_field_name(embed_dim)} $vec AS score]")
|
| 189 |
+
.sort_by("score")
|
| 190 |
+
.return_fields("smiles", "name", "category", "score")
|
| 191 |
+
.dialect(2)
|
| 192 |
+
)
|
| 193 |
+
|
| 194 |
+
results = self.redis_client.ft(self.index_name).search(query, query_params={"vec": query_vector})
|
| 195 |
+
|
| 196 |
+
neighbors: list[SimilarMolecule] = [
|
| 197 |
+
{"smiles": doc.smiles, "name": doc.name, "category": doc.category, "score": float(doc.score)}
|
| 198 |
+
for doc in results.docs
|
| 199 |
+
]
|
| 200 |
+
|
| 201 |
+
return neighbors
|
| 202 |
+
|
| 203 |
+
except Exception as e:
|
| 204 |
+
logger.error(f"Failed to find similar molecules: {e}")
|
| 205 |
+
return []
|
| 206 |
+
|
| 207 |
+
@staticmethod
|
| 208 |
+
def embedding_field_name(dim: int) -> str:
|
| 209 |
+
return f"embedding_{dim}"
|
| 210 |
+
|
| 211 |
+
@staticmethod
|
| 212 |
+
def molecule_index_prefix(smiles: str) -> str:
|
| 213 |
+
return f"mol:{smiles}"
|