entities.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /**
  2. * Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  6. */
  7. import { Column, Table } from '../../../mol-data/db';
  8. import { Entities, EntitySubtype } from '../../../mol-model/structure/model/properties/common';
  9. import { getEntityType, getEntitySubtype } from '../../../mol-model/structure/model/types';
  10. import { ElementIndex, EntityIndex, Model } from '../../../mol-model/structure/model';
  11. import { BasicData, BasicSchema, Entity } from './schema';
  12. export function getEntityData(data: BasicData): Entities {
  13. let entityData: Entity;
  14. if (!data.entity.id.isDefined) {
  15. const entityIds = new Set<string>();
  16. const ids: ReturnType<Entity['id']['value']>[] = [];
  17. const types: ReturnType<Entity['type']['value']>[] = [];
  18. const { label_entity_id, label_comp_id } = data.atom_site;
  19. for (let i = 0 as ElementIndex, il = data.atom_site._rowCount; i < il; i++) {
  20. const entityId = label_entity_id.value(i);
  21. if (!entityIds.has(entityId)) {
  22. ids.push(entityId);
  23. types.push(getEntityType(label_comp_id.value(i)));
  24. entityIds.add(entityId);
  25. }
  26. }
  27. const { entity_id: sphere_entity_id } = data.ihm_sphere_obj_site;
  28. for (let i = 0 as ElementIndex, il = data.ihm_sphere_obj_site._rowCount; i < il; i++) {
  29. const entityId = sphere_entity_id.value(i);
  30. if (!entityIds.has(entityId)) {
  31. ids.push(entityId);
  32. types.push('polymer');
  33. entityIds.add(entityId);
  34. }
  35. }
  36. const { entity_id: gaussian_entity_id } = data.ihm_gaussian_obj_site;
  37. for (let i = 0 as ElementIndex, il = data.ihm_gaussian_obj_site._rowCount; i < il; i++) {
  38. const entityId = gaussian_entity_id.value(i);
  39. if (!entityIds.has(entityId)) {
  40. ids.push(entityId);
  41. types.push('polymer');
  42. entityIds.add(entityId);
  43. }
  44. }
  45. entityData = Table.ofPartialColumns(BasicSchema.entity, {
  46. id: Column.ofArray({ array: ids, schema: BasicSchema.entity.id }),
  47. type: Column.ofArray({ array: types, schema: BasicSchema.entity.type }),
  48. }, ids.length);
  49. } else {
  50. entityData = data.entity;
  51. }
  52. const getEntityIndex = Column.createIndexer<string, EntityIndex>(entityData.id);
  53. //
  54. const subtypes: EntitySubtype[] = new Array(entityData._rowCount);
  55. subtypes.fill('other');
  56. const entityIds = new Set<string>();
  57. let assignSubtype = false;
  58. if (data.entity_poly && data.entity_poly.type.isDefined) {
  59. const { entity_id, type, _rowCount } = data.entity_poly;
  60. for (let i = 0; i < _rowCount; ++i) {
  61. const entityId = entity_id.value(i);
  62. subtypes[getEntityIndex(entityId)] = type.value(i);
  63. entityIds.add(entityId);
  64. }
  65. } else {
  66. assignSubtype = true;
  67. }
  68. if (data.pdbx_entity_branch && data.pdbx_entity_branch.entity_id.isDefined) {
  69. const { entity_id, type, _rowCount } = data.pdbx_entity_branch;
  70. for (let i = 0; i < _rowCount; ++i) {
  71. const entityId = entity_id.value(i);
  72. subtypes[getEntityIndex(entityId)] = type.value(i);
  73. entityIds.add(entityId);
  74. }
  75. } else {
  76. assignSubtype = true;
  77. }
  78. if (entityIds.size < subtypes.length) {
  79. // still unassigned subtypes, need to derive from component id/type
  80. assignSubtype = true;
  81. }
  82. if (assignSubtype) {
  83. const chemCompType = new Map<string, string>();
  84. if (data.chem_comp) {
  85. const { id, type } = data.chem_comp;
  86. for (let i = 0, il = data.chem_comp._rowCount; i < il; i++) {
  87. chemCompType.set(id.value(i), type.value(i));
  88. }
  89. }
  90. if (data.atom_site) {
  91. const { label_entity_id, label_comp_id } = data.atom_site;
  92. for (let i = 0 as ElementIndex, il = data.atom_site._rowCount; i < il; i++) {
  93. const entityId = label_entity_id.value(i);
  94. if (!entityIds.has(entityId)) {
  95. const compId = label_comp_id.value(i);
  96. const compType = chemCompType.get(compId) || '';
  97. subtypes[getEntityIndex(entityId)] = getEntitySubtype(compId, compType);
  98. entityIds.add(entityId);
  99. }
  100. }
  101. }
  102. // TODO how to handle coarse?
  103. }
  104. const subtypeColumn = Column.ofArray({ array: subtypes, schema: EntitySubtype });
  105. return {
  106. data: entityData,
  107. subtype: subtypeColumn,
  108. getEntityIndex
  109. };
  110. }
  111. export function getEntitiesWithPRD(data: BasicData, entities: Entities, structAsymMap: Model['properties']['structAsymMap']): Entities {
  112. if (!data.pdbx_molecule || !data.pdbx_molecule.prd_id.isDefined) {
  113. return entities;
  114. }
  115. const prdIds: string[] = new Array(entities.data._rowCount);
  116. prdIds.fill('');
  117. const { asym_id, prd_id, _rowCount } = data.pdbx_molecule;
  118. for (let i = 0; i < _rowCount; ++i) {
  119. const asymId = asym_id.value(i);
  120. const entityId = structAsymMap.get(asymId)?.entity_id;
  121. if (entityId !== undefined) {
  122. prdIds[entities.getEntityIndex(entityId)] = prd_id.value(i);
  123. }
  124. }
  125. const prdIdColumn = Column.ofArray({ array: prdIds, schema: Column.Schema.str });
  126. return {
  127. ...entities,
  128. prd_id: prdIdColumn
  129. };
  130. }