Skip to content

Commit

Permalink
Merge pull request #1108 from virtualcell/dan-ss-is2D-flag
Browse files Browse the repository at this point in the history
Added is2D flag, domain name bug fixed in the math
  • Loading branch information
danv61 committed Jan 22, 2024
2 parents cbfca2b + 404532d commit 1dfc9e1
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,18 @@
*/
@SuppressWarnings("serial")
public class MolecularTypeSpecsTableModel extends VCellSortTableModel<MolecularComponentPattern> implements java.beans.PropertyChangeListener {


// TODO: sas is null for molecules added late (after the application is created)
// TODO: add is2D flag here as a checkbox (var is SpeciesContextSpec) - membrane species may have it set to true, for compartment species is always false
// TODO: math is wrong for a model with a membrane species, saving model fails, see model aaa-SS-membrane, see issue #1097

private enum ColumnType {
COLUMN_SITE("Site"),
COLUMN_MOLECULE("Molecule"),
COLUMN_STRUCTURE("Location"),
COLUMN_STATE("Initial State"),
COLUMN_RADIUS("Radius"),
COLUMN_DIFFUSION("Diffusion Rate");
COLUMN_RADIUS("Radius (nm)"),
COLUMN_DIFFUSION("Diffusion Rate (um^2/s)");

public final String label;
private ColumnType(String label){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.util.List;
import java.util.TreeSet;

import cbit.vcell.model.Membrane;
import org.vcell.model.rbm.SpeciesPattern;
import org.vcell.util.Displayable;
import org.vcell.util.gui.GuiUtils;
Expand Down Expand Up @@ -65,6 +66,7 @@ public enum ColumnType {
COLUMN_SPECIESCONTEXT("Species"),
COLUMN_STRUCTURE("Structure"),
COLUMN_DEPICTION("Depiction"),
COLUMN_IS2D("Is 2D"),
COLUMN_CLAMPED("Clamped"),
COLUMN_RULES("Rules"),
COLUMN_INITIAL("Initial Condition"),
Expand Down Expand Up @@ -142,6 +144,7 @@ public Class<?> getColumnClass(int column) {
case COLUMN_RULES:{
return RulesProvenance.class;
}
case COLUMN_IS2D:
case COLUMN_CLAMPED:
case COLUMN_WELLMIXED:
case COLUMN_FORCECONTINUOUS:{
Expand All @@ -163,21 +166,36 @@ public String getColumnName(int columnIndex){
}

private void refreshColumns(){
SimulationContext simContext = getSimulationContext();
columns.clear();
columns.addAll(Arrays.asList(ColumnType.values())); // initialize to all columns
if (getSimulationContext() == null || !getSimulationContext().isStoch()){
if(simContext == null) {
columns.remove(ColumnType.COLUMN_IS2D);
columns.remove(ColumnType.COLUMN_FORCECONTINUOUS);
columns.remove(ColumnType.COLUMN_WELLMIXED);
columns.remove(ColumnType.COLUMN_DIFFUSION);
columns.remove(ColumnType.COLUMN_CLAMPED);
columns.remove(ColumnType.COLUMN_RULES);
return;
}
if(!simContext.getApplicationType().equals(SimulationContext.Application.SPRINGSALAD)) {
columns.remove(ColumnType.COLUMN_IS2D);
}
if (getSimulationContext() == null || getSimulationContext().getGeometry().getDimension() == 0){
if (!simContext.isStoch()){
columns.remove(ColumnType.COLUMN_FORCECONTINUOUS);
}
if (simContext.getGeometry().getDimension() == 0){
columns.remove(ColumnType.COLUMN_IS2D);
columns.remove(ColumnType.COLUMN_WELLMIXED);
columns.remove(ColumnType.COLUMN_DIFFUSION);
}
if (getSimulationContext() == null || getSimulationContext().isRuleBased()) {
if (simContext.isRuleBased()) {
// the NFSim simulator used for rule-based doesn't accept clamped or force continuous
columns.remove(ColumnType.COLUMN_IS2D);
columns.remove(ColumnType.COLUMN_CLAMPED);
columns.remove(ColumnType.COLUMN_FORCECONTINUOUS);
}
if (getSimulationContext() == null || getSimulationContext().getApplicationType().equals(SimulationContext.Application.SPRINGSALAD)) {
if (simContext.getApplicationType().equals(SimulationContext.Application.SPRINGSALAD)) {
columns.remove(ColumnType.COLUMN_DIFFUSION);
columns.remove(ColumnType.COLUMN_FORCECONTINUOUS);
columns.remove(ColumnType.COLUMN_WELLMIXED);
Expand Down Expand Up @@ -225,8 +243,11 @@ public Object getValueAt(int row, int col) {
case COLUMN_DEPICTION:{
return scSpec.getSpeciesContext().getSpeciesPattern();
}
case COLUMN_IS2D: {
return scSpec.getIs2D();
}
case COLUMN_CLAMPED:{
return new Boolean(scSpec.isConstant());
return scSpec.isConstant();
}
case COLUMN_RULES:{
return null;
Expand All @@ -251,7 +272,7 @@ public Object getValueAt(int row, int col) {
}
}
case COLUMN_FORCECONTINUOUS:{
return new Boolean(scSpec.isForceContinuous());
return scSpec.isForceContinuous();
}
default:{
return null;
Expand Down Expand Up @@ -283,6 +304,16 @@ public boolean isCellEditable(int rowIndex, int columnIndex) {
case COLUMN_DEPICTION:{
return false;
}
case COLUMN_IS2D:{
if(!bEditable) {
return false;
}
Structure structure = speciesContextSpec.getSpeciesContext().getStructure();
if(structure instanceof Membrane) {
return true;
}
return false;
}
case COLUMN_CLAMPED:{
if(!bEditable) {
return false; // the table wants this column un-editable
Expand Down Expand Up @@ -528,6 +559,16 @@ public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
SpeciesContextSpec scSpec = getValueAt(rowIndex);
ColumnType columnType = columns.get(columnIndex);
switch (columnType){
case COLUMN_IS2D: {
boolean is2D = ((Boolean)aValue).booleanValue();
if(is2D) {
scSpec.setIs2D(true);
} else {
scSpec.setIs2D(false);
}
fireTableRowsUpdated(rowIndex,rowIndex);
break;
}
case COLUMN_CLAMPED:{
boolean bFixed = ((Boolean)aValue).booleanValue();
if (bFixed){
Expand Down Expand Up @@ -659,27 +700,36 @@ public int compare(SpeciesContextSpec speciesContextSpec1, SpeciesContextSpec sp
return name2.compareToIgnoreCase(name1);
}
}
case COLUMN_IS2D: {
Boolean bIs2D1 = speciesContextSpec1.getIs2D();
Boolean bIs2D2 = speciesContextSpec2.getIs2D();
if (ascending){
return bIs2D1.compareTo(bIs2D2);
}else{
return bIs2D2.compareTo(bIs2D1);
}
}
case COLUMN_CLAMPED : {
Boolean bClamped1 = new Boolean(speciesContextSpec1.isConstant());
Boolean bClamped2 = new Boolean(speciesContextSpec2.isConstant());
Boolean bClamped1 = speciesContextSpec1.isConstant();
Boolean bClamped2 = speciesContextSpec2.isConstant();
if (ascending){
return bClamped1.compareTo(bClamped2);
}else{
return bClamped2.compareTo(bClamped1);
}
}
case COLUMN_FORCECONTINUOUS : {
Boolean bForceContinuous1 = new Boolean(speciesContextSpec1.isForceContinuous());
Boolean bForceContinuous2 = new Boolean(speciesContextSpec2.isForceContinuous());
Boolean bForceContinuous1 = speciesContextSpec1.isForceContinuous();
Boolean bForceContinuous2 = speciesContextSpec2.isForceContinuous();
if (ascending){
return bForceContinuous1.compareTo(bForceContinuous2);
}else{
return bForceContinuous2.compareTo(bForceContinuous1);
}
}
case COLUMN_WELLMIXED : {
Boolean bWellMixed1 = new Boolean(speciesContextSpec1.isWellMixed());
Boolean bWellMixed2 = new Boolean(speciesContextSpec2.isWellMixed());
Boolean bWellMixed1 = speciesContextSpec1.isWellMixed();
Boolean bWellMixed2 = speciesContextSpec2.isWellMixed();
if (ascending){
return bWellMixed1.compareTo(bWellMixed2);
}else{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,8 @@ private static Set<String> getAutoCompletionWords() {
autoCompletionWords.add(VCML.ParticleDriftZ);
autoCompletionWords.add(VCML.Subtype);
autoCompletionWords.add(VCML.TransitionCondition);
autoCompletionWords.add(VCML.BondLength);
autoCompletionWords.add(VCML.BondLength);
autoCompletionWords.add(VCML.Is2D);
autoCompletionWords.add(VCML.Links);
autoCompletionWords.add(VCML.LinkSeparator);
autoCompletionWords.add(VCML.ParticleComponentRadius);
Expand Down Expand Up @@ -850,6 +851,7 @@ public static Set<String> getkeywords() {
keywords.add(VCML.TransitionCondition);
keywords.add(VCML.BondLength);
keywords.add(VCML.Links);
keywords.add(VCML.Is2D);
keywords.add(VCML.ParticleComponentRadius);
keywords.add(VCML.ParticleComponentDiffusionRate);
keywords.add(VCML.ParticleComponentLocation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole
gbc.gridy = 5;
gbc.anchor = GridBagConstraints.SOUTH;
gbc.insets = new Insets(2, 2, 2, 2);
sitesPanel.add(new JLabel(" X: "), gbc);
sitesPanel.add(new JLabel(" X (nm) "), gbc);

gbc = new GridBagConstraints();
gbc.gridx = 1;
Expand All @@ -536,7 +536,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole
gbc.gridy = 5;
gbc.anchor = GridBagConstraints.SOUTH;
gbc.insets = new Insets(2, 2, 2, 2);
sitesPanel.add(new JLabel(" Y: "), gbc);
sitesPanel.add(new JLabel(" Y (nm) "), gbc);

gbc = new GridBagConstraints();
gbc.gridx = 3;
Expand All @@ -552,7 +552,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole
gbc.gridy = 5;
gbc.anchor = GridBagConstraints.SOUTH;
gbc.insets = new Insets(2, 2, 2, 2);
sitesPanel.add(new JLabel(" Z: "), gbc);
sitesPanel.add(new JLabel(" Z (nm) "), gbc);

gbc = new GridBagConstraints();
gbc.gridx = 5;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ protected void addInitialConditions(Domain domain, SpeciesContextSpec[] speciesC
// species initial values (either function or constant)
//
for (int i = 0; i < speciesContextSpecs.length; i++){

SpeciesContextSpec.SpeciesContextSpecParameter initParam = null;//can be concentration or amount
Expression iniExp = null;
StructureMapping sm = getSimulationContext().getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,6 @@
*/
public class LangevinMathMapping extends AbstractStochMathMapping {

/**
* @param model cbit.vcell.model.Model
* @param geometry cbit.vcell.geometry.Geometry
*/
protected LangevinMathMapping(SimulationContext simContext, MathMappingCallback callback, NetworkGenerationRequirements networkGenerationRequirements) {
super(simContext, callback, networkGenerationRequirements);
}
Expand Down Expand Up @@ -1100,7 +1096,8 @@ private List<ParticleObservable> addObservables(
}else{
particleObservableType = ParticleObservable.ObservableType.Species;
}
ParticleObservable particleObservable = new VolumeParticleObservable(getMathSymbol(observableCountParameter, geometryClass),domain,particleObservableType);
Domain d = new Domain(geometryClass);
ParticleObservable particleObservable = new VolumeParticleObservable(getMathSymbol(observableCountParameter, geometryClass),d,particleObservableType);

switch (rbmObservable.getSequence()){
case Multimolecular:{
Expand Down Expand Up @@ -1131,7 +1128,8 @@ private List<ParticleObservable> addObservables(
if (mathMappingParameter instanceof SpeciesCountParameter){
SpeciesCountParameter speciesCountParameter = (SpeciesCountParameter)mathMappingParameter;
ParticleObservable.ObservableType particleObservableType = ParticleObservable.ObservableType.Species;
ParticleObservable particleObservable = new VolumeParticleObservable(getMathSymbol(speciesCountParameter, geometryClass),domain,particleObservableType);
Domain d = new Domain(geometryClass);
ParticleObservable particleObservable = new VolumeParticleObservable(getMathSymbol(speciesCountParameter, geometryClass),d,particleObservableType);
particleObservable.setSequence(Sequence.Multimolecular);
SpeciesPattern speciesPattern = speciesCountParameter.getSpeciesContext().getSpeciesPattern();
VolumeParticleSpeciesPattern vpsp = speciesPatternMap.get(speciesPattern);
Expand All @@ -1153,6 +1151,10 @@ private HashMap<SpeciesPattern, VolumeParticleSpeciesPattern> addSpeciesPatterns
Map<MolecularComponentPattern, LangevinParticleMolecularComponent> mcToLpmc = new LinkedHashMap<> ();
LangevinParticleMolecularType particleMolecularType = new LangevinParticleMolecularType(molecularType.getName());
SpeciesContextSpec scs = molecularTypeToSpeciesContextSpecMap.get(molecularType); // scs may be null for Sink and Source
if(scs != null) {
boolean is2D = scs.getIs2D();
particleMolecularType.setIs2D(is2D);
}
for (MolecularComponent molecularComponent : molecularType.getComponentList()) {
String pmcName = molecularComponent.getName();
String pmcId = particleMolecularType.getName() + "_" + molecularComponent.getName();
Expand Down Expand Up @@ -1231,7 +1233,18 @@ private HashMap<SpeciesPattern, VolumeParticleSpeciesPattern> addSpeciesPatterns
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());
Structure structure = speciesPatternStructureMap.get(speciesPattern);
StructureMapping sm = getSimulationContext().getGeometryContext().getStructureMapping(structure);
GeometryClass gc = sm.getGeometryClass();
SubDomain sd = mathDesc.getSubDomain(gc.getName());
Domain d = new Domain(sd);

// TODO: other useful code
// Structure structures[] = getSimulationContext().getGeometryContext().getModel().getStructures();
// GeometryClass[] geometryClass = getSimulationContext().getGeometryContext().getGeometry().getGeometryClasses();
// Structure[] mappedStructures = getSimulationContext().getGeometryContext().getStructuresFromGeometryClass(geometryClass[i]);

VolumeParticleSpeciesPattern volumeParticleSpeciesPattern = new VolumeParticleSpeciesPattern(speciesPatternName, d, structure.getName());

for (MolecularTypePattern molecularTypePattern : speciesPattern.getMolecularTypePatterns()){
ParticleMolecularType particleMolecularType = mathDesc.getParticleMolecularType(molecularTypePattern.getMolecularType().getName());
Expand Down Expand Up @@ -1393,8 +1406,10 @@ protected void refreshVariables() throws MappingException {
throw new MappingException(e.getMessage());
}
//we always add variables, all species are independent variables, no matter they are constant or not.
String countMathSymbol = getMathSymbol(spCountParm, getSimulationContext().getGeometryContext().getStructureMapping(scs.getSpeciesContext().getStructure()).getGeometryClass());
scm.setVariable(new VolumeParticleVariable(countMathSymbol,defaultDomain));
GeometryClass gc = getSimulationContext().getGeometryContext().getStructureMapping(scs.getSpeciesContext().getStructure()).getGeometryClass();
String countMathSymbol = getMathSymbol(spCountParm, gc);
Domain d = new Domain(gc);
scm.setVariable(new VolumeParticleVariable(countMathSymbol,d));
mathSymbolMapping.put(scm.getSpeciesContext(),scm.getVariable().getName());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,17 @@ public void targetPropertyChange(PropertyChangeEvent evt){
private Boolean bWellMixed = DEFAULT_WELL_MIXED;
private Boolean bForceContinuous = DEFAULT_FORCECONTINUOUS;

private Set<MolecularInternalLinkSpec> internalLinkSet = new LinkedHashSet<>(); // SpringSaLaD
// SpringSaLaD specific entities
private Set<MolecularInternalLinkSpec> internalLinkSet = new LinkedHashSet<>();
private Map<MolecularComponentPattern, SiteAttributesSpec> siteAttributesMap = new LinkedHashMap<>();
// is2D flag, used by the solver for collision / overlapping calculations, exact meaning uncertain
// membrane species may have it set to true, for compartment species is always false
// for now we have it hardcoded to false and non-editable
// TODO: slowly add it to export and persistence, eventually make it editable for membrane species
// Obs: it's really an attribute of a MolecularTypePattern, or even better of a so called "MolecularTypePatternSpec",
// but since all species in SS are single molecule by design it's okay to have it here
// TODO: add getIs2DSQL() and readIs2DSQL(), similar to getSiteAttributesSQL(), readSiteAttributesSQL
private boolean is2D = false;

protected transient java.beans.VetoableChangeSupport vetoPropertyChange;
private SpeciesContextSpecParameter[] fieldParameters = null;
Expand Down Expand Up @@ -1927,6 +1936,12 @@ void setSpeciesContextReference(SpeciesContext sc) throws MappingException{
}
}

public void setIs2D(boolean is2D) {
this.is2D = is2D;
}
public boolean getIs2D() {
return this.is2D;
}

/**
* This method was created by a SmartGuide.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

@SuppressWarnings("serial")
public class LangevinParticleMolecularType extends ParticleMolecularType {


private boolean is2D = false;
private Set<Pair<LangevinParticleMolecularComponent, LangevinParticleMolecularComponent>> internalLinkSpec = new LinkedHashSet<> ();


Expand All @@ -43,6 +44,7 @@ public String getVCML() {
if (getComponentList().size() == 0 && getAnchorList().size() == 0) {
buffer.append(" "+VCML.EndBlock+"\n");
} else {
buffer.append("\n " + VCML.Is2D + " " + getIs2D());
if(internalLinkSpec.size() > 0) {
buffer.append("\n " + VCML.Links + " " + VCML.BeginBlock);
for(Pair<LangevinParticleMolecularComponent, LangevinParticleMolecularComponent> pair : internalLinkSpec) {
Expand Down Expand Up @@ -74,6 +76,10 @@ public void read(CommentStringTokenizer tokens) throws MathFormatException {
if (token.equalsIgnoreCase(VCML.EndBlock)) {
break;
}
if(token.equalsIgnoreCase(VCML.Is2D)) {
token = tokens.nextToken();
setIs2D(Boolean.getBoolean(token));
}
if (token.equalsIgnoreCase(VCML.Links)) {
token = tokens.nextToken();
if (!token.equalsIgnoreCase(VCML.BeginBlock)){
Expand Down Expand Up @@ -124,5 +130,11 @@ public Set<Pair<LangevinParticleMolecularComponent, LangevinParticleMolecularCom
public void setInternalLinkSpec(Set<Pair<LangevinParticleMolecularComponent, LangevinParticleMolecularComponent>> internalLinkSpec) {
this.internalLinkSpec = internalLinkSpec;
}


public boolean getIs2D() {
return is2D;
}
public void setIs2D(boolean is2D) {
this.is2D = is2D;
}
}
1 change: 1 addition & 0 deletions vcell-core/src/main/java/cbit/vcell/math/VCML.java
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ public class VCML {

public final static String LangevinParticleJumpProcess = "LangevinParticleJumpProcess"; // Langevin particle
public final static String LangevinParticleMolecularType = "LangevinParticleMolecularType";
public final static String Is2D = "Is2D";
public final static String Subtype = "Subtype"; // particle Langevin / SpringSaLaD
public final static String TransitionCondition = "TransitionCondition"; // particle Langevin / SpringSaLaD
public final static String BondLength = "BondLength"; // particle Langevin / SpringSaLaD
Expand Down
Loading

0 comments on commit 1dfc9e1

Please sign in to comment.