use of cbit.vcell.bionetgen.BNGParameter 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();
if (NetworkConstraints.SPECIES_LIMIT_PARAMETER.equals(s)) {
System.out.println("found NetworkConstraints seciesLimit parameter.");
continue;
}
if (NetworkConstraints.REACTIONS_LIMIT_PARAMETER.equals(s)) {
System.out.println("found NetworkConstraints reactionsLimit parameter.");
continue;
}
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();
// which may never happen since we encountered this problem only one time in many years
if (baseName.contains(",") && (baseName.length() > 192)) {
int pos = baseName.indexOf(",");
baseName = baseName.substring(0, pos);
}
// System.out.println(i + ": " + baseName);
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 = baseName;
} else {
reactionName = baseName + "_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);
}
}
if (!bngReaction.isMichaelisMenten()) {
// MassAction
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);
}
} else {
// MichaelisMenten
HMM_IRRKinetics targetKinetics = new HMM_IRRKinetics(sr);
sr.setKinetics(targetKinetics);
KineticsParameter vmax = targetKinetics.getVmaxParameter();
KineticsParameter km = targetKinetics.getKmParameter();
String vmaxNewName = rr.getKineticLaw().getLocalParameter(RbmKineticLawParameterType.MichaelisMentenVmax).getName();
if (!vmax.getName().equals(vmaxNewName)) {
targetKinetics.renameParameter(vmax.getName(), vmaxNewName);
vmax = targetKinetics.getVmaxParameter();
}
applyKineticsExpressions(forwardBNGReaction, vmax, targetKinetics);
final String kmNewName = rr.getKineticLaw().getLocalParameter(RbmKineticLawParameterType.MichaelisMentenKm).getName();
if (!km.getName().equals(kmNewName)) {
targetKinetics.renameParameter(km.getName(), kmNewName);
km = targetKinetics.getKmParameter();
}
applyKineticsExpressions(forwardBNGReaction, km, targetKinetics);
}
reactionStepMap.put(reactionName, sr);
} else if (reverseBNGReactionsMap.containsValue(bngReaction) && !directBNGReactionsMap.containsKey(bngReaction.getKey())) {
// reverse only (must be irreversible, cannot be Michaelis-Menten)
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);
}
Aggregations