use of cbit.vcell.model.ReactionRule in project vcell by virtualcell.
the class NetworkTransformer method transform.
private void transform(SimulationContext simContext, SimulationContext transformedSimulationContext, ArrayList<ModelEntityMapping> entityMappings, MathMappingCallback mathMappingCallback, NetworkGenerationRequirements networkGenerationRequirements) {
String msg = "Generating network: flattening...";
mathMappingCallback.setMessage(msg);
TaskCallbackMessage tcm = new TaskCallbackMessage(TaskCallbackStatus.Clean, "");
simContext.appendToConsole(tcm);
tcm = new TaskCallbackMessage(TaskCallbackStatus.TaskStart, msg);
simContext.appendToConsole(tcm);
long startTime = System.currentTimeMillis();
System.out.println("Convert to bngl, execute BNG, retrieve the results.");
try {
BNGOutputSpec outputSpec = generateNetwork(simContext, mathMappingCallback, networkGenerationRequirements);
if (mathMappingCallback.isInterrupted()) {
msg = "Canceled by user.";
tcm = new TaskCallbackMessage(TaskCallbackStatus.Error, msg);
simContext.appendToConsole(tcm);
throw new UserCancelException(msg);
}
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println(" " + elapsedTime + " milliseconds");
Model model = transformedSimulationContext.getModel();
ReactionContext reactionContext = transformedSimulationContext.getReactionContext();
// ---- Parameters -----------------------------------------------------------------------------------------------
startTime = System.currentTimeMillis();
for (int i = 0; i < outputSpec.getBNGParams().length; i++) {
BNGParameter p = outputSpec.getBNGParams()[i];
// System.out.println(i+1 + ":\t\t"+ p.toString());
if (model.getRbmModelContainer().getParameter(p.getName()) != null) {
// if it's already there we don't try to add it again; this should be true for all of them!
continue;
}
String s = p.getName();
FakeSeedSpeciesInitialConditionsParameter fakeICParam = FakeSeedSpeciesInitialConditionsParameter.fromString(s);
if (speciesEquivalenceMap.containsKey(fakeICParam)) {
// we get rid of the fake parameters we use as keys
continue;
}
FakeReactionRuleRateParameter fakeKineticParam = FakeReactionRuleRateParameter.fromString(s);
if (fakeKineticParam != null) {
System.out.println("found fakeKineticParam " + fakeKineticParam.fakeParameterName);
// we get rid of the fake parameters we use as keys
continue;
}
throw new RuntimeException("unexpected parameter " + p.getName() + " in internal BNG processing");
// Expression exp = new Expression(p.getValue());
// exp.bindExpression(model.getRbmModelContainer().getSymbolTable());
// model.getRbmModelContainer().addParameter(p.getName(), exp, model.getUnitSystem().getInstance_TBD());
}
endTime = System.currentTimeMillis();
elapsedTime = endTime - startTime;
msg = "Adding " + outputSpec.getBNGParams().length + " parameters to model, " + elapsedTime + " ms";
System.out.println(msg);
// ---- Species ------------------------------------------------------------------------------------------------------------
mathMappingCallback.setMessage("generating network: adding species...");
mathMappingCallback.setProgressFraction(progressFractionQuota / 4.0f);
startTime = System.currentTimeMillis();
System.out.println("\nSpecies :");
// the reactions will need this map to recover the names of species knowing only the networkFileIndex
HashMap<Integer, String> speciesMap = new HashMap<Integer, String>();
LinkedHashMap<String, Species> sMap = new LinkedHashMap<String, Species>();
LinkedHashMap<String, SpeciesContext> scMap = new LinkedHashMap<String, SpeciesContext>();
LinkedHashMap<String, BNGSpecies> crossMap = new LinkedHashMap<String, BNGSpecies>();
List<SpeciesContext> noMapForThese = new ArrayList<SpeciesContext>();
// final int decimalTickCount = Math.max(outputSpec.getBNGSpecies().length/10, 1);
for (int i = 0; i < outputSpec.getBNGSpecies().length; i++) {
BNGSpecies s = outputSpec.getBNGSpecies()[i];
// System.out.println(i+1 + ":\t\t"+ s.toString());
String key = s.getConcentration().infix();
FakeSeedSpeciesInitialConditionsParameter fakeParam = FakeSeedSpeciesInitialConditionsParameter.fromString(key);
if (fakeParam != null) {
Pair<SpeciesContext, Expression> value = speciesEquivalenceMap.get(fakeParam);
// the species context of the original model
SpeciesContext originalsc = value.one;
Expression initial = value.two;
// replace the fake initial condition with the real one
s.setConcentration(initial);
// we'll have to find the species context from the cloned model which correspond to the original species
SpeciesContext sc = model.getSpeciesContext(originalsc.getName());
// System.out.println(sc.getName() + ", " + sc.getSpecies().getCommonName() + " ...is one of the original seed species.");
// existing name
speciesMap.put(s.getNetworkFileIndex(), sc.getName());
sMap.put(sc.getName(), sc.getSpecies());
scMap.put(sc.getName(), sc);
crossMap.put(sc.getName(), s);
noMapForThese.add(sc);
continue;
}
// all these species are new!
// generate unique name for the species
int count = 0;
String speciesName = null;
String nameRoot = "s";
String speciesPatternNameString = s.extractName();
while (true) {
speciesName = nameRoot + count;
if (Model.isNameUnused(speciesName, model) && !sMap.containsKey(speciesName) && !scMap.containsKey(speciesName)) {
break;
}
count++;
}
// newly created name
speciesMap.put(s.getNetworkFileIndex(), speciesName);
SpeciesContext speciesContext;
if (s.hasCompartment()) {
String speciesPatternCompartmentString = s.extractCompartment();
speciesContext = new SpeciesContext(new Species(speciesName, s.getName()), model.getStructure(speciesPatternCompartmentString), null);
} else {
speciesContext = new SpeciesContext(new Species(speciesName, s.getName()), model.getStructure(0), null);
}
speciesContext.setName(speciesName);
try {
if (speciesPatternNameString != null) {
SpeciesPattern sp = RbmUtils.parseSpeciesPattern(speciesPatternNameString, model);
speciesContext.setSpeciesPattern(sp);
}
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException("Bad format for species pattern string: " + e.getMessage());
}
// speciesContext.setSpeciesPatternString(speciesPatternString);
// model.addSpecies(speciesContext.getSpecies());
// model.addSpeciesContext(speciesContext);
sMap.put(speciesName, speciesContext.getSpecies());
scMap.put(speciesName, speciesContext);
crossMap.put(speciesName, s);
// }
if (mathMappingCallback.isInterrupted()) {
msg = "Canceled by user.";
tcm = new TaskCallbackMessage(TaskCallbackStatus.Error, msg);
simContext.appendToConsole(tcm);
throw new UserCancelException(msg);
}
// if(i%50 == 0) {
// System.out.println(i+"");
// }
// if(i%decimalTickCount == 0) {
// int multiplier = i/decimalTickCount;
// float progress = progressFractionQuota/4.0f + progressFractionQuotaSpecies*multiplier;
// mathMappingCallback.setProgressFraction(progress);
// }
}
for (SpeciesContext sc1 : model.getSpeciesContexts()) {
boolean found = false;
for (Map.Entry<String, SpeciesContext> entry : scMap.entrySet()) {
SpeciesContext sc2 = entry.getValue();
if (sc1.getName().equals(sc2.getName())) {
found = true;
// System.out.println("found species context " + sc1.getName() + " of species " + sc1.getSpecies().getCommonName() + " // " + sc2.getSpecies().getCommonName());
break;
}
}
if (found == false) {
// we add to the map the species context and the species which exist in the model but which are not in the map yet
// the only ones in this situation should be plain species which were not given to bngl for flattening (they are flat already)
// System.out.println("species context " + sc1.getName() + " not found in the map. Adding it.");
scMap.put(sc1.getName(), sc1);
sMap.put(sc1.getName(), sc1.getSpecies());
noMapForThese.add(sc1);
}
}
for (Species s1 : model.getSpecies()) {
boolean found = false;
for (Map.Entry<String, Species> entry : sMap.entrySet()) {
Species s2 = entry.getValue();
if (s1.getCommonName().equals(s2.getCommonName())) {
found = true;
// System.out.println("found species " + s1.getCommonName());
break;
}
}
if (found == false) {
System.err.println("species " + s1.getCommonName() + " not found in the map!");
}
}
SpeciesContext[] sca = new SpeciesContext[scMap.size()];
scMap.values().toArray(sca);
Species[] sa = new HashSet<Species>(sMap.values()).toArray(new Species[0]);
model.setSpecies(sa);
model.setSpeciesContexts(sca);
boolean isSpatial = transformedSimulationContext.getGeometry().getDimension() > 0;
for (SpeciesContext sc : sca) {
if (noMapForThese.contains(sc)) {
continue;
}
SpeciesContextSpec scs = reactionContext.getSpeciesContextSpec(sc);
Parameter param = scs.getParameter(SpeciesContextSpec.ROLE_InitialConcentration);
BNGSpecies s = crossMap.get(sc.getName());
param.setExpression(s.getConcentration());
SpeciesContext origSpeciesContext = simContext.getModel().getSpeciesContext(s.getName());
if (origSpeciesContext != null) {
ModelEntityMapping em = new ModelEntityMapping(origSpeciesContext, sc);
entityMappings.add(em);
} else {
ModelEntityMapping em = new ModelEntityMapping(new GeneratedSpeciesSymbolTableEntry(sc), sc);
if (isSpatial) {
scs.initializeForSpatial();
}
entityMappings.add(em);
}
}
// for(SpeciesContext sc : sca) { // clean all the species patterns from the flattened species, we have no sp now
// sc.setSpeciesPattern(null);
// }
endTime = System.currentTimeMillis();
elapsedTime = endTime - startTime;
msg = "Adding " + outputSpec.getBNGSpecies().length + " species to model, " + elapsedTime + " ms";
System.out.println(msg);
// ---- Reactions -----------------------------------------------------------------------------------------------------
mathMappingCallback.setMessage("generating network: adding reactions...");
mathMappingCallback.setProgressFraction(progressFractionQuota / 4.0f * 3.0f);
startTime = System.currentTimeMillis();
System.out.println("\nReactions :");
Map<String, HashSet<String>> ruleKeyMap = new HashMap<String, HashSet<String>>();
Map<String, BNGReaction> directBNGReactionsMap = new HashMap<String, BNGReaction>();
Map<String, BNGReaction> reverseBNGReactionsMap = new HashMap<String, BNGReaction>();
for (int i = 0; i < outputSpec.getBNGReactions().length; i++) {
BNGReaction r = outputSpec.getBNGReactions()[i];
if (!r.isRuleReversed()) {
// direct
directBNGReactionsMap.put(r.getKey(), r);
} else {
reverseBNGReactionsMap.put(r.getKey(), r);
}
//
// for each rule name, store set of keySets (number of unique keysets are number of generated reactions from this ruleName).
//
HashSet<String> keySet = ruleKeyMap.get(r.getRuleName());
if (keySet == null) {
keySet = new HashSet<String>();
ruleKeyMap.put(r.getRuleName(), keySet);
}
keySet.add(r.getKey());
}
Map<String, ReactionStep> reactionStepMap = new HashMap<String, ReactionStep>();
for (int i = 0; i < outputSpec.getBNGReactions().length; i++) {
BNGReaction bngReaction = outputSpec.getBNGReactions()[i];
// System.out.println(i+1 + ":\t\t"+ r.writeReaction());
String baseName = bngReaction.getRuleName();
String reactionName = null;
HashSet<String> keySetsForThisRule = ruleKeyMap.get(bngReaction.getRuleName());
if (keySetsForThisRule.size() == 1 && model.getReactionStep(bngReaction.getRuleName()) == null && !reactionStepMap.containsKey(bngReaction.getRuleName())) {
// we can reuse the reaction rule labels
reactionName = bngReaction.getRuleName();
} else {
reactionName = bngReaction.getRuleName() + "_0";
while (true) {
if (model.getReactionStep(reactionName) == null && !reactionStepMap.containsKey(reactionName)) {
// we can reuse the reaction rule labels
break;
}
reactionName = TokenMangler.getNextEnumeratedToken(reactionName);
}
}
//
if (directBNGReactionsMap.containsValue(bngReaction)) {
BNGReaction forwardBNGReaction = bngReaction;
BNGReaction reverseBNGReaction = reverseBNGReactionsMap.get(bngReaction.getKey());
String name = forwardBNGReaction.getRuleName();
if (name.endsWith(ReactionRule.DirectHalf)) {
name = name.substring(0, name.indexOf(ReactionRule.DirectHalf));
}
if (name.endsWith(ReactionRule.InverseHalf)) {
name = name.substring(0, name.indexOf(ReactionRule.InverseHalf));
}
ReactionRule rr = model.getRbmModelContainer().getReactionRule(name);
Structure structure = rr.getStructure();
boolean bReversible = reverseBNGReaction != null;
SimpleReaction sr = new SimpleReaction(model, structure, reactionName, bReversible);
for (int j = 0; j < forwardBNGReaction.getReactants().length; j++) {
BNGSpecies s = forwardBNGReaction.getReactants()[j];
String scName = speciesMap.get(s.getNetworkFileIndex());
SpeciesContext sc = model.getSpeciesContext(scName);
Reactant reactant = sr.getReactant(scName);
if (reactant == null) {
int stoichiometry = 1;
sr.addReactant(sc, stoichiometry);
} else {
int stoichiometry = reactant.getStoichiometry();
stoichiometry += 1;
reactant.setStoichiometry(stoichiometry);
}
}
for (int j = 0; j < forwardBNGReaction.getProducts().length; j++) {
BNGSpecies s = forwardBNGReaction.getProducts()[j];
String scName = speciesMap.get(s.getNetworkFileIndex());
SpeciesContext sc = model.getSpeciesContext(scName);
Product product = sr.getProduct(scName);
if (product == null) {
int stoichiometry = 1;
sr.addProduct(sc, stoichiometry);
} else {
int stoichiometry = product.getStoichiometry();
stoichiometry += 1;
product.setStoichiometry(stoichiometry);
}
}
MassActionKinetics targetKinetics = new MassActionKinetics(sr);
sr.setKinetics(targetKinetics);
KineticsParameter kforward = targetKinetics.getForwardRateParameter();
KineticsParameter kreverse = targetKinetics.getReverseRateParameter();
String kforwardNewName = rr.getKineticLaw().getLocalParameter(RbmKineticLawParameterType.MassActionForwardRate).getName();
if (!kforward.getName().equals(kforwardNewName)) {
targetKinetics.renameParameter(kforward.getName(), kforwardNewName);
kforward = targetKinetics.getForwardRateParameter();
}
final String kreverseNewName = rr.getKineticLaw().getLocalParameter(RbmKineticLawParameterType.MassActionReverseRate).getName();
if (!kreverse.getName().equals(kreverseNewName)) {
targetKinetics.renameParameter(kreverse.getName(), kreverseNewName);
kreverse = targetKinetics.getReverseRateParameter();
}
applyKineticsExpressions(forwardBNGReaction, kforward, targetKinetics);
if (reverseBNGReaction != null) {
applyKineticsExpressions(reverseBNGReaction, kreverse, targetKinetics);
}
// String fieldParameterName = kforward.getName();
// fieldParameterName += "_" + r.getRuleName();
// kforward.setName(fieldParameterName);
reactionStepMap.put(reactionName, sr);
} else if (reverseBNGReactionsMap.containsValue(bngReaction) && !directBNGReactionsMap.containsKey(bngReaction.getKey())) {
// reverse only (must be irreversible)
BNGReaction reverseBNGReaction = reverseBNGReactionsMap.get(bngReaction.getKey());
ReactionRule rr = model.getRbmModelContainer().getReactionRule(reverseBNGReaction.extractRuleName());
Structure structure = rr.getStructure();
boolean bReversible = false;
SimpleReaction sr = new SimpleReaction(model, structure, reactionName, bReversible);
for (int j = 0; j < reverseBNGReaction.getReactants().length; j++) {
BNGSpecies s = reverseBNGReaction.getReactants()[j];
String scName = speciesMap.get(s.getNetworkFileIndex());
SpeciesContext sc = model.getSpeciesContext(scName);
Reactant reactant = sr.getReactant(scName);
if (reactant == null) {
int stoichiometry = 1;
sr.addReactant(sc, stoichiometry);
} else {
int stoichiometry = reactant.getStoichiometry();
stoichiometry += 1;
reactant.setStoichiometry(stoichiometry);
}
}
for (int j = 0; j < reverseBNGReaction.getProducts().length; j++) {
BNGSpecies s = reverseBNGReaction.getProducts()[j];
String scName = speciesMap.get(s.getNetworkFileIndex());
SpeciesContext sc = model.getSpeciesContext(scName);
Product product = sr.getProduct(scName);
if (product == null) {
int stoichiometry = 1;
sr.addProduct(sc, stoichiometry);
} else {
int stoichiometry = product.getStoichiometry();
stoichiometry += 1;
product.setStoichiometry(stoichiometry);
}
}
MassActionKinetics k = new MassActionKinetics(sr);
sr.setKinetics(k);
KineticsParameter kforward = k.getForwardRateParameter();
KineticsParameter kreverse = k.getReverseRateParameter();
String kforwardNewName = rr.getKineticLaw().getLocalParameter(RbmKineticLawParameterType.MassActionForwardRate).getName();
if (!kforward.getName().equals(kforwardNewName)) {
k.renameParameter(kforward.getName(), kforwardNewName);
kforward = k.getForwardRateParameter();
}
final String kreverseNewName = rr.getKineticLaw().getLocalParameter(RbmKineticLawParameterType.MassActionReverseRate).getName();
if (!kreverse.getName().equals(kreverseNewName)) {
k.renameParameter(kreverse.getName(), kreverseNewName);
kreverse = k.getReverseRateParameter();
}
applyKineticsExpressions(reverseBNGReaction, kforward, k);
// String fieldParameterName = kforward.getName();
// fieldParameterName += "_" + r.getRuleName();
// kforward.setName(fieldParameterName);
reactionStepMap.put(reactionName, sr);
}
}
for (ReactionStep rs : model.getReactionSteps()) {
reactionStepMap.put(rs.getName(), rs);
}
ReactionStep[] reactionSteps = new ReactionStep[reactionStepMap.size()];
reactionStepMap.values().toArray(reactionSteps);
model.setReactionSteps(reactionSteps);
if (mathMappingCallback.isInterrupted()) {
msg = "Canceled by user.";
tcm = new TaskCallbackMessage(TaskCallbackStatus.Error, msg);
simContext.appendToConsole(tcm);
throw new UserCancelException(msg);
}
endTime = System.currentTimeMillis();
elapsedTime = endTime - startTime;
msg = "Adding " + outputSpec.getBNGReactions().length + " reactions to model, " + elapsedTime + " ms";
System.out.println(msg);
// clean all the reaction rules
model.getRbmModelContainer().getReactionRuleList().clear();
// ---- Observables -------------------------------------------------------------------------------------------------
mathMappingCallback.setMessage("generating network: adding observables...");
mathMappingCallback.setProgressFraction(progressFractionQuota / 8.0f * 7.0f);
startTime = System.currentTimeMillis();
System.out.println("\nObservables :");
RbmModelContainer rbmmc = model.getRbmModelContainer();
for (int i = 0; i < outputSpec.getObservableGroups().length; i++) {
ObservableGroup o = outputSpec.getObservableGroups()[i];
if (rbmmc.getParameter(o.getObservableGroupName()) != null) {
System.out.println(" ...already exists.");
// if it's already there we don't try to add it again; this should be true for all of them!
continue;
}
ArrayList<Expression> terms = new ArrayList<Expression>();
for (int j = 0; j < o.getListofSpecies().length; j++) {
Expression term = Expression.mult(new Expression(o.getSpeciesMultiplicity()[j]), new Expression(speciesMap.get(o.getListofSpecies()[j].getNetworkFileIndex())));
terms.add(term);
}
Expression exp = Expression.add(terms.toArray(new Expression[terms.size()])).flatten();
exp.bindExpression(rbmmc.getSymbolTable());
RbmObservable originalObservable = rbmmc.getObservable(o.getObservableGroupName());
VCUnitDefinition observableUnitDefinition = originalObservable.getUnitDefinition();
rbmmc.removeObservable(originalObservable);
Parameter newParameter = rbmmc.addParameter(o.getObservableGroupName(), exp, observableUnitDefinition);
RbmObservable origObservable = simContext.getModel().getRbmModelContainer().getObservable(o.getObservableGroupName());
ModelEntityMapping em = new ModelEntityMapping(origObservable, newParameter);
entityMappings.add(em);
}
if (mathMappingCallback.isInterrupted()) {
msg = "Canceled by user.";
tcm = new TaskCallbackMessage(TaskCallbackStatus.Error, msg);
simContext.appendToConsole(tcm);
throw new UserCancelException(msg);
}
endTime = System.currentTimeMillis();
elapsedTime = endTime - startTime;
msg = "Adding " + outputSpec.getObservableGroups().length + " observables to model, " + elapsedTime + " ms";
System.out.println(msg);
} catch (PropertyVetoException ex) {
ex.printStackTrace(System.out);
throw new RuntimeException(ex.getMessage());
} catch (ExpressionBindingException ex) {
ex.printStackTrace(System.out);
throw new RuntimeException(ex.getMessage());
} catch (ModelException ex) {
ex.printStackTrace(System.out);
throw new RuntimeException(ex.getMessage());
} catch (ExpressionException ex) {
ex.printStackTrace(System.out);
throw new RuntimeException(ex.getMessage());
} catch (ClassNotFoundException ex) {
throw new RuntimeException(ex.getMessage());
} catch (IOException ex) {
throw new RuntimeException(ex.getMessage());
}
System.out.println("Done transforming");
msg = "Generating math...";
System.out.println(msg);
mathMappingCallback.setMessage(msg);
mathMappingCallback.setProgressFraction(progressFractionQuota);
}
use of cbit.vcell.model.ReactionRule in project vcell by virtualcell.
the class RulebasedMathMapping method addSpeciesPatterns.
private HashMap<SpeciesPattern, VolumeParticleSpeciesPattern> addSpeciesPatterns(Domain domain, List<ReactionRule> rrList) throws MathException {
// Particle Molecular Types
//
Model model = getSimulationContext().getModel();
List<RbmObservable> observableList = model.getRbmModelContainer().getObservableList();
List<MolecularType> molecularTypeList = model.getRbmModelContainer().getMolecularTypeList();
for (MolecularType molecularType : molecularTypeList) {
ParticleMolecularType particleMolecularType = new ParticleMolecularType(molecularType.getName());
for (MolecularComponent molecularComponent : molecularType.getComponentList()) {
String pmcName = molecularComponent.getName();
String pmcId = particleMolecularType.getName() + "_" + molecularComponent.getName();
ParticleMolecularComponent particleMolecularComponent = new ParticleMolecularComponent(pmcId, pmcName);
for (ComponentStateDefinition componentState : molecularComponent.getComponentStateDefinitions()) {
ParticleComponentStateDefinition pcsd = particleMolecularComponent.getComponentStateDefinition(componentState.getName());
if (pcsd == null) {
particleMolecularComponent.addComponentStateDefinition(new ParticleComponentStateDefinition(componentState.getName()));
}
}
particleMolecularType.addMolecularComponent(particleMolecularComponent);
}
if (!molecularType.isAnchorAll()) {
List<String> anchorList = new ArrayList<>();
for (Structure struct : molecularType.getAnchors()) {
anchorList.add(struct.getName());
}
particleMolecularType.setAnchorList(anchorList);
}
mathDesc.addParticleMolecularType(particleMolecularType);
}
//
// Assemble list of all Species Patterns (from observables, reaction rules, and seed species).
//
// linked hash set maintains insertion order
LinkedHashMap<SpeciesPattern, Structure> speciesPatternStructureMap = new LinkedHashMap<SpeciesPattern, Structure>();
for (RbmObservable observable : observableList) {
for (SpeciesPattern speciesPattern : observable.getSpeciesPatternList()) {
speciesPatternStructureMap.put(speciesPattern, observable.getStructure());
}
}
for (ReactionRule reactionRule : rrList) {
for (ReactantPattern rp : reactionRule.getReactantPatterns()) {
speciesPatternStructureMap.put(rp.getSpeciesPattern(), rp.getStructure());
}
for (ProductPattern pp : reactionRule.getProductPatterns()) {
speciesPatternStructureMap.put(pp.getSpeciesPattern(), pp.getStructure());
}
}
for (SpeciesContext sc : model.getSpeciesContexts()) {
if (!sc.hasSpeciesPattern()) {
continue;
}
speciesPatternStructureMap.put(sc.getSpeciesPattern(), sc.getStructure());
}
//
// add list of unique speciesPatterns
//
HashMap<String, VolumeParticleSpeciesPattern> speciesPatternVCMLMap = new HashMap<String, VolumeParticleSpeciesPattern>();
HashMap<SpeciesPattern, VolumeParticleSpeciesPattern> speciesPatternMap = new HashMap<SpeciesPattern, VolumeParticleSpeciesPattern>();
String speciesPatternName = "speciesPattern0";
for (SpeciesPattern speciesPattern : speciesPatternStructureMap.keySet()) {
VolumeParticleSpeciesPattern volumeParticleSpeciesPattern = new VolumeParticleSpeciesPattern(speciesPatternName, domain, speciesPatternStructureMap.get(speciesPattern).getName());
for (MolecularTypePattern molecularTypePattern : speciesPattern.getMolecularTypePatterns()) {
ParticleMolecularType particleMolecularType = mathDesc.getParticleMolecularType(molecularTypePattern.getMolecularType().getName());
ParticleMolecularTypePattern particleMolecularTypePattern = new ParticleMolecularTypePattern(particleMolecularType);
String participantMatchLabel = molecularTypePattern.getParticipantMatchLabel();
if (molecularTypePattern.getParticipantMatchLabel() != null) {
particleMolecularTypePattern.setMatchLabel(participantMatchLabel);
}
for (MolecularComponentPattern molecularComponentPattern : molecularTypePattern.getComponentPatternList()) {
MolecularComponent molecularComponent = molecularComponentPattern.getMolecularComponent();
ParticleMolecularComponent particleMolecularComponent = particleMolecularType.getMolecularComponent(molecularComponent.getName());
ParticleMolecularComponentPattern particleMolecularComponentPattern = new ParticleMolecularComponentPattern(particleMolecularComponent);
ComponentStatePattern componentState = molecularComponentPattern.getComponentStatePattern();
if (componentState != null) {
if (componentState.isAny()) {
ParticleComponentStatePattern pcsp = new ParticleComponentStatePattern();
particleMolecularComponentPattern.setComponentStatePattern(pcsp);
} else {
String name = componentState.getComponentStateDefinition().getName();
ParticleComponentStateDefinition pcsd = particleMolecularComponent.getComponentStateDefinition(name);
// ParticleComponentStateDefinition pcsd = new ParticleComponentStateDefinition(componentState.getComponentStateDefinition().getName());
// particleMolecularComponent.addComponentStateDefinition(pcsd);
ParticleComponentStatePattern pcsp = new ParticleComponentStatePattern(pcsd);
particleMolecularComponentPattern.setComponentStatePattern(pcsp);
}
} else {
ParticleComponentStatePattern pcsp = new ParticleComponentStatePattern();
particleMolecularComponentPattern.setComponentStatePattern(pcsp);
}
switch(molecularComponentPattern.getBondType()) {
case Specified:
{
particleMolecularComponentPattern.setBondType(ParticleBondType.Specified);
particleMolecularComponentPattern.setBondId(molecularComponentPattern.getBondId());
break;
}
case Exists:
{
particleMolecularComponentPattern.setBondType(ParticleBondType.Exists);
particleMolecularComponentPattern.setBondId(-1);
break;
}
case None:
{
particleMolecularComponentPattern.setBondType(ParticleBondType.None);
particleMolecularComponentPattern.setBondId(-1);
break;
}
case Possible:
{
particleMolecularComponentPattern.setBondType(ParticleBondType.Possible);
particleMolecularComponentPattern.setBondId(-1);
break;
}
}
particleMolecularTypePattern.addMolecularComponentPattern(particleMolecularComponentPattern);
}
volumeParticleSpeciesPattern.addMolecularTypePattern(particleMolecularTypePattern);
}
String speciesPatternVCML = volumeParticleSpeciesPattern.getVCML("tempName");
VolumeParticleSpeciesPattern uniqueVolumeParticleSpeciesPattern = speciesPatternVCMLMap.get(speciesPatternVCML);
if (uniqueVolumeParticleSpeciesPattern == null) {
speciesPatternVCMLMap.put(speciesPatternVCML, volumeParticleSpeciesPattern);
speciesPatternName = TokenMangler.getNextEnumeratedToken(speciesPatternName);
speciesPatternMap.put(speciesPattern, volumeParticleSpeciesPattern);
} else {
speciesPatternMap.put(speciesPattern, uniqueVolumeParticleSpeciesPattern);
}
}
return speciesPatternMap;
}
use of cbit.vcell.model.ReactionRule in project vcell by virtualcell.
the class RulebasedMathMapping method refreshMathDescription.
/**
* This method was created in VisualAge.
*/
@Override
protected void refreshMathDescription() throws MappingException, MatrixException, MathException, ExpressionException, ModelException {
// use local variable instead of using getter all the time.
SimulationContext simContext = getSimulationContext();
GeometryClass geometryClass = simContext.getGeometry().getGeometrySpec().getSubVolumes()[0];
Domain domain = new Domain(geometryClass);
// local structure mapping list
StructureMapping[] structureMappings = simContext.getGeometryContext().getStructureMappings();
// We have to check if all the reactions are able to transform to stochastic jump processes before generating the math.
String stochChkMsg = simContext.getModel().isValidForStochApp();
if (!(stochChkMsg.equals(""))) {
throw new ModelException("Problem updating math description: " + simContext.getName() + "\n" + stochChkMsg);
}
simContext.checkValidity();
//
if (simContext.getGeometry().getDimension() > 0) {
throw new MappingException("rule-based particle math mapping not implemented for spatial geometry - dimension >= 1");
}
//
for (int i = 0; i < structureMappings.length; i++) {
if (structureMappings[i] instanceof MembraneMapping) {
if (((MembraneMapping) structureMappings[i]).getCalculateVoltage()) {
throw new MappingException("electric potential not yet supported for particle models");
}
}
}
//
// fail if any events
//
BioEvent[] bioEvents = simContext.getBioEvents();
if (bioEvents != null && bioEvents.length > 0) {
throw new MappingException("events not yet supported for particle-based models");
}
//
// verify that all structures are mapped to subvolumes and all subvolumes are mapped to a structure
//
Structure[] structures = simContext.getGeometryContext().getModel().getStructures();
for (int i = 0; i < structures.length; i++) {
StructureMapping sm = simContext.getGeometryContext().getStructureMapping(structures[i]);
if (sm == null || (sm instanceof FeatureMapping && ((FeatureMapping) sm).getGeometryClass() == null)) {
throw new MappingException("model structure '" + structures[i].getName() + "' not mapped to a geometry subVolume");
}
if (sm != null && (sm instanceof MembraneMapping) && ((MembraneMapping) sm).getVolumeFractionParameter() != null) {
Expression volFractExp = ((MembraneMapping) sm).getVolumeFractionParameter().getExpression();
try {
if (volFractExp != null) {
double volFract = volFractExp.evaluateConstant();
if (volFract >= 1.0) {
throw new MappingException("model structure '" + (getSimulationContext().getModel().getStructureTopology().getInsideFeature(((MembraneMapping) sm).getMembrane()).getName() + "' has volume fraction >= 1.0"));
}
}
} catch (ExpressionException e) {
e.printStackTrace(System.out);
}
}
}
SubVolume[] subVolumes = simContext.getGeometryContext().getGeometry().getGeometrySpec().getSubVolumes();
for (int i = 0; i < subVolumes.length; i++) {
Structure[] mappedStructures = simContext.getGeometryContext().getStructuresFromGeometryClass(subVolumes[i]);
if (mappedStructures == null || mappedStructures.length == 0) {
throw new MappingException("geometry subVolume '" + subVolumes[i].getName() + "' not mapped from a model structure");
}
}
//
// gather only those reactionRules that are not "excluded"
//
ArrayList<ReactionRule> rrList = new ArrayList<ReactionRule>();
for (ReactionRuleSpec reactionRuleSpec : simContext.getReactionContext().getReactionRuleSpecs()) {
if (!reactionRuleSpec.isExcluded()) {
rrList.add(reactionRuleSpec.getReactionRule());
}
}
//
for (ReactionRule reactionRule : rrList) {
UnresolvedParameter[] unresolvedParameters = reactionRule.getKineticLaw().getUnresolvedParameters();
if (unresolvedParameters != null && unresolvedParameters.length > 0) {
StringBuffer buffer = new StringBuffer();
for (int j = 0; j < unresolvedParameters.length; j++) {
if (j > 0) {
buffer.append(", ");
}
buffer.append(unresolvedParameters[j].getName());
}
throw new MappingException("In Application '" + simContext.getName() + "', " + reactionRule.getDisplayType() + " '" + reactionRule.getName() + "' contains unresolved identifier(s): " + buffer);
}
}
//
// create new MathDescription (based on simContext's previous MathDescription if possible)
//
MathDescription oldMathDesc = simContext.getMathDescription();
mathDesc = null;
if (oldMathDesc != null) {
if (oldMathDesc.getVersion() != null) {
mathDesc = new MathDescription(oldMathDesc.getVersion());
} else {
mathDesc = new MathDescription(oldMathDesc.getName());
}
} else {
mathDesc = new MathDescription(simContext.getName() + "_generated");
}
//
// temporarily place all variables in a hashtable (before binding) and discarding duplicates
//
VariableHash varHash = new VariableHash();
//
// conversion factors
//
Model model = simContext.getModel();
varHash.addVariable(new Constant(getMathSymbol(model.getKMOLE(), null), getIdentifierSubstitutions(model.getKMOLE().getExpression(), model.getKMOLE().getUnitDefinition(), null)));
varHash.addVariable(new Constant(getMathSymbol(model.getN_PMOLE(), null), getIdentifierSubstitutions(model.getN_PMOLE().getExpression(), model.getN_PMOLE().getUnitDefinition(), null)));
varHash.addVariable(new Constant(getMathSymbol(model.getPI_CONSTANT(), null), getIdentifierSubstitutions(model.getPI_CONSTANT().getExpression(), model.getPI_CONSTANT().getUnitDefinition(), null)));
varHash.addVariable(new Constant(getMathSymbol(model.getFARADAY_CONSTANT(), null), getIdentifierSubstitutions(model.getFARADAY_CONSTANT().getExpression(), model.getFARADAY_CONSTANT().getUnitDefinition(), null)));
varHash.addVariable(new Constant(getMathSymbol(model.getFARADAY_CONSTANT_NMOLE(), null), getIdentifierSubstitutions(model.getFARADAY_CONSTANT_NMOLE().getExpression(), model.getFARADAY_CONSTANT_NMOLE().getUnitDefinition(), null)));
varHash.addVariable(new Constant(getMathSymbol(model.getGAS_CONSTANT(), null), getIdentifierSubstitutions(model.getGAS_CONSTANT().getExpression(), model.getGAS_CONSTANT().getUnitDefinition(), null)));
varHash.addVariable(new Constant(getMathSymbol(model.getTEMPERATURE(), null), getIdentifierSubstitutions(new Expression(simContext.getTemperatureKelvin()), model.getTEMPERATURE().getUnitDefinition(), null)));
Enumeration<SpeciesContextMapping> enum1 = getSpeciesContextMappings();
while (enum1.hasMoreElements()) {
SpeciesContextMapping scm = enum1.nextElement();
if (scm.getVariable() instanceof StochVolVariable) {
varHash.addVariable(scm.getVariable());
}
}
// deals with model parameters
ModelParameter[] modelParameters = simContext.getModel().getModelParameters();
for (int j = 0; j < modelParameters.length; j++) {
Expression expr = getSubstitutedExpr(modelParameters[j].getExpression(), true, false);
expr = getIdentifierSubstitutions(expr, modelParameters[j].getUnitDefinition(), geometryClass);
varHash.addVariable(newFunctionOrConstant(getMathSymbol(modelParameters[j], geometryClass), expr, geometryClass));
}
// added July 2009, ElectricalStimulusParameter electric mapping tab
ElectricalStimulus[] elecStimulus = simContext.getElectricalStimuli();
if (elecStimulus.length > 0) {
throw new MappingException("Modles with electrophysiology are not supported for stochastic applications.");
}
for (int j = 0; j < structureMappings.length; j++) {
if (structureMappings[j] instanceof MembraneMapping) {
MembraneMapping memMapping = (MembraneMapping) structureMappings[j];
Parameter initialVoltageParm = memMapping.getInitialVoltageParameter();
try {
Expression exp = initialVoltageParm.getExpression();
exp.evaluateConstant();
varHash.addVariable(newFunctionOrConstant(getMathSymbol(memMapping.getMembrane().getMembraneVoltage(), memMapping.getGeometryClass()), getIdentifierSubstitutions(memMapping.getInitialVoltageParameter().getExpression(), memMapping.getInitialVoltageParameter().getUnitDefinition(), memMapping.getGeometryClass()), memMapping.getGeometryClass()));
} catch (ExpressionException e) {
e.printStackTrace(System.out);
throw new MappingException("Membrane initial voltage: " + initialVoltageParm.getName() + " cannot be evaluated as constant.");
}
}
}
//
for (ReactionRule reactionRule : rrList) {
// if (reactionRule.getKineticLaw() instanceof LumpedKinetics){
// throw new RuntimeException("Lumped Kinetics not yet supported for RuleBased Modeling");
// }
LocalParameter[] parameters = reactionRule.getKineticLaw().getLocalParameters();
for (LocalParameter parameter : parameters) {
//
if ((parameter.getRole() == RbmKineticLawParameterType.RuleRate)) {
continue;
}
//
if (!reactionRule.isReversible() && parameter.getRole() == RbmKineticLawParameterType.MassActionReverseRate) {
continue;
}
Expression expr = getSubstitutedExpr(parameter.getExpression(), true, false);
varHash.addVariable(newFunctionOrConstant(getMathSymbol(parameter, geometryClass), getIdentifierSubstitutions(expr, parameter.getUnitDefinition(), geometryClass), geometryClass));
}
}
// the parameter "Size" is already put into mathsymbolmapping in refreshSpeciesContextMapping()
for (int i = 0; i < structureMappings.length; i++) {
StructureMapping sm = structureMappings[i];
StructureMapping.StructureMappingParameter parm = sm.getParameterFromRole(StructureMapping.ROLE_Size);
if (parm.getExpression() != null) {
try {
double value = parm.getExpression().evaluateConstant();
varHash.addVariable(new Constant(getMathSymbol(parm, sm.getGeometryClass()), new Expression(value)));
} catch (ExpressionException e) {
// varHash.addVariable(new Function(getMathSymbol0(parm,sm),getIdentifierSubstitutions(parm.getExpression(),parm.getUnitDefinition(),sm)));
e.printStackTrace(System.out);
throw new MappingException("Size of structure:" + sm.getNameScope().getName() + " cannot be evaluated as constant.");
}
}
}
SpeciesContextSpec[] speciesContextSpecs = getSimulationContext().getReactionContext().getSpeciesContextSpecs();
addInitialConditions(domain, speciesContextSpecs, varHash);
//
if (simContext.getGeometryContext().getGeometry() != null) {
try {
mathDesc.setGeometry(simContext.getGeometryContext().getGeometry());
} catch (java.beans.PropertyVetoException e) {
e.printStackTrace(System.out);
throw new MappingException("failure setting geometry " + e.getMessage());
}
} else {
throw new MappingException("Geometry must be defined in Application " + simContext.getName());
}
//
// create subDomains
//
SubVolume subVolume = simContext.getGeometry().getGeometrySpec().getSubVolumes()[0];
SubDomain subDomain = new CompartmentSubDomain(subVolume.getName(), 0);
mathDesc.addSubDomain(subDomain);
//
// define all molecules and unique species patterns (add molecules to mathDesc and speciesPatterns to varHash).
//
HashMap<SpeciesPattern, VolumeParticleSpeciesPattern> speciesPatternMap = addSpeciesPatterns(domain, rrList);
HashSet<VolumeParticleSpeciesPattern> uniqueParticleSpeciesPatterns = new HashSet<>(speciesPatternMap.values());
for (VolumeParticleSpeciesPattern volumeParticleSpeciesPattern : uniqueParticleSpeciesPatterns) {
varHash.addVariable(volumeParticleSpeciesPattern);
}
//
// define observables (those explicitly declared and those corresponding to seed species.
//
List<ParticleObservable> observables = addObservables(geometryClass, domain, speciesPatternMap);
for (ParticleObservable particleObservable : observables) {
varHash.addVariable(particleObservable);
}
try {
addParticleJumpProcesses(varHash, geometryClass, subDomain, speciesPatternMap);
} catch (PropertyVetoException e1) {
e1.printStackTrace();
throw new MappingException(e1.getMessage(), e1);
}
//
for (int i = 0; i < fieldMathMappingParameters.length; i++) {
if (fieldMathMappingParameters[i] instanceof UnitFactorParameter || fieldMathMappingParameters[i] instanceof ObservableConcentrationParameter) {
varHash.addVariable(newFunctionOrConstant(getMathSymbol(fieldMathMappingParameters[i], geometryClass), getIdentifierSubstitutions(fieldMathMappingParameters[i].getExpression(), fieldMathMappingParameters[i].getUnitDefinition(), geometryClass), fieldMathMappingParameters[i].getGeometryClass()));
}
}
//
// set Variables to MathDescription all at once with the order resolved by "VariableHash"
//
mathDesc.setAllVariables(varHash.getAlphabeticallyOrderedVariables());
//
for (SpeciesContext sc : model.getSpeciesContexts()) {
if (!sc.hasSpeciesPattern()) {
throw new MappingException("species " + sc.getName() + " has no molecular pattern");
}
VolumeParticleSpeciesPattern volumeParticleSpeciesPattern = speciesPatternMap.get(sc.getSpeciesPattern());
ArrayList<ParticleInitialCondition> particleInitialConditions = new ArrayList<ParticleProperties.ParticleInitialCondition>();
// initial conditions from scs
SpeciesContextSpec scs = simContext.getReactionContext().getSpeciesContextSpec(sc);
Parameter initialCountParameter = scs.getInitialCountParameter();
Expression e = getIdentifierSubstitutions(new Expression(initialCountParameter, getNameScope()), initialCountParameter.getUnitDefinition(), geometryClass);
particleInitialConditions.add(new ParticleInitialConditionCount(e, new Expression(0.0), new Expression(0.0), new Expression(0.0)));
ParticleProperties particleProperies = new ParticleProperties(volumeParticleSpeciesPattern, new Expression(0.0), new Expression(0.0), new Expression(0.0), new Expression(0.0), particleInitialConditions);
subDomain.addParticleProperties(particleProperies);
}
//
for (int i = 0; i < fieldMathMappingParameters.length; i++) {
if (fieldMathMappingParameters[i] instanceof UnitFactorParameter) {
Variable variable = newFunctionOrConstant(getMathSymbol(fieldMathMappingParameters[i], geometryClass), getIdentifierSubstitutions(fieldMathMappingParameters[i].getExpression(), fieldMathMappingParameters[i].getUnitDefinition(), geometryClass), fieldMathMappingParameters[i].getGeometryClass());
if (mathDesc.getVariable(variable.getName()) == null) {
mathDesc.addVariable(variable);
}
}
if (fieldMathMappingParameters[i] instanceof ObservableConcentrationParameter) {
Variable variable = newFunctionOrConstant(getMathSymbol(fieldMathMappingParameters[i], geometryClass), getIdentifierSubstitutions(fieldMathMappingParameters[i].getExpression(), fieldMathMappingParameters[i].getUnitDefinition(), geometryClass), fieldMathMappingParameters[i].getGeometryClass());
if (mathDesc.getVariable(variable.getName()) == null) {
mathDesc.addVariable(variable);
}
}
}
if (!mathDesc.isValid()) {
System.out.println(mathDesc.getVCML_database());
throw new MappingException("generated an invalid mathDescription: " + mathDesc.getWarning());
}
}
use of cbit.vcell.model.ReactionRule in project vcell by virtualcell.
the class RulebasedMathMapping method addParticleJumpProcesses.
private void addParticleJumpProcesses(VariableHash varHash, GeometryClass geometryClass, SubDomain subDomain, HashMap<SpeciesPattern, VolumeParticleSpeciesPattern> speciesPatternMap) throws ExpressionException, MappingException, MathException, PropertyVetoException {
ArrayList<ReactionRule> rrList = new ArrayList<>();
for (ReactionRuleSpec rrSpec : getSimulationContext().getReactionContext().getReactionRuleSpecs()) {
if (!rrSpec.isExcluded()) {
rrList.add(rrSpec.getReactionRule());
}
}
for (ReactionRule reactionRule : rrList) {
String jpName = TokenMangler.mangleToSName(reactionRule.getName());
ArrayList<ParticleVariable> reactantParticles = new ArrayList<ParticleVariable>();
for (ReactantPattern reactantSpeciesPattern : reactionRule.getReactantPatterns()) {
reactantParticles.add(speciesPatternMap.get(reactantSpeciesPattern.getSpeciesPattern()));
}
ArrayList<ParticleVariable> productParticles = new ArrayList<ParticleVariable>();
for (ProductPattern productSpeciesPattern : reactionRule.getProductPatterns()) {
productParticles.add(speciesPatternMap.get(productSpeciesPattern.getSpeciesPattern()));
}
ArrayList<Action> forwardActions = new ArrayList<Action>();
ArrayList<Action> reverseActions = new ArrayList<Action>();
for (ParticleVariable reactant : reactantParticles) {
forwardActions.add(new Action(reactant, Action.ACTION_DESTROY, new Expression(1.0)));
reverseActions.add(new Action(reactant, Action.ACTION_CREATE, new Expression(1.0)));
}
for (ParticleVariable product : productParticles) {
forwardActions.add(new Action(product, Action.ACTION_CREATE, new Expression(1.0)));
reverseActions.add(new Action(product, Action.ACTION_DESTROY, new Expression(1.0)));
}
RbmKineticLaw kinetics = reactionRule.getKineticLaw();
if (kinetics.getRateLawType() == RbmKineticLaw.RateLawType.MassAction) {
boolean constantMassActionKineticCoefficients = true;
StringBuffer errorMessage = new StringBuffer();
Parameter forward_rateParameter = kinetics.getLocalParameter(RbmKineticLawParameterType.MassActionForwardRate);
Expression substitutedForwardRate = MathUtilities.substituteModelParameters(forward_rateParameter.getExpression(), reactionRule.getNameScope().getScopedSymbolTable());
if (!substitutedForwardRate.flatten().isNumeric()) {
errorMessage.append("flattened Kf for reactionRule(" + reactionRule.getName() + ") is not numeric, exp = '" + substitutedForwardRate.flatten().infix() + "'");
constantMassActionKineticCoefficients = false;
}
if (reactionRule.isReversible()) {
Parameter reverse_rateParameter = kinetics.getLocalParameter(RbmKineticLawParameterType.MassActionReverseRate);
if (reverse_rateParameter == null || reverse_rateParameter.getExpression() == null) {
throw new MappingException("reverse rate constant for reaction rule " + reactionRule.getName() + " is missing");
}
Expression substitutedReverseRate = MathUtilities.substituteModelParameters(reverse_rateParameter.getExpression(), reactionRule.getNameScope().getScopedSymbolTable());
if (!substitutedReverseRate.flatten().isNumeric()) {
errorMessage.append("flattened Kr for reactionRule(" + reactionRule.getName() + ") is not numeric, exp = '" + substitutedReverseRate.flatten().infix() + "'");
constantMassActionKineticCoefficients = false;
}
}
if (constantMassActionKineticCoefficients) {
addStrictMassActionParticleJumpProcess(varHash, geometryClass, subDomain, reactionRule, jpName, reactantParticles, productParticles, forwardActions, reverseActions);
} else {
throw new MappingException("not mass action: " + errorMessage.toString());
// addGeneralParticleJumpProcess(varHash, geometryClass, subDomain,
// reactionRule, jpName,
// reactantParticles, productParticles,
// forwardActions, reverseActions);
}
} else {
throw new MappingException("rule-based math generation unsupported for Kinetic Law: " + kinetics.getRateLawType());
}
}
// end reactionRules
}
use of cbit.vcell.model.ReactionRule in project vcell by virtualcell.
the class RulebasedTransformer method transform.
private void transform(SimulationContext originalSimContext, SimulationContext transformedSimulationContext, ArrayList<ModelEntityMapping> entityMappings, MathMappingCallback mathMappingCallback) throws PropertyVetoException {
Model newModel = transformedSimulationContext.getModel();
Model originalModel = originalSimContext.getModel();
ModelEntityMapping em = null;
// list of rules created from the reactions; we apply the symmetry factor computed by bionetgen only to these
Set<ReactionRule> fromReactions = new HashSet<>();
for (SpeciesContext newSpeciesContext : newModel.getSpeciesContexts()) {
final SpeciesContext originalSpeciesContext = originalModel.getSpeciesContext(newSpeciesContext.getName());
// map new and old species contexts
em = new ModelEntityMapping(originalSpeciesContext, newSpeciesContext);
entityMappings.add(em);
if (newSpeciesContext.hasSpeciesPattern()) {
// it's perfect already and can't be improved
continue;
}
try {
MolecularType newmt = newModel.getRbmModelContainer().createMolecularType();
newModel.getRbmModelContainer().addMolecularType(newmt, false);
MolecularTypePattern newmtp_sc = new MolecularTypePattern(newmt);
SpeciesPattern newsp_sc = new SpeciesPattern();
newsp_sc.addMolecularTypePattern(newmtp_sc);
newSpeciesContext.setSpeciesPattern(newsp_sc);
RbmObservable newo = new RbmObservable(newModel, "O0_" + newmt.getName() + "_tot", newSpeciesContext.getStructure(), RbmObservable.ObservableType.Molecules);
MolecularTypePattern newmtp_ob = new MolecularTypePattern(newmt);
SpeciesPattern newsp_ob = new SpeciesPattern();
newsp_ob.addMolecularTypePattern(newmtp_ob);
newo.addSpeciesPattern(newsp_ob);
newModel.getRbmModelContainer().addObservable(newo);
// map new observable to old species context
em = new ModelEntityMapping(originalSpeciesContext, newo);
entityMappings.add(em);
} catch (ModelException e) {
e.printStackTrace();
throw new RuntimeException("unable to transform species context: " + e.getMessage());
} catch (PropertyVetoException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ReactionSpec[] reactionSpecs = transformedSimulationContext.getReactionContext().getReactionSpecs();
for (ReactionSpec reactionSpec : reactionSpecs) {
if (reactionSpec.isExcluded()) {
// we create rules only from those reactions which are not excluded
continue;
}
ReactionStep rs = reactionSpec.getReactionStep();
String name = rs.getName();
String mangled = TokenMangler.fixTokenStrict(name);
mangled = newModel.getReactionName(mangled);
Kinetics k = rs.getKinetics();
if (!(k instanceof MassActionKinetics)) {
throw new RuntimeException("Only Mass Action Kinetics supported at this time, reaction \"" + rs.getName() + "\" uses kinetic law type \"" + rs.getKinetics().getName() + "\"");
}
boolean bReversible = rs.isReversible();
ReactionRule rr = new ReactionRule(newModel, mangled, rs.getStructure(), bReversible);
fromReactions.add(rr);
MassActionKinetics massActionKinetics = (MassActionKinetics) k;
List<Reactant> rList = rs.getReactants();
List<Product> pList = rs.getProducts();
// counting the stoichiometry - 2A+B means 3 reactants
int numReactants = 0;
for (Reactant r : rList) {
numReactants += r.getStoichiometry();
if (numReactants > 2) {
String message = "NFSim doesn't support more than 2 reactants within a reaction: " + name;
throw new RuntimeException(message);
}
}
int numProducts = 0;
for (Product p : pList) {
numProducts += p.getStoichiometry();
if (bReversible && numProducts > 2) {
String message = "NFSim doesn't support more than 2 products within a reversible reaction: " + name;
throw new RuntimeException(message);
}
}
RateLawType rateLawType = RateLawType.MassAction;
RbmKineticLaw kineticLaw = new RbmKineticLaw(rr, rateLawType);
try {
String forwardRateName = massActionKinetics.getForwardRateParameter().getName();
Expression forwardRateExp = massActionKinetics.getForwardRateParameter().getExpression();
String reverseRateName = massActionKinetics.getReverseRateParameter().getName();
Expression reverseRateExp = massActionKinetics.getReverseRateParameter().getExpression();
LocalParameter fR = kineticLaw.getLocalParameter(RbmKineticLawParameterType.MassActionForwardRate);
fR.setName(forwardRateName);
LocalParameter rR = kineticLaw.getLocalParameter(RbmKineticLawParameterType.MassActionReverseRate);
rR.setName(reverseRateName);
if (rs.hasReactant()) {
kineticLaw.setParameterValue(fR, forwardRateExp, true);
}
if (rs.hasProduct()) {
kineticLaw.setParameterValue(rR, reverseRateExp, true);
}
//
for (KineticsParameter reaction_p : massActionKinetics.getKineticsParameters()) {
if (reaction_p.getRole() == Kinetics.ROLE_UserDefined) {
LocalParameter rule_p = kineticLaw.getLocalParameter(reaction_p.getName());
if (rule_p == null) {
//
// after lazy parameter creation we didn't find a user-defined rule parameter with this same name.
//
// there must be a global symbol with the same name, that the local reaction parameter has overridden.
//
ParameterContext.LocalProxyParameter rule_proxy_parameter = null;
for (ProxyParameter proxyParameter : kineticLaw.getProxyParameters()) {
if (proxyParameter.getName().equals(reaction_p.getName())) {
rule_proxy_parameter = (LocalProxyParameter) proxyParameter;
}
}
if (rule_proxy_parameter != null) {
// we want to convert to local
boolean bConvertToGlobal = false;
kineticLaw.convertParameterType(rule_proxy_parameter, bConvertToGlobal);
} else {
// could find neither local parameter nor proxy parameter
throw new RuntimeException("user defined parameter " + reaction_p.getName() + " from reaction " + rs.getName() + " didn't map to a reactionRule parameter");
}
} else if (rule_p.getRole() == RbmKineticLawParameterType.UserDefined) {
kineticLaw.setParameterValue(rule_p, reaction_p.getExpression(), true);
rule_p.setUnitDefinition(reaction_p.getUnitDefinition());
} else {
throw new RuntimeException("user defined parameter " + reaction_p.getName() + " from reaction " + rs.getName() + " mapped to a reactionRule parameter with unexpected role " + rule_p.getRole().getDescription());
}
}
}
} catch (ExpressionException e) {
e.printStackTrace();
throw new RuntimeException("Problem attempting to set RbmKineticLaw expression: " + e.getMessage());
}
rr.setKineticLaw(kineticLaw);
KineticsParameter[] kpList = k.getKineticsParameters();
ModelParameter[] mpList = rs.getModel().getModelParameters();
ModelParameter mp = rs.getModel().getModelParameter(kpList[0].getName());
ReactionParticipant[] rpList = rs.getReactionParticipants();
for (ReactionParticipant p : rpList) {
if (p instanceof Reactant) {
int stoichiometry = p.getStoichiometry();
for (int i = 0; i < stoichiometry; i++) {
SpeciesPattern speciesPattern = new SpeciesPattern(rs.getModel(), p.getSpeciesContext().getSpeciesPattern());
ReactantPattern reactantPattern = new ReactantPattern(speciesPattern, p.getStructure());
rr.addReactant(reactantPattern);
}
} else if (p instanceof Product) {
int stoichiometry = p.getStoichiometry();
for (int i = 0; i < stoichiometry; i++) {
SpeciesPattern speciesPattern = new SpeciesPattern(rs.getModel(), p.getSpeciesContext().getSpeciesPattern());
ProductPattern productPattern = new ProductPattern(speciesPattern, p.getStructure());
rr.addProduct(productPattern);
}
}
}
// commented code below is probably obsolete, we verify (above) in the reaction the number of participants,
// no need to do it again in the corresponding rule
// if(rr.getReactantPatterns().size() > 2) {
// String message = "NFSim doesn't support more than 2 reactants within a reaction: " + name;
// throw new RuntimeException(message);
// }
// if(rr.getProductPatterns().size() > 2) {
// String message = "NFSim doesn't support more than 2 products within a reaction: " + name;
// throw new RuntimeException(message);
// }
newModel.removeReactionStep(rs);
newModel.getRbmModelContainer().addReactionRule(rr);
}
for (ReactionRuleSpec rrs : transformedSimulationContext.getReactionContext().getReactionRuleSpecs()) {
if (rrs == null) {
continue;
}
ReactionRule rr = rrs.getReactionRule();
if (rrs.isExcluded()) {
// delete those rules which are disabled (excluded) in the Specifications / Reaction table
newModel.getRbmModelContainer().removeReactionRule(rr);
continue;
}
}
// now that we generated the rules we can delete the reaction steps they're coming from
for (ReactionStep rs : newModel.getReactionSteps()) {
newModel.removeReactionStep(rs);
}
try {
// we invoke bngl just for the purpose of generating the xml file, which we'll then use to extract the symmetry factor
generateNetwork(transformedSimulationContext, fromReactions, mathMappingCallback);
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Finished RuleBased Transformer.");
}
Aggregations