/*************************************************************************
* *
* This file is part of the 20n/act project. *
* 20n/act enables DNA prediction for synthetic biology/bioengineering. *
* Copyright (C) 2017 20n Labs, Inc. *
* *
* Please direct all queries to act@20n.com. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
*************************************************************************/
package com.act.biointerpretation.l2expansion;
import chemaxon.calculations.clean.Cleaner;
import chemaxon.formats.MolFormatException;
import chemaxon.reaction.ReactionException;
import chemaxon.struc.Molecule;
import chemaxon.struc.MoleculeGraph;
import com.act.analysis.chemicals.molecules.MoleculeExporter;
import com.act.analysis.chemicals.molecules.MoleculeFormat;
import com.act.analysis.chemicals.molecules.MoleculeFormat$;
import com.act.biointerpretation.Utils.ReactionProjector;
import com.act.biointerpretation.sars.Sar;
import com.act.biointerpretation.sars.SerializableReactor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* Generates all predictions for a given PredictionSeed.
*/
public class AllPredictionsGenerator implements PredictionGenerator {
private String moleculeFormat;
private static final Integer CLEAN_DIMENSION = 2;
final ReactionProjector projector;
Integer nextUid = 0; // Keeps track of the next available unique id to assign to a prediction
public AllPredictionsGenerator(ReactionProjector projector) {
this.projector = projector;
this.moleculeFormat = MoleculeFormat.stdInchi$.MODULE$.toString();
}
// Allow for the caller to change the format.
public AllPredictionsGenerator(ReactionProjector projector, String format) {
this.projector = projector;
moleculeFormat = format;
}
@Override
public List<L2Prediction> getPredictions(PredictionSeed seed) throws IOException, ReactionException {
List<Molecule> substrates = seed.getSubstrates();
cleanAndAromatize(substrates);
List<Sar> sars = seed.getSars();
SerializableReactor reactor = seed.getRo();
// If one or more SARs are supplied, test them before applying the reactor.
for (Sar sar : sars) {
if (!sar.test(substrates)) {
return Collections.emptyList();
}
}
Molecule[] substratesArray = substrates.toArray(new Molecule[substrates.size()]);
try {
Map<Molecule[], List<Molecule[]>> projectionMap =
projector.getRoProjectionMap(substratesArray, reactor.getReactor());
return getAllPredictions(projectionMap, seed.getProjectorName());
} catch (ReactionException e) {
StringBuilder builder = new StringBuilder();
builder.append(e.getMessage())
.append(": substrates, reactor: ").append(getMoleculeStrings(substratesArray))
.append(",").append(reactor.getReactorSmarts());
throw new ReactionException(builder.toString());
}
}
/**
* Returns all predictions corresponding to a given projection map
*
* @param projectionMap The map from substrates to products.
* @return The list of predictions.
* @throws IOException
*/
private List<L2Prediction> getAllPredictions(Map<Molecule[], List<Molecule[]>> projectionMap,
String name) throws IOException {
List<L2Prediction> result = new ArrayList<>();
for (Molecule[] substrates : projectionMap.keySet()) {
List<L2PredictionChemical> predictedSubstrates =
L2PredictionChemical.getPredictionChemicals(getMoleculeStrings(substrates));
for (Molecule[] products : projectionMap.get(substrates)) {
List<L2PredictionChemical> predictedProducts =
L2PredictionChemical.getPredictionChemicals(getMoleculeStrings(products));
L2Prediction prediction = new L2Prediction(nextUid, predictedSubstrates, name, predictedProducts);
result.add(prediction);
nextUid++;
}
}
return result;
}
/**
* Translate an array of Chemaxon Molecules into a List of their string representations
*
* @param mols An array of molecules.
* @return An array of inchis corresponding to the supplied molecules.
*/
private List<String> getMoleculeStrings(Molecule[] mols) throws IOException {
List<String> moleculeStrings = new ArrayList<>();
MoleculeFormat.MoleculeFormatType moleculeFormat = MoleculeFormat$.MODULE$.getName(this.moleculeFormat);
for (Molecule mol : mols) {
// Grabs the string through the exporter.
// Default is "inchi:AuxNone,SAbs,Woff", which means no aux information and absolute stereo.
moleculeStrings.add(MoleculeExporter.exportMolecule(mol, moleculeFormat));
}
return moleculeStrings;
}
/**
* Aromatizes all molecules in the input array
*
* @param molecules Molecules to aromatize.
* @throws MolFormatException
*/
private void cleanAndAromatize(List<Molecule> molecules) throws MolFormatException {
for (Molecule mol : molecules) {
mol.aromatize(MoleculeGraph.AROM_BASIC);
Cleaner.clean(mol, CLEAN_DIMENSION);
}
}
}