@@ -4,6 +4,7 @@ import { sayerror } from '#dom'
44import { dofetch3 } from '#common/dofetch'
55import { first_genetrack_tolist } from '#common/1stGenetk'
66import type { DmrConfig , DmrDom , DmrResult , BedItem } from './DmrTypes.ts'
7+ import { getDefaultDMRSettings } from './settings/defaults.ts'
78
89class DmrPlot extends PlotBase implements RxComponent {
910 static type = 'dmr'
@@ -14,7 +15,7 @@ class DmrPlot extends PlotBase implements RxComponent {
1415 constructor ( opts : any , api : any ) {
1516 super ( opts , api )
1617 this . dom = {
17- header : opts . header ,
18+ header : opts ? .header ,
1819 holder : opts . holder . append ( 'div' ) ,
1920 error : opts . holder . append ( 'div' ) ,
2021 loading : opts . holder . append ( 'div' ) . text ( 'Running DMR analysis…' )
@@ -33,16 +34,34 @@ class DmrPlot extends PlotBase implements RxComponent {
3334 const config = this . state . config as DmrConfig
3435 if ( this . dom . header ) this . dom . header . text ( config . headerText || 'DMR Analysis' )
3536
37+ validateConfig ( config )
38+
3639 this . dom . holder . selectAll ( '*' ) . remove ( )
3740 this . dom . error . selectAll ( '*' ) . remove ( )
3841 this . dom . loading . style ( 'display' , 'block' )
3942
4043 try {
41- const { genome, dslabel, chr, start, stop, group1, group2 } = config
44+ const { genome, dslabel, geneName, group1, group2, settings } = config
45+
46+ // Resolve gene name to genomic coordinates
47+ const geneResult = await dofetch3 ( 'genelookup' , {
48+ body : { deep : 1 , input : geneName , genome }
49+ } )
50+ if ( geneResult . error || ! geneResult . gmlst ?. length ) {
51+ throw new Error ( `Could not find coordinates for gene "${ geneName } "` )
52+ }
53+ const gm = geneResult . gmlst [ 0 ]
54+ const chr = gm . chr
55+ const start = Math . max ( 0 , gm . start - settings . dmr . pad )
56+ const stop = gm . stop + settings . dmr . pad
57+
4258 const dmrResult : DmrResult = await dofetch3 ( 'termdb/dmr' , {
4359 body : { genome, dslabel, chr, start, stop, group1, group2 }
4460 } )
45- if ( dmrResult . error ) throw new Error ( dmrResult . error )
61+ if ( ! dmrResult || dmrResult . error ) {
62+ sayerror ( this . dom . error , dmrResult ?. error || 'No result returned from server' )
63+ throw new Error ( dmrResult ?. error || 'No result returned from server' )
64+ }
4665
4766 const genomeObj = this . app . opts . genome
4867 const tklst : { type : string ; name : string ; bedItems ?: BedItem [ ] ; __isgene ?: boolean } [ ] = [ ]
@@ -68,7 +87,7 @@ class DmrPlot extends PlotBase implements RxComponent {
6887 stop,
6988 tklst,
7089 nobox : true ,
71- width : 800 ,
90+ width : settings . dmr . blockWidth ,
7291 hidegenelegend : true
7392 } )
7493 } catch ( e : unknown ) {
@@ -82,5 +101,22 @@ class DmrPlot extends PlotBase implements RxComponent {
82101export const componentInit = getCompInit ( DmrPlot )
83102
84103export function getPlotConfig ( opts : Partial < DmrConfig > ) : DmrConfig {
85- return copyMerge ( { chartType : 'dmr' , headerText : 'DMR Analysis' } , opts )
104+ validateConfig ( opts )
105+
106+ const config = {
107+ settings : {
108+ dmr : getDefaultDMRSettings ( opts )
109+ }
110+ }
111+ return copyMerge ( config , opts )
112+ }
113+
114+ /** Runs in both getPlotConfig and main() because will only run in main()
115+ * when plot is loaded from a saved state (e.g. mass session file).*/
116+ function validateConfig ( opts ) {
117+ if ( ! opts . genome ) throw new Error ( 'genome is required for DMR plot' )
118+ if ( ! opts . dslabel ) throw new Error ( 'dslabel is required for DMR plot' )
119+ if ( ! opts . geneName ) throw new Error ( 'geneName is required for DMR plot' )
120+ if ( ! opts . group1 ) throw new Error ( 'group1 is required for DMR plot' )
121+ if ( ! opts . group2 ) throw new Error ( 'group2 is required for DMR plot' )
86122}
0 commit comments