@wentorai/research-plugins 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -22
- package/curated/analysis/README.md +71 -56
- package/curated/domains/README.md +176 -67
- package/curated/literature/README.md +71 -47
- package/curated/research/README.md +91 -58
- package/curated/tools/README.md +88 -87
- package/curated/writing/README.md +80 -45
- package/mcp-configs/cloud-docs/confluence-mcp.json +37 -0
- package/mcp-configs/cloud-docs/google-drive-mcp.json +35 -0
- package/mcp-configs/cloud-docs/notion-mcp.json +29 -0
- package/mcp-configs/communication/discord-mcp.json +29 -0
- package/mcp-configs/communication/slack-mcp.json +29 -0
- package/mcp-configs/communication/telegram-mcp.json +28 -0
- package/mcp-configs/database/neo4j-mcp.json +37 -0
- package/mcp-configs/database/postgres-mcp.json +28 -0
- package/mcp-configs/database/sqlite-mcp.json +29 -0
- package/mcp-configs/dev-platform/github-mcp.json +31 -0
- package/mcp-configs/dev-platform/gitlab-mcp.json +34 -0
- package/mcp-configs/email/email-mcp.json +40 -0
- package/mcp-configs/email/gmail-mcp.json +37 -0
- package/mcp-configs/registry.json +178 -149
- package/mcp-configs/repository/dataverse-mcp.json +33 -0
- package/mcp-configs/repository/huggingface-mcp.json +29 -0
- package/openclaw.plugin.json +2 -2
- package/package.json +2 -2
- package/skills/analysis/dataviz/algorithm-visualizer-guide/SKILL.md +259 -0
- package/skills/analysis/dataviz/bokeh-visualization-guide/SKILL.md +270 -0
- package/skills/analysis/dataviz/chart-image-generator/SKILL.md +229 -0
- package/skills/analysis/dataviz/d3-visualization-guide/SKILL.md +281 -0
- package/skills/analysis/dataviz/echarts-visualization-guide/SKILL.md +250 -0
- package/skills/analysis/dataviz/metabase-analytics-guide/SKILL.md +242 -0
- package/skills/analysis/dataviz/plotly-interactive-guide/SKILL.md +266 -0
- package/skills/analysis/dataviz/redash-analytics-guide/SKILL.md +284 -0
- package/skills/analysis/econometrics/econml-causal-guide/SKILL.md +163 -0
- package/skills/analysis/econometrics/mostly-harmless-guide/SKILL.md +139 -0
- package/skills/analysis/econometrics/panel-data-analyst/SKILL.md +259 -0
- package/skills/analysis/econometrics/python-causality-guide/SKILL.md +134 -0
- package/skills/analysis/econometrics/stata-accounting-guide/SKILL.md +269 -0
- package/skills/analysis/econometrics/stata-analyst-guide/SKILL.md +245 -0
- package/skills/analysis/statistics/data-anomaly-detection/SKILL.md +157 -0
- package/skills/analysis/statistics/ml-experiment-tracker/SKILL.md +212 -0
- package/skills/analysis/statistics/pywayne-statistics-guide/SKILL.md +192 -0
- package/skills/analysis/statistics/quantitative-methods-guide/SKILL.md +193 -0
- package/skills/analysis/statistics/senior-data-scientist-guide/SKILL.md +223 -0
- package/skills/analysis/wrangling/csv-data-analyzer/SKILL.md +170 -0
- package/skills/analysis/wrangling/data-cleaning-pipeline/SKILL.md +266 -0
- package/skills/analysis/wrangling/data-cog-guide/SKILL.md +178 -0
- package/skills/analysis/wrangling/stata-data-cleaning/SKILL.md +276 -0
- package/skills/analysis/wrangling/survey-data-processing/SKILL.md +298 -0
- package/skills/domains/ai-ml/ai-model-benchmarking/SKILL.md +209 -0
- package/skills/domains/ai-ml/annotated-dl-papers-guide/SKILL.md +159 -0
- package/skills/domains/ai-ml/dl-transformer-finetune/SKILL.md +239 -0
- package/skills/domains/ai-ml/generative-ai-guide/SKILL.md +146 -0
- package/skills/domains/ai-ml/huggingface-inference-guide/SKILL.md +196 -0
- package/skills/domains/ai-ml/keras-deep-learning/SKILL.md +210 -0
- package/skills/domains/ai-ml/llm-from-scratch-guide/SKILL.md +124 -0
- package/skills/domains/ai-ml/ml-pipeline-guide/SKILL.md +295 -0
- package/skills/domains/ai-ml/nlp-toolkit-guide/SKILL.md +247 -0
- package/skills/domains/ai-ml/pytorch-guide/SKILL.md +281 -0
- package/skills/domains/ai-ml/pytorch-lightning-guide/SKILL.md +244 -0
- package/skills/domains/ai-ml/tensorflow-guide/SKILL.md +241 -0
- package/skills/domains/biomedical/bioagents-guide/SKILL.md +308 -0
- package/skills/domains/biomedical/medgeclaw-guide/SKILL.md +345 -0
- package/skills/domains/biomedical/medical-imaging-guide/SKILL.md +305 -0
- package/skills/domains/business/architecture-design-guide/SKILL.md +279 -0
- package/skills/domains/business/innovation-management-guide/SKILL.md +257 -0
- package/skills/domains/business/operations-research-guide/SKILL.md +258 -0
- package/skills/domains/chemistry/molecular-dynamics-guide/SKILL.md +237 -0
- package/skills/domains/chemistry/pubchem-api-guide/SKILL.md +180 -0
- package/skills/domains/chemistry/spectroscopy-analysis-guide/SKILL.md +290 -0
- package/skills/domains/cs/distributed-systems-guide/SKILL.md +268 -0
- package/skills/domains/cs/formal-verification-guide/SKILL.md +298 -0
- package/skills/domains/ecology/species-distribution-guide/SKILL.md +343 -0
- package/skills/domains/economics/imf-data-api-guide/SKILL.md +174 -0
- package/skills/domains/economics/post-labor-economics/SKILL.md +254 -0
- package/skills/domains/economics/pricing-psychology-guide/SKILL.md +273 -0
- package/skills/domains/economics/world-bank-data-guide/SKILL.md +179 -0
- package/skills/domains/education/assessment-design-guide/SKILL.md +213 -0
- package/skills/domains/education/educational-research-methods/SKILL.md +179 -0
- package/skills/domains/education/mooc-analytics-guide/SKILL.md +206 -0
- package/skills/domains/finance/portfolio-optimization-guide/SKILL.md +279 -0
- package/skills/domains/finance/risk-modeling-guide/SKILL.md +260 -0
- package/skills/domains/finance/stata-accounting-research/SKILL.md +372 -0
- package/skills/domains/geoscience/climate-modeling-guide/SKILL.md +215 -0
- package/skills/domains/geoscience/satellite-remote-sensing/SKILL.md +193 -0
- package/skills/domains/geoscience/seismology-data-guide/SKILL.md +208 -0
- package/skills/domains/humanities/ethical-philosophy-guide/SKILL.md +244 -0
- package/skills/domains/humanities/history-research-guide/SKILL.md +260 -0
- package/skills/domains/humanities/political-history-guide/SKILL.md +241 -0
- package/skills/domains/law/legal-nlp-guide/SKILL.md +236 -0
- package/skills/domains/law/patent-analysis-guide/SKILL.md +257 -0
- package/skills/domains/law/regulatory-compliance-guide/SKILL.md +267 -0
- package/skills/domains/math/symbolic-computation-guide/SKILL.md +263 -0
- package/skills/domains/math/topology-data-analysis/SKILL.md +305 -0
- package/skills/domains/pharma/clinical-trial-design-guide/SKILL.md +271 -0
- package/skills/domains/pharma/drug-target-interaction/SKILL.md +242 -0
- package/skills/domains/pharma/pharmacovigilance-guide/SKILL.md +216 -0
- package/skills/domains/physics/astrophysics-data-guide/SKILL.md +305 -0
- package/skills/domains/physics/particle-physics-guide/SKILL.md +287 -0
- package/skills/domains/social-science/network-analysis-guide/SKILL.md +310 -0
- package/skills/domains/social-science/psychology-research-guide/SKILL.md +270 -0
- package/skills/domains/social-science/sociology-research-guide/SKILL.md +238 -0
- package/skills/literature/discovery/paper-recommendation-guide/SKILL.md +120 -0
- package/skills/literature/discovery/semantic-paper-radar/SKILL.md +144 -0
- package/skills/literature/discovery/zotero-arxiv-daily-guide/SKILL.md +94 -0
- package/skills/literature/fulltext/core-api-guide/SKILL.md +144 -0
- package/skills/literature/fulltext/institutional-repository-guide/SKILL.md +212 -0
- package/skills/literature/fulltext/open-access-mining-guide/SKILL.md +341 -0
- package/skills/literature/metadata/academic-paper-summarizer/SKILL.md +101 -0
- package/skills/literature/metadata/wikidata-api-guide/SKILL.md +156 -0
- package/skills/literature/search/arxiv-batch-reporting/SKILL.md +133 -0
- package/skills/literature/search/arxiv-paper-processor/SKILL.md +141 -0
- package/skills/literature/search/baidu-scholar-guide/SKILL.md +110 -0
- package/skills/literature/search/chatpaper-guide/SKILL.md +122 -0
- package/skills/literature/search/deep-literature-search/SKILL.md +149 -0
- package/skills/literature/search/deepgit-search-guide/SKILL.md +147 -0
- package/skills/literature/search/pasa-paper-search-guide/SKILL.md +138 -0
- package/skills/research/automation/ai-scientist-v2-guide/SKILL.md +284 -0
- package/skills/research/automation/aim-experiment-guide/SKILL.md +234 -0
- package/skills/research/automation/datagen-research-guide/SKILL.md +131 -0
- package/skills/research/automation/kedro-pipeline-guide/SKILL.md +216 -0
- package/skills/research/automation/mle-agent-guide/SKILL.md +139 -0
- package/skills/research/automation/paper-to-agent-guide/SKILL.md +116 -0
- package/skills/research/automation/rd-agent-guide/SKILL.md +246 -0
- package/skills/research/automation/research-paper-orchestrator/SKILL.md +254 -0
- package/skills/research/deep-research/academic-deep-research/SKILL.md +190 -0
- package/skills/research/deep-research/auto-deep-research-guide/SKILL.md +141 -0
- package/skills/research/deep-research/deep-research-pro/SKILL.md +213 -0
- package/skills/research/deep-research/deep-research-work/SKILL.md +204 -0
- package/skills/research/deep-research/deep-searcher-guide/SKILL.md +253 -0
- package/skills/research/deep-research/gpt-researcher-guide/SKILL.md +191 -0
- package/skills/research/deep-research/khoj-research-guide/SKILL.md +200 -0
- package/skills/research/deep-research/local-deep-research-guide/SKILL.md +253 -0
- package/skills/research/deep-research/tongyi-deep-research-guide/SKILL.md +217 -0
- package/skills/research/funding/eu-horizon-guide/SKILL.md +244 -0
- package/skills/research/funding/grant-budget-guide/SKILL.md +284 -0
- package/skills/research/funding/nih-reporter-api-guide/SKILL.md +166 -0
- package/skills/research/funding/nsf-award-api-guide/SKILL.md +133 -0
- package/skills/research/methodology/academic-mentor-guide/SKILL.md +169 -0
- package/skills/research/methodology/claude-scientific-guide/SKILL.md +122 -0
- package/skills/research/methodology/deep-innovator-guide/SKILL.md +242 -0
- package/skills/research/methodology/osf-api-guide/SKILL.md +165 -0
- package/skills/research/methodology/research-paper-kb/SKILL.md +263 -0
- package/skills/research/methodology/research-town-guide/SKILL.md +263 -0
- package/skills/research/paper-review/automated-review-guide/SKILL.md +281 -0
- package/skills/research/paper-review/paper-compare-guide/SKILL.md +238 -0
- package/skills/research/paper-review/paper-digest-guide/SKILL.md +240 -0
- package/skills/research/paper-review/paper-research-assistant/SKILL.md +231 -0
- package/skills/research/paper-review/research-quality-filter/SKILL.md +261 -0
- package/skills/research/paper-review/review-response-guide/SKILL.md +275 -0
- package/skills/tools/code-exec/google-colab-guide/SKILL.md +276 -0
- package/skills/tools/code-exec/kaggle-api-guide/SKILL.md +216 -0
- package/skills/tools/code-exec/overleaf-cli-guide/SKILL.md +279 -0
- package/skills/tools/diagram/code-flow-visualizer/SKILL.md +197 -0
- package/skills/tools/diagram/excalidraw-diagram-guide/SKILL.md +170 -0
- package/skills/tools/diagram/json-data-visualizer/SKILL.md +270 -0
- package/skills/tools/diagram/mermaid-architect-guide/SKILL.md +219 -0
- package/skills/tools/diagram/tldraw-whiteboard-guide/SKILL.md +397 -0
- package/skills/tools/document/docsgpt-guide/SKILL.md +130 -0
- package/skills/tools/document/large-document-reader/SKILL.md +202 -0
- package/skills/tools/document/paper-parse-guide/SKILL.md +243 -0
- package/skills/tools/knowledge-graph/citation-network-builder/SKILL.md +244 -0
- package/skills/tools/knowledge-graph/concept-map-generator/SKILL.md +284 -0
- package/skills/tools/knowledge-graph/graphiti-guide/SKILL.md +219 -0
- package/skills/tools/ocr-translate/pdf-math-translate-guide/SKILL.md +141 -0
- package/skills/tools/ocr-translate/zotero-pdf-translate-guide/SKILL.md +95 -0
- package/skills/tools/ocr-translate/zotero-pdf2zh-guide/SKILL.md +143 -0
- package/skills/tools/scraping/dataset-finder-guide/SKILL.md +253 -0
- package/skills/tools/scraping/easy-spider-guide/SKILL.md +250 -0
- package/skills/tools/scraping/google-scholar-scraper/SKILL.md +255 -0
- package/skills/tools/scraping/repository-harvesting-guide/SKILL.md +310 -0
- package/skills/writing/citation/academic-citation-manager/SKILL.md +314 -0
- package/skills/writing/citation/jabref-reference-guide/SKILL.md +127 -0
- package/skills/writing/citation/jasminum-zotero-guide/SKILL.md +103 -0
- package/skills/writing/citation/obsidian-citation-guide/SKILL.md +164 -0
- package/skills/writing/citation/obsidian-zotero-guide/SKILL.md +137 -0
- package/skills/writing/citation/papersgpt-zotero-guide/SKILL.md +132 -0
- package/skills/writing/citation/papis-cli-guide/SKILL.md +213 -0
- package/skills/writing/citation/zotero-better-bibtex-guide/SKILL.md +107 -0
- package/skills/writing/citation/zotero-better-notes-guide/SKILL.md +121 -0
- package/skills/writing/citation/zotero-gpt-guide/SKILL.md +111 -0
- package/skills/writing/citation/zotero-mcp-guide/SKILL.md +164 -0
- package/skills/writing/citation/zotero-mdnotes-guide/SKILL.md +162 -0
- package/skills/writing/citation/zotero-reference-guide/SKILL.md +139 -0
- package/skills/writing/citation/zotero-scholar-guide/SKILL.md +294 -0
- package/skills/writing/citation/zotfile-attachment-guide/SKILL.md +140 -0
- package/skills/writing/composition/ml-paper-writing/SKILL.md +163 -0
- package/skills/writing/composition/paper-debugger-guide/SKILL.md +143 -0
- package/skills/writing/composition/scientific-writing-resources/SKILL.md +151 -0
- package/skills/writing/composition/scientific-writing-wrapper/SKILL.md +153 -0
- package/skills/writing/latex/latex-drawing-collection/SKILL.md +154 -0
- package/skills/writing/latex/latex-templates-collection/SKILL.md +159 -0
- package/skills/writing/latex/md-to-pdf-academic/SKILL.md +230 -0
- package/skills/writing/latex/tex-render-guide/SKILL.md +243 -0
- package/skills/writing/polish/academic-tone-guide/SKILL.md +209 -0
- package/skills/writing/polish/conciseness-editing-guide/SKILL.md +225 -0
- package/skills/writing/polish/paper-polish-guide/SKILL.md +160 -0
- package/skills/writing/templates/graphical-abstract-guide/SKILL.md +183 -0
- package/skills/writing/templates/novathesis-guide/SKILL.md +152 -0
- package/skills/writing/templates/scientific-article-pdf/SKILL.md +261 -0
- package/skills/writing/templates/sjtuthesis-guide/SKILL.md +197 -0
- package/skills/writing/templates/thuthesis-guide/SKILL.md +181 -0
- package/skills/literature/fulltext/repository-harvesting-guide/SKILL.md +0 -207
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: operations-research-guide
|
|
3
|
+
description: "Optimization and operations research methods for business and logistics"
|
|
4
|
+
metadata:
|
|
5
|
+
openclaw:
|
|
6
|
+
emoji: "gear"
|
|
7
|
+
category: "domains"
|
|
8
|
+
subcategory: "business"
|
|
9
|
+
keywords: ["optimization", "operations-research", "linear-programming", "scheduling", "supply-chain", "simulation"]
|
|
10
|
+
source: "wentor"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Operations Research Guide
|
|
14
|
+
|
|
15
|
+
A skill for applying operations research (OR) methods to business, logistics, and resource allocation problems. Covers linear programming, integer programming, scheduling, network optimization, simulation, and decision analysis using Python optimization libraries.
|
|
16
|
+
|
|
17
|
+
## Linear Programming
|
|
18
|
+
|
|
19
|
+
### Problem Formulation and Solving
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from scipy.optimize import linprog
|
|
23
|
+
import numpy as np
|
|
24
|
+
|
|
25
|
+
def solve_production_planning():
|
|
26
|
+
"""
|
|
27
|
+
Example: A factory produces two products (A and B).
|
|
28
|
+
Product A: profit $40, uses 2h labor + 1kg material
|
|
29
|
+
Product B: profit $30, uses 1h labor + 2kg material
|
|
30
|
+
Constraints: 100h labor available, 80kg material available
|
|
31
|
+
Maximize total profit.
|
|
32
|
+
"""
|
|
33
|
+
# linprog minimizes, so negate for maximization
|
|
34
|
+
c = [-40, -30] # objective coefficients (negated)
|
|
35
|
+
|
|
36
|
+
# Inequality constraints: A_ub @ x <= b_ub
|
|
37
|
+
A_ub = [
|
|
38
|
+
[2, 1], # labor constraint
|
|
39
|
+
[1, 2], # material constraint
|
|
40
|
+
]
|
|
41
|
+
b_ub = [100, 80]
|
|
42
|
+
|
|
43
|
+
# Non-negativity bounds
|
|
44
|
+
bounds = [(0, None), (0, None)]
|
|
45
|
+
|
|
46
|
+
result = linprog(c, A_ub=A_ub, b_ub=b_ub, bounds=bounds, method="highs")
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
"product_A": result.x[0],
|
|
50
|
+
"product_B": result.x[1],
|
|
51
|
+
"max_profit": -result.fun,
|
|
52
|
+
"status": "optimal" if result.success else "infeasible",
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Using PuLP for Readable Models
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from pulp import LpProblem, LpMaximize, LpVariable, lpSum, value
|
|
60
|
+
|
|
61
|
+
def workforce_scheduling():
|
|
62
|
+
"""
|
|
63
|
+
Workforce scheduling: minimize staffing cost while meeting
|
|
64
|
+
demand for each day of the week. Workers work 5 consecutive days.
|
|
65
|
+
"""
|
|
66
|
+
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
|
|
67
|
+
demand = [17, 13, 15, 19, 14, 16, 11]
|
|
68
|
+
cost_per_worker = 1 # uniform cost
|
|
69
|
+
|
|
70
|
+
prob = LpProblem("workforce_scheduling", LpMaximize)
|
|
71
|
+
|
|
72
|
+
# x[i] = number of workers starting on day i
|
|
73
|
+
x = {i: LpVariable(f"start_{days[i]}", lowBound=0, cat="Integer")
|
|
74
|
+
for i in range(7)}
|
|
75
|
+
|
|
76
|
+
# Minimize total workers
|
|
77
|
+
prob += -lpSum(x[i] for i in range(7))
|
|
78
|
+
|
|
79
|
+
# Each day, workers starting on days [d-4, d-3, ..., d] are available
|
|
80
|
+
for d in range(7):
|
|
81
|
+
workers_available = lpSum(x[(d - j) % 7] for j in range(5))
|
|
82
|
+
prob += workers_available >= demand[d], f"demand_{days[d]}"
|
|
83
|
+
|
|
84
|
+
prob.solve()
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
"status": prob.status,
|
|
88
|
+
"schedule": {days[i]: int(value(x[i])) for i in range(7)},
|
|
89
|
+
"total_workers": int(sum(value(x[i]) for i in range(7))),
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Integer and Mixed-Integer Programming
|
|
94
|
+
|
|
95
|
+
### Vehicle Routing Problem
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from itertools import combinations
|
|
99
|
+
|
|
100
|
+
def solve_tsp_mtz(distances: np.ndarray) -> dict:
|
|
101
|
+
"""
|
|
102
|
+
Solve the Traveling Salesman Problem using Miller-Tucker-Zemlin formulation.
|
|
103
|
+
distances: n x n distance matrix
|
|
104
|
+
Returns optimal tour and total distance.
|
|
105
|
+
"""
|
|
106
|
+
from pulp import LpProblem, LpMinimize, LpVariable, LpBinary, lpSum, value
|
|
107
|
+
|
|
108
|
+
n = len(distances)
|
|
109
|
+
prob = LpProblem("TSP", LpMinimize)
|
|
110
|
+
|
|
111
|
+
# Binary variables: x[i][j] = 1 if edge (i,j) in tour
|
|
112
|
+
x = {(i, j): LpVariable(f"x_{i}_{j}", cat=LpBinary)
|
|
113
|
+
for i in range(n) for j in range(n) if i != j}
|
|
114
|
+
|
|
115
|
+
# Subtour elimination variables
|
|
116
|
+
u = {i: LpVariable(f"u_{i}", lowBound=1, upBound=n - 1)
|
|
117
|
+
for i in range(1, n)}
|
|
118
|
+
|
|
119
|
+
# Objective: minimize total distance
|
|
120
|
+
prob += lpSum(distances[i][j] * x[i, j] for i, j in x)
|
|
121
|
+
|
|
122
|
+
# Each city visited exactly once
|
|
123
|
+
for i in range(n):
|
|
124
|
+
prob += lpSum(x[i, j] for j in range(n) if j != i) == 1
|
|
125
|
+
prob += lpSum(x[j, i] for j in range(n) if j != i) == 1
|
|
126
|
+
|
|
127
|
+
# MTZ subtour elimination
|
|
128
|
+
for i in range(1, n):
|
|
129
|
+
for j in range(1, n):
|
|
130
|
+
if i != j:
|
|
131
|
+
prob += u[i] - u[j] + (n - 1) * x[i, j] <= n - 2
|
|
132
|
+
|
|
133
|
+
prob.solve()
|
|
134
|
+
|
|
135
|
+
# Extract tour
|
|
136
|
+
tour = [0]
|
|
137
|
+
current = 0
|
|
138
|
+
for _ in range(n - 1):
|
|
139
|
+
for j in range(n):
|
|
140
|
+
if j != current and (current, j) in x and value(x[current, j]) > 0.5:
|
|
141
|
+
tour.append(j)
|
|
142
|
+
current = j
|
|
143
|
+
break
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
"tour": tour,
|
|
147
|
+
"total_distance": value(prob.objective),
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Queuing Theory
|
|
152
|
+
|
|
153
|
+
### M/M/c Queue Analysis
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from math import factorial, exp
|
|
157
|
+
|
|
158
|
+
def mmc_queue(arrival_rate: float, service_rate: float,
|
|
159
|
+
n_servers: int) -> dict:
|
|
160
|
+
"""
|
|
161
|
+
Analyze an M/M/c queue (Poisson arrivals, exponential service, c servers).
|
|
162
|
+
arrival_rate: lambda (customers per unit time)
|
|
163
|
+
service_rate: mu (customers served per unit time per server)
|
|
164
|
+
n_servers: c (number of parallel servers)
|
|
165
|
+
"""
|
|
166
|
+
rho = arrival_rate / (n_servers * service_rate)
|
|
167
|
+
|
|
168
|
+
if rho >= 1:
|
|
169
|
+
return {"stable": False, "utilization": rho}
|
|
170
|
+
|
|
171
|
+
# Erlang C formula: probability of waiting
|
|
172
|
+
a = arrival_rate / service_rate
|
|
173
|
+
sum_terms = sum(a ** k / factorial(k) for k in range(n_servers))
|
|
174
|
+
erlang_c = (a ** n_servers / factorial(n_servers)) / (
|
|
175
|
+
(a ** n_servers / factorial(n_servers)) + (1 - rho) * sum_terms
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
# Performance metrics
|
|
179
|
+
Lq = erlang_c * rho / (1 - rho) # avg queue length
|
|
180
|
+
Wq = Lq / arrival_rate # avg wait time
|
|
181
|
+
W = Wq + 1 / service_rate # avg time in system
|
|
182
|
+
L = arrival_rate * W # avg number in system
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
"stable": True,
|
|
186
|
+
"utilization": round(rho, 4),
|
|
187
|
+
"prob_wait": round(erlang_c, 4),
|
|
188
|
+
"avg_queue_length": round(Lq, 4),
|
|
189
|
+
"avg_wait_time": round(Wq, 4),
|
|
190
|
+
"avg_system_time": round(W, 4),
|
|
191
|
+
"avg_in_system": round(L, 4),
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Simulation Methods
|
|
196
|
+
|
|
197
|
+
### Discrete-Event Simulation
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
import simpy
|
|
201
|
+
import random
|
|
202
|
+
|
|
203
|
+
def simulate_service_center(n_servers: int, arrival_rate: float,
|
|
204
|
+
service_rate: float, sim_time: float = 480):
|
|
205
|
+
"""
|
|
206
|
+
Discrete-event simulation of a service center using SimPy.
|
|
207
|
+
sim_time: simulation duration in minutes (default 8-hour day).
|
|
208
|
+
"""
|
|
209
|
+
wait_times = []
|
|
210
|
+
|
|
211
|
+
def customer(env, server):
|
|
212
|
+
arrival_time = env.now
|
|
213
|
+
with server.request() as req:
|
|
214
|
+
yield req
|
|
215
|
+
wait = env.now - arrival_time
|
|
216
|
+
wait_times.append(wait)
|
|
217
|
+
yield env.timeout(random.expovariate(service_rate))
|
|
218
|
+
|
|
219
|
+
def customer_generator(env, server):
|
|
220
|
+
customer_id = 0
|
|
221
|
+
while True:
|
|
222
|
+
yield env.timeout(random.expovariate(arrival_rate))
|
|
223
|
+
customer_id += 1
|
|
224
|
+
env.process(customer(env, server))
|
|
225
|
+
|
|
226
|
+
env = simpy.Environment()
|
|
227
|
+
server = simpy.Resource(env, capacity=n_servers)
|
|
228
|
+
env.process(customer_generator(env, server))
|
|
229
|
+
env.run(until=sim_time)
|
|
230
|
+
|
|
231
|
+
return {
|
|
232
|
+
"customers_served": len(wait_times),
|
|
233
|
+
"avg_wait": np.mean(wait_times) if wait_times else 0,
|
|
234
|
+
"max_wait": max(wait_times) if wait_times else 0,
|
|
235
|
+
"pct_waited": sum(1 for w in wait_times if w > 0) / len(wait_times) * 100,
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Decision Analysis
|
|
240
|
+
|
|
241
|
+
### Multi-Criteria Decision Making
|
|
242
|
+
|
|
243
|
+
| Method | Description | Best For |
|
|
244
|
+
|--------|-------------|----------|
|
|
245
|
+
| AHP (Analytic Hierarchy Process) | Pairwise comparison matrix | Structured group decisions |
|
|
246
|
+
| TOPSIS | Distance to ideal/anti-ideal solution | Ranking alternatives |
|
|
247
|
+
| Weighted scoring | Simple weighted sum | Quick comparisons |
|
|
248
|
+
| Decision trees | Sequential decision under uncertainty | Multi-stage problems |
|
|
249
|
+
|
|
250
|
+
## Tools and Libraries
|
|
251
|
+
|
|
252
|
+
- **PuLP**: Python LP/MIP modeling with multiple solver backends
|
|
253
|
+
- **OR-Tools (Google)**: Constraint programming, routing, scheduling
|
|
254
|
+
- **Gurobi / CPLEX**: Commercial high-performance MIP solvers (free academic licenses)
|
|
255
|
+
- **SimPy**: Python discrete-event simulation framework
|
|
256
|
+
- **SciPy optimize**: Linear programming, nonlinear optimization
|
|
257
|
+
- **Pyomo**: Algebraic modeling language for optimization in Python
|
|
258
|
+
- **AMPL**: Commercial algebraic modeling language
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: molecular-dynamics-guide
|
|
3
|
+
description: "Molecular dynamics simulation setup, execution, and trajectory analysis"
|
|
4
|
+
metadata:
|
|
5
|
+
openclaw:
|
|
6
|
+
emoji: "atom-symbol"
|
|
7
|
+
category: "domains"
|
|
8
|
+
subcategory: "chemistry"
|
|
9
|
+
keywords: ["molecular-dynamics", "simulation", "gromacs", "openmm", "force-field", "trajectory"]
|
|
10
|
+
source: "wentor"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Molecular Dynamics Guide
|
|
14
|
+
|
|
15
|
+
A skill for setting up, running, and analyzing molecular dynamics (MD) simulations. Covers force field selection, system preparation, simulation protocols, trajectory analysis, and free energy calculations using GROMACS, OpenMM, and MDAnalysis.
|
|
16
|
+
|
|
17
|
+
## System Preparation
|
|
18
|
+
|
|
19
|
+
### Building a Simulation System
|
|
20
|
+
|
|
21
|
+
The standard workflow for preparing an MD simulation:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
1. Obtain structure (PDB, homology model, or docking pose)
|
|
25
|
+
2. Clean structure (add missing atoms, fix protonation states)
|
|
26
|
+
3. Assign force field parameters
|
|
27
|
+
4. Solvate in explicit water box
|
|
28
|
+
5. Add counterions to neutralize charge
|
|
29
|
+
6. Energy minimize
|
|
30
|
+
7. Equilibrate (NVT then NPT)
|
|
31
|
+
8. Production run
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### GROMACS System Setup
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# 1. Generate topology from PDB
|
|
38
|
+
gmx pdb2gmx -f protein.pdb -o processed.gro -water tip3p -ff amber99sb-ildn
|
|
39
|
+
|
|
40
|
+
# 2. Define simulation box (dodecahedron, 1.0 nm buffer)
|
|
41
|
+
gmx editconf -f processed.gro -o boxed.gro -c -d 1.0 -bt dodecahedron
|
|
42
|
+
|
|
43
|
+
# 3. Solvate
|
|
44
|
+
gmx solvate -cp boxed.gro -cs spc216.gro -o solvated.gro -p topol.top
|
|
45
|
+
|
|
46
|
+
# 4. Add ions to neutralize and set ionic strength (0.15 M NaCl)
|
|
47
|
+
gmx grompp -f ions.mdp -c solvated.gro -p topol.top -o ions.tpr
|
|
48
|
+
gmx genion -s ions.tpr -o ionized.gro -p topol.top -pname NA -nname CL -neutral -conc 0.15
|
|
49
|
+
|
|
50
|
+
# 5. Energy minimization
|
|
51
|
+
gmx grompp -f minim.mdp -c ionized.gro -p topol.top -o em.tpr
|
|
52
|
+
gmx mdrun -deffnm em
|
|
53
|
+
|
|
54
|
+
# 6. NVT equilibration (100 ps, 300 K)
|
|
55
|
+
gmx grompp -f nvt.mdp -c em.gro -r em.gro -p topol.top -o nvt.tpr
|
|
56
|
+
gmx mdrun -deffnm nvt
|
|
57
|
+
|
|
58
|
+
# 7. NPT equilibration (100 ps, 300 K, 1 bar)
|
|
59
|
+
gmx grompp -f npt.mdp -c nvt.gro -r nvt.gro -t nvt.cpt -p topol.top -o npt.tpr
|
|
60
|
+
gmx mdrun -deffnm npt
|
|
61
|
+
|
|
62
|
+
# 8. Production MD (100 ns)
|
|
63
|
+
gmx grompp -f md.mdp -c npt.gro -t npt.cpt -p topol.top -o md.tpr
|
|
64
|
+
gmx mdrun -deffnm md
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Force Field Selection
|
|
68
|
+
|
|
69
|
+
### Common Force Fields
|
|
70
|
+
|
|
71
|
+
| Force Field | Strengths | Typical Use |
|
|
72
|
+
|-------------|-----------|------------|
|
|
73
|
+
| AMBER ff14SB | Protein structure, dynamics | Protein simulations |
|
|
74
|
+
| AMBER ff19SB | Improved backbone dihedrals | Latest protein simulations |
|
|
75
|
+
| CHARMM36m | Proteins, lipids, carbohydrates | Membrane systems |
|
|
76
|
+
| OPLS-AA/M | Small molecules, organic liquids | Drug-like molecules |
|
|
77
|
+
| GAFF2 | General small molecules | Ligand parameterization |
|
|
78
|
+
| CGenFF | CHARMM-compatible small molecules | Ligands in CHARMM systems |
|
|
79
|
+
|
|
80
|
+
### OpenMM System Setup
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from openmm.app import PDBFile, ForceField, Modeller, Simulation
|
|
84
|
+
from openmm.app import PME, HBonds, NoCutoff
|
|
85
|
+
from openmm import LangevinMiddleIntegrator, MonteCarloBarostat
|
|
86
|
+
from openmm.unit import kelvin, atmospheres, nanometers, picoseconds
|
|
87
|
+
|
|
88
|
+
def setup_openmm_simulation(pdb_path: str,
|
|
89
|
+
temperature: float = 300,
|
|
90
|
+
pressure: float = 1.0,
|
|
91
|
+
timestep: float = 0.002) -> Simulation:
|
|
92
|
+
"""
|
|
93
|
+
Set up an OpenMM molecular dynamics simulation.
|
|
94
|
+
pdb_path: path to prepared PDB file
|
|
95
|
+
temperature: simulation temperature in Kelvin
|
|
96
|
+
pressure: pressure in atmospheres
|
|
97
|
+
timestep: integration timestep in picoseconds
|
|
98
|
+
"""
|
|
99
|
+
pdb = PDBFile(pdb_path)
|
|
100
|
+
forcefield = ForceField("amber14-all.xml", "amber14/tip3pfb.xml")
|
|
101
|
+
|
|
102
|
+
modeller = Modeller(pdb.topology, pdb.positions)
|
|
103
|
+
modeller.addSolvent(forcefield, padding=1.0 * nanometers,
|
|
104
|
+
ionicStrength=0.15)
|
|
105
|
+
|
|
106
|
+
system = forcefield.createSystem(
|
|
107
|
+
modeller.topology,
|
|
108
|
+
nonbondedMethod=PME,
|
|
109
|
+
nonbondedCutoff=1.0 * nanometers,
|
|
110
|
+
constraints=HBonds,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Barostat for NPT ensemble
|
|
114
|
+
system.addForce(
|
|
115
|
+
MonteCarloBarostat(pressure * atmospheres, temperature * kelvin)
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
integrator = LangevinMiddleIntegrator(
|
|
119
|
+
temperature * kelvin,
|
|
120
|
+
1.0 / picoseconds,
|
|
121
|
+
timestep * picoseconds,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
simulation = Simulation(modeller.topology, system, integrator)
|
|
125
|
+
simulation.context.setPositions(modeller.positions)
|
|
126
|
+
|
|
127
|
+
# Energy minimization
|
|
128
|
+
simulation.minimizeEnergy()
|
|
129
|
+
|
|
130
|
+
return simulation
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Trajectory Analysis
|
|
134
|
+
|
|
135
|
+
### Structural Analysis with MDAnalysis
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
import MDAnalysis as mda
|
|
139
|
+
from MDAnalysis.analysis import rms, align, diffusionmap
|
|
140
|
+
import numpy as np
|
|
141
|
+
|
|
142
|
+
def analyze_trajectory(topology: str, trajectory: str) -> dict:
|
|
143
|
+
"""
|
|
144
|
+
Comprehensive trajectory analysis: RMSD, RMSF, radius of gyration.
|
|
145
|
+
topology: topology file (GRO, PDB, PSF)
|
|
146
|
+
trajectory: trajectory file (XTC, TRR, DCD)
|
|
147
|
+
"""
|
|
148
|
+
u = mda.Universe(topology, trajectory)
|
|
149
|
+
protein = u.select_atoms("protein and name CA")
|
|
150
|
+
|
|
151
|
+
# RMSD over time (C-alpha atoms)
|
|
152
|
+
ref = mda.Universe(topology)
|
|
153
|
+
rmsd_analysis = rms.RMSD(u, ref, select="protein and name CA")
|
|
154
|
+
rmsd_analysis.run()
|
|
155
|
+
rmsd_data = rmsd_analysis.results.rmsd # shape: (n_frames, 3)
|
|
156
|
+
|
|
157
|
+
# RMSF per residue
|
|
158
|
+
align.AlignTraj(u, ref, select="protein and name CA", in_memory=True).run()
|
|
159
|
+
rmsf = rms.RMSF(protein).run()
|
|
160
|
+
|
|
161
|
+
# Radius of gyration
|
|
162
|
+
rg_values = []
|
|
163
|
+
for ts in u.trajectory:
|
|
164
|
+
rg_values.append(protein.radius_of_gyration())
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
"n_frames": len(u.trajectory),
|
|
168
|
+
"rmsd_mean_nm": np.mean(rmsd_data[:, 2]) / 10, # A to nm
|
|
169
|
+
"rmsd_final_nm": rmsd_data[-1, 2] / 10,
|
|
170
|
+
"rmsf_mean_nm": np.mean(rmsf.results.rmsf) / 10,
|
|
171
|
+
"rg_mean_nm": np.mean(rg_values) / 10,
|
|
172
|
+
"rg_std_nm": np.std(rg_values) / 10,
|
|
173
|
+
"simulation_time_ns": u.trajectory[-1].time / 1000,
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Hydrogen Bond Analysis
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
from MDAnalysis.analysis.hydrogenbonds import HydrogenBondAnalysis
|
|
181
|
+
|
|
182
|
+
def analyze_hbonds(universe: mda.Universe,
|
|
183
|
+
donor_sel: str = "protein",
|
|
184
|
+
acceptor_sel: str = "protein") -> dict:
|
|
185
|
+
"""Analyze hydrogen bonds over the trajectory."""
|
|
186
|
+
hbonds = HydrogenBondAnalysis(
|
|
187
|
+
universe,
|
|
188
|
+
donors_sel=f"({donor_sel}) and (name N* or name O*)",
|
|
189
|
+
acceptors_sel=f"({acceptor_sel}) and (name O* or name N*)",
|
|
190
|
+
d_a_cutoff=3.5,
|
|
191
|
+
d_h_a_angle_cutoff=150,
|
|
192
|
+
)
|
|
193
|
+
hbonds.run()
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
"total_hbonds_detected": len(hbonds.results.hbonds),
|
|
197
|
+
"mean_per_frame": len(hbonds.results.hbonds) / hbonds.n_frames,
|
|
198
|
+
"unique_pairs": len(set(
|
|
199
|
+
(int(r[1]), int(r[3])) for r in hbonds.results.hbonds
|
|
200
|
+
)),
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Free Energy Methods
|
|
205
|
+
|
|
206
|
+
### Umbrella Sampling
|
|
207
|
+
|
|
208
|
+
Umbrella sampling computes the potential of mean force (PMF) along a reaction coordinate:
|
|
209
|
+
|
|
210
|
+
1. Generate windows along the reaction coordinate (e.g., distance between two groups)
|
|
211
|
+
2. Run restrained simulations at each window with a harmonic bias
|
|
212
|
+
3. Combine windows using WHAM (Weighted Histogram Analysis Method)
|
|
213
|
+
4. Report the free energy profile (PMF)
|
|
214
|
+
|
|
215
|
+
### Alchemical Free Energy Perturbation
|
|
216
|
+
|
|
217
|
+
Used for computing binding free energies and solvation free energies:
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
Lambda schedule: 0.0, 0.1, 0.2, ..., 0.9, 1.0
|
|
221
|
+
At lambda=0: full interaction (bound state)
|
|
222
|
+
At lambda=1: no interaction (unbound state)
|
|
223
|
+
|
|
224
|
+
Each lambda window: independent MD simulation
|
|
225
|
+
Analysis: MBAR or TI to combine lambda windows
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Tools and Software
|
|
229
|
+
|
|
230
|
+
- **GROMACS**: High-performance MD engine (free, GPU-accelerated)
|
|
231
|
+
- **OpenMM**: Python-native MD with GPU support
|
|
232
|
+
- **AMBER**: Comprehensive MD package (academic license)
|
|
233
|
+
- **NAMD**: Scalable MD for large biomolecular systems
|
|
234
|
+
- **MDAnalysis**: Python trajectory analysis library
|
|
235
|
+
- **MDTraj**: Lightweight trajectory analysis
|
|
236
|
+
- **PyMOL / VMD**: Molecular visualization and movie generation
|
|
237
|
+
- **PLUMED**: Free energy and enhanced sampling methods plugin
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pubchem-api-guide
|
|
3
|
+
description: "Search PubChem for chemical compounds, structures, and bioassay data"
|
|
4
|
+
metadata:
|
|
5
|
+
openclaw:
|
|
6
|
+
emoji: "⚗️"
|
|
7
|
+
category: "domains"
|
|
8
|
+
subcategory: "chemistry"
|
|
9
|
+
keywords: ["pubchem", "chemistry", "compounds", "structures", "bioassay", "pharmacology"]
|
|
10
|
+
source: "https://pubchem.ncbi.nlm.nih.gov/docs/pug-rest"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# PubChem PUG REST API Guide
|
|
14
|
+
|
|
15
|
+
## Overview
|
|
16
|
+
|
|
17
|
+
PubChem is the world's largest free chemistry database, maintained by the National Center for Biotechnology Information (NCBI) at the U.S. National Library of Medicine. It contains information on over 115 million chemical compounds, 300 million substances from hundreds of data sources, and over 1.5 million bioassay experiments. PubChem is a critical resource for researchers in chemistry, pharmacology, drug discovery, toxicology, and related life sciences.
|
|
18
|
+
|
|
19
|
+
The PUG REST (Power User Gateway RESTful) API provides programmatic access to PubChem's three primary databases: Compound (standardized chemical structures), Substance (depositor-provided records), and BioAssay (biological screening results). The API supports searches by name, molecular formula, structure similarity, substructure, and various identifiers including CID, SID, InChI, and SMILES.
|
|
20
|
+
|
|
21
|
+
PUG REST is entirely free, requires no authentication, and returns data in JSON, XML, CSV, SDF, and other formats. It is designed for both simple lookups and complex cheminformatics workflows.
|
|
22
|
+
|
|
23
|
+
## Authentication
|
|
24
|
+
|
|
25
|
+
No authentication is required. PubChem PUG REST is a free public service.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# No API key needed
|
|
29
|
+
curl "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/aspirin/JSON"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Core Endpoints
|
|
33
|
+
|
|
34
|
+
### Get Compound by Name
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
GET https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{name}/JSON
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
curl -s "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/caffeine/JSON" \
|
|
42
|
+
| python3 -m json.tool
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Get Compound Properties
|
|
46
|
+
|
|
47
|
+
Retrieve specific properties for a compound by CID.
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
GET https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{cid}/property/{properties}/JSON
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Available properties:** MolecularFormula, MolecularWeight, CanonicalSMILES, InChI, InChIKey, IUPACName, XLogP, ExactMass, HBondDonorCount, HBondAcceptorCount, RotatableBondCount, TPSA
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
curl -s "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/ibuprofen/property/MolecularFormula,MolecularWeight,CanonicalSMILES,IUPACName,XLogP/JSON" \
|
|
57
|
+
| python3 -m json.tool
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Search by Molecular Formula
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
curl -s "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/fastformula/C8H10N4O2/property/IUPACName,MolecularWeight,CanonicalSMILES/JSON" \
|
|
64
|
+
| python3 -m json.tool
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Similarity Search
|
|
68
|
+
|
|
69
|
+
Find compounds structurally similar to a given compound (Tanimoto threshold).
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
curl -s "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/fastsimilarity_2d/cid/2244/property/IUPACName,MolecularWeight,CanonicalSMILES/JSON?Threshold=90" \
|
|
73
|
+
| python3 -m json.tool
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Get BioAssay Data
|
|
77
|
+
|
|
78
|
+
Retrieve biological activity data for a compound.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
curl -s "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/2244/assaysummary/JSON" \
|
|
82
|
+
| python3 -m json.tool
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Python Example: Drug-Likeness Screening
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
import requests
|
|
89
|
+
import time
|
|
90
|
+
|
|
91
|
+
PUG_REST = "https://pubchem.ncbi.nlm.nih.gov/rest/pug"
|
|
92
|
+
|
|
93
|
+
def get_compound_properties(name):
|
|
94
|
+
"""Fetch key drug-likeness properties for a named compound."""
|
|
95
|
+
props = "MolecularWeight,XLogP,HBondDonorCount,HBondAcceptorCount,TPSA,RotatableBondCount,IUPACName"
|
|
96
|
+
url = f"{PUG_REST}/compound/name/{name}/property/{props}/JSON"
|
|
97
|
+
resp = requests.get(url)
|
|
98
|
+
resp.raise_for_status()
|
|
99
|
+
data = resp.json()
|
|
100
|
+
return data.get("PropertyTable", {}).get("Properties", [{}])[0]
|
|
101
|
+
|
|
102
|
+
def check_lipinski(props):
|
|
103
|
+
"""Check Lipinski's Rule of Five for oral drug-likeness."""
|
|
104
|
+
violations = 0
|
|
105
|
+
mw = props.get("MolecularWeight", 0)
|
|
106
|
+
logp = props.get("XLogP", 0)
|
|
107
|
+
hbd = props.get("HBondDonorCount", 0)
|
|
108
|
+
hba = props.get("HBondAcceptorCount", 0)
|
|
109
|
+
|
|
110
|
+
if mw > 500: violations += 1
|
|
111
|
+
if logp > 5: violations += 1
|
|
112
|
+
if hbd > 5: violations += 1
|
|
113
|
+
if hba > 10: violations += 1
|
|
114
|
+
return violations
|
|
115
|
+
|
|
116
|
+
drug_candidates = ["metformin", "atorvastatin", "lisinopril", "omeprazole"]
|
|
117
|
+
print(f"{'Compound':<20} {'MW':>8} {'LogP':>6} {'HBD':>4} {'HBA':>4} {'Violations':>10}")
|
|
118
|
+
print("-" * 60)
|
|
119
|
+
|
|
120
|
+
for drug in drug_candidates:
|
|
121
|
+
props = get_compound_properties(drug)
|
|
122
|
+
violations = check_lipinski(props)
|
|
123
|
+
print(f"{drug:<20} {props.get('MolecularWeight', 0):>8.1f} "
|
|
124
|
+
f"{props.get('XLogP', 0):>6.1f} "
|
|
125
|
+
f"{props.get('HBondDonorCount', 0):>4} "
|
|
126
|
+
f"{props.get('HBondAcceptorCount', 0):>4} "
|
|
127
|
+
f"{violations:>10}")
|
|
128
|
+
time.sleep(0.3)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Python Example: Compound Comparison
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
import requests
|
|
135
|
+
|
|
136
|
+
def compare_compounds(cid_list):
|
|
137
|
+
"""Compare properties of multiple compounds by CID."""
|
|
138
|
+
cids = ",".join(str(c) for c in cid_list)
|
|
139
|
+
props = "IUPACName,MolecularFormula,MolecularWeight,CanonicalSMILES,XLogP"
|
|
140
|
+
url = f"{PUG_REST}/compound/cid/{cids}/property/{props}/JSON"
|
|
141
|
+
resp = requests.get(url)
|
|
142
|
+
resp.raise_for_status()
|
|
143
|
+
return resp.json().get("PropertyTable", {}).get("Properties", [])
|
|
144
|
+
|
|
145
|
+
# Compare aspirin (2244), ibuprofen (3672), acetaminophen (1983)
|
|
146
|
+
results = compare_compounds([2244, 3672, 1983])
|
|
147
|
+
for compound in results:
|
|
148
|
+
print(f"\n{compound.get('IUPACName', 'Unknown')}")
|
|
149
|
+
print(f" Formula: {compound.get('MolecularFormula')}")
|
|
150
|
+
print(f" MW: {compound.get('MolecularWeight')}")
|
|
151
|
+
print(f" SMILES: {compound.get('CanonicalSMILES')}")
|
|
152
|
+
print(f" LogP: {compound.get('XLogP')}")
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Common Research Patterns
|
|
156
|
+
|
|
157
|
+
**Structure-Activity Relationship (SAR) Analysis:** Use similarity searches to find structural analogs of lead compounds, then retrieve bioassay data to compare biological activity across the series.
|
|
158
|
+
|
|
159
|
+
**Virtual Screening:** Screen large compound libraries against drug-likeness filters (Lipinski's rules, Veber's rules) using property endpoints to prioritize candidates for experimental testing.
|
|
160
|
+
|
|
161
|
+
**Chemical Identifier Resolution:** Translate between compound names, CIDs, InChI, InChIKey, and SMILES notations. Essential for data integration across heterogeneous chemistry databases.
|
|
162
|
+
|
|
163
|
+
**Toxicology Research:** Access bioassay results and safety data for compounds to support toxicity profiling and risk assessment in environmental health research.
|
|
164
|
+
|
|
165
|
+
## Rate Limits and Best Practices
|
|
166
|
+
|
|
167
|
+
- **Rate limit:** Maximum 5 requests per second; add 200ms delays between requests
|
|
168
|
+
- **No more than 400 requests per minute** from a single IP
|
|
169
|
+
- **Batch requests:** Use comma-separated CIDs (up to 200) in a single request to minimize API calls
|
|
170
|
+
- **Async operations:** For large similarity/substructure searches, use the async workflow with list keys
|
|
171
|
+
- **Response formats:** Use JSON for programmatic access, SDF for structure files, CSV for tabular data
|
|
172
|
+
- **Caching:** Compound data is relatively static; cache property lookups aggressively
|
|
173
|
+
- **Error handling:** HTTP 404 means compound not found; 503 means server busy (retry with backoff)
|
|
174
|
+
|
|
175
|
+
## References
|
|
176
|
+
|
|
177
|
+
- PubChem PUG REST Documentation: https://pubchem.ncbi.nlm.nih.gov/docs/pug-rest
|
|
178
|
+
- PubChem PUG REST Tutorial: https://pubchem.ncbi.nlm.nih.gov/docs/pug-rest-tutorial
|
|
179
|
+
- PubChem Compound Database: https://pubchem.ncbi.nlm.nih.gov/
|
|
180
|
+
- PubChem Power User Gateway: https://pubchem.ncbi.nlm.nih.gov/docs/power-user-gateway
|