Переглянути джерело

Issue #805: tmdet extension moved into rcsb-saguaro-3d

cycle20 1 рік тому
батько
коміт
b1a3221ee5

+ 0 - 417
src/tmdet-extension/LICENSE

@@ -1,417 +0,0 @@
-Copyright (C) 2022, Protein Bioinformatics Research Group, RCNS
-
-Authors:
-
-* Gabor Tusnady (tusnady.gabor at ttk.hu)
-* Csongor Gerdan (gerdan.csongor at ttk.hu)
-
-=======================================================================
-
-Attribution-NonCommercial 4.0 International
-
-=======================================================================
-
-Creative Commons Corporation ("Creative Commons") is not a law firm and
-does not provide legal services or legal advice. Distribution of
-Creative Commons public licenses does not create a lawyer-client or
-other relationship. Creative Commons makes its licenses and related
-information available on an "as-is" basis. Creative Commons gives no
-warranties regarding its licenses, any material licensed under their
-terms and conditions, or any related information. Creative Commons
-disclaims all liability for damages resulting from their use to the
-fullest extent possible.
-
-Using Creative Commons Public Licenses
-
-Creative Commons public licenses provide a standard set of terms and
-conditions that creators and other rights holders may use to share
-original works of authorship and other material subject to copyright
-and certain other rights specified in the public license below. The
-following considerations are for informational purposes only, are not
-exhaustive, and do not form part of our licenses.
-
-     Considerations for licensors: Our public licenses are
-     intended for use by those authorized to give the public
-     permission to use material in ways otherwise restricted by
-     copyright and certain other rights. Our licenses are
-     irrevocable. Licensors should read and understand the terms
-     and conditions of the license they choose before applying it.
-     Licensors should also secure all rights necessary before
-     applying our licenses so that the public can reuse the
-     material as expected. Licensors should clearly mark any
-     material not subject to the license. This includes other CC-
-     licensed material, or material used under an exception or
-     limitation to copyright. More considerations for licensors:
-    wiki.creativecommons.org/Considerations_for_licensors
-
-     Considerations for the public: By using one of our public
-     licenses, a licensor grants the public permission to use the
-     licensed material under specified terms and conditions. If
-     the licensor's permission is not necessary for any reason--for
-     example, because of any applicable exception or limitation to
-     copyright--then that use is not regulated by the license. Our
-     licenses grant only permissions under copyright and certain
-     other rights that a licensor has authority to grant. Use of
-     the licensed material may still be restricted for other
-     reasons, including because others have copyright or other
-     rights in the material. A licensor may make special requests,
-     such as asking that all changes be marked or described.
-     Although not required by our licenses, you are encouraged to
-     respect those requests where reasonable. More considerations
-     for the public:
-    wiki.creativecommons.org/Considerations_for_licensees
-
-=======================================================================
-
-Creative Commons Attribution-NonCommercial 4.0 International Public
-License
-
-By exercising the Licensed Rights (defined below), You accept and agree
-to be bound by the terms and conditions of this Creative Commons
-Attribution-NonCommercial 4.0 International Public License ("Public
-License"). To the extent this Public License may be interpreted as a
-contract, You are granted the Licensed Rights in consideration of Your
-acceptance of these terms and conditions, and the Licensor grants You
-such rights in consideration of benefits the Licensor receives from
-making the Licensed Material available under these terms and
-conditions.
-
-
-Section 1 -- Definitions.
-
-  a. Adapted Material means material subject to Copyright and Similar
-     Rights that is derived from or based upon the Licensed Material
-     and in which the Licensed Material is translated, altered,
-     arranged, transformed, or otherwise modified in a manner requiring
-     permission under the Copyright and Similar Rights held by the
-     Licensor. For purposes of this Public License, where the Licensed
-     Material is a musical work, performance, or sound recording,
-     Adapted Material is always produced where the Licensed Material is
-     synched in timed relation with a moving image.
-
-  b. Adapter's License means the license You apply to Your Copyright
-     and Similar Rights in Your contributions to Adapted Material in
-     accordance with the terms and conditions of this Public License.
-
-  c. Copyright and Similar Rights means copyright and/or similar rights
-     closely related to copyright including, without limitation,
-     performance, broadcast, sound recording, and Sui Generis Database
-     Rights, without regard to how the rights are labeled or
-     categorized. For purposes of this Public License, the rights
-     specified in Section 2(b)(1)-(2) are not Copyright and Similar
-     Rights.
-  d. Effective Technological Measures means those measures that, in the
-     absence of proper authority, may not be circumvented under laws
-     fulfilling obligations under Article 11 of the WIPO Copyright
-     Treaty adopted on December 20, 1996, and/or similar international
-     agreements.
-
-  e. Exceptions and Limitations means fair use, fair dealing, and/or
-     any other exception or limitation to Copyright and Similar Rights
-     that applies to Your use of the Licensed Material.
-
-  f. Licensed Material means the artistic or literary work, database,
-     or other material to which the Licensor applied this Public
-     License.
-
-  g. Licensed Rights means the rights granted to You subject to the
-     terms and conditions of this Public License, which are limited to
-     all Copyright and Similar Rights that apply to Your use of the
-     Licensed Material and that the Licensor has authority to license.
-
-  h. Licensor means the individual(s) or entity(ies) granting rights
-     under this Public License.
-
-  i. NonCommercial means not primarily intended for or directed towards
-     commercial advantage or monetary compensation. For purposes of
-     this Public License, the exchange of the Licensed Material for
-     other material subject to Copyright and Similar Rights by digital
-     file-sharing or similar means is NonCommercial provided there is
-     no payment of monetary compensation in connection with the
-     exchange.
-
-  j. Share means to provide material to the public by any means or
-     process that requires permission under the Licensed Rights, such
-     as reproduction, public display, public performance, distribution,
-     dissemination, communication, or importation, and to make material
-     available to the public including in ways that members of the
-     public may access the material from a place and at a time
-     individually chosen by them.
-
-  k. Sui Generis Database Rights means rights other than copyright
-     resulting from Directive 96/9/EC of the European Parliament and of
-     the Council of 11 March 1996 on the legal protection of databases,
-     as amended and/or succeeded, as well as other essentially
-     equivalent rights anywhere in the world.
-
-  l. You means the individual or entity exercising the Licensed Rights
-     under this Public License. Your has a corresponding meaning.
-
-
-Section 2 -- Scope.
-
-  a. License grant.
-
-       1. Subject to the terms and conditions of this Public License,
-          the Licensor hereby grants You a worldwide, royalty-free,
-          non-sublicensable, non-exclusive, irrevocable license to
-          exercise the Licensed Rights in the Licensed Material to:
-
-            a. reproduce and Share the Licensed Material, in whole or
-               in part, for NonCommercial purposes only; and
-
-            b. produce, reproduce, and Share Adapted Material for
-               NonCommercial purposes only.
-
-       2. Exceptions and Limitations. For the avoidance of doubt, where
-          Exceptions and Limitations apply to Your use, this Public
-          License does not apply, and You do not need to comply with
-          its terms and conditions.
-
-       3. Term. The term of this Public License is specified in Section
-          6(a).
-
-       4. Media and formats; technical modifications allowed. The
-          Licensor authorizes You to exercise the Licensed Rights in
-          all media and formats whether now known or hereafter created,
-          and to make technical modifications necessary to do so. The
-          Licensor waives and/or agrees not to assert any right or
-          authority to forbid You from making technical modifications
-          necessary to exercise the Licensed Rights, including
-          technical modifications necessary to circumvent Effective
-          Technological Measures. For purposes of this Public License,
-          simply making modifications authorized by this Section 2(a)
-          (4) never produces Adapted Material.
-
-       5. Downstream recipients.
-
-            a. Offer from the Licensor -- Licensed Material. Every
-               recipient of the Licensed Material automatically
-               receives an offer from the Licensor to exercise the
-               Licensed Rights under the terms and conditions of this
-               Public License.
-
-            b. No downstream restrictions. You may not offer or impose
-               any additional or different terms or conditions on, or
-               apply any Effective Technological Measures to, the
-               Licensed Material if doing so restricts exercise of the
-               Licensed Rights by any recipient of the Licensed
-               Material.
-
-       6. No endorsement. Nothing in this Public License constitutes or
-          may be construed as permission to assert or imply that You
-          are, or that Your use of the Licensed Material is, connected
-          with, or sponsored, endorsed, or granted official status by,
-          the Licensor or others designated to receive attribution as
-          provided in Section 3(a)(1)(A)(i).
-
-  b. Other rights.
-
-       1. Moral rights, such as the right of integrity, are not
-          licensed under this Public License, nor are publicity,
-          privacy, and/or other similar personality rights; however, to
-          the extent possible, the Licensor waives and/or agrees not to
-          assert any such rights held by the Licensor to the limited
-          extent necessary to allow You to exercise the Licensed
-          Rights, but not otherwise.
-
-       2. Patent and trademark rights are not licensed under this
-          Public License.
-
-       3. To the extent possible, the Licensor waives any right to
-          collect royalties from You for the exercise of the Licensed
-          Rights, whether directly or through a collecting society
-          under any voluntary or waivable statutory or compulsory
-          licensing scheme. In all other cases the Licensor expressly
-          reserves any right to collect such royalties, including when
-          the Licensed Material is used other than for NonCommercial
-          purposes.
-
-
-Section 3 -- License Conditions.
-
-Your exercise of the Licensed Rights is expressly made subject to the
-following conditions.
-
-  a. Attribution.
-
-       1. If You Share the Licensed Material (including in modified
-          form), You must:
-
-            a. retain the following if it is supplied by the Licensor
-               with the Licensed Material:
-
-                 i. identification of the creator(s) of the Licensed
-                    Material and any others designated to receive
-                    attribution, in any reasonable manner requested by
-                    the Licensor (including by pseudonym if
-                    designated);
-
-                ii. a copyright notice;
-
-               iii. a notice that refers to this Public License;
-
-                iv. a notice that refers to the disclaimer of
-                    warranties;
-
-                 v. a URI or hyperlink to the Licensed Material to the
-                    extent reasonably practicable;
-
-            b. indicate if You modified the Licensed Material and
-               retain an indication of any previous modifications; and
-
-            c. indicate the Licensed Material is licensed under this
-               Public License, and include the text of, or the URI or
-               hyperlink to, this Public License.
-
-       2. You may satisfy the conditions in Section 3(a)(1) in any
-          reasonable manner based on the medium, means, and context in
-          which You Share the Licensed Material. For example, it may be
-          reasonable to satisfy the conditions by providing a URI or
-          hyperlink to a resource that includes the required
-          information.
-
-       3. If requested by the Licensor, You must remove any of the
-          information required by Section 3(a)(1)(A) to the extent
-          reasonably practicable.
-
-       4. If You Share Adapted Material You produce, the Adapter's
-          License You apply must not prevent recipients of the Adapted
-          Material from complying with this Public License.
-
-
-Section 4 -- Sui Generis Database Rights.
-
-Where the Licensed Rights include Sui Generis Database Rights that
-apply to Your use of the Licensed Material:
-
-  a. for the avoidance of doubt, Section 2(a)(1) grants You the right
-     to extract, reuse, reproduce, and Share all or a substantial
-     portion of the contents of the database for NonCommercial purposes
-     only;
-
-  b. if You include all or a substantial portion of the database
-     contents in a database in which You have Sui Generis Database
-     Rights, then the database in which You have Sui Generis Database
-     Rights (but not its individual contents) is Adapted Material; and
-
-  c. You must comply with the conditions in Section 3(a) if You Share
-     all or a substantial portion of the contents of the database.
-
-For the avoidance of doubt, this Section 4 supplements and does not
-replace Your obligations under this Public License where the Licensed
-Rights include other Copyright and Similar Rights.
-
-
-Section 5 -- Disclaimer of Warranties and Limitation of Liability.
-
-  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
-     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
-     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
-     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
-     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
-     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
-     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
-     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
-     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
-     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
-
-  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
-     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
-     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
-     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
-     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
-     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
-     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
-     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
-     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
-
-  c. The disclaimer of warranties and limitation of liability provided
-     above shall be interpreted in a manner that, to the extent
-     possible, most closely approximates an absolute disclaimer and
-     waiver of all liability.
-
-
-Section 6 -- Term and Termination.
-
-  a. This Public License applies for the term of the Copyright and
-     Similar Rights licensed here. However, if You fail to comply with
-     this Public License, then Your rights under this Public License
-     terminate automatically.
-
-  b. Where Your right to use the Licensed Material has terminated under
-     Section 6(a), it reinstates:
-
-       1. automatically as of the date the violation is cured, provided
-          it is cured within 30 days of Your discovery of the
-          violation; or
-
-       2. upon express reinstatement by the Licensor.
-
-     For the avoidance of doubt, this Section 6(b) does not affect any
-     right the Licensor may have to seek remedies for Your violations
-     of this Public License.
-
-  c. For the avoidance of doubt, the Licensor may also offer the
-     Licensed Material under separate terms or conditions or stop
-     distributing the Licensed Material at any time; however, doing so
-     will not terminate this Public License.
-
-  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
-     License.
-
-
-Section 7 -- Other Terms and Conditions.
-
-  a. The Licensor shall not be bound by any additional or different
-     terms or conditions communicated by You unless expressly agreed.
-
-  b. Any arrangements, understandings, or agreements regarding the
-     Licensed Material not stated herein are separate from and
-     independent of the terms and conditions of this Public License.
-
-
-Section 8 -- Interpretation.
-
-  a. For the avoidance of doubt, this Public License does not, and
-     shall not be interpreted to, reduce, limit, restrict, or impose
-     conditions on any use of the Licensed Material that could lawfully
-     be made without permission under this Public License.
-
-  b. To the extent possible, if any provision of this Public License is
-     deemed unenforceable, it shall be automatically reformed to the
-     minimum extent necessary to make it enforceable. If the provision
-     cannot be reformed, it shall be severed from this Public License
-     without affecting the enforceability of the remaining terms and
-     conditions.
-
-  c. No term or condition of this Public License will be waived and no
-     failure to comply consented to unless expressly agreed to by the
-     Licensor.
-
-  d. Nothing in this Public License constitutes or may be interpreted
-     as a limitation upon, or waiver of, any privileges and immunities
-     that apply to the Licensor or You, including from the legal
-     processes of any jurisdiction or authority.
-
-=======================================================================
-
-Creative Commons is not a party to its public
-licenses. Notwithstanding, Creative Commons may elect to apply one of
-its public licenses to material it publishes and in those instances
-will be considered the “Licensor.” The text of the Creative Commons
-public licenses is dedicated to the public domain under the CC0 Public
-Domain Dedication. Except for the limited purpose of indicating that
-material is shared under a Creative Commons public license or as
-otherwise permitted by the Creative Commons policies published at
-creativecommons.org/policies, Creative Commons does not authorize the
-use of the trademark "Creative Commons" or any other trademark or logo
-of Creative Commons without its prior written consent including,
-without limitation, in connection with any unauthorized modifications
-to any of its public licenses or any other arrangements,
-understandings, or agreements concerning use of licensed material. For
-the avoidance of doubt, this paragraph does not form part of the
-public licenses.
-
-Creative Commons may be contacted at creativecommons.org.
-

+ 0 - 55
src/tmdet-extension/README.md

@@ -1,55 +0,0 @@
-# TMDET Extension
-
-TmMol* is a Mol* extension to visualize transmembrane regions and topology
-according to data of http://pdbtm.enzim.hu/ served by PDBe.
-
-
-# Usage
-
-`loadWithUNITMPMembraneRepresentation` call on an initialized
-`PluginUIContext` object downloads structure and annotation data
-from the given URLs.
-
-For example:
-
-```
-<script type="text/javascript" src="./tm_molstar.js"></script>
-<script type="text/javascript">
-    // init viewer
-    var viewer = new tm_molstar.Viewer('app', {
-        layoutShowControls: false,
-        layoutIsExpanded: false,
-        viewportShowExpand: true,
-        collapseLeftPanel: true
-    });
-
-    var pdbId = '1a0s';
-
-    tm_molstar.loadWithUNITMPMembraneRepresentation(viewer.plugin, {
-
-        // URL to get mmCIF/PDBx data
-        structureUrl: `https://cs.litemol.org/${pdbId}/full`,
-
-        // URL to load PDBTM information according to FunPDBe Data Exchange Format
-        regionDescriptorUrl: `http://localhost:8000/tmdet-data/${pdbId}.json`,
-    });
-...
-
-```
-
-Please see the `index.html` and `index.ts` files of the demo
-application in the `src/apps/tm-viwer` folder and example data
-files in `data/tmdet-example-annotations` folder for more details.
-
-# Authors
-
-* Gabor Tusnady (tusnady.gabor at ttk.hu), Protein Bioinformatics Research Group, RCNS.
-* Csongor Gerdan (gerdan.csongor at ttk.hu), Protein Bioinformatics Research Group, RCNS.
-
-# License
-
-Creative Commons Attribution-NonCommercial 4.0 International Public
-License
-
-Please see the LICENSE file for more details or visit
-https://creativecommons.org/licenses/by-nc/4.0/.

+ 0 - 41
src/tmdet-extension/algorithm.ts

@@ -1,41 +0,0 @@
-/**
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-/**
- * Copyright (C) 2022, Protein Bioinformatics Research Group, RCNS
- *
- * Licensed under CC BY-NC 4.0, see LICENSE file for more info.
- *
- * @author Gabor Tusnady <tusnady.gabor@ttk.hu>
- * @author Csongor Gerdan <gerdan.csongor@ttk.hu>
- */
-
-import { Vec3 } from 'molstar/lib/mol-math/linear-algebra';
-import { ParamDefinition as PD } from 'molstar/lib/mol-util/param-definition';
-import 'molstar/lib/mol-util/polyfill';
-
-export const TMDETParams = {
-    numberOfSpherePoints: PD.Numeric(140, { min: 35, max: 700, step: 1 }, { description: 'Number of spheres/directions to test for membrane placement. Original value is 350.' }),
-    stepSize: PD.Numeric(1, { min: 0.25, max: 4, step: 0.25 }, { description: 'Thickness of membrane slices that will be tested' }),
-    minThickness: PD.Numeric(20, { min: 10, max: 30, step: 1}, { description: 'Minimum membrane thickness used during refinement' }),
-    maxThickness: PD.Numeric(40, { min: 30, max: 50, step: 1}, { description: 'Maximum membrane thickness used during refinement' }),
-    adjust: PD.Numeric(14, { min: 0, max: 30, step: 1 }, { description: 'Minimum length of membrane-spanning regions (original values: 14 for alpha-helices and 5 for beta sheets). Set to 0 to not optimize membrane thickness.' }),
-};
-export type TMDETParams = typeof TMDETParams
-export type TMDETProps = PD.Values<TMDETParams>
-
-const v3dot = Vec3.dot;
-
-export function isInMembranePlane(testPoint: Vec3, normalVector: Vec3, planePoint1: Vec3, planePoint2: Vec3): boolean {
-    const d1 = -v3dot(normalVector, planePoint1);
-    const d2 = -v3dot(normalVector, planePoint2);
-    return _isInMembranePlane(testPoint, normalVector, Math.min(d1, d2), Math.max(d1, d2));
-}
-
-function _isInMembranePlane(testPoint: Vec3, normalVector: Vec3, min: number, max: number): boolean {
-    const d = -v3dot(normalVector, testPoint);
-    return d > min && d < max;
-}

+ 0 - 346
src/tmdet-extension/behavior.ts

@@ -1,346 +0,0 @@
-/**
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-/**
- * Copyright (C) 2022, Protein Bioinformatics Research Group, RCNS
- *
- * Licensed under CC BY-NC 4.0, see LICENSE file for more info.
- *
- * @author Gabor Tusnady <tusnady.gabor@ttk.hu>
- * @author Csongor Gerdan <gerdan.csongor@ttk.hu>
- */
-
-import { ParamDefinition as PD } from 'molstar/lib/mol-util/param-definition';
-import { StructureRepresentationPresetProvider, PresetStructureRepresentations } from 'molstar/lib/mol-plugin-state/builder/structure/representation-preset';
-import { StateObject, StateObjectRef, StateObjectCell, StateTransformer, StateTransform } from 'molstar/lib/mol-state';
-import { Task } from 'molstar/lib/mol-task';
-import { PluginBehavior } from 'molstar/lib/mol-plugin/behavior';
-import { PluginStateObject, PluginStateTransform } from 'molstar/lib/mol-plugin-state/objects';
-import { PluginContext } from 'molstar/lib/mol-plugin/context';
-import { DefaultQueryRuntimeTable } from 'molstar/lib/mol-script/runtime/query/compiler';
-import { StructureSelectionQuery, StructureSelectionCategory } from 'molstar/lib/mol-plugin-state/helpers/structure-selection-query';
-import { MolScriptBuilder as MS } from 'molstar/lib/mol-script/language/builder';
-import { GenericRepresentationRef } from 'molstar/lib/mol-plugin-state/manager/structure/hierarchy-state';
-import { PluginUIContext } from 'molstar/lib/mol-plugin-ui/context';
-// import { Gunzip } from "zlibt2";
-
-
-// TMDET imports
-import { MembraneOrientationRepresentationProvider, MembraneOrientationParams, MembraneOrientationRepresentation } from './representation';
-import { MembraneOrientationProvider, TmDetDescriptorCache, isTransmembrane as tmSymbol, setMembraneOrientation } from './prop';
-import { applyTransformations, createMembraneOrientation } from './transformation';
-import { ComponentsType, PDBTMDescriptor, PMS } from './types';
-import { registerTmDetSymmetry } from './symmetry';
-import { TmDetLabelProvider } from './labeling';
-import { TmDetColorThemeProvider, updateSiteColors } from './tmdet-color-theme';
-//import { loadInitialSnapshot, rotateCamera, storeCameraSnapshot } from './camera';
-import { DebugUtil } from './debug-utils';
-
-const TMDET_MEMB_ORI_REPRESENTATION_TAG = 'tmdet-membrane-orientation-3d';
-const TMDET_MEMBRANE_ORIENTATION = 'TMDET Membrane Orientation';
-export const TMDET_STRUCTURE_PRESET_ID = 'tmdet-preset-membrane-orientation';
-
-export const TMDETMembraneOrientation = PluginBehavior.create<{ autoAttach: boolean }>({
-    name: 'tmdet-membrane-orientation-prop',
-    category: 'custom-props',
-    display: {
-        name: TMDET_MEMBRANE_ORIENTATION,
-        description: 'Data calculated with TMDET algorithm.'
-    },
-    ctor: class extends PluginBehavior.Handler<{ autoAttach: boolean }> {
-        private provider = MembraneOrientationProvider
-
-        register(): void {
-            console.log('TMDET REGISER');
-            DefaultQueryRuntimeTable.addCustomProp(this.provider.descriptor);
-
-            this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach);
-
-            this.ctx.representation.structure.registry.add(MembraneOrientationRepresentationProvider);
-            this.ctx.query.structure.registry.add(isTransmembrane);
-
-            this.ctx.representation.structure.themes.colorThemeRegistry.add(TmDetColorThemeProvider);
-            this.ctx.managers.lociLabels.addProvider(TmDetLabelProvider);
-
-            this.ctx.genericRepresentationControls.set(TMDET_MEMB_ORI_REPRESENTATION_TAG, selection => {
-                const refs: GenericRepresentationRef[] = [];
-                selection.structures.forEach(structure => {
-                    const memRepr = structure.genericRepresentations?.filter(r => r.cell.transform.transformer.id === MembraneOrientation3D.id)[0];
-                    if (memRepr) refs.push(memRepr);
-                });
-                return [refs, 'Membrane Orientation'];
-            });
-            this.ctx.builders.structure.representation.registerPreset(MembraneOrientationPreset);
-        }
-
-        update(p: { autoAttach: boolean }) {
-            let updated = this.params.autoAttach !== p.autoAttach;
-            this.params.autoAttach = p.autoAttach;
-            this.ctx.customStructureProperties.setDefaultAutoAttach(this.provider.descriptor.name, this.params.autoAttach);
-            return updated;
-        }
-
-        unregister() {
-            DefaultQueryRuntimeTable.removeCustomProp(this.provider.descriptor);
-
-            this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
-
-            this.ctx.representation.structure.registry.remove(MembraneOrientationRepresentationProvider);
-            this.ctx.query.structure.registry.remove(isTransmembrane);
-
-            this.ctx.genericRepresentationControls.delete(TMDET_MEMB_ORI_REPRESENTATION_TAG);
-            this.ctx.builders.structure.representation.unregisterPreset(MembraneOrientationPreset);
-
-            this.ctx.representation.structure.themes.colorThemeRegistry.remove(TmDetColorThemeProvider);
-            this.ctx.managers.lociLabels.removeProvider(TmDetLabelProvider);
-        }
-    },
-    params: () => ({
-        autoAttach: PD.Boolean(false)
-    })
-});
-
-//
-
-export const isTransmembrane = StructureSelectionQuery('Residues Embedded in Membrane', MS.struct.modifier.union([
-    MS.struct.modifier.wholeResidues([
-        MS.struct.modifier.union([
-            MS.struct.generator.atomGroups({
-                'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
-                'atom-test': tmSymbol.symbol(),
-            })
-        ])
-    ])
-]), {
-    description: 'Select residues that are embedded between the membrane layers.',
-    category: StructureSelectionCategory.Residue,
-    ensureCustomProperties: (ctx, structure) => {
-        return MembraneOrientationProvider.attach(ctx, structure);
-    }
-});
-
-
-
-
-//
-// //////////////////////////// TMDET VIEWER FUNCTIONS
-//
-
-
-
-
-export async function loadWithUNITMPMembraneRepresentation(plugin: PluginUIContext, params: any) {
-    //storeCameraSnapshot(plugin); // store if it is not stored yet
-
-    //loadInitialSnapshot(plugin); // load if there is a stored one
-    setTimeout(() => { plugin.clear(); }, 100); // clear scene after some delay
-
-    updateSiteColors(params.side1);
-
-    setTimeout(() => { (async () => {
-        const pdbtmDescriptor: PDBTMDescriptor = await downloadRegionDescriptor(plugin, params);
-        pdbtmDescriptor.side1 = params.side1;
-        TmDetDescriptorCache.add(pdbtmDescriptor);
-
-        const membraneOrientation = createMembraneOrientation(pdbtmDescriptor);
-        setMembraneOrientation(membraneOrientation);
-
-        // load structure
-        await loadStructure(plugin, params, pdbtmDescriptor);
-        // cartoon, colors etc.
-        await createStructureRepresentation(plugin, pdbtmDescriptor);
-
-        //
-        // It also resets the camera because the membranes render 1st and the structure might not be fully visible
-        //
-        //rotateCamera(plugin);
-    })(); }, 500);
-}
-
-async function downloadRegionDescriptor(plugin: PluginUIContext, params: any): Promise<any> {
-    // run a fetch task
-    const downloadResult: string = await plugin.runTask(plugin.fetch({ url: params.regionDescriptorUrl })) as string;
-    const pdbtmDescriptor: any = JSON.parse(downloadResult);
-    return pdbtmDescriptor;
-}
-
-async function createStructureRepresentation(plugin: PluginUIContext, pdbtmDescriptor: any) {
-    // get the first structure of the first model
-    const structure: StateObjectRef<PMS> = plugin.managers.structure.hierarchy.current.models[0].structures[0].cell;
-    const components = await createStructureComponents(plugin, structure);
-
-    applyTransformations(plugin, pdbtmDescriptor);
-
-    await buildStructureRepresentation(plugin, pdbtmDescriptor, components);
-}
-
-async function createStructureComponents(plugin: PluginUIContext, structure: StateObjectCell<PMS, StateTransform<StateTransformer<StateObject<any, StateObject.Type<any>>, StateObject<any, StateObject.Type<any>>, any>>>) {
-    return {
-        polymer: await plugin.builders.structure.tryCreateComponentStatic(structure, 'polymer'),
-        ligand: await plugin.builders.structure.tryCreateComponentStatic(structure, 'ligand'),
-        water: await plugin.builders.structure.tryCreateComponentStatic(structure, 'water'),
-    };
-}
-
-async function buildStructureRepresentation(plugin: PluginUIContext, pdbtmDescriptor: PDBTMDescriptor, components: ComponentsType) {
-    const builder = plugin.builders.structure.representation;
-    const update = plugin.build();
-    if (components.polymer) {
-        builder.buildRepresentation(update, components.polymer, {
-                type: 'cartoon',
-                color: TmDetColorThemeProvider.name as any, colorParams: { pdbtmDescriptor }
-            },
-            { tag: 'polymer' }
-        );
-    }
-    if (components.ligand)
-        builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick' }, { tag: 'ligand' });
-    if (components.water)
-        builder.buildRepresentation(update, components.water, { type: 'ball-and-stick', typeParams: { alpha: 0.6 } }, { tag: 'water' });
-    await update.commit();
-}
-
-async function loadStructure(ctx: PluginUIContext, params: any, pdbtmDescriptor: PDBTMDescriptor): Promise<void> {
-
-    // replace original symmetry format function
-    registerTmDetSymmetry(pdbtmDescriptor);
-
-    let format: "mmcif"|"pdb" = "mmcif";
-    // check url to determine file format and compression
-    const match: string[] = params.structureUrl.match(new RegExp('/(pdb|cif)(.gz)?$/g/'));
-    DebugUtil.log(`format: ${params.format}`);
-    if ((params.format != 'mmcif' || params.format != 'pdb') && match != null) {
-        if (match[0].startsWith('cif')) {
-            format = 'mmcif';
-        }
-        if (match[0].startsWith('pdb')) {
-            format = 'pdb';
-        }
-    } else if (params.format) {
-        format = params.format;
-    }
-
-    const builders = ctx.builders;
-    const data = await downloadData(ctx, params, pdbtmDescriptor);
-
-    const trajectory = await builders.structure.parseTrajectory(data, format);
-
-
-    // create membrane representation
-    await builders.structure.hierarchy.applyPreset(
-        trajectory, 'default', { representationPreset: TMDET_STRUCTURE_PRESET_ID as any });
-}
-
-
-async function downloadData(ctx: PluginUIContext, params: any, pdbtmDescriptor: PDBTMDescriptor) {
-
-    // let gzipped: boolean = false;
-    // if (params.compression || params.structureUrl.endsWith('gz')) {
-    //     gzipped = true;
-    // }
-
-    const builders = ctx.builders;
-    let downloadResult = await ctx.runTask(ctx.fetch({ url: params.structureUrl, type: "string" }));
-    DebugUtil.log('First 50 chars of input data', downloadResult.slice(0, 50));
-    // TODO: temporary solution
-    // TODO: downloadResult = downloadResult.replace(/HETATM.+\n/mg, ''); // remove all hetatom stuffs
-    // TODO: const uncompressed: string = await ungzip(downloadResult); // it does not work right now
-    // console.log(uncompressed.slice(0, 100));
-
-    return await builders.data.rawData({
-        data: downloadResult,
-        label: `${pdbtmDescriptor.pdb_id}`,
-    }); // , { state: { isGhost: true } });
-
-}
-
-// async function ungzip(data: Uint8Array) {
-//     // TODO: it does not work :(
-//     return new Gunzip(data).decompress();
-// }
-
-//
-// //////////////////////////// END OF TMDET VIEWER SECTION
-//
-
-
-
-
-type MembraneOrientation3DType = typeof MembraneOrientation3D
-const MembraneOrientation3D = PluginStateTransform.BuiltIn({
-    name: TMDET_MEMB_ORI_REPRESENTATION_TAG,
-    display: {
-        name: TMDET_MEMBRANE_ORIENTATION,
-        description: 'Membrane Orientation planes and rims. Data calculated with TMDET algorithm.'
-    },
-    from: PluginStateObject.Molecule.Structure,
-    to: PluginStateObject.Shape.Representation3D,
-    params: () => {
-        return {
-            ...MembraneOrientationParams,
-        };
-    }
-})({
-    canAutoUpdate({ oldParams, newParams }) {
-        return true;
-    },
-    apply({ a, params }, plugin: PluginContext) {
-        return Task.create(TMDET_MEMBRANE_ORIENTATION, async ctx => {
-            await MembraneOrientationProvider.attach({ runtime: ctx, assetManager: plugin.managers.asset }, a.data);
-            const repr = MembraneOrientationRepresentation({ webgl: plugin.canvas3d?.webgl, ...plugin.representation.structure.themes }, () => MembraneOrientationParams);
-            await repr.createOrUpdate(params, a.data).runInContext(ctx);
-            return new PluginStateObject.Shape.Representation3D({ repr, sourceData: a.data }, { label: TMDET_MEMBRANE_ORIENTATION });
-        });
-    },
-    update({ a, b, newParams }, plugin: PluginContext) {
-        return Task.create(TMDET_MEMBRANE_ORIENTATION, async ctx => {
-            await MembraneOrientationProvider.attach({ runtime: ctx, assetManager: plugin.managers.asset }, a.data);
-            const props = { ...b.data.repr.props, ...newParams };
-            await b.data.repr.createOrUpdate(props, a.data).runInContext(ctx);
-            b.data.sourceData = a.data;
-            return StateTransformer.UpdateResult.Updated;
-        });
-    },
-    isApplicable(a) {
-        return MembraneOrientationProvider.isApplicable(a.data);
-    }
-});
-
-export const MembraneOrientationPreset = StructureRepresentationPresetProvider({
-    id: TMDET_STRUCTURE_PRESET_ID,
-    display: {
-        name: TMDET_MEMBRANE_ORIENTATION, group: 'Annotation',
-        description: 'Shows orientation of membrane layers. Data calculated with TMDET algorithm.' // TODO add ' or obtained via RCSB PDB'
-    },
-    isApplicable(a) {
-        return MembraneOrientationProvider.isApplicable(a.data);
-    },
-    params: () => StructureRepresentationPresetProvider.CommonParams,
-    async apply(ref, params, plugin) {
-        const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
-        const structure  = structureCell?.obj?.data;
-        if (!structureCell || !structure) return {};
-
-        if (!MembraneOrientationProvider.get(structure).value) {
-            await plugin.runTask(Task.create(TMDET_MEMBRANE_ORIENTATION, async runtime => {
-                await MembraneOrientationProvider.attach({ runtime, assetManager: plugin.managers.asset }, structure);
-            }));
-        }
-
-        const membraneOrientation = await tryCreateMembraneOrientation(plugin, structureCell);
-        const colorTheme =  TmDetColorThemeProvider.name as any;
-        const preset = await PresetStructureRepresentations.auto.apply(ref, { ...params, theme: { globalName: colorTheme, focus: { name: colorTheme } } }, plugin);
-
-        return { components: preset.components, representations: { ...preset.representations, membraneOrientation } };
-    }
-});
-
-export function tryCreateMembraneOrientation(plugin: PluginContext, structure: StateObjectRef<PMS>, params?: StateTransformer.Params<MembraneOrientation3DType>, initialState?: Partial<StateTransform.State>) {
-    const state = plugin.state.data;
-    const membraneOrientation = state.build().to(structure)
-        .applyOrUpdateTagged(TMDET_MEMB_ORI_REPRESENTATION_TAG, MembraneOrientation3D, params, { state: initialState });
-    return membraneOrientation.commit({ revertOnError: true });
-}

+ 0 - 66
src/tmdet-extension/camera.ts

@@ -1,66 +0,0 @@
-/**
- * Copyright (C) 2022, Protein Bioinformatics Research Group, RCNS
- *
- * Licensed under CC BY-NC 4.0, see LICENSE file for more info.
- *
- * @author Gabor Tusnady <tusnady.gabor@ttk.hu>
- * @author Csongor Gerdan <gerdan.csongor@ttk.hu>
- */
-
-import { PluginUIContext } from 'molstar/lib/mol-plugin-ui/context';
-import { Quat, Vec3 } from 'molstar/lib/mol-math/linear-algebra';
-import { PluginCommands } from 'molstar/lib/mol-plugin/commands';
-import { Camera } from 'molstar/lib/mol-canvas3d/camera';
-import { DebugUtil } from './debug-utils';
-
-let initialSnapshot: Camera.Snapshot;
-
-export function storeCameraSnapshot(plugin: PluginUIContext): void {
-    if (!initialSnapshot) {
-        initialSnapshot = plugin.canvas3d!.camera.getSnapshot();
-        DebugUtil.log('initialSnapshot stored:', initialSnapshot);
-    }
-}
-
-export function loadInitialSnapshot(plugin: PluginUIContext): void {
-    if (!initialSnapshot) {
-        DebugUtil.log('initialSnapshot is undefined');
-    } else {
-        DebugUtil.log('Loading initial snapshot:', initialSnapshot);
-        PluginCommands.Camera.Reset(plugin, { snapshot: initialSnapshot });
-    }
-}
-
-export async function rotateCamera(plugin: PluginUIContext) {
-    function rot90q(v: Vec3, axis: Vec3 = Vec3.create(1, 0, 0)): Vec3 {
-        const q = Quat.setAxisAngle(Quat(), axis, -Math.PI/2);
-        return Vec3.transformQuat(Vec3(), v, q);
-    }
-    function sub(v: Vec3, u: Vec3): Vec3 {
-        return Vec3.sub(Vec3(), v, u);
-    }
-    function add(v: Vec3, u: Vec3): Vec3 {
-        return Vec3.add(Vec3(), v, u);
-    }
-
-    if (!plugin.canvas3d) {
-        return;
-    }
-
-    const cam = plugin.canvas3d!.camera;
-    const snapshot = cam.getSnapshot();
-    const newSnapshot = {
-        ...snapshot,
-        // target + rotateBy90(postition - target)
-        position: add(snapshot.target, rot90q(sub(snapshot.position, snapshot.target))),
-        target: snapshot.target,
-        up: Vec3.negUnitZ
-    };
-    const duration = 100;
-    PluginCommands.Camera.Reset(plugin, { snapshot: newSnapshot, durationMs: duration }).then(() => {
-        setTimeout(()=> {
-            requestAnimationFrame(() => plugin.canvas3d?.requestCameraReset());
-        }, duration + 50); // The 2nd reset needs some delay
-    });
-
-}

+ 0 - 178
src/tmdet-extension/debug-utils.ts

@@ -1,178 +0,0 @@
-/**
- * Copyright (C) 2022, Protein Bioinformatics Research Group, RCNS
- *
- * Licensed under CC BY-NC 4.0, see LICENSE file for more info.
- *
- * @author Gabor Tusnady <tusnady.gabor@ttk.hu>
- * @author Csongor Gerdan <gerdan.csongor@ttk.hu>
- */
-
-import { mmCIF_Database } from "molstar/lib/mol-io/reader/cif/schema/mmcif";
-import { Mat4, Vec3 } from "molstar/lib/mol-math/linear-algebra";
-import { MmcifFormat } from "molstar/lib/mol-model-formats/structure/mmcif";
-import { Model } from "molstar/lib/mol-model/structure";
-import { AtomicConformation } from "molstar/lib/mol-model/structure/model/properties/atomic";
-import { createStructureRepresentationParams } from "molstar/lib/mol-plugin-state/helpers/structure-representation-params";
-import { StateTransforms } from "molstar/lib/mol-plugin-state/transforms";
-import { PluginUIContext } from "molstar/lib/mol-plugin-ui/context";
-import { Expression } from "molstar/lib/mol-script/language/expression";
-import { Color } from "molstar/lib/mol-util/color";
-import { rotateCamera as RC } from "./camera";
-import { TmDetDescriptorCache } from "./prop";
-import { getChainExpression as GCE, getCurrentHierarchy as GCH, transformationForStateTransform, transformWholeModel } from "./transformation";
-import { PDBTMTransformationMatrix } from "./types";
-
-export namespace DebugUtil {
-    let plugin: PluginUIContext;
-    let logEnabled = false;
-
-    export function init(ctx: PluginUIContext) {
-        plugin = ctx;
-    }
-
-    //
-    // logging
-    //
-    export function enableLog() {
-        logEnabled = true;
-        console.log('DebugUtil Enabled', logEnabled);
-    }
-
-    export function disableLog() {
-        logEnabled = false;
-    }
-
-    export function log(...args: any[]) {
-        if (logEnabled) {
-            console.log(...args);
-        }
-    }
-
-    //
-    //
-    // lin.alg.
-    //
-
-    export function transformVector(v: Vec3, matrix: Mat4): Vec3 {
-        const result = Vec3.transformMat4(Vec3(), v, matrix);
-        log("transformVector: Input v & matrix:", v, Mat4.makeTable(matrix));
-        log("transformVector: Result vector:", result);
-        return result;
-    }
-
-    export function descriptorMxToMat4(matrix: PDBTMTransformationMatrix): Mat4 {
-        log("descriptorMxToMat4: Input:", matrix);
-        const result = transformationForStateTransform(matrix);
-        log("descriptorMxToMat4: Result:", result);
-        return result;
-    }
-
-
-    //
-    // structure utils
-    //
-
-    export const getChainExpression = GCE;
-
-    export function getCellOfFirstStructure() {
-        return getCell();
-    }
-
-    export function getCell(structureIndex: number = 0, modelIndex: number = 0) {
-        return getCurrentHierarchy().models[structureIndex].structures[modelIndex].cell;
-    }
-
-    export function getCurrentHierarchy() {
-        return GCH(plugin);
-    }
-
-    export function getModelOfFirstStructure() {
-        return getCellOfFirstStructure().obj?.data.model;
-    }
-
-    // in case of mmCIF format
-    export function dumpAtomProperties(authAtomId: number) {
-        const model: Model|undefined = getModelOfFirstStructure();
-        log("First model:", model);
-        if(!model) {
-            return;
-        }
-
-        const rowCount = model.atomicHierarchy.atoms._rowCount;
-        const conformation: AtomicConformation = model.atomicConformation;
-        const db: mmCIF_Database = (model.sourceData as MmcifFormat).data.db;
-        const atom_site = db.atom_site;
-        for (let index = 0; index < rowCount; index++) {
-            if (conformation.atomId.value(index) == authAtomId) {
-                log("Model Atom Conformation:", {
-                    atomIdParameter: authAtomId,
-                    atomId: conformation.atomId.value(index),
-                    coords: [
-                        conformation.x[index],
-                        conformation.y[index],
-                        conformation.z[index]
-                    ],
-                    xyzDefined: conformation.xyzDefined
-                });
-
-                log("Atom Source Data (mmCIF database):", {
-                    authId: atom_site.auth_atom_id.value(index),
-                    compId: atom_site.auth_comp_id.value(index),
-                    authAsymId: atom_site.auth_asym_id.value(index),
-                    authSeqId: atom_site.auth_seq_id.value(index),
-                    coords: [
-                        atom_site.Cartn_x.value(index),
-                        atom_site.Cartn_y.value(index),
-                        atom_site.Cartn_z.value(index)
-                    ]
-                });
-            }
-        }
-    }
-
-
-    export function getCachesOfEachStructure() {
-        let sIndex = 0;
-        getCurrentHierarchy().structures.forEach(struct => {
-            let cIndex = 0;
-            struct.components.forEach(component => {
-                log(`struct: ${sIndex}; component: ${cIndex}`, component.cell.cache);
-                cIndex++;
-            });
-            sIndex++;
-        });
-    }
-
-    export function color(expression: Expression, color: number[], structureIndex: number = 0, modelIndex: number = 0) {
-        const structure = getCell(structureIndex, modelIndex);
-        const stateBuilder = plugin.build().to(structure);
-        stateBuilder.apply(
-            StateTransforms.Model.StructureSelectionFromExpression,
-            { expression: expression }
-        )
-        .apply(
-            StateTransforms.Representation.StructureRepresentation3D,
-            createStructureRepresentationParams(plugin, structure.obj?.data, {
-                type: 'ball-and-stick',
-                color: 'uniform', colorParams: { value: Color.fromArray(color, 0) }
-            })
-        );
-        stateBuilder.commit();
-    }
-
-    export function transform(entityId: string) {
-        const tmx = TmDetDescriptorCache.get(entityId)?.additional_entry_annotations.membrane.transformation_matrix;
-        transformWholeModel(plugin, tmx!);
-    }
-
-    //
-    // Camera
-    //
-    export function rotateCamera() {
-        RC(plugin);
-    }
-
-    export function requestCameraReset() {
-        requestAnimationFrame(() => plugin.canvas3d?.requestCameraReset({ durationMs: 1000 }));
-    }
-}

+ 0 - 98
src/tmdet-extension/labeling.ts

@@ -1,98 +0,0 @@
-/**
- * Copyright (C) 2022, Protein Bioinformatics Research Group, RCNS
- *
- * Licensed under CC BY-NC 4.0, see LICENSE file for more info.
- *
- * @author Gabor Tusnady <tusnady.gabor@ttk.hu>
- * @author Csongor Gerdan <gerdan.csongor@ttk.hu>
- */
-
-import { Loci } from 'molstar/lib/mol-model/loci';
-import { StructureElement } from 'molstar/lib/mol-model/structure';
-import { LociLabel, LociLabelProvider } from 'molstar/lib/mol-plugin-state/manager/loci-label';
-import { TmDetChainListCache, TmDetDescriptorCache } from './prop';
-import { createResidueListsPerChain, getChainAndResidueIds } from './tmdet-color-theme';
-import { ChainList, getResidue, ResidueItem } from './types';
-
-const siteLabels = [
-    "Side1",
-    "Side2",
-    "TM alpha",
-    "TM beta",
-    "TM re-entrant loop",
-    "Interfacial Helix",
-    "Unknown localization",
-    "Membrane Inside"
-];
-const DefaultResidueLabel = 6; // Unknown localization
-
-
-export const TmDetLabelProvider: LociLabelProvider = {
-    label: (loci: Loci): LociLabel => {
-        let labelText = siteLabels[DefaultResidueLabel];
-
-        if (loci.kind == 'element-loci') {
-            const unit = loci.elements[0].unit;
-            const pdbId = unit.model.entryId;
-
-            const descriptor = TmDetDescriptorCache.get(pdbId);
-            if (!descriptor) {
-                return labelText;
-            }
-
-            let chainList =  TmDetChainListCache.get(pdbId);
-            if (!chainList) {
-                const tmType = descriptor.additional_entry_annotations.tm_type;
-                chainList = createResidueListsPerChain(descriptor.chains, descriptor.side1, tmType);
-                TmDetChainListCache.set(pdbId, chainList);
-            }
-
-            const location = StructureElement.Loci.getFirstLocation(loci);
-            const { chainId, residueId } = getChainAndResidueIds(location!);
-            const residue = getResidue(chainList, chainId!, residueId!);
-            if (residue) {
-                labelText = siteLabels[residue?.siteId];
-                let regionText = getRegionText(chainList, chainId!, residue);
-                labelText = `${labelText}: ${regionText}`
-            }
-
-        }
-        return labelText;
-    }
-}
-
-function getRegionText(chainList: ChainList, chainId: string, residue: ResidueItem): string {
-    let value = "Unknown region range";
-
-    const chain = chainList.filter((chain) => chain.chainId === chainId)[0];
-    if (chain) {
-        // find start of region
-        const residues = chain.residues;
-        const  authId = parseInt(residue.authId!)
-        let previous = residues[residues.length-1];
-        for (let i = residues.length-1; i > 0; i--) {
-            const current = residues[i];
-            const currentId = parseInt(current.authId!);
-            // cancel loop when siteId changes
-            if (currentId < authId && current.siteId != residue.siteId) {
-                break;
-            }
-            previous = current;
-        }
-        value = `[ ${previous.authId}`;
-
-        // find end of region
-        previous = residues[0];
-        for (let current of residues) {
-            const currentId = parseInt(current.authId!);
-            // cancel loop when siteId changes
-            if (authId < currentId && current.siteId !== residue.siteId) {
-                break;
-            }
-            previous = current;
-        }
-        value = `${value}-${previous.authId} ]`;
-    }
-
-    return value;
-}

+ 0 - 134
src/tmdet-extension/prop.ts

@@ -1,134 +0,0 @@
-/**
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-/**
- * Copyright (C) 2022, Protein Bioinformatics Research Group, RCNS
- *
- * Licensed under CC BY-NC 4.0, see LICENSE file for more info.
- *
- * @author Gabor Tusnady <tusnady.gabor@ttk.hu>
- * @author Csongor Gerdan <gerdan.csongor@ttk.hu>
- */
-
-import { ParamDefinition as PD } from 'molstar/lib/mol-util/param-definition';
-import { Structure, StructureProperties, Unit } from 'molstar/lib/mol-model/structure';
-import { CustomPropertyDescriptor } from 'molstar/lib/mol-model/custom-property';
-import { isInMembranePlane, TMDETParams } from './algorithm';
-import { CustomStructureProperty } from 'molstar/lib/mol-model-props/common/custom-structure-property';
-import { CustomProperty } from 'molstar/lib/mol-model-props/common/custom-property';
-import { Vec3 } from 'molstar/lib/mol-math/linear-algebra';
-import { QuerySymbolRuntime } from 'molstar/lib/mol-script/runtime/query/base';
-import { CustomPropSymbol } from 'molstar/lib/mol-script/language/symbol';
-import { Type } from 'molstar/lib/mol-script/language/type';
-import { ChainList, PDBTMDescriptor } from './types';
-
-export const MembraneOrientationParams = {
-    ...TMDETParams
-};
-export type MembraneOrientationParams = typeof MembraneOrientationParams
-export type MembraneOrientationProps = PD.Values<MembraneOrientationParams>
-
-/**
- * Simple storage to made PDBTM descriptor available globally.
- *
- * @author Csongor Gerdan <gerdan.csongor@ttk.hu>
- */
-class DescriptorCache {
-    private map: Map<string, PDBTMDescriptor>;
-
-    constructor() {
-        this.map = new Map<string, PDBTMDescriptor>();
-    }
-
-    add(descriptor: PDBTMDescriptor) {
-        const key = descriptor.pdb_id.toLowerCase();
-        if (!this.map.has(key)) {
-            this.map.set(key, descriptor);
-        }
-    }
-
-    get(key: string) {
-        key = key.toLowerCase();
-        return this.map.get(key);
-    }
-
-}
-export const TmDetDescriptorCache = new DescriptorCache();
-
-class ChainListCache {
-    private map: Map<string, ChainList>;
-
-    constructor() {
-        this.map = new Map<string, ChainList>();
-    }
-
-    set(key: string, chains: ChainList) {
-        key = key.toLowerCase();
-        if (!this.map.has(key)) {
-            this.map.set(key, chains);
-        }
-    }
-
-    get(key: string) {
-        key = key.toLowerCase();
-        return this.map.get(key);
-    }
-}
-export const TmDetChainListCache = new ChainListCache();
-
-export interface MembraneOrientation {
-    // point in membrane boundary
-    readonly planePoint1: Vec3,
-    // point in opposite side of membrane boundary
-    readonly planePoint2: Vec3,
-    // normal vector of membrane layer
-    readonly normalVector: Vec3,
-    // the radius of the membrane layer
-    readonly radius: number,
-    readonly centroid: Vec3
-}
-
-const pos = Vec3();
-export const isTransmembrane = QuerySymbolRuntime.Dynamic(
-        CustomPropSymbol('computed', 'tmdet-membrane-orientation.is-transmembrane', Type.Bool),
-        ctx => {
-            const { unit, structure } = ctx.element;
-            const { x, y, z } = StructureProperties.atom;
-            if (!Unit.isAtomic(unit)) return 0;
-            const membraneOrientation = MembraneOrientationProvider.get(structure).value;
-            if (!membraneOrientation) return 0;
-            Vec3.set(pos, x(ctx.element), y(ctx.element), z(ctx.element));
-            const { normalVector, planePoint1, planePoint2 } = membraneOrientation;
-            return isInMembranePlane(pos, normalVector, planePoint1, planePoint2);
-        }
-);
-
-export let membraneOrientation: MembraneOrientation;
-export function setMembraneOrientation(orientation: MembraneOrientation) {
-    membraneOrientation = orientation;
-}
-export const MembraneOrientationProvider: CustomStructureProperty.Provider<MembraneOrientationParams, MembraneOrientation> = CustomStructureProperty.createProvider({
-    label: 'TMDET Membrane Orientation Provider',
-    descriptor: CustomPropertyDescriptor({
-        name: 'tmdet_computed_membrane_orientation',
-        symbols: { isTransmembrane: isTransmembrane },
-        // TODO `cifExport`
-    }),
-    type: 'root',
-    defaultParams: MembraneOrientationParams,
-//    getParams: (data: Structure) => MembraneOrientationParams,
-    getParams: function(data: Structure) {
-        //DebugUtil.log('getParams:: DEBUG', MembraneOrientationParams);
-        return MembraneOrientationParams;
-    },
-    isApplicable: (data: Structure) => true,
-    obtain: async (ctx: CustomProperty.Context, data: Structure, props: Partial<MembraneOrientationProps>) => {
-        //DebugUtil.log('obtain:: DEBUG', data.customPropertyDescriptors);
-        let result = membraneOrientation;
-        //DebugUtil.log("RESULT of 'obtain:'", result);
-        return { value: result };
-    }
-});

+ 0 - 149
src/tmdet-extension/representation.ts

@@ -1,149 +0,0 @@
-/**
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import { ParamDefinition as PD } from 'molstar/lib/mol-util/param-definition';
-import { Vec3, Mat4 } from 'molstar/lib/mol-math/linear-algebra';
-import { Representation, RepresentationContext, RepresentationParamsGetter } from 'molstar/lib/mol-repr/representation';
-import { Structure } from 'molstar/lib/mol-model/structure';
-import { StructureRepresentationProvider, StructureRepresentation, StructureRepresentationStateBuilder } from 'molstar/lib/mol-repr/structure/representation';
-import { MembraneOrientation, MembraneOrientationProvider } from './prop';
-import { ThemeRegistryContext } from 'molstar/lib/mol-theme/theme';
-import { ShapeRepresentation } from 'molstar/lib/mol-repr/shape/representation';
-import { Shape } from 'molstar/lib/mol-model/shape';
-import { RuntimeContext } from 'molstar/lib/mol-task';
-import { Lines } from 'molstar/lib/mol-geo/geometry/lines/lines';
-import { Mesh } from 'molstar/lib/mol-geo/geometry/mesh/mesh';
-import { LinesBuilder } from 'molstar/lib/mol-geo/geometry/lines/lines-builder';
-import { Circle } from 'molstar/lib/mol-geo/primitive/circle';
-import { transformPrimitive } from 'molstar/lib/mol-geo/primitive/primitive';
-import { MeshBuilder } from 'molstar/lib/mol-geo/geometry/mesh/mesh-builder';
-import { MarkerActions } from 'molstar/lib/mol-util/marker-action';
-import { lociLabel } from 'molstar/lib/mol-theme/label';
-import { ColorNames } from 'molstar/lib/mol-util/color/names';
-import { CustomProperty } from 'molstar/lib/mol-model-props/common/custom-property';
-
-const SharedParams = {
-    color: PD.Color(ColorNames.lightgrey),
-    radiusFactor: PD.Numeric(1.2, { min: 0.1, max: 3.0, step: 0.01 }, { description: 'Scale the radius of the membrane layer' })
-};
-
-const BilayerPlanesParams = {
-    ...Mesh.Params,
-    ...SharedParams,
-    sectorOpacity: PD.Numeric(0.5, { min: 0, max: 1, step: 0.01 }),
-};
-export type BilayerPlanesParams = typeof BilayerPlanesParams
-export type BilayerPlanesProps = PD.Values<BilayerPlanesParams>
-
-const BilayerRimsParams = {
-    ...Lines.Params,
-    ...SharedParams,
-    lineSizeAttenuation: PD.Boolean(true),
-    linesSize: PD.Numeric(0.3, { min: 0.01, max: 50, step: 0.01 }),
-    dashedLines: PD.Boolean(true),
-};
-export type BilayerRimsParams = typeof BilayerRimsParams
-export type BilayerRimsProps = PD.Values<BilayerRimsParams>
-
-const MembraneOrientationVisuals = {
-    'bilayer-planes': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerPlanesParams>) => ShapeRepresentation(getBilayerPlanes, Mesh.Utils, { modifyState: s => ({ ...s, markerActions: MarkerActions.Highlighting }), modifyProps: p => ({ ...p, alpha: p.sectorOpacity, ignoreLight: true, doubleSided: false }) }),
-    'bilayer-rims': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerRimsParams>) => ShapeRepresentation(getBilayerRims, Lines.Utils, { modifyState: s => ({ ...s, markerActions: MarkerActions.Highlighting }) })
-};
-
-export const MembraneOrientationParams = {
-    ...BilayerPlanesParams,
-    ...BilayerRimsParams,
-    visuals: PD.MultiSelect(['bilayer-planes', 'bilayer-rims'], PD.objectToOptions(MembraneOrientationVisuals)),
-};
-export type MembraneOrientationParams = typeof MembraneOrientationParams
-export type MembraneOrientationProps = PD.Values<MembraneOrientationParams>
-
-export function getMembraneOrientationParams(ctx: ThemeRegistryContext, structure: Structure) {
-    return PD.clone(MembraneOrientationParams);
-}
-
-export type MembraneOrientationRepresentation = StructureRepresentation<MembraneOrientationParams>
-export function MembraneOrientationRepresentation(ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, MembraneOrientationParams>): MembraneOrientationRepresentation {
-    return Representation.createMulti('TMDET Membrane Orientation', ctx, getParams, StructureRepresentationStateBuilder, MembraneOrientationVisuals as unknown as Representation.Def<Structure, MembraneOrientationParams>);
-}
-
-export const MembraneOrientationRepresentationProvider = StructureRepresentationProvider({
-    name: 'tmdet-membrane-orientation',
-    label: 'TMDET Membrane Orientation',
-    description: 'Displays a grid of points representing membrane layers.',
-    factory: MembraneOrientationRepresentation,
-    getParams: getMembraneOrientationParams,
-    defaultValues: PD.getDefaultValues(MembraneOrientationParams),
-    defaultColorTheme: { name: 'shape-group' },
-    defaultSizeTheme: { name: 'shape-group' },
-    isApplicable: (structure: Structure) => structure.elementCount > 0,
-    ensureCustomProperties: {
-        attach: (ctx: CustomProperty.Context, structure: Structure) => MembraneOrientationProvider.attach(ctx, structure, void 0, true),
-        detach: (data) => MembraneOrientationProvider.ref(data, false)
-    }
-});
-
-function membraneLabel(data: Structure) {
-    return `${lociLabel(Structure.Loci(data))} | TMDET Membrane Orientation`;
-}
-
-function getBilayerRims(ctx: RuntimeContext, data: Structure, props: BilayerRimsProps, shape?: Shape<Lines>): Shape<Lines> {
-    const { planePoint1: p1, planePoint2: p2, centroid, radius } = MembraneOrientationProvider.get(data).value!;
-    const scaledRadius = props.radiusFactor * radius;
-    const builder = LinesBuilder.create(128, 64, shape?.geometry);
-    getLayerCircle(builder, p1, centroid, scaledRadius, props);
-    getLayerCircle(builder, p2, centroid, scaledRadius, props);
-    return Shape.create('Bilayer rims', data, builder.getLines(), () => props.color, () => props.linesSize, () => membraneLabel(data));
-}
-
-function getLayerCircle(builder: LinesBuilder, p: Vec3, centroid: Vec3, radius: number, props: BilayerRimsProps, shape?: Shape<Lines>) {
-    const circle = getCircle(p, centroid, radius);
-    const { indices, vertices } = circle;
-    for (let j = 0, jl = indices.length; j < jl; j += 3) {
-        if (props.dashedLines && j % 2 === 1) continue; // draw every other segment to get dashes
-        const start = indices[j] * 3;
-        const end = indices[j + 1] * 3;
-        const startX = vertices[start];
-        const startY = vertices[start + 1];
-        const startZ = vertices[start + 2];
-        const endX = vertices[end];
-        const endY = vertices[end + 1];
-        const endZ = vertices[end + 2];
-        builder.add(startX, startY, startZ, endX, endY, endZ, 0);
-    }
-}
-
-const tmpMat = Mat4();
-const tmpV = Vec3();
-function getCircle(p: Vec3, centroid: Vec3, radius: number) {
-    if (Vec3.dot(Vec3.unitY, Vec3.sub(tmpV, p, centroid)) === 0) {
-        Mat4.targetTo(tmpMat, p, centroid, Vec3.unitY);
-    } else {
-        Mat4.targetTo(tmpMat, p, centroid, Vec3.unitX);
-    }
-    Mat4.setTranslation(tmpMat, p);
-    Mat4.mul(tmpMat, tmpMat, Mat4.rotX90);
-
-    const circle = Circle({ radius, segments: 64 });
-    return transformPrimitive(circle, tmpMat);
-}
-
-function getBilayerPlanes(ctx: RuntimeContext, data: Structure, props: BilayerPlanesProps, shape?: Shape<Mesh>): Shape<Mesh> {
-    const { planePoint1: p1, planePoint2: p2, centroid, radius } = MembraneOrientationProvider.get(data).value!;
-    const state = MeshBuilder.createState(128, 64, shape && shape.geometry);
-    const scaledRadius = props.radiusFactor * radius;
-    getLayerPlane(state, p1, centroid, scaledRadius);
-    getLayerPlane(state, p2, centroid, scaledRadius);
-    return Shape.create('Bilayer planes', data, MeshBuilder.getMesh(state), () => props.color, () => 1, () => membraneLabel(data));
-}
-
-function getLayerPlane(state: MeshBuilder.State, p: Vec3, centroid: Vec3, radius: number) {
-    const circle = getCircle(p, centroid, radius);
-    state.currentGroup = 0;
-    MeshBuilder.addPrimitive(state, Mat4.id, circle);
-    MeshBuilder.addPrimitiveFlipped(state, Mat4.id, circle);
-}

+ 0 - 158
src/tmdet-extension/symmetry.ts

@@ -1,158 +0,0 @@
-/**
- * Copyright (C) 2022, Protein Bioinformatics Research Group, RCNS
- *
- * Licensed under CC BY-NC 4.0, see LICENSE file for more info.
- *
- * @author Gabor Tusnady <tusnady.gabor@ttk.hu>
- * @author Csongor Gerdan <gerdan.csongor@ttk.hu>
- */
-
-import { MmcifFormat } from 'molstar/lib/mol-model-formats/structure/mmcif';
-import { Column, Table } from 'molstar/lib/mol-data/db';
-import { mmCIF_Schema } from 'molstar/lib/mol-io/reader/cif/schema/mmcif';
-import { Model } from 'molstar/lib/mol-model/structure';
-import { ModelSymmetry } from 'molstar/lib/mol-model-formats/structure/property/symmetry';
-import { PDBTMDescriptor } from './types';
-import { DebugUtil } from './debug-utils';
-
-
-export function registerTmDetSymmetry(pdbtmDescriptor: PDBTMDescriptor) {
-    ModelSymmetry.Provider.formatRegistry.remove('mmCIF');
-    const excludedChains = constructChainListFromOperations(pdbtmDescriptor);
-    ModelSymmetry.Provider.formatRegistry.add('mmCIF',  function(model: Model) {
-        return tmDetSymmetryFromMmCif(model, excludedChains);
-    });
-}
-
-function constructChainListFromOperations(pdbtmDescriptor: PDBTMDescriptor): string[] {
-    const excludedChains: string[] = [];
-    // add chain deletes
-    const biomatrix = pdbtmDescriptor.additional_entry_annotations.biomatrix;
-    if (biomatrix?.chain_deletes) {
-        biomatrix.chain_deletes.forEach(
-            chainId => excludedChains.push(chainId)
-        );
-    }
-    // exclude result of transformations
-    if (biomatrix?.matrix_list) {
-        biomatrix.matrix_list.forEach(
-            matrix => matrix.apply_to_chain_list.forEach(
-                applyItem => excludedChains.push(applyItem.new_chain_id)
-            )
-        );
-    }
-
-    return excludedChains;
-}
-
-function tmDetSymmetryFromMmCif(model: Model, excludedChains: string[]) {
-    if (!MmcifFormat.is(model.sourceData)) return;
-
-    let data = model.sourceData.data.db;
-    excludedChains = union(
-        excludedChains,
-        Array.from(data.pdbx_nonpoly_scheme.asym_id.toArray())
-    );
-
-    const updated_pdbx_struct_assembly_gen = createPdbxStructAssemblyGen(
-        data.pdbx_struct_assembly_gen,
-        excludedChains
-    );
-    DebugUtil.log('Non-poly entities:', Table.formatToString(data.pdbx_entity_nonpoly));
-    DebugUtil.log('Non-poly chains:', data.pdbx_nonpoly_scheme.asym_id.toArray());
-
-    const only_identity_operation = createPdbxStructOperList(data.pdbx_struct_oper_list);
-
-    return ModelSymmetry.fromData({
-        symmetry: data.symmetry,
-        cell: data.cell,
-        struct_ncs_oper: data.struct_ncs_oper,
-        atom_sites: data.atom_sites,
-        pdbx_struct_assembly: data.pdbx_struct_assembly,
-        pdbx_struct_assembly_gen: updated_pdbx_struct_assembly_gen,
-        pdbx_struct_oper_list: only_identity_operation
-    });
-}
-
-function createPdbxStructAssemblyGen(pdbx_struct_assembly_gen: Table<mmCIF_Schema['pdbx_struct_assembly_gen']>,
-    excludedChains: string[]): Table<mmCIF_Schema['pdbx_struct_assembly_gen']> {
-
-    const asym_id_list_column = createAsymIdColumn(
-        pdbx_struct_assembly_gen, excludedChains
-    );
-
-    // create table with new column
-    let updated_pdbx_struct_assembly_gen = Table.ofColumns(
-        pdbx_struct_assembly_gen._schema,
-        {
-            assembly_id: Column.ofStringArray([ '1' ]),
-            asym_id_list: asym_id_list_column,
-            //oper_expression: data.pdbx_struct_assembly_gen.oper_expression
-            // NOTE: we expect here pdbx_struct_assembly_gen has only one row
-            oper_expression: Column.ofStringArray([ '1' ])
-        }
-    );
-    DebugUtil.log('Orig. assembly_gen', Table.formatToString(pdbx_struct_assembly_gen));
-    DebugUtil.log('Updated assembly_gen', Table.formatToString(updated_pdbx_struct_assembly_gen));
-
-    return updated_pdbx_struct_assembly_gen;
-}
-
-function createPdbxStructOperList(pdbx_struct_oper_list: Table<mmCIF_Schema['pdbx_struct_oper_list']>):
-    Table<mmCIF_Schema['pdbx_struct_oper_list']> {
-
-    let updated_pdbx_struct_oper_list = Table.ofColumns(
-        pdbx_struct_oper_list._schema,
-        {
-            id: Column.ofStringArray([ '1' ]),
-            type: Column.ofArray({
-                array: [ 'identity operation' ],
-                schema: pdbx_struct_oper_list.type.schema
-            }),
-            name: Column.ofStringArray([ '1_555' ]),
-            symmetry_operation: Column.ofStringArray([ 'x,y,z' ]),
-            matrix:  Column.ofArray({
-                array: [[ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]],
-                schema: pdbx_struct_oper_list.matrix.schema
-            }),
-            vector: Column.ofArray({
-                array: [ [ 0, 0, 0 ] ],
-                schema: pdbx_struct_oper_list.vector.schema
-            })
-        }
-    );
-
-    DebugUtil.log('Orig. pdbx_struct_oper_list', Table.formatToString(pdbx_struct_oper_list));
-    DebugUtil.log('Updated pdbx_struct_oper_list', Table.formatToString(updated_pdbx_struct_oper_list));
-
-    return updated_pdbx_struct_oper_list;
-}
-
-function createAsymIdColumn(pdbx_struct_assembly_gen: Table<mmCIF_Schema['pdbx_struct_assembly_gen']>,
-    excludedChains: string[]) {
-
-    let asym_id_list: string[] = [];
-    for (let i = 0; i < pdbx_struct_assembly_gen._rowCount; i++) {
-        const currentAsymIdList = pdbx_struct_assembly_gen.asym_id_list.value(i);
-        asym_id_list = asym_id_list.concat(currentAsymIdList);
-    }
-    asym_id_list = minus(asym_id_list, excludedChains);
-    DebugUtil.log('Excluded chains:', excludedChains);
-    DebugUtil.log('Included chains:', asym_id_list);
-
-    return Column.ofStringListArray([ asym_id_list ]);
-}
-
-// difference of two string arrays (interpreted as sets)
-function minus(a: string[], b: string[]): string[] {
-    const b_set = new Set(b);
-    const difference = a.filter(x => !b_set.has(x));
-    return Array.from(new Set(difference).values());
-}
-
-// union of two string arrays (interpreted as sets)
-function union(a: string[], b: string[]): string[] {
-    const a_set = new Set(a);
-    b.forEach(item => a_set.add(item));
-    return Array.from(a_set.values());
-}

+ 0 - 258
src/tmdet-extension/tmdet-color-theme.ts

@@ -1,258 +0,0 @@
-/**
- * Copyright (C) 2022, Protein Bioinformatics Research Group, RCNS
- *
- * Licensed under CC BY-NC 4.0, see LICENSE file for more info.
- *
- * @author Gabor Tusnady <tusnady.gabor@ttk.hu>
- * @author Csongor Gerdan <gerdan.csongor@ttk.hu>
- */
-
-import { StructureElement, Unit } from 'molstar/lib/mol-model/structure';
-import { ColorTheme } from 'molstar/lib/mol-theme/color';
-import { ThemeDataContext } from 'molstar/lib/mol-theme/theme';
-import { Color } from 'molstar/lib/mol-util/color';
-import { ColorNames } from 'molstar/lib/mol-util/color/names';
-import { ParamDefinition as PD } from 'molstar/lib/mol-util/param-definition';
-import { Location } from 'molstar/lib/mol-model/location';
-import { ChainList, getResidue, PDBTMChain } from './types';
-import { TmDetChainListCache, TmDetDescriptorCache } from './prop';
-
-
-export type TmDetColorThemeParams = {
-    pdbtmDescriptor: any
-};
-
-export function TmDetColorTheme(
-    ctx: ThemeDataContext,
-    props: PD.Values<TmDetColorThemeParams>
-): ColorTheme<TmDetColorThemeParams> {
-    let descriptorChains: PDBTMChain[] = [];
-    let pdbtmDescriptor = props.pdbtmDescriptor;
-    const pdbId = ctx.structure?.model.entryId;
-
-    // If it is not given as parameter,
-    // but there is one in the cache for this structure.
-    if (!pdbtmDescriptor) {
-        if (pdbId) {
-            pdbtmDescriptor = TmDetDescriptorCache.get(pdbId);
-        }
-    }
-    if (pdbtmDescriptor) {
-        descriptorChains = pdbtmDescriptor.chains;
-    }
-
-    const tmType = pdbtmDescriptor.additional_entry_annotations.tm_type;
-    const chainList = createResidueListsPerChain(descriptorChains, pdbtmDescriptor.side1, tmType);
-    if (pdbId) {
-        TmDetChainListCache.set(pdbId, chainList);
-    }
-
-    return {
-        factory: TmDetColorTheme,
-        granularity: 'group', //'residue' as any,
-        color: (location: Location) => getColor(location, chainList),
-        props: props,
-        description: 'TMDet...',
-    };
-}
-
-const DefaultResidueColor = ColorNames.lightgrey;
-
-enum SiteIndexes {
-    Side1 = 0,
-    Side2 = 1,
-    TmAlpha = 2,
-    TmBeta = 3,
-    TmReentrantLoop = 4,
-    InterfacialHelix = 5,
-    UnknownLocalization = 6,
-    MembraneInside = 7,
-    Periplasm = 8
-};
-
-// Old default values - it is overwritten by ult_* CSS classes
-// See below updateSiteColors().
-const siteColors = [
-    Color.fromArray([255,100,100], 0), // Side1
-    Color.fromArray([100,100,255], 0), // Side2
-    Color.fromArray([255,255,  0], 0), // TM alpha
-    Color.fromArray([255,255,  0], 0), // TM beta
-    Color.fromArray([255,127,  0], 0), // TM re-entrant loop
-    Color.fromArray([0,255,    0], 0), // Interfacial Helix
-    Color.fromArray([196,196,196], 0), // Unknow localization
-    Color.fromArray([0,255,    0], 0), // Membrane Inside
-    Color.fromArray([255, 0, 255], 0)  // Periplasm
-];
-
-const siteCssNames = [
-    "ult_side1",
-    "ult_side2",
-    "ult_alpha",
-    "ult_beta",
-    "ult_reentrant",
-    "ult_ifh",
-    "ult_unknown",
-    "ult_membins",
-    "ult_periplasm"
-];
-
-const regionColorMapFromCss = new Map();
-
-// set default values
-siteCssNames.forEach((className, index) => {
-    regionColorMapFromCss.set(className, siteColors[index]);
-});
-
-function getColor(location: Location, chains: ChainList): Color {
-    let color = DefaultResidueColor;
-
-    // TODO: How to solve cases when chain operation occurs?
-    if (StructureElement.Location.is(location) && Unit.isAtomic(location.unit)) {
-
-        const { chainId, residueId } = getChainAndResidueIds(location);
-        color = residueColor(chains, chainId!, residueId!);
-    }
-    return color;
-}
-
-export function getChainAndResidueIds(location: Location) {
-    let chainId = undefined;
-    let residueId = undefined;
-
-    if (StructureElement.Location.is(location) && Unit.isAtomic(location.unit)) {
-        const atomicHierarchy = location.unit.model.atomicHierarchy;
-        const residueIdx = StructureElement.residueIndex(location);
-        const chainIdx = StructureElement.Location.chainIndex(location);
-
-        residueId = atomicHierarchy.residues.label_seq_id.value(residueIdx).toString();
-        chainId = atomicHierarchy.chains.label_asym_id.value(chainIdx).toString();
-    }
-    return {
-        chainId: chainId,
-        residueId: residueId
-    };
-}
-
-export function createResidueListsPerChain(chains: PDBTMChain[], side1: string|null, tmType: string) {
-
-    const chainList: ChainList = [];
-    const hasBeta = chains.some(chain => chain.additional_chain_annotations.type == "beta");
-
-    chains.forEach((chain: PDBTMChain) => {
-        const chainType = chain.additional_chain_annotations.type;
-        chainList.push({ chainId: chain.chain_label, type: chainType, residues: [] });
-        let annotationErrorLogged = false;
-        chain.residues.forEach((residue) => {
-            let siteId = residue.site_data![0].site_id_ref - 1;
-            let siteColorId = siteId;
-            if (tmType == "Tm_Alpha" && hasBeta && side1 == "Periplasm") {
-                if (siteId == SiteIndexes.Side1) {
-                    siteColorId = SiteIndexes.Periplasm;
-                } else if (siteId == SiteIndexes.Side2) {
-                    if (chainType == "non_tm" || chainType == "alpha") {
-                        siteColorId = SiteIndexes.Side1;
-                    } else if (chainType == "beta") {
-                        siteColorId = SiteIndexes.Side2;
-                    }
-                }
-            } else if (chainType == "beta") {
-                if (side1 == "Periplasm" && siteColorId == SiteIndexes.Side1
-                    || side1 == "Outside" && siteColorId == SiteIndexes.Side2) {
-                    siteColorId = SiteIndexes.Periplasm;
-                } else if (!annotationErrorLogged && side1 == "Inside" && siteColorId == SiteIndexes.Side1) {
-                    console.error(`Annotation error: beta chain has inside region ${chain.chain_label}:${residue.pdb_res_label}`);
-                    annotationErrorLogged = true;
-                }
-            }
-
-            chainList[chainList.length - 1].residues.push({
-                authId: residue.pdb_res_label,
-                siteId: siteId,
-                siteColorId: siteColorId
-            });
-        });
-    });
-
-    return chainList;
-}
-
-function residueColor(chains: ChainList, chainId: string, residueId: string): Color {
-    let color = DefaultResidueColor;
-
-    const residue = getResidue(chains, chainId, residueId);
-    if (residue) {
-        color = siteColors[residue.siteColorId];
-    }
-
-    return color;
-}
-
-// Provider
-
-export const TmDetColorThemeProvider: ColorTheme.Provider<TmDetColorThemeParams, 'tmdet-custom-color-theme'> = {
-    name: 'tmdet-custom-color-theme',
-    label: 'TMDet Topology Theme',
-    category: 'TMDet',
-    factory: TmDetColorTheme,
-    getParams: () => ({ pdbtmDescriptor: { isOptional: true } }),
-    defaultValues: { pdbtmDescriptor: undefined },
-    isApplicable: () => true,
-};
-
-
-
-// Colors from CSS rules
-
-function loadRegionColorsFromStyleSheets(prefix: string = 'ult_'): void {
-    const sheets: CSSStyleSheet[] = Array.from(document.styleSheets);
-    sheets.forEach((sheet: CSSStyleSheet) => {
-        const rules: CSSRule[] = Array.from(sheet.cssRules);
-        rules.forEach((rule: CSSRule) => fetchRule(rule, prefix));
-    });
-}
-
-export function updateSiteColors(side1: "Inside"|"Outside"|null): void {
-    if (!side1) {
-        return;
-    }
-    loadRegionColorsFromStyleSheets();
-    if (regionColorMapFromCss.size == 0) {
-        console.warn('Cannot read any region-related color rules');
-    }
-
-    siteCssNames.forEach((ultClassName, index) => {
-        const color = regionColorMapFromCss.get(ultClassName);
-        if (color != null) {
-            siteColors[index] = color;
-        }
-    });
-
-    const inside = regionColorMapFromCss.get("ult_inside");
-    const outside = regionColorMapFromCss.get("ult_outside");
-    if (side1 == "Inside") {
-        siteColors[SiteIndexes.Side1] = inside;
-        siteColors[SiteIndexes.Side2] = outside;
-    } else if (side1 == "Outside") {
-        siteColors[SiteIndexes.Side1] = outside;
-        siteColors[SiteIndexes.Side2] = inside;
-    }
-}
-
-function fetchRule(rule: CSSRule, prefix: string) {
-    let styleRule = rule as CSSStyleRule;
-    if (styleRule.selectorText?.startsWith('.' + prefix)) {
-        const value = styleRule.style.getPropertyValue('fill');
-        const color: Color = getStyleColor(value);
-        const key = styleRule.selectorText.slice(1);
-        regionColorMapFromCss.set(key, color);
-    }
-}
-
-function getStyleColor(cssColorText: string): Color {
-    const values = cssColorText?.match(/\d+/g);
-    let intValues = values?.map(value => parseInt(value));
-    if (!intValues) {
-        intValues = [ 0, 0, 0 ];
-    }
-    return Color.fromArray(intValues, 0);
-}

+ 0 - 181
src/tmdet-extension/transformation.ts

@@ -1,181 +0,0 @@
-/**
- * Copyright (C) 2022, Protein Bioinformatics Research Group, RCNS
- *
- * Licensed under CC BY-NC 4.0, see LICENSE file for more info.
- *
- * @author Gabor Tusnady <tusnady.gabor@ttk.hu>
- * @author Csongor Gerdan <gerdan.csongor@ttk.hu>
- */
-
-import { MolScriptBuilder as MS } from 'molstar/lib/mol-script/language/builder';
-import { PluginUIContext } from 'molstar/lib/mol-plugin-ui/context';
-import { Mat4, Vec3 } from 'molstar/lib/mol-math/linear-algebra';
-import { PDBTMDescriptor, PDBTMTransformationMatrix, PMS } from './types';
-import { createStructureRepresentationParams } from 'molstar/lib/mol-plugin-state/helpers/structure-representation-params';
-import { StateTransforms } from 'molstar/lib/mol-plugin-state/transforms';
-import { StateObjectRef, StateBuilder } from 'molstar/lib/mol-state';
-import { Expression } from 'molstar/lib/mol-script/language/expression';
-import { MembraneOrientation } from './prop';
-import { TmDetColorThemeProvider } from './tmdet-color-theme';
-import { DebugUtil } from './debug-utils';
-
-export function applyTransformations(plugin: PluginUIContext, pdbtmDescriptor: PDBTMDescriptor) {
-    const annotations = pdbtmDescriptor.additional_entry_annotations;
-
-    const membraneTransformation = transformationForStateTransform(pdbtmDescriptor.additional_entry_annotations.membrane.transformation_matrix);
-
-    if (annotations?.biomatrix?.matrix_list) {
-        annotations.biomatrix.matrix_list.forEach(function(mx) {
-            mx.apply_to_chain_list.forEach(function(chainPair) {
-                let id  = chainPair.chain_id;
-                let newId = chainPair.new_chain_id;
-                if (annotations.biomatrix.chain_deletes?.includes(newId)) {
-                    DebugUtil.log(`${id} -> ${newId} transformation skipped due to delete rule`);
-                    return;
-                }
-                const mtx = transformationForStateTransform(mx.transformation_matrix);
-                const composedTransformation = Mat4.mul(Mat4(), membraneTransformation, mtx);
-                chainTransformation(plugin, composedTransformation, id, newId);
-                // await plugin.runTask(Task.create(`TMDET: Transform '${id}' into '${newId}'`, async () => {
-                //     chainTransformation(plugin, mx.transformation_matrix, id, newId);
-                // }));
-            });
-        });
-    }
-
-    // WARNING: the components cannot be accessed here (created by chainTransformations in the above loop)
-    //          Maybe due to some kind of synchronization behavior.
-    //          plugin.runTask with "await" also cannot synchronize here.
-    //
-    // So this function call transforms only already existing components due to a side effect of another issue.
-    transformWholeModel(plugin, pdbtmDescriptor.additional_entry_annotations.membrane.transformation_matrix);
-    // await plugin.runTask(Task.create(`TMDET: Apply membrane transformation`, async () => {
-    //     transformWholeModel(plugin, pdbtmDescriptor.additional_entry_annotations.membrane.transformation_matrix);
-    // }));
-
-}
-
-export function transformWholeModel(plugin: PluginUIContext, membraneMatrix: PDBTMTransformationMatrix) {
-    //
-    // membrane transformation
-    //
-    const membraneTransformation = transformationForStateTransform(membraneMatrix);
-
-    // transform each component
-    DebugUtil.log("STRUCTURES", getCurrentHierarchy(plugin).structures);
-    getCurrentHierarchy(plugin).structures[0].components.forEach(component => {
-        const structure: StateObjectRef<PMS> = component.cell;
-        const update: StateBuilder.To<any, any> = plugin.build().to(structure);
-
-        const label = component.cell.obj!.label.toUpperCase();
-        DebugUtil.log("memb.transform of", label, component.cell.obj?.id);
-        DebugUtil.log(`${label} component.cell.obj:`, component.cell.obj);
-        // DebugUtil.log(`${label} component:`, component);
-
-        update
-            .apply(StateTransforms.Model.TransformStructureConformation, {
-                "transform": { name: "matrix", params: { data: membraneTransformation, transpose: false } }
-            });
-        update.commit();
-    });
-}
-
-/**
- * Perform transformation on a chain.
- *
- * @param plugin UI context
- * @param transformationMatrix 4x4 matrix describes transformation and translation
- * @param chainId Id of chain to be selected for transformation
- */
-export function chainTransformation(plugin: PluginUIContext, transformationMatrix: Mat4, chainId: string, newId: string): void {
-    const query: Expression = getChainExpression(chainId);
-
-//    const transformation = transformationForStateTransform(transformationMatrix);
-    const transformation = transformationMatrix;
-    const structure: StateObjectRef<PMS> = plugin.managers.structure.hierarchy.current.models[0].structures[0].cell;
-    const update: StateBuilder.To<any, any> = plugin.build().to(structure);
-
-    update
-        .apply(
-            StateTransforms.Model.StructureSelectionFromExpression,
-            { label: newId, expression: query }
-        )
-        .apply(StateTransforms.Model.TransformStructureConformation, {
-            "transform": { name: "matrix", params: { data: transformation, transpose: false } }
-        })
-        .apply(
-            StateTransforms.Representation.StructureRepresentation3D,
-            createStructureRepresentationParams(plugin, structure.obj?.data, {
-                type: 'cartoon',
-                color: TmDetColorThemeProvider.name as any //, colorParams: { pdbtmDescriptor }
-            })
-        );
-    update.commit();
-    DebugUtil.log(`${chainId}->${newId} DONE`);
-}
-
-// function vadd(a: Vec3, b: Vec3): Vec3 {
-//     return Vec3.add(Vec3.zero(), a, b);
-// }
-
-function vneg(u: Vec3): Vec3 {
-    return Vec3.negate(Vec3.zero(), u);
-}
-
-export function createMembraneOrientation(pdbtmDescriptor: PDBTMDescriptor): MembraneOrientation {
-    const membrane = pdbtmDescriptor.additional_entry_annotations.membrane;
-
-    const membraneNormal: Vec3 = Vec3.fromObj(membrane.normal);
-    const result: MembraneOrientation = {
-        planePoint1: membraneNormal,
-        planePoint2: vneg(membraneNormal),
-        centroid: Vec3.zero(),
-        normalVector: membraneNormal,
-
-        // (NOTE: the TMDET extension calculates and sets it during applying preset)
-        radius: membrane.radius
-    };
-
-    return result;
-}
-
-export function transformationForStateTransform(tmatrix: PDBTMTransformationMatrix): Mat4 {
-    // matrix expected in column-major order
-    const mx: Mat4 = Mat4.fromArray(Mat4.zero(),
-        [
-            tmatrix.rowx.x, tmatrix.rowy.x, tmatrix.rowz.x, 0,
-            tmatrix.rowx.y, tmatrix.rowy.y, tmatrix.rowz.y, 0,
-            tmatrix.rowx.z, tmatrix.rowy.z, tmatrix.rowz.z, 0,
-                         0,              0,              0, 1
-        ], 0
-    );
-    Mat4.setTranslation(mx, Vec3.create(
-        tmatrix.rowx.t,
-        tmatrix.rowy.t,
-        tmatrix.rowz.t
-    ));
-    // TODO: DebugUtil.log('MAT4\n', Mat4.makeTable(mx));
-    return mx;
-}
-
-export function getAtomGroupExpression(chainId: string, auth_array: number[]): Expression {
-    // TODO DebugUtil.log('auth_array:', auth_array);
-    const query: Expression =
-        MS.struct.generator.atomGroups({
-            'residue-test': MS.core.set.has([MS.set( ...auth_array ), MS.ammp('auth_seq_id')]),
-            'chain-test': MS.core.rel.eq([chainId, MS.ammp('label_asym_id')])
-        });
-    return query;
-}
-
-export function getChainExpression(chainId: string): Expression {
-    const query: Expression =
-        MS.struct.generator.atomGroups({
-            'chain-test': MS.core.rel.eq([chainId, MS.ammp('label_asym_id')])
-        });
-    return query;
-}
-
-export function getCurrentHierarchy(plugin: PluginUIContext) {
-    return plugin.managers.structure.hierarchy.current;
-}

+ 0 - 100
src/tmdet-extension/types.ts

@@ -1,100 +0,0 @@
-/**
- * Copyright (C) 2022, Protein Bioinformatics Research Group, RCNS
- *
- * Licensed under CC BY-NC 4.0, see LICENSE file for more info.
- *
- * @author Gabor Tusnady <tusnady.gabor@ttk.hu>
- * @author Csongor Gerdan <gerdan.csongor@ttk.hu>
- */
-
-import { PluginStateObject } from "molstar/lib/mol-plugin-state/objects";
-import { StateObject, StateTransformer } from 'molstar/lib/mol-state';
-import { StateObjectSelector } from "molstar/lib/mol-state/object";
-
-export type PMS = PluginStateObject.Molecule.Structure;
-
-export type PDBTMChain = {
-    chain_label: string,
-    additional_chain_annotations: {
-        type: string,
-        num_tm: number
-    },
-    residues: {
-        pdb_res_label?: string,
-        aa_type?: string,
-        site_data?: { site_id_ref: number, confidence_classification: string }[]
-    }[]
-};
-export type PDBTMRegion = { site: string, auth_ids: number[], color: number[] };
-export type PDBTMVec3 = { x: number, y: number, z: number };
-type PDBTMTransformationMatrixRow = { x: number, y: number, z: number, t: number };
-export type PDBTMTransformationMatrix = {
-    rowx: PDBTMTransformationMatrixRow,
-    rowy: PDBTMTransformationMatrixRow,
-    rowz: PDBTMTransformationMatrixRow
-};
-export type PDBTMDescriptor = {
-    pdb_id: string,
-    side1: "Inside"|"Outside"|null,
-    chains: PDBTMChain[],
-    site: { site_id: number, label: string }[],
-    additional_entry_annotations: {
-        tm_type: string,
-        membrane: {
-            normal: PDBTMVec3,
-            transformation_matrix: PDBTMTransformationMatrix,
-            radius: number
-        },
-        biomatrix: {
-            chain_deletes: string[],
-            matrix_list: {
-                matrix_id: string,
-                apply_to_chain_list: {
-                    chain_id: string,
-                    new_chain_id: string
-                }[],
-                transformation_matrix: PDBTMTransformationMatrix
-            }[]
-        }
-    }
-};
-
-type StructureComponentType = StateObjectSelector<
-        PMS,
-        StateTransformer<StateObject<any, StateObject.Type<any>>,
-        StateObject<any, StateObject.Type<any>>, any>
-    > | undefined;
-
-export type ComponentsType = { polymer: StructureComponentType; ligand: StructureComponentType; water: StructureComponentType };
-
-// for coloring and labeling
-export type ResidueItem = {
-    authId: string|undefined,
-    siteId: number,     // for labels
-    siteColorId: number // for site colors
-};
-export type Chain = {
-    chainId: string,
-    type: string,
-    residues: ResidueItem[]
-};
-export type ChainList = Chain[];
-
-export function getResidue(chains: ChainList, chainId: string, residueId: string): ResidueItem|undefined {
-    let result = undefined;
-    const chain = getChain(chains, chainId);
-    if (chain) {
-        result = chain.residues.filter((res) => res.authId === residueId)[0];
-    }
-
-    return result;
-}
-
-export function getChain(chains: ChainList, chainId: string): Chain|undefined {
-    let result = undefined;
-    const chain = chains.filter((chain) => chain.chainId === chainId)[0];
-    if (chain) {
-        result = chain;
-    }
-    return result;
-}