state.ts 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /**
  2. * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { PluginStateObject as PSO, PluginStateTransform } from '../../mol-plugin-state/objects';
  7. import { ParamDefinition as PD } from '../../mol-util/param-definition';
  8. import { Task } from '../../mol-task';
  9. import { CellPack as _CellPack, Cell, CellPacking } from './data';
  10. import { createStructureFromCellPack } from './model';
  11. import { IngredientFiles } from './util';
  12. import { Asset } from '../../mol-util/assets';
  13. import { PluginContext } from '../../mol-plugin/context';
  14. import { CellPackInfoProvider } from './property';
  15. import { Structure, StructureSymmetry, Unit } from '../../mol-model/structure';
  16. import { ModelSymmetry } from '../../mol-model-formats/structure/property/symmetry';
  17. export const DefaultCellPackBaseUrl = 'https://mesoscope.scripps.edu/data/cellPACK_data/cellPACK_database_1.1.0/';
  18. export class CellPack extends PSO.Create<_CellPack>({ name: 'CellPack', typeClass: 'Object' }) { }
  19. export { ParseCellPack };
  20. type ParseCellPack = typeof ParseCellPack
  21. const ParseCellPack = PluginStateTransform.BuiltIn({
  22. name: 'parse-cellpack',
  23. display: { name: 'Parse CellPack', description: 'Parse CellPack from JSON data' },
  24. from: PSO.Format.Json,
  25. to: CellPack
  26. })({
  27. apply({ a }) {
  28. return Task.create('Parse CellPack', async ctx => {
  29. const cell = a.data as Cell;
  30. const packings: CellPacking[] = [];
  31. const { compartments, cytoplasme } = cell;
  32. if (compartments) {
  33. for (const name in compartments) {
  34. const { surface, interior } = compartments[name];
  35. if (surface) packings.push({ name, location: 'surface', ingredients: surface.ingredients });
  36. if (interior) packings.push({ name, location: 'interior', ingredients: interior.ingredients });
  37. }
  38. }
  39. if (cytoplasme) packings.push({ name: 'Cytoplasme', location: 'cytoplasme', ingredients: cytoplasme.ingredients });
  40. return new CellPack({ cell, packings });
  41. });
  42. }
  43. });
  44. export { StructureFromCellpack };
  45. type StructureFromCellpack = typeof ParseCellPack
  46. const StructureFromCellpack = PluginStateTransform.BuiltIn({
  47. name: 'structure-from-cellpack',
  48. display: { name: 'Structure from CellPack', description: 'Create Structure from CellPack Packing' },
  49. from: CellPack,
  50. to: PSO.Molecule.Structure,
  51. params: a => {
  52. const options = a ? a.data.packings.map((d, i) => [i, d.name] as const) : [];
  53. return {
  54. packing: PD.Select(0, options),
  55. baseUrl: PD.Text(DefaultCellPackBaseUrl),
  56. ingredientFiles: PD.FileList({ accept: '.cif,.bcif,.pdb' })
  57. };
  58. }
  59. })({
  60. apply({ a, params, cache }, plugin: PluginContext) {
  61. return Task.create('Structure from CellPack', async ctx => {
  62. const packing = a.data.packings[params.packing];
  63. const ingredientFiles: IngredientFiles = {};
  64. if (params.ingredientFiles !== null) {
  65. for (const file of params.ingredientFiles) {
  66. ingredientFiles[file.name] = file;
  67. }
  68. }
  69. const { structure, assets, colors } = await createStructureFromCellPack(plugin, packing, params.baseUrl, ingredientFiles).runInContext(ctx);
  70. await CellPackInfoProvider.attach({ runtime: ctx, assetManager: plugin.managers.asset }, structure, {
  71. info: { packingsCount: a.data.packings.length, packingIndex: params.packing, colors }
  72. });
  73. (cache as any).assets = assets;
  74. return new PSO.Molecule.Structure(structure, { label: packing.name });
  75. });
  76. },
  77. dispose({ b, cache }) {
  78. const assets = (cache as any).assets as Asset.Wrapper[];
  79. if(assets) {
  80. for (const a of assets) a.dispose();
  81. }
  82. if (b) {
  83. b.data.customPropertyDescriptors.dispose();
  84. for (const m of b.data.models) {
  85. m.customProperties.dispose();
  86. }
  87. }
  88. }
  89. });
  90. export { GetAllAssamblyinOne };
  91. type GetAllAssamblyinOne = typeof GetAllAssamblyinOne
  92. const GetAllAssamblyinOne = PluginStateTransform.BuiltIn({
  93. name: 'get assambly from model',
  94. display: { name: 'get assambly from model' },
  95. isDecorator: true,
  96. from: PSO.Molecule.Model,
  97. to: PSO.Molecule.Structure,
  98. params: {
  99. }
  100. })({
  101. canAutoUpdate({ newParams }) {
  102. return true;
  103. },
  104. apply({ a, params }) {
  105. return Task.create('Build Structure', async ctx => {
  106. // TODO: optimze
  107. // TODO: think of ways how to fast-track changes to this for animations
  108. const model = a.data;
  109. let initial_structure = Structure.ofModel(model);
  110. const structures: Structure[] = [];
  111. let structure: Structure = initial_structure;
  112. // the list of asambly *?
  113. const symmetry = ModelSymmetry.Provider.get(model);
  114. if (symmetry){
  115. if (symmetry.assemblies.length !== 0) {
  116. for (const a of symmetry.assemblies) {
  117. const s = await StructureSymmetry.buildAssembly(initial_structure, a.id).runInContext(ctx);
  118. structures.push(s);
  119. }
  120. const builder = Structure.Builder({ label: name });
  121. let offsetInvariantId = 0;
  122. for (const s of structures) {
  123. let maxInvariantId = 0;
  124. for (const u of s.units) {
  125. const invariantId = u.invariantId + offsetInvariantId;
  126. if (u.invariantId > maxInvariantId) maxInvariantId = u.invariantId;
  127. builder.addUnit(u.kind, u.model, u.conformation.operator, u.elements, Unit.Trait.None, invariantId);
  128. }
  129. offsetInvariantId += maxInvariantId + 1;
  130. }
  131. structure = builder.getStructure();
  132. for( let i = 0, il = structure.models.length; i < il; ++i) {
  133. const { trajectoryInfo } = structure.models[i];
  134. trajectoryInfo.size = il;
  135. trajectoryInfo.index = i;
  136. }
  137. }
  138. }
  139. return new PSO.Molecule.Structure(structure, { label: a.label, description: `${a.description}` });
  140. });
  141. },
  142. dispose({ b }) {
  143. b?.data.customPropertyDescriptors.dispose();
  144. }
  145. });
  146. export { GetAllAssamblyinOneStructure };
  147. type GetAllAssamblyinOneStructure = typeof GetAllAssamblyinOneStructure
  148. const GetAllAssamblyinOneStructure = PluginStateTransform.BuiltIn({
  149. name: 'get assambly from structure',
  150. display: { name: 'get assambly from structure' },
  151. isDecorator: true,
  152. from: PSO.Molecule.Structure,
  153. to: PSO.Molecule.Structure,
  154. params(a) {
  155. return { };
  156. }
  157. })({
  158. apply({ a, params }) {
  159. return Task.create('Build Structure Assemblies', async ctx => {
  160. // TODO: optimze
  161. // TODO: think of ways how to fast-track changes to this for animations
  162. const initial_structure = a.data;
  163. const structures: Structure[] = [];
  164. let structure: Structure = initial_structure;
  165. // the list of asambly *?
  166. const symmetry = ModelSymmetry.Provider.get(initial_structure.model);
  167. if (symmetry){
  168. if (symmetry.assemblies.length !== 0) {
  169. for (const a of symmetry.assemblies) {
  170. const s = await StructureSymmetry.buildAssembly(initial_structure, a.id!).runInContext(ctx);
  171. structures.push(s);
  172. }
  173. const builder = Structure.Builder({ label: name });
  174. let offsetInvariantId = 0;
  175. for (const s of structures) {
  176. let maxInvariantId = 0;
  177. for (const u of s.units) {
  178. const invariantId = u.invariantId + offsetInvariantId;
  179. if (u.invariantId > maxInvariantId) maxInvariantId = u.invariantId;
  180. builder.addUnit(u.kind, u.model, u.conformation.operator, u.elements, Unit.Trait.None, invariantId);
  181. }
  182. offsetInvariantId += maxInvariantId + 1;
  183. }
  184. structure = builder.getStructure();
  185. for( let i = 0, il = structure.models.length; i < il; ++i) {
  186. const { trajectoryInfo } = structure.models[i];
  187. trajectoryInfo.size = il;
  188. trajectoryInfo.index = i;
  189. }
  190. }
  191. }
  192. return new PSO.Molecule.Structure(structure, { label: a.label, description: `${a.description}` });
  193. });
  194. }
  195. });