preferred-assembly.ts 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. */
  6. import { Column, Table } from '../../mol-data/db';
  7. import { toTable } from '../../mol-io/reader/cif/schema';
  8. import { CifWriter } from '../../mol-io/writer/cif';
  9. import { Model } from '../../mol-model/structure';
  10. import { ModelSymmetry } from '../../mol-model-formats/structure/property/symmetry';
  11. import { MmcifFormat } from '../../mol-model-formats/structure/mmcif';
  12. import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
  13. export namespace PDBePreferredAssembly {
  14. export type Property = string
  15. export function getFirstFromModel(model: Model): Property {
  16. const symmetry = ModelSymmetry.Provider.get(model);
  17. return symmetry?.assemblies.length ? symmetry.assemblies[0].id : '';
  18. }
  19. export function get(model: Model): Property {
  20. return model._staticPropertyData.__PDBePreferredAssebly__ || getFirstFromModel(model);
  21. }
  22. function set(model: Model, prop: Property) {
  23. (model._staticPropertyData.__PDBePreferredAssebly__ as Property) = prop;
  24. }
  25. export const Schema = {
  26. pdbe_preferred_assembly: {
  27. assembly_id: Column.Schema.str
  28. }
  29. };
  30. export type Schema = typeof Schema
  31. export const Descriptor = CustomPropertyDescriptor({
  32. name: 'pdbe_preferred_assembly',
  33. cifExport: {
  34. prefix: 'pdbe',
  35. context(ctx): Property { return get(ctx.firstModel); },
  36. categories: [{
  37. name: 'pdbe_preferred_assembly',
  38. instance(ctx: Property) {
  39. return CifWriter.Category.ofTable(Table.ofArrays(Schema.pdbe_preferred_assembly, { assembly_id: [ctx] }));
  40. }
  41. }]
  42. }
  43. });
  44. function fromCifData(model: Model): string | undefined {
  45. if (!MmcifFormat.is(model.sourceData)) return void 0;
  46. const cat = model.sourceData.data.frame.categories.pdbe_preferred_assembly;
  47. if (!cat) return void 0;
  48. return toTable(Schema.pdbe_preferred_assembly, cat).assembly_id.value(0) || getFirstFromModel(model);
  49. }
  50. export async function attachFromCifOrApi(model: Model, params: {
  51. // optional JSON source
  52. PDBe_apiSourceJson?: (model: Model) => Promise<any>
  53. }) {
  54. if (model.customProperties.has(Descriptor)) return true;
  55. let asmName: string | undefined = fromCifData(model);
  56. if (asmName === void 0 && params.PDBe_apiSourceJson) {
  57. const data = await params.PDBe_apiSourceJson(model);
  58. if (!data) return false;
  59. asmName = asmNameFromJson(model, data);
  60. } else {
  61. return false;
  62. }
  63. if (!asmName) return false;
  64. model.customProperties.add(Descriptor);
  65. set(model, asmName);
  66. return true;
  67. }
  68. }
  69. function asmNameFromJson(modelData: Model, data: any): string {
  70. const assemblies = data[0] && data[0].assemblies;
  71. if (!assemblies || !assemblies.length) return PDBePreferredAssembly.getFirstFromModel(modelData);
  72. for (const asm of assemblies) {
  73. if (asm.preferred) {
  74. return asm.assembly_id;
  75. }
  76. }
  77. return assemblies[0].assembly_id;
  78. }