package com.plectix.simulator.parser.builders; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import com.plectix.simulator.interfaces.ConnectedComponentInterface; import com.plectix.simulator.interfaces.ObservableInterface; import com.plectix.simulator.parser.DocumentFormatException; import com.plectix.simulator.parser.ParseErrorException; import com.plectix.simulator.parser.abstractmodel.ModelPerturbation; import com.plectix.simulator.parser.abstractmodel.perturbations.LinearExpressionMonome; import com.plectix.simulator.parser.abstractmodel.perturbations.ModelLinearExpression; import com.plectix.simulator.parser.abstractmodel.perturbations.conditions.ModelConjuctionCondition; import com.plectix.simulator.parser.abstractmodel.perturbations.conditions.ModelSpeciesCondition; import com.plectix.simulator.parser.abstractmodel.perturbations.conditions.ModelTimeCondition; import com.plectix.simulator.parser.abstractmodel.perturbations.conditions.PerturbationCondition; import com.plectix.simulator.parser.abstractmodel.perturbations.modifications.AbstractOnceModification; import com.plectix.simulator.parser.abstractmodel.perturbations.modifications.ModelRateModification; import com.plectix.simulator.parser.abstractmodel.perturbations.modifications.ModificationType; import com.plectix.simulator.parser.abstractmodel.perturbations.modifications.PerturbationModification; import com.plectix.simulator.simulationclasses.perturbations.AbstractModification; import com.plectix.simulator.simulationclasses.perturbations.AddOnceModification; import com.plectix.simulator.simulationclasses.perturbations.ComplexCondition; import com.plectix.simulator.simulationclasses.perturbations.ComplexPerturbation; import com.plectix.simulator.simulationclasses.perturbations.ConditionInterface; import com.plectix.simulator.simulationclasses.perturbations.DeleteOnceModification; import com.plectix.simulator.simulationclasses.perturbations.PerturbationRule; import com.plectix.simulator.simulationclasses.perturbations.RateModification; import com.plectix.simulator.simulationclasses.perturbations.SpeciesCondition; import com.plectix.simulator.simulationclasses.perturbations.TimeCondition; import com.plectix.simulator.simulationclasses.perturbations.util.LinearExpression; import com.plectix.simulator.simulationclasses.perturbations.util.VectorObservable; import com.plectix.simulator.simulationclasses.perturbations.util.VectorRule; import com.plectix.simulator.simulator.KappaSystem; import com.plectix.simulator.simulator.SimulationArguments; import com.plectix.simulator.simulator.SimulationData; import com.plectix.simulator.staticanalysis.Agent; import com.plectix.simulator.staticanalysis.Rule; import com.plectix.simulator.util.SpeciesManager; final class PerturbationsBuilder { private final SubstanceBuilder substanceBuilder; private final SimulationArguments simulationArguments; private final KappaSystem kappaSystem; public PerturbationsBuilder(SimulationData simulationData) { this.kappaSystem = simulationData.getKappaSystem(); this.simulationArguments = simulationData.getSimulationArguments(); this.substanceBuilder = new SubstanceBuilder(kappaSystem); } public final List<ComplexPerturbation<?,?>> build(List<ModelPerturbation> perturbations, MasterSolutionModel masterSolutionModel) throws ParseErrorException, DocumentFormatException { List<ComplexPerturbation<?,?>> result = new ArrayList<ComplexPerturbation<?,?>>(); for (ModelPerturbation modelPerturbation : perturbations) { ComplexPerturbation<?, ?> realPerturbation = convert(modelPerturbation); if (masterSolutionModel != null) masterSolutionModel.checkCorrect(realPerturbation, modelPerturbation); if (realPerturbation != null) { result.add(realPerturbation); } } return result; } private final Rule findRule(String ruleName) throws DocumentFormatException { if (ruleName == null) { // TODO throw document format exception return null; } for (Rule rule : kappaSystem.getRules()) { if (ruleName.equals(rule.getName())) { return rule; } } return null; } private final LinearExpression<VectorRule> createRateExpression ( ModelLinearExpression expression) throws DocumentFormatException { LinearExpression<VectorRule> result = new LinearExpression<VectorRule>(); for (LinearExpressionMonome monome : expression.getPolynome()) { Rule foundRule = findRule(monome.getEntityName()); double multiplier = monome.getMultiplier(); if (foundRule != null) { result.addMonome(new VectorRule(foundRule), multiplier); } else { result.addMonome(multiplier); } } return result; } private final LinearExpression<VectorObservable> createSpeciesExpression ( ModelLinearExpression expression) throws DocumentFormatException { LinearExpression<VectorObservable> result = new LinearExpression<VectorObservable>(); for (LinearExpressionMonome monome : expression.getPolynome()) { ObservableInterface observable = this.checkObservableForExistance(monome.getEntityName()); double coeffient = monome.getMultiplier(); if (observable != null) { result.addMonome(new VectorObservable(observable, kappaSystem.getObservables()), coeffient); } else { result.addMonome(coeffient); } } return result; } private RateModification convert(ModelRateModification modelModification) throws DocumentFormatException { LinearExpression<VectorRule> expression = createRateExpression(modelModification.getExpression()); Rule rule = findRule(modelModification.getArgument()); return new RateModification(rule, expression); } private ConditionInterface convert(PerturbationCondition modelCondition) throws DocumentFormatException { switch (modelCondition.getType()) { case COMPLEX: { ModelConjuctionCondition modelConjuctionCondition = (ModelConjuctionCondition) modelCondition; Collection<ConditionInterface> conditions = new LinkedHashSet<ConditionInterface>(); for (PerturbationCondition simpleCondition : modelConjuctionCondition.getConditions()) { conditions.add(this.convert(simpleCondition)); } return new ComplexCondition(conditions); } case TIME: { ModelTimeCondition modelTimeCondition = (ModelTimeCondition) modelCondition; return new TimeCondition(modelTimeCondition.getBounds()); } case SPECIES : { ModelSpeciesCondition modelSpeciesCondition = (ModelSpeciesCondition) modelCondition; ObservableInterface component = checkObservableForExistance(modelSpeciesCondition .getPickedObservableName()); LinearExpression<VectorObservable> speciesExpression = createSpeciesExpression(modelSpeciesCondition.getExpression()); return new SpeciesCondition(component, speciesExpression, modelSpeciesCondition.inequalitySign(), kappaSystem.getObservables()); } } return null; } private AbstractModification convert(PerturbationModification modelModification) throws DocumentFormatException, ParseErrorException { switch (modelModification.getType()) { case RATE: { return this.convert((ModelRateModification)modelModification); } default: { AbstractOnceModification modelOnceModification = (AbstractOnceModification) modelModification; List<Agent> agentList = substanceBuilder.buildAgents(modelOnceModification.getSubstanceAgents()); List<ConnectedComponentInterface> ccList = SpeciesManager.formConnectedComponents(agentList); for (ConnectedComponentInterface cc : ccList) { List<ConnectedComponentInterface> ccL = new ArrayList<ConnectedComponentInterface>(); ccL.add(cc); int quantity = modelOnceModification.getQuantity(); if (modelOnceModification.getType() == ModificationType.ADDONCE) { PerturbationRule rule = new PerturbationRule(null, ccL, "", 0, (int) kappaSystem.generateNextRuleId(), simulationArguments.needToStorify()); kappaSystem.addRule(rule); return new AddOnceModification(rule, quantity); } else { PerturbationRule rule = new PerturbationRule(ccL, null, "", 0, (int) kappaSystem.generateNextRuleId(), simulationArguments.needToStorify()); kappaSystem.addRule(rule); return new DeleteOnceModification(rule, quantity); } } } } return null; } private final <C extends ConditionInterface, M extends AbstractModification> ComplexPerturbation<?, ?> construct(C condition, M modification) { // tricky one, yeah ;) return new ComplexPerturbation<C, M>(condition, modification); } private final ComplexPerturbation<?, ?> convert(ModelPerturbation abstractPerturbation) throws ParseErrorException, DocumentFormatException { ConditionInterface condition = this.convert(abstractPerturbation.getCondition()); AbstractModification modification = this.convert(abstractPerturbation.getModification()); return this.construct(condition, modification); } private final ObservableInterface checkObservableForExistance(String observableName) throws DocumentFormatException { if (observableName == null) { return null; } for (ObservableInterface cc : kappaSystem.getObservables().getComponentList()) { if ((cc.getName() != null) && (cc.getName().equals(observableName))) { return cc; } } throw new DocumentFormatException("'" + observableName + "' must be in observables!"); } }