Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
32 changes: 32 additions & 0 deletions client/plots/matrix/matrix.groups.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { sample_match_termvaluesetting } from '#shared/filter.js'
import { getSampleSorter, getTermSorter, getSampleGroupSorter, getMclassSorter } from './matrix.sort'
import { dtsnvindel, dtcnv, dtfusionrna, dtgeneexpression, dtsv } from '#shared/common.js'
import { ROOT_SAMPLE_TYPE } from '#shared/terms.js'

export function getTermOrder(data) {
const s = this.settings.matrix
Expand Down Expand Up @@ -136,6 +137,37 @@ export function getSampleGroups(data) {
sampleGroups.set(key, grp)
}
sampleGroups.get(key).lst.push(row)
} else if (this.state.termdbConfig.hasSampleAncestry) {
// has sample ancestry
// group samples by sample type (hardcoded to be root sample type)
let key, name
if (!row._ref_) continue
if (row._ref_.sampleType === ROOT_SAMPLE_TYPE) {
// sample is root sample
key = row.sample
name = row.label
} else {
// sample is not root sample
// check its ancestors
if (!row._ref_.ancestors?.length) continue
const ancestors = row._ref_.ancestors.filter(a => a.sample_type === ROOT_SAMPLE_TYPE)
if (!ancestors.length) continue
if (ancestors.length > 1) throw new Error('multiple root samples present')
const ancestor = ancestors[0]
key = ancestor.ancestor_id
name = ancestor.ancestor_name
}
if (!key) continue
if (!sampleGroups.has(key)) {
const grp = {
name,
id: key,
lst: [],
legendGroups: {}
}
sampleGroups.set(key, grp)
}
sampleGroups.get(key).lst.push(row)
} else {
defaultSampleGrp.lst.push(row)
}
Expand Down
44 changes: 42 additions & 2 deletions server/src/termdb.server.init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,19 @@ export function server_init_db_queries(ds) {
}
if (tables.has('sampleidmap')) {
const i2s = new Map(),
s2i = new Map()
s2i = new Map(),
i2type = new Map()
const rows = cn.prepare('SELECT * FROM sampleidmap').all()
let totalCount = 0
for (const { id, name } of rows) {
for (const { id, name, sample_type } of rows) {
i2s.set(id, name)
s2i.set(name, id)
i2type.set(id, sample_type)
totalCount++ //for dbs without cohorts or types
}
q.id2sampleName = id => i2s.get(id)
q.sampleName2id = s => s2i.get(s)
q.id2sampleType = id => i2type.get(id)
if (tables.has('cohort_sample_types')) {
const rows = cn.prepare('SELECT * from cohort_sample_types').all()
q.getCohortSampleCount = cohortKey => {
Expand Down Expand Up @@ -569,6 +572,43 @@ export function server_init_db_queries(ds) {
const rows = sql.all()
return rows
}

if (ds.cohort.termdb.hasSampleAncestry) {
// ds has sample ancestry
// store sample ancestry in sample refs
const i2ancestors = new Map()
{
const rows = cn.prepare('SELECT * FROM sample_ancestry').all()
for (const row of rows) {
const id = row.sample_id
if (!i2ancestors.has(id)) i2ancestors.set(id, [])
const ancestors = i2ancestors.get(id)
const ancestor = {
ancestor_id: row.ancestor_id,
ancestor_name: q.id2sampleName(row.ancestor_id),
sample_type: q.id2sampleType(row.ancestor_id),
distance: row.distance
}
ancestors.push(ancestor)
}
}

const i2refs = new Map()
{
const rows = cn.prepare('SELECT * FROM sampleidmap').all()
for (const row of rows) {
const id = row.id
const name = row.name
const refs: any = { label: name, sample: id, sampleType: q.id2sampleType(id) }
const ancestors = i2ancestors.get(row.id)
if (ancestors) refs.ancestors = ancestors
Object.freeze(refs)
i2refs.set(id, refs)
}
}

q.id2sampleRefs = id => structuredClone(i2refs.get(id)) // returns sample refs to be used in bySampleId{} object, returning clone as some code (e.g. server/src/termdb.get_matrix.js) needs to modify the sample refs object
}
}

// ds computes term visibility in dictionary based on client auth; returns list of visible terms
Expand Down
Loading