diff --git a/src/apps/viewer/extensions/cellpack/model.ts b/src/apps/viewer/extensions/cellpack/model.ts index 179e3c8fec205ba19a2047ec0e0bc35cbc636396..4383c786faf2ed9ad9dc8e877454527643f9386d 100644 --- a/src/apps/viewer/extensions/cellpack/model.ts +++ b/src/apps/viewer/extensions/cellpack/model.ts @@ -8,7 +8,7 @@ import { StateAction } from '../../../../mol-state'; import { PluginContext } from '../../../../mol-plugin/context'; import { PluginStateObject as PSO } from '../../../../mol-plugin/state/objects'; import { ParamDefinition as PD } from '../../../../mol-util/param-definition'; -import { Ingredient, Packing } from './data'; +import { Ingredient, CellPacking } from './data'; import { getFromPdb, getFromCellPackDB } from './util'; import { Model, Structure, StructureSymmetry, StructureSelection, Queries, QueryContext } from '../../../../mol-model/structure'; import { trajectoryFromMmCIF } from '../../../../mol-model-formats/structure/mmcif'; @@ -106,8 +106,9 @@ async function getIngredientStructure(ingredient: Ingredient, baseUrl: string) { return assembly } -export function createStructureFromCellPack(ingredients: Packing['ingredients'], baseUrl: string) { +export function createStructureFromCellPack(packing: CellPacking, baseUrl: string) { return Task.create('Create Packing Structure', async ctx => { + const { ingredients, name } = packing const structures: Structure[] = [] for (const iName in ingredients) { if (ctx.shouldUpdate) ctx.update(iName) @@ -115,7 +116,7 @@ export function createStructureFromCellPack(ingredients: Packing['ingredients'], if (s) structures.push(s) } - const builder = Structure.Builder() + const builder = Structure.Builder({ label: name }) let offsetInvariantId = 0 for (const s of structures) { let maxInvariantId = 0 diff --git a/src/apps/viewer/extensions/cellpack/state.ts b/src/apps/viewer/extensions/cellpack/state.ts index b8b6ce3470d93741ecdaae2bbeb308e43f10d2d6..79a992a960ca4e4967e65034aec2de419801c241 100644 --- a/src/apps/viewer/extensions/cellpack/state.ts +++ b/src/apps/viewer/extensions/cellpack/state.ts @@ -64,9 +64,9 @@ const StructureFromCellpack = PluginStateTransform.BuiltIn({ })({ apply({ a, params }) { return Task.create('Structure from CellPack', async ctx => { - const { ingredients, name } = a.data.packings[params.packing] - const structure = await createStructureFromCellPack(ingredients, params.baseUrl).runInContext(ctx) - return new PSO.Molecule.Structure(structure, { label: name }) + const packing = a.data.packings[params.packing] + const structure = await createStructureFromCellPack(packing, params.baseUrl).runInContext(ctx) + return new PSO.Molecule.Structure(structure, { label: packing.name }) }); } }); diff --git a/src/mol-model-formats/structure/mmcif/parser.ts b/src/mol-model-formats/structure/mmcif/parser.ts index 4ac7d77b791e3489d15071892928b3486e3767b4..b9446b4bc3a648d950deecabbcec6dab7103a251 100644 --- a/src/mol-model-formats/structure/mmcif/parser.ts +++ b/src/mol-model-formats/structure/mmcif/parser.ts @@ -207,14 +207,18 @@ function createStandardModel(format: mmCIF_Format, atom_site: AtomSite, sourceIn } const coarse = EmptyIHMCoarse; - const label = format.data.entry.id.valueKind(0) === Column.ValueKind.Present + const entry = format.data.entry.id.valueKind(0) === Column.ValueKind.Present ? format.data.entry.id.value(0) : format.data._name; + const label: string[] = [] + if (entry) label.push(entry) + if (format.data.struct.title.valueKind(0) === Column.ValueKind.Present) label.push(format.data.struct.title.value(0)) + return { id: UUID.create22(), - label, - entry: label, + label: label.join(' | '), + entry, sourceData: format, modelNum, entities, @@ -240,11 +244,16 @@ function createModelIHM(format: mmCIF_Format, data: IHMData, formatData: FormatD const entry = format.data.entry.id.valueKind(0) === Column.ValueKind.Present ? format.data.entry.id.value(0) : format.data._name; - const label = data.model_group_name ? `${data.model_name}: ${data.model_group_name}` : data.model_name + + const label: string[] = [] + if (entry) label.push(entry) + if (format.data.struct.title.valueKind(0) === Column.ValueKind.Present) label.push(format.data.struct.title.value(0)) + if (data.model_group_name) label.push(data.model_name) + if (data.model_group_name) label.push(data.model_group_name) return { id: UUID.create22(), - label, + label: label.join(' | '), entry, sourceData: format, modelNum: data.model_id, diff --git a/src/mol-model/structure/structure/structure.ts b/src/mol-model/structure/structure/structure.ts index 708eee3f3c2486c91dca749130c4438b5cb1aa48..08bc5c107c58568d9053260b751fce0817ec47c9 100644 --- a/src/mol-model/structure/structure/structure.ts +++ b/src/mol-model/structure/structure/structure.ts @@ -55,6 +55,7 @@ class Structure { elementCount: number, polymerResidueCount: number, coordinateSystem: SymmetryOperator, + label: string, propertyData?: any, customProps?: CustomProperties } = { @@ -62,7 +63,8 @@ class Structure { transformHash: -1, elementCount: 0, polymerResidueCount: 0, - coordinateSystem: SymmetryOperator.Default + coordinateSystem: SymmetryOperator.Default, + label: '' }; subsetBuilder(isSorted: boolean) { @@ -153,6 +155,10 @@ class Structure { return this._props.coordinateSystem; } + get label() { + return this._props.label; + } + get boundary() { return this.lookup3d.boundary; } @@ -268,6 +274,9 @@ class Structure { if (props.coordinateSystem) this._props.coordinateSystem = props.coordinateSystem; else if (props.parent) this._props.coordinateSystem = props.parent.coordinateSystem; + if (props.label) this._props.label = props.label; + else if (props.parent) this._props.label = props.parent.label; + if (props.masterModel) this._props.masterModel = props.masterModel; else if (props.parent) this._props.masterModel = props.parent.masterModel; @@ -368,6 +377,7 @@ namespace Structure { export interface Props { parent?: Structure coordinateSystem?: SymmetryOperator + label?: string /** Master model for structures of a protein model and multiple ligand models */ masterModel?: Model /** Representative model for structures of a model trajectory */ @@ -420,7 +430,7 @@ namespace Structure { count = units.length } - return create(units, { representativeModel: trajectory[0] }); + return create(units, { representativeModel: trajectory[0], label: trajectory[0].label }); } /** @@ -431,7 +441,7 @@ namespace Structure { */ export function ofModel(model: Model): Structure { const chains = model.atomicHierarchy.chainAtomSegments; - const builder = new StructureBuilder(); + const builder = new StructureBuilder({ label: model.label }); for (let c = 0 as ChainIndex; c < chains.count; c++) { const start = chains.offsets[c]; diff --git a/src/mol-model/structure/structure/symmetry.ts b/src/mol-model/structure/structure/symmetry.ts index 4ae63f47d445fde4356a68d8e4b5f7c395d51097..b472051b1e9cd5473d486353441768dfa06cc34e 100644 --- a/src/mol-model/structure/structure/symmetry.ts +++ b/src/mol-model/structure/structure/symmetry.ts @@ -25,7 +25,7 @@ namespace StructureSymmetry { if (!assembly) throw new Error(`Assembly '${asmName}' is not defined.`); const coordinateSystem = SymmetryOperator.create(assembly.id, Mat4.identity(), { id: assembly.id, operList: [] }) - const assembler = Structure.Builder({ coordinateSystem }); + const assembler = Structure.Builder({ coordinateSystem, label: structure.label }); const queryCtx = new QueryContext(structure); @@ -138,7 +138,7 @@ function getOperatorsCached333(symmetry: ModelSymmetry) { } function assembleOperators(structure: Structure, operators: ReadonlyArray<SymmetryOperator>) { - const assembler = Structure.Builder(); + const assembler = Structure.Builder({ label: structure.label }); const { units } = structure; for (const oper of operators) { for (const unit of units) { diff --git a/src/mol-plugin/state/transforms/model.ts b/src/mol-plugin/state/transforms/model.ts index f78a0e94a39c5dd89ca824c87e2a170769168b79..5b3192e61aba717b8a0858b0df4a01d90096d009 100644 --- a/src/mol-plugin/state/transforms/model.ts +++ b/src/mol-plugin/state/transforms/model.ts @@ -96,7 +96,7 @@ const TrajectoryFromMmCif = PluginStateTransform.BuiltIn({ if (!block) throw new Error(`Data block '${[header]}' not found.`); const models = await trajectoryFromMmCIF(block).runInContext(ctx); if (models.length === 0) throw new Error('No models found.'); - const props = { label: models[0].label, description: `${models.length} model${models.length === 1 ? '' : 's'}` }; + const props = { label: `${models[0].entry}`, description: `${models.length} model${models.length === 1 ? '' : 's'}` }; return new SO.Molecule.Trajectory(models, props); }); } @@ -114,7 +114,7 @@ const TrajectoryFromPDB = PluginStateTransform.BuiltIn({ const parsed = await parsePDB(a.data, a.label).runInContext(ctx); if (parsed.isError) throw new Error(parsed.message); const models = await trajectoryFromPDB(parsed.result).runInContext(ctx); - const props = { label: models[0].label, description: `${models.length} model${models.length === 1 ? '' : 's'}` }; + const props = { label: `${models[0].entry}`, description: `${models.length} model${models.length === 1 ? '' : 's'}` }; return new SO.Molecule.Trajectory(models, props); }); } @@ -132,7 +132,7 @@ const TrajectoryFromGRO = PluginStateTransform.BuiltIn({ const parsed = await parseGRO(a.data).runInContext(ctx); if (parsed.isError) throw new Error(parsed.message); const models = await trajectoryFromGRO(parsed.result).runInContext(ctx); - const props = { label: models[0].label, description: `${models.length} model${models.length === 1 ? '' : 's'}` }; + const props = { label: `${models[0].entry}`, description: `${models.length} model${models.length === 1 ? '' : 's'}` }; return new SO.Molecule.Trajectory(models, props); }); } @@ -156,7 +156,7 @@ const ModelFromTrajectory = PluginStateTransform.BuiltIn({ apply({ a, params }) { if (params.modelIndex < 0 || params.modelIndex >= a.data.length) throw new Error(`Invalid modelIndex ${params.modelIndex}`); const model = a.data[params.modelIndex]; - const label = a.data.length === 1 ? model.entry : `${model.entry}: ${model.modelNum}` + const label = `Model ${model.modelNum}` const description = a.data.length === 1 ? undefined : `Model ${params.modelIndex + 1} of ${a.data.length}` return new SO.Molecule.Model(model, { label, description }); } @@ -172,7 +172,7 @@ const StructureFromTrajectory = PluginStateTransform.BuiltIn({ apply({ a }) { return Task.create('Build Structure', async ctx => { const s = Structure.ofTrajectory(a.data); - const props = { label: a.data[0].label, description: s.elementCount === 1 ? '1 element' : `${s.elementCount} elements` }; + const props = { label: s.label, description: s.elementCount === 1 ? '1 element' : `${s.elementCount} elements` }; return new SO.Molecule.Structure(s, props); }) }