Skip to content

Commit 910f783

Browse files
committed
add search function, add support for asas-sn bands
1 parent ef6b039 commit 910f783

6 files changed

Lines changed: 148 additions & 0 deletions

File tree

src/App.jsx

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ export default function App() {
122122
const [filterOpen, setFilterOpen] = useState(true);
123123
const [bottomH, setBottomH] = useState(504);
124124
const [activeBands, setActiveBands] = useState(null);
125+
const [searchInput, setSearchInput] = useState('');
126+
const [searchError, setSearchError] = useState(null);
125127

126128
const containerRef = useRef(null);
127129
const dsRef = useRef(null);
@@ -191,6 +193,26 @@ export default function App() {
191193
}
192194
};
193195

196+
const searchByID = async () => {
197+
const id = searchInput.trim();
198+
if (!id || !dsRef.current) return;
199+
setLoading(true);
200+
setSearchError(null);
201+
setError(null);
202+
try {
203+
const found = await dsRef.current.findBySourceId(id);
204+
if (found) {
205+
setCurrentRow(found);
206+
} else {
207+
setSearchError(`No star with ID ${id}`);
208+
}
209+
} catch (err) {
210+
setSearchError(err.message);
211+
} finally {
212+
setLoading(false);
213+
}
214+
};
215+
194216
const toggleClass = (cls) =>
195217
setEnabledClasses((prev) => {
196218
const next = new Set(prev);
@@ -499,6 +521,58 @@ export default function App() {
499521
</svg>
500522
Random star
501523
</button>
524+
525+
<form
526+
onSubmit={(e) => { e.preventDefault(); searchByID(); }}
527+
style={{ ...GLASS, padding: '14px 16px' }}
528+
>
529+
<div style={{ ...KICKER, marginBottom: 8 }}>
530+
Search by Gaia DR3 ID
531+
</div>
532+
<div style={{ display: 'flex', gap: 6 }}>
533+
<input
534+
type="text"
535+
inputMode="numeric"
536+
value={searchInput}
537+
onChange={(e) => { setSearchInput(e.target.value); setSearchError(null); }}
538+
disabled={loading}
539+
style={{
540+
flex: 1, minWidth: 0,
541+
padding: '8px 10px', borderRadius: 6,
542+
border: '1px solid rgba(125,169,255,0.2)',
543+
background: 'rgba(125,169,255,0.08)',
544+
color: '#e8ecf6',
545+
fontFamily: 'JetBrains Mono, monospace', fontSize: 15,
546+
letterSpacing: 0.3, outline: 'none',
547+
}}
548+
/>
549+
<button
550+
type="submit"
551+
disabled={loading || !searchInput.trim()}
552+
style={{
553+
padding: '0 14px', borderRadius: 6,
554+
border: '1px solid rgba(125,169,255,0.25)',
555+
background: 'rgba(125,169,255,0.12)',
556+
color: ACCENT,
557+
fontFamily: 'JetBrains Mono, monospace', fontSize: 14,
558+
fontWeight: 700, letterSpacing: 1.1, textTransform: 'uppercase',
559+
cursor: (loading || !searchInput.trim()) ? 'default' : 'pointer',
560+
opacity: (loading || !searchInput.trim()) ? 0.45 : 1,
561+
}}
562+
>
563+
Go
564+
</button>
565+
</div>
566+
{searchError && (
567+
<div style={{
568+
marginTop: 8,
569+
fontFamily: 'JetBrains Mono, monospace', fontSize: 13,
570+
color: '#ff8a72', wordBreak: 'break-all',
571+
}}>
572+
{searchError}
573+
</div>
574+
)}
575+
</form>
502576
</div>
503577
)}
504578

src/bands.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ export const SURVEY_LIBRARY = [
2727
survey: 'CSS',
2828
bands: [
2929
{ key: 'clear_CSS', label: 'clear', color: '#c8d4e8' },
30+
{ key: 'clear', label: 'clear', color: '#c8d4e8' },
31+
],
32+
},
33+
{
34+
survey: 'ASAS-SN',
35+
bands: [
36+
{ key: 'g_ASASSN', label: 'g', color: '#6ee7a8' },
37+
{ key: 'V_ASASSN', label: 'V', color: '#f4c542' },
3038
],
3139
},
3240
];

src/data/DataSource.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,14 @@ export class DataSource {
4141
async getSummary() {
4242
return null;
4343
}
44+
45+
/**
46+
* Find a row by its gaia_dr3_source_id. Returns the row object or null.
47+
* @param {string|number|bigint} id
48+
* @returns {Promise<object|null>}
49+
*/
50+
// eslint-disable-next-line no-unused-vars
51+
async findBySourceId(id) {
52+
throw new Error("DataSource.findBySourceId not implemented");
53+
}
4454
}

src/data/HFDataSource.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,38 @@ export class HFDataSource extends DataSource {
8787
return collected;
8888
}
8989

90+
// Uses the datasets-server /filter endpoint so the lookup happens server-side
91+
// at full int64 precision (gaia_dr3_source_id is 19 digits; JS Number rounds).
92+
// Datasets store the id as either int64 or string; DuckDB's WHERE is type-
93+
// strict, so we try the quoted-string form first then the bare-int form.
94+
async findBySourceId(id) {
95+
const numeric = String(id).trim();
96+
if (!/^\d+$/.test(numeric)) {
97+
throw new Error("Source ID must be numeric");
98+
}
99+
let lastErr = null;
100+
for (const literal of [`'${numeric}'`, numeric]) {
101+
const url = `${BASE}/filter?${this._qs({
102+
dataset: this.dataset,
103+
config: this.config,
104+
split: this.split,
105+
where: `gaia_dr3_source_id=${literal}`,
106+
length: "1",
107+
})}`;
108+
const res = await fetch(url);
109+
if (!res.ok) {
110+
lastErr = `Search failed: ${res.status} ${res.statusText}`;
111+
continue;
112+
}
113+
const data = await res.json();
114+
const rows = (data?.rows || []).map((r) => r.row);
115+
if (rows[0]) return rows[0];
116+
lastErr = null;
117+
}
118+
if (lastErr) throw new Error(lastErr);
119+
return null;
120+
}
121+
90122
// Fetches a pre-computed summary.json from the dataset repo. Build/upload via
91123
// scripts/build_summary.py. Returns null gracefully if absent so the app
92124
// degrades to global random sampling without sky map or class filter.

src/data/HFDiskDataSource.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,24 @@ export class HFDiskDataSource extends DataSource {
160160
return this._summary;
161161
}
162162

163+
// Arrow ids are int64 (BigInt); compare as strings to preserve precision.
164+
async findBySourceId(id) {
165+
await this._scan();
166+
const target = String(id).trim();
167+
for (let shardIdx = 0; shardIdx < this._shards.length; shardIdx++) {
168+
const table = await this._loadShard(shardIdx);
169+
const idCol = table.getChild("gaia_dr3_source_id");
170+
if (!idCol) return null;
171+
for (let i = 0; i < table.numRows; i++) {
172+
const v = idCol.get(i);
173+
if (v != null && String(v) === target) {
174+
return extractRow(table, table.schema.fields, i);
175+
}
176+
}
177+
}
178+
return null;
179+
}
180+
163181
async _loadShard(idx) {
164182
if (this._cachedShard?.idx === idx) return this._cachedShard.table;
165183
const file = this._shards[idx];

src/data/LocalDataSource.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ export class LocalDataSource extends DataSource {
5757
return rows.slice(offset, offset + length);
5858
}
5959

60+
async findBySourceId(id) {
61+
const rows = await this._load();
62+
const target = String(id).trim();
63+
return rows.find((r) => String(r.gaia_dr3_source_id) === target) ?? null;
64+
}
65+
6066
async getSummary() {
6167
const rows = await this._load();
6268
const classIndices = {};

0 commit comments

Comments
 (0)