luna215 / molstar

A comprehensive macromolecular library
https://molstar.org
MIT License
0 stars 0 forks source link

push atom elements to array instead of logging them to the console #2

Open m-iguel opened 1 year ago

m-iguel commented 1 year ago

Hey,

It's-a me, Miguel!!

I'm sorry to keep bothering but I thought I might take your word and ask future questions.

I modified the code in the index.js file to render what I am looking for to then modify the rest. However, I am having some trouble with creating an array of atoms. So here I will post the code of the index.js file:

/**
 * Copyright (c) 2019-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
 *
 * @author Alexander Rose <alexander.rose@weirdbyte.de>
 */
import { __assign, __awaiter, __generator } from "tslib";
import { createPluginUI } from '../../mol-plugin-ui/react18';
import { DefaultPluginUISpec } from '../../mol-plugin-ui/spec';
import { PluginCommands } from '../../mol-plugin/commands';
import { Asset } from '../../mol-util/assets';
import { Color } from '../../mol-util/color';
import './index.html';
import { Structure } from '../../mol-model/structure';
import { StructureElement, toStructureElementLoci } from '../../mol-model/structure';

require('mol-plugin-ui/skin/light.scss');
var Canvas3DPresets = {
    illustrative: {
        canvas3d: {
            postprocessing: {
                occlusion: {
                    name: 'on',
                    params: {
                        samples: 32,
                        multiScale: { name: 'off', params: {} },
                        radius: 5,
                        bias: 0.8,
                        blurKernelSize: 15,
                        resolutionScale: 1,
                        color: Color(0x000000),
                    }
                },
                outline: {
                    name: 'on',
                    params: {
                        scale: 1,
                        threshold: 0.33,
                        color: Color(0x000000),
                        includeTransparent: true,
                    }
                },
                shadow: {
                    name: 'off',
                    params: {}
                },
            },
            renderer: {
                ambientIntensity: 1.0,
                light: []
            }
        }
    }
};

var LightingDemo = /** @class */ (function () {
    function LightingDemo() {
        this.radius = 5;
        this.bias = 1.1;
        this.preset = 'illustrative';
        this.atoms = [];

    }
    LightingDemo.prototype.init = function (target) {
        return __awaiter(this, void 0, void 0, function () {
            var _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        _a = this;
                        return [4 /*yield*/, createPluginUI(typeof target === 'string' ? document.getElementById(target) : target, __assign(__assign({}, DefaultPluginUISpec()), { layout: {
                                    initial: {
                                        isExpanded: false,
                                        showControls: false
                                    },
                                }, components: {
                                    controls: { left: 'none', right: 'none', top: 'none', bottom: 'none' }
                                } }))];
                    case 1:
                        _a.plugin = _b.sent();
                        return [2 /*return*/];
                }
            });
        });
    };
    var atoms = [];

    LightingDemo.prototype.load = function (_a) {
        var _b;
        var url = _a.url, _c = _a.format, format = _c === void 0 ? 'mmcif' : _c, _d = _a.isBinary, isBinary = _d === void 0 ? true : _d, _e = _a.assemblyId, assemblyId = _e === void 0 ? '' : _e;
        return __awaiter(this, void 0, void 0, function () {
            var data, trajectory, model, structure, polymer;
            // Create an empty array to store atoms

            return __generator(this, function (_f) {
                switch (_f.label) {
                    case 0: return [4 /*yield*/, this.plugin.clear()];
                    case 1:
                        _f.sent();
                        return [4 /*yield*/, this.plugin.builders.data.download({ url: Asset.Url(url), isBinary: isBinary }, { state: { isGhost: true } })];
                    case 2:
                        data = _f.sent();
                        return [4 /*yield*/, this.plugin.builders.structure.parseTrajectory(data, format)];
                    case 3:
                        trajectory = _f.sent();
                        return [4 /*yield*/, this.plugin.builders.structure.createModel(trajectory)];
                    case 4:
                        model = _f.sent();
                        return [4 /*yield*/, this.plugin.builders.structure.createStructure(model, assemblyId ? { name: 'assembly', params: { id: assemblyId } } : { name: 'model', params: {} })];
                    case 5:
                        structure = _f.sent();
                        return [4 /*yield*/, this.plugin.builders.structure.tryCreateComponentStatic(structure, 'polymer')];
                    case 6:
                        polymer = _f.sent();
                        if (!polymer) return [3 /*break*/, 8];
                        return [4 /*yield*/, this.plugin.builders.structure.representation.addRepresentation(polymer, { type: 'cartoon', color: 'illustrative' })];
                    case 7:
                        _f.sent();
                        _f.label = 8;
                    case 8: 
                        Structure.eachAtomicHierarchyElement((_b = this.plugin.managers.structure.hierarchy.selection.structures[0].cell.obj) === null || _b === void 0 ? void 0 : _b.data, {
                            // Instead of logging the atom, push it to the atoms array
                            atom: function (a) { this.atoms.push(a); console.log(a)}.bind(this)
                        });
                        // Add distance measurement
                        console.log(this.atoms)
                        console.log(typeof this.atoms[0])
                        if (this.atoms.length >= 100) {
                            // Convert atoms to loci
                            var lociA = StructureElement.Loci(structure, [this.atoms[3]]);

                            var lociB = StructureElement.Loci(structure, [this.atoms[99]]);
                            console.log(structure)
                            console.log(lociA)
                            console.log(lociB)

                            // Pass loci to addDistance
                            this.plugin.managers.structure.measurement.addDistance(lociA, lociB, {
                                label: 'Distance 1-100',
                                lineParams: {
                                    alpha: 1,
                                    color: 0xff0000,
                                    sizeAttenuation: true
                                },
                                labelParams: {
                                    attachment: 'end',
                                    yOffset: 1
                                }
                            });
                        }
                        return [2 /*return*/];
                }
            });
        });
    };

    return LightingDemo; 
}());
window.LightingDemo = new LightingDemo();

The thing is that, when you log any element of the atoms array in the console, all of them show that they are the same element, so afterwards, the lociA and lociB objects are also equal and that is why I think the distance measurement is not being rendered, because the starting and ending point is the same. This is what I think is happening, it might as well be something else.

Anyway, I post this here, because even though I know you are not that familiar with the measurementManager class in molstar, you are familiar with this code and might spot something I don't.

Just for reference, I will leve here the sourcecode of the addDistance function (https://github.com/molstar/molstar/blob/master/src/mol-plugin-state/manager/structure/measurement.ts#L97)

I think this approach might be ok, in this case I am trying to join atoms 3 and 100, but for some reason I don't seem to create the atoms array properly. Do you see any reason for this? Would you try a different approach?

I'm sorry to bother, but I'd love to hear from you :)

Thanks,

Miguel

luna215 commented 1 year ago

@M-iguel You don't want to modify the index.js file directly. If you run npm run watch-playground, this automatically updates the index.js file whenever you make changes to src/apps/playground/index.ts.

I also checked it out, and you're right. It seems that converting the atom to a Loci type produces the same Loci (this could be a bug or we could be doing it wrong). I think another approach might iterating through the residues instead of the atoms. Here's what I got:

https://github.com/luna215/molstar/assets/7971405/de25faa6-dea4-4592-9dc4-69ab545471f0

Check out the pull request to see the code changes: https://github.com/luna215/molstar/pull/3