Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
60787db
docs: update repository URL to DeePTB-Lab organization
QG-phy Jan 1, 2026
1f104eb
feat(ci): add master branch to test workflow triggers
QG-phy Jan 1, 2026
d29ea8f
feat: add export HR functionality to parameter editor
QG-phy Jan 2, 2026
5c9e4d5
feat: add working directory selection to header
QG-phy Jan 2, 2026
cdeafaa
feat(ui): improve theme toggle and path display
QG-phy Jan 2, 2026
8c5b066
refactor(ui): optimize parameter editor layout and labels
QG-phy Jan 2, 2026
f97c4e5
feat(desktop): Set window size to 1000x600 pixels
QG-phy Jan 2, 2026
d83dd23
refactor: remove dynamic lambda add/remove functionality
QG-phy Jan 2, 2026
15021a8
refactor: reduce parameter editor section spacing
QG-phy Jan 2, 2026
473cb88
feat: add company logo to application header
QG-phy Jan 2, 2026
fc29da6
feat: implement dynamic version display
QG-phy Jan 2, 2026
c415169
feat: update header logo size and remove desktop label
QG-phy Jan 2, 2026
51c3760
feat: add output_dir parameter to save_hr_file
QG-phy Jan 2, 2026
789dde3
feat: rename Fermi energy label to Center energy
QG-phy Jan 2, 2026
db1a68b
feat: enhance lambda parsing in addsoc and improve plot tools
QG-phy Jan 2, 2026
8aa16b5
feat: update input config format and improve integration tests
QG-phy Jan 2, 2026
7d4a360
feat: add conditional test skip for frontend serving check
QG-phy Jan 2, 2026
a4045c1
feat: migrate from uv dev-dependencies to dependency-groups
QG-phy Jan 2, 2026
7b1f6b3
test: fix integration tests to use correct Python and PYTHONPATH
QG-phy Jan 2, 2026
54fb418
fix: correct GitHub workflow typo and adjust sidebar width
QG-phy Jan 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Unit Tests

on:
push:
branches: [ main, develop ]
branches: [master, main, develop ]
pull_request:
branches: [ main, develop ]
branches: [master, main, develop ]
workflow_dispatch:

jobs:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

### Install via uv (Recommended)
```bash
git clone https://github.com/qqgu/TBSOC.git
git clone https://github.com/DeePTB-Lab/TBSOC.git
cd TBSOC
uv sync
```
Expand Down
18 changes: 7 additions & 11 deletions example/TaAs/input.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
{
"lambdas":[0.4, 0.1],
"posfile":"./POSCAR",
"winfile":"./wannier90.win",
"hrfile":"./wannier90_hr.dat",
"kpfile":"./KPOINTS",
"eigfile":"./EIGENVAL",
"outdir":"./",
"EMIN":-3,
"EMAX":3,
"lambdas": {
"Ta:d": 0.4,
"As:p": 0.1
},
"Efermi":6.4553,
"fit_emin": -3.0,
"fit_emax": 3.0
"weight_sigma": 2.0,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

rg -nP -C5 'weight_sigma' --type=py

Repository: DeePTB-Lab/TBSOC

Length of output: 1395


🏁 Script executed:

rg -nP -B5 -A10 'sigma\s*=' tbsoc/entrypoints/fitsoc.py | head -40

Repository: DeePTB-Lab/TBSOC

Length of output: 674


🏁 Script executed:

# Check for any docstrings or comments about weight_sigma or sigma parameter
rg -nP 'weight|sigma' tbsoc/server/schemas.py -A2 -B2

Repository: DeePTB-Lab/TBSOC

Length of output: 194


🏁 Script executed:

# Search for usage of sigma variable in fitsoc.py to understand its purpose
rg -nP '\bsigma\b' tbsoc/entrypoints/fitsoc.py

Repository: DeePTB-Lab/TBSOC

Length of output: 385


Fix inconsistent default for weight_sigma: schema specifies 2.0 but runtime code uses 0.5.

The parameter has default handling and partial documentation, but with critical inconsistencies:

  1. Default mismatch: Schema defines weight_sigma: float = 2.0 but fitsoc.py uses jdata.get('weight_sigma', 0.5). Update either the schema or runtime code to use the same default.
  2. Documentation gaps: Add docstring to the schema field explaining: (a) purpose—standard deviation for Gaussian weighting in band analysis, (b) units—eV, (c) suggested valid range (e.g., 0.1–5.0 eV).
🤖 Prompt for AI Agents
In example/TaAs/input.json around line 7 update runtime/schema to use a
consistent default for weight_sigma: change the runtime usage (in fitsoc.py
where it reads jdata.get('weight_sigma', 0.5)) to use 2.0 to match the schema
(or alternatively change the schema default to 0.5 if you prefer that baseline)
so both places use the same value; additionally add a docstring/comment to the
schema field describing purpose ("standard deviation for Gaussian weighting in
band analysis"), units ("eV"), and a suggested valid range ("0.1–5.0 eV").

"EMIN": -15,
"EMAX": 10
}
14 changes: 14 additions & 0 deletions example/TaAs/input_old.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"lambdas":[0.4, 0.1],
"posfile":"./POSCAR",
"winfile":"./wannier90.win",
"hrfile":"./wannier90_hr.dat",
"kpfile":"./KPOINTS",
"eigfile":"./EIGENVAL",
"outdir":"./",
"EMIN":-3,
"EMAX":3,
"Efermi":6.4553,
"fit_emin": -3.0,
"fit_emax": 3.0
}
Binary file added frontend/public/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
158 changes: 138 additions & 20 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,24 @@ function App() {
// Theme State
const [currentTheme, setCurrentTheme] = useState(localStorage.getItem('theme') || 'Light');
const [themeConfig, setThemeConfig] = useState(null);

// Working Directory State (Lifted from ParameterEditor)
const [currentPath, setCurrentPath] = useState('');
const [appVersion, setAppVersion] = useState('');

// Load Theme
// Initial Data Load
React.useEffect(() => {
// Load Version
fetch('/api/version')
.then(res => res.json())
.then(data => setAppVersion(`v${data.version}`))
.catch(console.error);

// Load Theme
fetch(`/themes/${currentTheme.toLowerCase()}.json`)
.then(res => res.json())
.then(config => {
setThemeConfig(config);
// Apply CSS variables
if (config.css) {
Object.entries(config.css).forEach(([key, value]) => {
document.documentElement.style.setProperty(key, value);
Expand All @@ -57,8 +67,26 @@ function App() {
localStorage.setItem('theme', currentTheme);
})
.catch(err => console.error("Failed to load theme:", err));

// Load Current Directory
fetch('/api/current-directory')
.then(res => res.json())
.then(data => setCurrentPath(data.path))
.catch(console.error);
}, [currentTheme]);

const handleOpenFolder = async () => {
try {
const res = await fetch('/api/choose-directory', { method: 'POST' });
const data = await res.json();
if (data.path) {
setCurrentPath(data.path);
}
} catch (err) {
console.error("Failed to open folder:", err);
}
};

const handleDataLoaded = () => {
console.log("Data loaded, updating version");
setDataVersion(v => v + 1);
Expand Down Expand Up @@ -136,41 +164,131 @@ function App() {
return (
<ErrorBoundary>
<div className="container" style={{maxWidth: '100%', padding: '20px', height: '100vh', boxSizing: 'border-box', display: 'flex', flexDirection: 'column'}}>
<header style={{textAlign: 'center', marginBottom: '1em', flexShrink: 0}}>
<h1 style={{margin: '0.2em 0', fontSize: '2em'}}>TBSOC Desktop</h1>
<div style={{display: 'flex', justifyContent: 'center', gap: '20px', alignItems: 'center'}}>
<p style={{color: '#888', margin: 0}}>Tight-Binding SOC Fitter</p>
<div style={{padding: '2px 8px', background: '#333', borderRadius: '4px', fontSize: '0.8rem'}}>
Status: <span style={{color: status.includes('Error') ? '#ff6b6b' : '#42d392'}}>{status}</span>
<header style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
padding: '0 20px',
height: '60px',
borderBottom: '1px solid var(--border-color)',
background: 'var(--bg-card)',
marginBottom: '20px',
flexShrink: 0
}}>
<div style={{display: 'flex', alignItems: 'center', gap: '12px', flexShrink: 0}}>
<img src="/logo.png" alt="Logo" style={{height: '48px', width: 'auto'}} />
{/* App Title */}
<div style={{fontWeight: '700', fontSize: '1.1rem', color: 'var(--text-main)', letterSpacing: '-0.02em'}}>
TBSOC
</div>
{/* Version Badge */}
<span style={{fontSize: '0.75rem', color: 'var(--text-secondary)', border: '1px solid var(--border-color)', padding: '1px 6px', borderRadius: '4px'}}>{appVersion || 'v...'}</span>
</div>

{/* Center: Working Directory */}
<div style={{flex: 1, display: 'flex', justifyContent: 'center', alignItems: 'center', minWidth: 0, padding: '0 20px'}}>
<div style={{
display: 'flex',
alignItems: 'center',
background: 'var(--bg-secondary)',
padding: '4px 4px 4px 12px',
borderRadius: '8px',
border: '1px solid var(--border-color)',
maxWidth: '100%'
}}>
<span style={{
fontSize: '0.85rem',
fontFamily: 'monospace',
color: 'var(--text-secondary)',
marginRight: '12px',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
maxWidth: '400px',
direction: 'rtl',
textAlign: 'left'
}} title={currentPath}>
{currentPath || "No directory selected"}
</span>
<button
onClick={handleOpenFolder}
style={{
whiteSpace: 'nowrap',
padding: '4px 12px',
fontSize: '0.8rem',
background: 'var(--button-bg)',
color: 'var(--button-text)',
border: '1px solid var(--border-color)',
borderRadius: '6px',
cursor: 'pointer',
fontWeight: 500
}}
>
Open Folder
</button>
</div>
</div>

<div style={{display: 'flex', alignItems: 'center', gap: '20px', flexShrink: 0}}>
{/* Status Indicator */}
<div style={{display: 'flex', alignItems: 'center', gap: '8px', fontSize: '0.85rem', background: 'var(--bg-secondary)', padding: '4px 10px', borderRadius: '20px'}}>
<span style={{
display: 'block',
width: '8px',
height: '8px',
borderRadius: '50%',
background: status.includes('Error') ? '#ff6b6b' : (status === 'Idle' || status === 'Fitting Completed' ? '#42d392' : '#fbbf24')
}}></span>
<span style={{color: 'var(--text-main)', fontWeight: 500}}>{status}</span>
</div>
<select
value={currentTheme}
onChange={(e) => setCurrentTheme(e.target.value)}

{/* Divider */}
<div style={{height: '24px', width: '1px', background: 'var(--border-color)'}}></div>

{/* Theme Toggle Button */}
<button
onClick={() => setCurrentTheme(currentTheme === 'Light' ? 'Dark' : 'Light')}
title={`Switch to ${currentTheme === 'Light' ? 'Dark' : 'Light'} Mode`}
style={{
marginLeft: '10px',
padding: '4px 8px',
borderRadius: '4px',
background: 'var(--bg-secondary)',
border: '1px solid var(--border-color)',
background: 'var(--input-bg)',
borderRadius: '20px',
cursor: 'pointer',
fontSize: '0.85rem',
color: 'var(--text-main)',
fontSize: '0.9rem'
display: 'flex',
alignItems: 'center',
gap: '6px',
padding: '4px 12px',
transition: 'all 0.2s ease',
fontWeight: 500
}}
>
<option value="Dark">Dark Mode</option>
<option value="Light">Light Mode</option>
</select>
{currentTheme === 'Light' ? (
<>
<span>Theme</span>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="#4b5563" stroke="none"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
</>
) : (
<>
<span>Theme</span>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#fbbf24" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg>
</>
)}
</button>
</div>
</header>

<div style={{display: 'flex', gap: '20px', flex: 1, minHeight: 0}}>
<div style={{flex: '0 0 400px', minWidth: '350px'}}>
<div style={{flex: '0 0 300px', minWidth: '300px'}}>
<ParameterEditor
onRunFit={runFit}
onPreview={handlePreview}
onDataLoaded={handleDataLoaded}
externalLambdas={activeLambdas}
isFitting={status.startsWith("Fitting") || status === "Submitting..."}
onStopFit={handleStopFit}
currentPath={currentPath}
/>
</div>
<div style={{flex: 1, minWidth: 0, height: '100%'}}>
Expand Down
Loading