partridgejiang / Kekule.js

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

Is it possible to get formula/equation for a reaction? #225

Closed weasteam closed 3 years ago

weasteam commented 3 years ago

A formula can be generated for a molecular (https://www.npmjs.com/package/kekule), is it possible to get the formula/equation for a reaction?

partridgejiang commented 3 years ago

The reactants and products of a reaction are all molecules, so their formulas can be obtained with codes below:

let formulas = {'reactants': [], 'products': []};
for (let i = 0, l = reaction.getReactantCount(); i < l; ++i)
{
  let reactant = reaction.getReactantAt(i);  // reactant is an instance of molecule
  formulas.reactants.push(reactant.calcFormula());
}
for (let i = 0, l = reaction.getProductCount(); i < l; ++i)
{
  let reactant = reaction.getProductAt(i);  // reactant is an instance of molecule
  formulas.reactants.push(reactant.calcFormula());
}
weasteam commented 3 years ago

Thanks @partridgejiang

In your example code, how can I get the reaction? I have a reaction in the composer, how can I get the reaction from the composer?

var chemDoc = composer.getChemObj();

partridgejiang commented 3 years ago

The chemDoc from composer is actually an instance of ChemDocument (not Reaction). Each child object (including molecules) can be accessed by the getChildAt method of ChemDocument:

var chemDoc = composer.getChemObj();
var formulas = [];
for (var i = 0, l = chemDoc.getChildCount(); i < l; ++i)
{
  var child = chemDoc.getChildAt(i);
  if (child instanceof Kekule.Molecule)
  {
    formulas.push(child.calcFormula());
  }
}

Another approach is to utilize the iterateChildren method of ChemDocument:

var chemDoc = composer.getChemObj();
var formulas = [];
chemDoc.iterateChildren(function(child){
  if (child instanceof Kekule.Molecule)
  {
    formulas.push(child.calcFormula());
  }
});
weasteam commented 3 years ago

Thanks @partridgejiang

The first one works for me. Here is the code for those people looking for something similar:

        var chemDoc = composer.getChemObj();
        var formula = "";
        for (var i = 0, l = chemDoc.getChildCount(); i < l; ++i){
            var child = chemDoc.getChildAt(i);
            if (child instanceof window.Kekule.Molecule){
                formula = `${formula}${child.calcFormula().text}`;
            }
            else if (child instanceof window.Kekule.Glyph.AddSymbol){
                formula = `${formula} + `;
            }
            else if (child instanceof window.Kekule.Glyph.ReactionArrow){
                formula = `${formula} = `;
            }
        }