partridgejiang / Kekule.js

A Javascript cheminformatics toolkit.
http://partridgejiang.github.io/Kekule.js
MIT License
248 stars 61 forks source link

Error on Kekule.Indigo.enable() #190

Open dapalmi opened 3 years ago

dapalmi commented 3 years ago

Hi,

I am using the Chem Composer. I am loading following files from the dist folder: kekule.min.js kekule.css

I try to execute following steps:
var composer = this.getComposer('myComposer);
var chemDoc = composer.getChemObj();
var mol = Kekule.IO.saveFormatData(chemDoc, 'mol');
var smiles = Kekule.IO.saveFormatData(chemDoc, 'smi');
var molChemDoc = Kekule.IO.loadFormatData(mol, 'mol');
Kekule.Indigo.enable();
var smilesChemDoc = Kekule.IO.loadFormatData(smiles, 'smi');

But I get an error on Kekule.Indigo.enable()

ERROR TypeError: Cannot read property 'useMinFile' of null at Object.Kekule.Indigo.getIndigoPath (kekule.min.js:1) at Object.Kekule.Indigo.getIndigoScriptUrl (kekule.min.js:1) at Object.Kekule.Indigo.loadIndigoScript (kekule.min.js:1) at Object.enable (kekule.min.js:1)

partridgejiang commented 3 years ago

Hi @dapalmi, it seems that the script path is not recognized properly. Does the script is loaded in page by something like <script src="kekule.min.js"></script>? Or loaded by other methods? By the way, Kekule.Indigo.enable() is an async method, since it need to load and compile indigo.wasm is an asynchronous way. So it is better to use the following code:

Kekule.Indigo.enable(function(error){
  if (!error)
    var smilesChemDoc = Kekule.IO.loadFormatData(smiles, 'smi');
});
dapalmi commented 3 years ago

Hi @partridgejiang. Thanks for the prompt response. You are right. That might be the problem. I am using your JavaScript toolkit in an Angular application. I load the kekule.min.js via the script configuration (Angular Script Configuration). Do you have any advise for Angular applications? Which additional files are needed? Which path is expected? Thanks again

partridgejiang commented 3 years ago

Hi @dapalmi, please check the latest dist files, they may solve the path problem. However, if it still fails to recognize the script path, you can now set it manually:

Kekule.scriptSrcInfo.setValue('path', 'Your/Path/To/Kekule.js/');  
  // set the path where kekule.min.js located, and indigo.js/wasm should be under Your/Path/To/Kekule.js/extra/
Kekule.Indigo.enable(function(error){
  if (!error)
    var smilesChemDoc = Kekule.IO.loadFormatData(smiles, 'smi');
});
dapalmi commented 3 years ago

@partridgejiang, thanks a lot. That worked! For anyone else having this issue in an Angular application: I load the main kekule.min.js in the angular.json via the script configuration:

"scripts": [
    "src/kekule/kekule.min.js"
]

Then when using extra features like Indigo I created following hierarchy in the assets folder: assets/kekule/extra Then I copied all the js files from the extra folder there and load them via the assets configuration:

"assets": [
    "src/favicon.ico",
    "src/assets"
]

Finally I only had to set the path before calling e.g. Kekule.Indigo.enable(): Kekule.scriptSrcInfo.setValue('path', '/assets/kekule/');

dapalmi commented 3 years ago

@partridgejiang, thanks again for your support. I have one last question regarding SMILES in Kekule:

I am a software developer. Not a chemist. So excuse me if this question is stupid. For example when I create a SMILES from a ChemDoc via Kekule.IO.saveFormatData(chemDoc, 'smi') for Benzene, I get following SMILES:

c1ccccc1

But when I try to reverse this into a ChemDoc and load it e.g. into the ChemComposer like this ...

var chemDoc = Kekule.IO.loadFormatData(smiles, 'smi');
var composer = Kekule.Widget.getWidgetById(composerWidgetId);
composer.setChemObj(chemDoc);

... then I get following structure: image Even when I try to change the SMILES to uppercase (C1CCCCC1) I get following structure: image Only if I add the "equal" characters (C1=CC=CC=C1) I get the original structure: image Am I missing something here?

partridgejiang commented 3 years ago

@dapalmi, actually the structures of https://user-images.githubusercontent.com/13333306/94030450-d4c23400-fd8b-11ea-9ee5-9a8179df6ba6.png and https://user-images.githubusercontent.com/13333306/94030805-3a162500-fd8c-11ea-92c0-d9bbc7bd91f8.png are identical in chemistry, both of them represent benzene. The former marks the ring with aromatic bonds while the latter with single-double bonds (classic Kekule form). Additionally, there are build-in functions in Kekule.js to convert between those forms:

var molecule = Kekule.IO.loadFormatData('c1ccccc1', 'smi');  // benzene loaded from SMILES by Indigo are in aromatic bond form defaultly
molecule.kekulize();  // turn it to classic Kekule form with single-double bonds
// molecule.hucklize();  // a reversed operation, turn back into the aromatic bonds form
var composer = Kekule.Widget.getWidgetById(composerWidgetId);
composer.setChemObj(molecule);
palkx commented 3 years ago

Hi @partridgejiang, can you also give some advice on enabling Indigo module with ES6 syntax? I am importing in react, installed via npm.

import Kekule from 'kekule/dist/kekule.min.js';
import 'kekule/dist/themes/default/kekule.css';

But i can't get Indigo module to work with it. Also Kekule.scriptScrInfo is null. Thanks! I can edit webpack config, if i need to.

partridgejiang commented 3 years ago

Hi @mikkra, Kekule.js installed with npm is the stable but not the latest distribution. Please download the dist files from this repository and replace the ones in node_modules directory.

palkx commented 3 years ago

@partridgejiang same problem with latest version from repository. I am exposed indigo.js files, and it successfully loading them ( actually latest version trying to import only indigo.js), but Kekule.Indigo.isScriptLoaded() are still false. Also i am started getting weird errors on latest commit about Kekule.ChemWidget.Viewer:

Uncaught TypeError: Cannot read property 'apply' of undefined
    at Object.s [as Viewer] (kekule.min.js:1)
    at <anonymous>:1:19

Continuing to make it working... :)

palkx commented 3 years ago

@partridgejiang So, problem that is Kekule.EmscriptenUtils._getActualModule('IndigoModule'); returning false. I assume this is because it have wrong context, can be this related to webpack config? If i am not wrong it should receive window object as this, but it resolve just an empty object.

palkx commented 3 years ago

So, i solved this. I created fork, in which i added functions to expose/update context, and i manually setting execution context. (changes). I can create a PR with it, but i don't think such functions needed in this project. @partridgejiang Tell me if you want to merge them)

partridgejiang commented 3 years ago

@mikkra Sorry for the delaying of reply and thanks a lot for your efforts. Inspired by your solution, several functions has been added now for the users to manually controls the emscripten compiled modules:

You can got those updates from the latest dist files, enjoy, :).