Skip to content

Commit c096549

Browse files
committed
chore: update package configurations
1 parent defd0d6 commit c096549

11 files changed

Lines changed: 424 additions & 71 deletions

File tree

package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
{
22
"name": "harmonia",
33
"version": "0.1.0",
4-
"description": "Browser-based federated learning platform for privacy-preserving medical research using OMOP CDM",
4+
"description": "Federated causal inference for privacy-preserving multi-site observational health data",
55
"keywords": [
6+
"causal-inference",
67
"federated-learning",
78
"healthcare",
89
"privacy-preserving",
9-
"omop-cdm",
10-
"ohdsi",
11-
"machine-learning",
12-
"tensorflow"
10+
"partial-identification",
11+
"omop-cdm"
1312
],
1413
"homepage": "https://github.com/watilde/Harmonia#readme",
1514
"bugs": {

research/modules/1-manski-bounds/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "@harmonia/manski-bounds-module",
2+
"name": "@harmonia/1-manski-bounds",
33
"version": "0.1.0",
44
"private": true,
55
"description": "Scripts and pipelines for the Manski bounds module",

research/modules/1-manski-bounds/scripts/generate-pdf.js

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,62 @@ async function generatePDF(markdownFile, outputPDF) {
1717
// Convert to HTML
1818
const html = marked.parse(markdown);
1919

20-
// Create full HTML document with styling
20+
// Get the directory of the markdown file for resolving relative paths
21+
const markdownDir = path.dirname(path.resolve(markdownFile));
22+
23+
// Convert images to base64 and embed directly
24+
let processedHtml = html;
25+
const imageRegex = /src="figures\/([^"]+)"/g;
26+
let match;
27+
let imageCount = 0;
28+
29+
while ((match = imageRegex.exec(html)) !== null) {
30+
const imageName = match[1];
31+
const imagePath = path.join(markdownDir, 'figures', imageName);
32+
33+
try {
34+
if (fs.existsSync(imagePath)) {
35+
const imageData = fs.readFileSync(imagePath);
36+
const base64Image = imageData.toString('base64');
37+
const ext = path.extname(imageName).substring(1);
38+
const mimeType = ext === 'png' ? 'image/png' : 'image/jpeg';
39+
const dataUrl = `data:${mimeType};base64,${base64Image}`;
40+
41+
processedHtml = processedHtml.replace(
42+
`src="figures/${imageName}"`,
43+
`src="${dataUrl}"`
44+
);
45+
imageCount++;
46+
console.log(` ✓ Embedded image: ${imageName}`);
47+
} else {
48+
console.warn(` ⚠ Image not found: ${imagePath}`);
49+
}
50+
} catch (err) {
51+
console.warn(` ⚠ Failed to load image ${imageName}: ${err.message}`);
52+
}
53+
}
54+
55+
console.log(` ✓ Total images embedded: ${imageCount}`);
56+
57+
// Create full HTML document with styling and MathJax
2158
const fullHTML = `
2259
<!DOCTYPE html>
2360
<html>
2461
<head>
2562
<meta charset="UTF-8">
63+
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
64+
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
65+
<script>
66+
MathJax = {
67+
tex: {
68+
inlineMath: [['$', '$'], ['\\\\(', '\\\\)']],
69+
displayMath: [['$$', '$$'], ['\\\\[', '\\\\]']]
70+
},
71+
svg: {
72+
fontCache: 'global'
73+
}
74+
};
75+
</script>
2676
<style>
2777
body {
2878
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
@@ -91,6 +141,19 @@ async function generatePDF(markdownFile, outputPDF) {
91141
img {
92142
max-width: 100%;
93143
height: auto;
144+
display: block;
145+
margin: 1em auto;
146+
}
147+
figure {
148+
text-align: center;
149+
margin: 1.5em 0;
150+
page-break-inside: avoid;
151+
}
152+
figcaption, em {
153+
font-style: italic;
154+
color: #666;
155+
font-size: 0.9em;
156+
margin-top: 0.5em;
94157
}
95158
@media print {
96159
body {
@@ -106,7 +169,7 @@ async function generatePDF(markdownFile, outputPDF) {
106169
</style>
107170
</head>
108171
<body>
109-
${html}
172+
${processedHtml}
110173
</body>
111174
</html>
112175
`;
@@ -122,7 +185,23 @@ ${html}
122185

123186
// Set content
124187
console.log(' Rendering HTML...');
125-
await page.setContent(fullHTML, { waitUntil: 'networkidle0' });
188+
await page.setContent(fullHTML, {
189+
waitUntil: ['load', 'domcontentloaded', 'networkidle0']
190+
});
191+
192+
// Wait for images to load
193+
await page.evaluate(() => {
194+
return Promise.all(
195+
Array.from(document.images)
196+
.filter(img => !img.complete)
197+
.map(img => new Promise(resolve => {
198+
img.onload = img.onerror = resolve;
199+
}))
200+
);
201+
});
202+
203+
// Wait for MathJax to render
204+
await new Promise(resolve => setTimeout(resolve, 3000));
126205

127206
// Generate PDF
128207
console.log(' Generating PDF...');

research/modules/2-federated-partial-identification/package.json

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "@harmonia/federated-partial-identification",
2+
"name": "@harmonia/2-federated-partial-identification",
33
"version": "0.1.0",
44
"description": "Federated Partial Identification: Balke-Pearl bounds, Manski bounds, and aggregation strategies",
55
"private": true,
@@ -8,17 +8,6 @@
88
"paper:pdf": "./scripts/generate-pdf.sh",
99
"experiment:aggregation": "./experiments/run-aggregation-comparison.sh"
1010
},
11-
"dependencies": {
12-
"csv-parse": "^6.1.0"
13-
},
14-
"devDependencies": {
15-
"@types/jest": "^29.0.0",
16-
"@types/node": "^20.0.0",
17-
"jest": "^29.0.0",
18-
"ts-jest": "^29.0.0",
19-
"typescript": "^5.0.0",
20-
"ts-node": "^10.9.0"
21-
},
2211
"keywords": [
2312
"causal-inference",
2413
"partial-identification",

research/modules/2-federated-partial-identification/scripts/generate-pdf.js

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,62 @@ async function generatePDF(markdownFile, outputPDF) {
1717
// Convert to HTML
1818
const html = marked.parse(markdown);
1919

20-
// Create full HTML document with styling
20+
// Get the directory of the markdown file for resolving relative paths
21+
const markdownDir = path.dirname(path.resolve(markdownFile));
22+
23+
// Convert images to base64 and embed directly
24+
let processedHtml = html;
25+
const imageRegex = /src="figures\/([^"]+)"/g;
26+
let match;
27+
let imageCount = 0;
28+
29+
while ((match = imageRegex.exec(html)) !== null) {
30+
const imageName = match[1];
31+
const imagePath = path.join(markdownDir, 'figures', imageName);
32+
33+
try {
34+
if (fs.existsSync(imagePath)) {
35+
const imageData = fs.readFileSync(imagePath);
36+
const base64Image = imageData.toString('base64');
37+
const ext = path.extname(imageName).substring(1);
38+
const mimeType = ext === 'png' ? 'image/png' : 'image/jpeg';
39+
const dataUrl = `data:${mimeType};base64,${base64Image}`;
40+
41+
processedHtml = processedHtml.replace(
42+
`src="figures/${imageName}"`,
43+
`src="${dataUrl}"`
44+
);
45+
imageCount++;
46+
console.log(` ✓ Embedded image: ${imageName}`);
47+
} else {
48+
console.warn(` ⚠ Image not found: ${imagePath}`);
49+
}
50+
} catch (err) {
51+
console.warn(` ⚠ Failed to load image ${imageName}: ${err.message}`);
52+
}
53+
}
54+
55+
console.log(` ✓ Total images embedded: ${imageCount}`);
56+
57+
// Create full HTML document with styling and MathJax
2158
const fullHTML = `
2259
<!DOCTYPE html>
2360
<html>
2461
<head>
2562
<meta charset="UTF-8">
63+
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
64+
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
65+
<script>
66+
MathJax = {
67+
tex: {
68+
inlineMath: [['$', '$'], ['\\\\(', '\\\\)']],
69+
displayMath: [['$$', '$$'], ['\\\\[', '\\\\]']]
70+
},
71+
svg: {
72+
fontCache: 'global'
73+
}
74+
};
75+
</script>
2676
<style>
2777
body {
2878
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
@@ -91,6 +141,19 @@ async function generatePDF(markdownFile, outputPDF) {
91141
img {
92142
max-width: 100%;
93143
height: auto;
144+
display: block;
145+
margin: 1em auto;
146+
}
147+
figure {
148+
text-align: center;
149+
margin: 1.5em 0;
150+
page-break-inside: avoid;
151+
}
152+
figcaption, em {
153+
font-style: italic;
154+
color: #666;
155+
font-size: 0.9em;
156+
margin-top: 0.5em;
94157
}
95158
@media print {
96159
body {
@@ -106,7 +169,7 @@ async function generatePDF(markdownFile, outputPDF) {
106169
</style>
107170
</head>
108171
<body>
109-
${html}
172+
${processedHtml}
110173
</body>
111174
</html>
112175
`;
@@ -122,7 +185,23 @@ ${html}
122185

123186
// Set content
124187
console.log(' Rendering HTML...');
125-
await page.setContent(fullHTML, { waitUntil: 'networkidle0' });
188+
await page.setContent(fullHTML, {
189+
waitUntil: ['load', 'domcontentloaded', 'networkidle0']
190+
});
191+
192+
// Wait for images to load
193+
await page.evaluate(() => {
194+
return Promise.all(
195+
Array.from(document.images)
196+
.filter(img => !img.complete)
197+
.map(img => new Promise(resolve => {
198+
img.onload = img.onerror = resolve;
199+
}))
200+
);
201+
});
202+
203+
// Wait for MathJax to render
204+
await new Promise(resolve => setTimeout(resolve, 3000));
126205

127206
// Generate PDF
128207
console.log(' Generating PDF...');

research/modules/3-federated-evalues/package.json

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "@harmonia/federated-evalues",
2+
"name": "@harmonia/3-federated-evalues",
33
"version": "0.1.0",
44
"description": "Federated E-values and Robustness Index for sensitivity analysis in multi-site causal inference",
55
"private": true,
@@ -8,17 +8,6 @@
88
"paper:pdf": "./scripts/generate-pdf.sh",
99
"experiment:fri": "./experiments/run-fri-validation.sh"
1010
},
11-
"dependencies": {
12-
"@harmonia/federated-partial-identification": "file:../federated-partial-identification"
13-
},
14-
"devDependencies": {
15-
"@types/jest": "^29.0.0",
16-
"@types/node": "^20.0.0",
17-
"jest": "^29.0.0",
18-
"ts-jest": "^29.0.0",
19-
"typescript": "^5.0.0",
20-
"ts-node": "^10.9.0"
21-
},
2211
"keywords": [
2312
"causal-inference",
2413
"sensitivity-analysis",

0 commit comments

Comments
 (0)