@@ -23,9 +23,6 @@ const { id } = Astro.params
2323const ret = loadAccessionMap ().get (id as string )
2424
2525if (! ret ) {
26- // Astro handles 404s for paths not returned by getStaticPaths
27- // For direct access, you might want a custom 404 page or redirect
28- // For now, we'll just show a message.
2926 throw new Error (` Accession not found: ${id } ` )
3027}
3128
@@ -86,18 +83,31 @@ const imageData = tryAndReadJSON<{ imageUrl?: string; pageUrl?: string }>(
8683const imageUrl = imageData ?.imageUrl
8784const pageUrl = imageData ?.pageUrl
8885
89- const statsParts = [
90- stats ?.total_length
91- ? ` ${Number (stats .total_length ).toLocaleString ()} bp total `
92- : null ,
93- stats ?.chromosome_count ? ` ${stats .chromosome_count } chromosomes ` : null ,
94- stats ?.scaffold_n50
95- ? ` scaffold N50: ${Number (stats .scaffold_n50 ).toLocaleString ()} `
96- : null ,
97- stats ?.contig_n50
98- ? ` contig N50: ${Number (stats .contig_n50 ).toLocaleString ()} `
99- : null ,
100- ].filter (Boolean )
86+ const buscoBreakdown = annotationInfo ?.busco
87+ ? [
88+ annotationInfo .busco .single_copy !== undefined
89+ ? ` ${(annotationInfo .busco .single_copy * 100 ).toFixed (1 )}% single-copy `
90+ : null ,
91+ annotationInfo .busco .duplicated !== undefined
92+ ? ` ${(annotationInfo .busco .duplicated * 100 ).toFixed (1 )}% duplicated `
93+ : null ,
94+ annotationInfo .busco .fragmented !== undefined
95+ ? ` ${(annotationInfo .busco .fragmented * 100 ).toFixed (1 )}% fragmented `
96+ : null ,
97+ annotationInfo .busco .missing !== undefined
98+ ? ` ${(annotationInfo .busco .missing * 100 ).toFixed (1 )}% missing `
99+ : null ,
100+ ].filter (Boolean )
101+ : []
102+
103+ const hasAssemblyStats =
104+ stats ?.total_length ||
105+ stats ?.chromosome_count ||
106+ stats ?.scaffold_count ||
107+ stats ?.contig_count ||
108+ gcPercent !== undefined ||
109+ genomeCoverage ||
110+ sequencingTech
101111---
102112
103113<Layout frontmatter ={ { title: scientificName }} >
@@ -177,7 +187,7 @@ const statsParts = [
177187 ) : null
178188 }
179189 {
180- pairedAccession && pairedAssemblyData ? (
190+ pairedAccession ? (
181191 <div >
182192 <b >
183193 { pairedLabel }
@@ -191,7 +201,15 @@ const statsParts = [
191201 </span >
192202 :
193203 </b >{ ' ' }
194- <a href = { ` /accession/${pairedAccession } ` } >{ pairedAccession } </a >
204+ { pairedAssemblyData ? (
205+ <a href = { ` /accession/${pairedAccession } ` } >{ pairedAccession } </a >
206+ ) : (
207+ <a
208+ href = { ` https://www.ncbi.nlm.nih.gov/datasets/genome/${pairedAccession }/ ` }
209+ >
210+ { pairedAccession }
211+ </a >
212+ )}
195213 { pairedAssemblyStatus === ' suppressed' ? (
196214 <>
197215 { ' ' }
@@ -212,39 +230,6 @@ const statsParts = [
212230 </div >
213231 ) : null
214232 }
215- {
216- statsParts .length ? (
217- <div >
218- <b >Assembly stats:</b >
219- <ul >
220- { statsParts .map (p => (
221- <li >{ p } </li >
222- ))}
223- </ul >
224- </div >
225- ) : null
226- }
227- {
228- gcPercent !== undefined ? (
229- <div >
230- <b >GC content:</b > { gcPercent } %
231- </div >
232- ) : null
233- }
234- {
235- genomeCoverage ? (
236- <div >
237- <b >Coverage:</b > { genomeCoverage } x
238- </div >
239- ) : null
240- }
241- {
242- sequencingTech ? (
243- <div >
244- <b >Sequencing:</b > { sequencingTech }
245- </div >
246- ) : null
247- }
248233 {
249234 bioprojectAccession ? (
250235 <div >
@@ -257,29 +242,139 @@ const statsParts = [
257242 </div >
258243 ) : null
259244 }
260- {
261- annotationInfo ? (
262- <div >
263- <b >Annotation:</b > { annotationInfo .name }
264- { annotationInfo .provider ? ` (${annotationInfo .provider }) ` : null }
265- { annotationInfo .release_date
266- ? ` , ${annotationInfo .release_date } `
267- : null }
245+ </div >
246+ {
247+ hasAssemblyStats ? (
248+ <div >
249+ <h2 >Assembly statistics</h2 >
250+ <dl class = { styles .statsTable } >
251+ { stats ?.total_length ? (
252+ <>
253+ <dt >Total length</dt >
254+ <dd >{ Number (stats .total_length ).toLocaleString ()} bp</dd >
255+ </>
256+ ) : null }
257+ { stats ?.ungapped_length ? (
258+ <>
259+ <dt >Ungapped length</dt >
260+ <dd >{ Number (stats .ungapped_length ).toLocaleString ()} bp</dd >
261+ </>
262+ ) : null }
263+ { stats ?.chromosome_count ? (
264+ <>
265+ <dt >Chromosomes</dt >
266+ <dd >{ stats .chromosome_count } </dd >
267+ </>
268+ ) : null }
269+ { stats ?.scaffold_count ? (
270+ <>
271+ <dt >Scaffolds</dt >
272+ <dd >{ stats .scaffold_count } </dd >
273+ </>
274+ ) : null }
275+ { stats ?.scaffold_n50 ? (
276+ <>
277+ <dt >Scaffold N50</dt >
278+ <dd >{ Number (stats .scaffold_n50 ).toLocaleString ()} </dd >
279+ </>
280+ ) : null }
281+ { stats ?.scaffold_l50 ? (
282+ <>
283+ <dt >Scaffold L50</dt >
284+ <dd >{ Number (stats .scaffold_l50 ).toLocaleString ()} </dd >
285+ </>
286+ ) : null }
287+ { stats ?.contig_count ? (
288+ <>
289+ <dt >Contigs</dt >
290+ <dd >{ stats .contig_count } </dd >
291+ </>
292+ ) : null }
293+ { stats ?.contig_n50 ? (
294+ <>
295+ <dt >Contig N50</dt >
296+ <dd >{ Number (stats .contig_n50 ).toLocaleString ()} </dd >
297+ </>
298+ ) : null }
299+ { stats ?.contig_l50 ? (
300+ <>
301+ <dt >Contig L50</dt >
302+ <dd >{ Number (stats .contig_l50 ).toLocaleString ()} </dd >
303+ </>
304+ ) : null }
305+ { gcPercent !== undefined ? (
306+ <>
307+ <dt >GC content</dt >
308+ <dd >{ gcPercent } %</dd >
309+ </>
310+ ) : null }
311+ { genomeCoverage ? (
312+ <>
313+ <dt >Coverage</dt >
314+ <dd >{ genomeCoverage } x</dd >
315+ </>
316+ ) : null }
317+ { sequencingTech ? (
318+ <>
319+ <dt >Sequencing</dt >
320+ <dd >{ sequencingTech } </dd >
321+ </>
322+ ) : null }
323+ </dl >
324+ </div >
325+ ) : null
326+ }
327+ {
328+ annotationInfo ? (
329+ <div >
330+ <h2 >Annotation</h2 >
331+ <dl class = { styles .statsTable } >
332+ { annotationInfo .name ? (
333+ <>
334+ <dt >Name</dt >
335+ <dd >
336+ { annotationInfo .name }
337+ { annotationInfo .provider
338+ ? ` (${annotationInfo .provider }) `
339+ : null }
340+ { annotationInfo .release_date
341+ ? ` , ${annotationInfo .release_date } `
342+ : null }
343+ </dd >
344+ </>
345+ ) : null }
346+ { annotationInfo .busco ?.complete !== undefined ? (
347+ <>
348+ <dt >BUSCO completeness</dt >
349+ <dd >
350+ { ` ${(annotationInfo .busco .complete * 100 ).toFixed (1 )}% complete ` }
351+ { buscoBreakdown .length ? ` (${buscoBreakdown .join (' , ' )}) ` : null }
352+ { annotationInfo .busco .busco_lineage
353+ ? ` — ${annotationInfo .busco .busco_lineage } `
354+ : null }
355+ </dd >
356+ </>
357+ ) : null }
268358 { annotationInfo .stats ?.gene_counts ? (
269- <div >
270- { annotationInfo .stats .gene_counts .total ?.toLocaleString ()} genes
271- —{ ' ' }
272- { annotationInfo .stats .gene_counts .protein_coding ?.toLocaleString ()} { ' ' }
273- protein-coding,{ ' ' }
274- { annotationInfo .stats .gene_counts .non_coding ?.toLocaleString ()} { ' ' }
275- non-coding,{ ' ' }
276- { annotationInfo .stats .gene_counts .pseudogene ?.toLocaleString ()} { ' ' }
277- pseudogenes
278- </div >
359+ <>
360+ <dt >Gene counts</dt >
361+ <dd >
362+ { annotationInfo .stats .gene_counts .total ?.toLocaleString ()} { ' ' }
363+ total —{ ' ' }
364+ { annotationInfo .stats .gene_counts .protein_coding ?.toLocaleString ()} { ' ' }
365+ protein-coding,{ ' ' }
366+ { annotationInfo .stats .gene_counts .non_coding ?.toLocaleString ()} { ' ' }
367+ non-coding,{ ' ' }
368+ { annotationInfo .stats .gene_counts .pseudogene ?.toLocaleString ()} { ' ' }
369+ pseudogenes
370+ </dd >
371+ </>
279372 ) : null }
280- </div >
281- ) : null
282- }
373+ </dl >
374+ </div >
375+ ) : null
376+ }
377+ <div >
283378 {
284379 comments ? (
285380 <div >
@@ -288,7 +383,6 @@ const statsParts = [
288383 </div >
289384 ) : null
290385 }
291-
292386 {
293387 imageUrl ? (
294388 <div class = { styles .imageContainer } >
0 commit comments