diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index f6ee0922c..000000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -/idea/vcs.xml \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 919ce1f1f..000000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index a55e7a179..000000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 36a3a10cb..000000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/hamcrest_core_1_3.xml b/.idea/libraries/hamcrest_core_1_3.xml deleted file mode 100644 index ba798e5d1..000000000 --- a/.idea/libraries/hamcrest_core_1_3.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/junit_4_13_2.xml b/.idea/libraries/junit_4_13_2.xml deleted file mode 100644 index 8fc914f23..000000000 --- a/.idea/libraries/junit_4_13_2.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 4e85f42b0..000000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 28c2a1165..000000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml deleted file mode 100644 index e96534fb2..000000000 --- a/.idea/uiDesigner.xml +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddfb..000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/colourPalettes/pairs.xml b/colourPalettes/pairs.xml new file mode 100644 index 000000000..6be85a5a8 --- /dev/null +++ b/colourPalettes/pairs.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/colourPalettes/singles.xml b/colourPalettes/singles.xml new file mode 100644 index 000000000..db42c8722 --- /dev/null +++ b/colourPalettes/singles.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iDynoMiCS-2.iml b/iDynoMiCS-2.iml index b1e9b8aa0..623d5cf0e 100644 --- a/iDynoMiCS-2.iml +++ b/iDynoMiCS-2.iml @@ -1,183 +1,14 @@ - - - - - - - - - - - - - - - - - - - - - - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + \ No newline at end of file diff --git a/protocol/stress_test_7cc.xml b/protocol/stress_test_7cc.xml new file mode 100644 index 000000000..aeb68b9db --- /dev/null +++ b/protocol/stress_test_7cc.xml @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/agent/Agent.java b/src/agent/Agent.java index 144222f39..98c4022f8 100644 --- a/src/agent/Agent.java +++ b/src/agent/Agent.java @@ -42,6 +42,13 @@ public class Agent implements AspectInterface, Settable, Instantiable protected static int UNIQUE_ID = 0; protected int _uid; + public static class AgentComparator implements java.util.Comparator { + @Override + public int compare(Agent a, Agent b) { + return a._uid - b._uid; + } + } + /** * The compartment the agent is currently in */ diff --git a/src/analysis/quantitative/Raster.java b/src/analysis/quantitative/Raster.java index 2284078fb..387fb609a 100644 --- a/src/analysis/quantitative/Raster.java +++ b/src/analysis/quantitative/Raster.java @@ -60,7 +60,7 @@ public class Raster { /** * Include additional debug and visual analysis output */ - private boolean _verbose = false; + private boolean _verbose = true; /* raster sizes including margins (rX and rY) and actual size */ private int rX, rY; @@ -143,6 +143,8 @@ public Raster(Compartment compartment, boolean verbose) */ public void rasterize( double voxelLength ) { + /* ensure up-to-date spatial tree */ + _agentContainer.refreshSpatialRegistry(); /* domain dimension lengths */ double[] dimLengths = _shape.getDimensionLengths(); @@ -177,7 +179,7 @@ public void rasterize( double voxelLength ) ( (Body) a.get( AspectRef.agentBody ) ).getSurfaces() ) { if ( _shape.getCollision(). - intersect( s, v, 0.0 ) &! colliders.contains(a) ) + intersect( v, s,0.0 ) ) //&! colliders.contains(a) { colliders.add(a); break; diff --git a/src/compartment/Compartment.java b/src/compartment/Compartment.java index 9e76d3d1d..66deae0f8 100644 --- a/src/compartment/Compartment.java +++ b/src/compartment/Compartment.java @@ -278,6 +278,7 @@ else if (simulatedLengths.length != 0) */ Spawner spawner; TreeMap spawners = new TreeMap(); + List spawnerList = new LinkedList(); for ( Element e : XmlHandler.getElements( xmlElem, XmlRef.spawnNode) ) { if ( e.hasAttribute( XmlRef.classAttribute ) ) @@ -294,9 +295,12 @@ else if (simulatedLengths.length != 0) + "by simulator."); } spawners.put(priority, spawner); + spawnerList.add(spawner); } } - /* verify whether this always returns in correct order (it should) */ + + + Collections.sort(spawnerList, new Spawner.spawnComparator()); for( Spawner s : spawners.values() ) s.spawn(); diff --git a/src/compartment/agentStaging/Spawner.java b/src/compartment/agentStaging/Spawner.java index 27f1d1f43..0e0ce6d26 100644 --- a/src/compartment/agentStaging/Spawner.java +++ b/src/compartment/agentStaging/Spawner.java @@ -54,6 +54,13 @@ public abstract class Spawner implements Settable, Instantiable, AspectInterface * the Spawner super class. */ protected BoundingBox _spawnDomain = new BoundingBox(); + + public static class spawnComparator implements java.util.Comparator { + @Override + public int compare(Spawner a, Spawner b) { + return a.getPriority() - b.getPriority(); + } + } public void instantiate(Element xmlElem, Settable parent) { diff --git a/src/dataIO/DrawMediator.java b/src/dataIO/DrawMediator.java index 1b3c1fbec..27de66cf1 100644 --- a/src/dataIO/DrawMediator.java +++ b/src/dataIO/DrawMediator.java @@ -1,5 +1,6 @@ package dataIO; +import java.util.Collections; import java.util.List; import agent.Agent; @@ -202,7 +203,9 @@ else if (_shape instanceof CylindricalShape) /* Draw all located agents. */ - for ( Agent a: _agents.getAllLocatedAgents() ) + List sortedAgents = _agents.getAllLocatedAgents(); + Collections.sort(sortedAgents, new Agent.AgentComparator()); + for ( Agent a: sortedAgents ) if ( a.isAspect(BODY) ) { List surfaces = ((Body) a.getValue(BODY)).getSurfaces(); diff --git a/src/expression/Expression.java b/src/expression/Expression.java index 6847cb7f5..651f15440 100644 --- a/src/expression/Expression.java +++ b/src/expression/Expression.java @@ -361,6 +361,9 @@ else if ( ! term.isEmpty() ) /* * Do the operator stuff here, in the same order that they appear in * OPERATORS. + * FIXME: we should group operators according to PEMDAS order instead of going 1 by 1 + * eg. if multiplication comes after division in an expression it should not be handled first! + * for now always use breakets to make sure evaluation order is correct. */ for ( String oper : OPERATORS ) for ( Integer i : eval.keySet() ) diff --git a/src/gui/GuiMenu.java b/src/gui/GuiMenu.java index ea08abdec..f5b593152 100644 --- a/src/gui/GuiMenu.java +++ b/src/gui/GuiMenu.java @@ -181,6 +181,11 @@ private static JMenu interactionMenu() menuItem.getAccessibleContext().setAccessibleDescription( "Draw raster to file"); menu.add(menuItem); + + menuItem = new JMenuItem(new GuiMenu.OccuranceMap()); + menuItem.getAccessibleContext().setAccessibleDescription( + "Draw agent occurance to file"); + menu.add(menuItem); /* * Draw species diagram */ @@ -519,6 +524,39 @@ public void actionPerformed(ActionEvent e) { } } + + public static class OccuranceMap extends AbstractAction + { + + /** + * + */ + private static final long serialVersionUID = 3011117385035501302L; + + public OccuranceMap() + { + super("OccuranceMap"); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (Helper.compartmentAvailable()) + { + if ( Helper.selectSpatialCompartment() == null ) + Log.printToScreen("No spatial compartment available.", + false ); + { + Raster raster = new Raster( + Helper.selectSpatialCompartment(), true ); + raster.rasterize( Double.valueOf( + Helper.obtainInput( null, "Raster scale" ) ) ); + raster.plot( raster.occuranceMap(Helper.obtainInput( null, "filter")) , 1.0, + Helper.obtainInput( null, "filename") ); + } + } + } + + } public static class Draw extends AbstractAction { diff --git a/src/idynomics/Global.java b/src/idynomics/Global.java index 02e7d91be..802ed45ca 100644 --- a/src/idynomics/Global.java +++ b/src/idynomics/Global.java @@ -131,7 +131,7 @@ public void updateSettings() /** * Version description. */ - public static String version_description = "July 2023"; + public static String version_description = "November 2023"; /** * Version number of this iteration of iDynoMiCS - required by update @@ -139,7 +139,7 @@ public void updateSettings() * * suggested Major.Minor.YYMMDD */ - public static String version_number = "2.0.230703"; + public static String version_number = "2.0.231109"; /** * default output location diff --git a/src/idynomics/Simulator.java b/src/idynomics/Simulator.java index f7c451ee8..095f4c9a7 100644 --- a/src/idynomics/Simulator.java +++ b/src/idynomics/Simulator.java @@ -122,7 +122,7 @@ public void instantiate(Element xmlElem, Settable parent) String seed = XmlHandler.gatherAttribute(xmlElem, XmlRef.seed); if ( ! Helper.isNullOrEmpty(seed) ) - ExtraMath.initialiseRandomNumberGenerator(Long.valueOf(seed)); + ExtraMath.initialiseRandomNumberGenerator(Double.valueOf(seed).longValue()); else seed = String.valueOf( ExtraMath.seed ); Log.out("Random seed: " + seed); diff --git a/src/idynomics/launchable/ProtocolLaunch.java b/src/idynomics/launchable/ProtocolLaunch.java index 2b8ad9bdd..cb66cafd4 100644 --- a/src/idynomics/launchable/ProtocolLaunch.java +++ b/src/idynomics/launchable/ProtocolLaunch.java @@ -5,7 +5,7 @@ public class ProtocolLaunch implements Launchable { @Override - public void initialize(String[] args) + public void initialize(String[] args) { for ( int i = 1; i < args.length; i++ ) { @@ -13,6 +13,11 @@ public void initialize(String[] args) break; Idynomics.setupSimulator( args[i] ); Idynomics.launchSimulator(); + try { + Idynomics.simThread.join(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } } diff --git a/src/idynomics/launchable/SamplerLaunch.java b/src/idynomics/launchable/SamplerLaunch.java index 524608d31..45304ad24 100644 --- a/src/idynomics/launchable/SamplerLaunch.java +++ b/src/idynomics/launchable/SamplerLaunch.java @@ -16,7 +16,7 @@ public void initialize(String[] args) boolean customSampling = false; int p, r; - if ( args == null || args.length == 1 || args[1] == null ) + if ( args == null || args.length <= 1 || args[1] == null ) { samplingChoice = Sampler.SampleMethod.valueOf( Helper.obtainInput( Sampler.SampleMethod.values(), @@ -25,7 +25,7 @@ public void initialize(String[] args) else samplingChoice = Sampler.SampleMethod.valueOf( args[1] ); - if ( args == null || args.length == 2 || args[2] == null ) + if ( args == null || args.length <= 2 || args[2] == null ) { if( Idynomics.global.protocolFile == null ) { @@ -44,7 +44,7 @@ public void initialize(String[] args) customSampling = true; p = 0; /* not used */ } - else if ( args == null || args.length == 3 || args[3] == null ) + else if ( args == null || args.length <= 3 || args[3] == null ) { p = Integer.valueOf( Helper.obtainInput("", "Number sampling levels/ stripes: ",true) ); @@ -53,7 +53,7 @@ else if ( args == null || args.length == 3 || args[3] == null ) p = Integer.valueOf( args[3] ); if ( samplingChoice == Sampler.SampleMethod.MORRIS && - ( args == null || args.length == 4 || args[4] == null ) ) + ( args == null || args.length <= 4 || args[4] == null ) ) { r = Integer.valueOf( Helper.obtainInput("", "Number of repetitions: ",true) ); @@ -61,7 +61,7 @@ else if ( args == null || args.length == 3 || args[3] == null ) } else if ( ( samplingChoice == Sampler.SampleMethod.SIMPLE || samplingChoice == Sampler.SampleMethod.LHC ) && - ( args == null || args.length == 4 || args[4] == null ) ) + ( args == null || args.length <= 4 || args[4] == null ) ) { boolean force_round = Helper.obtainInput("Force rounding?",true); if( force_round ) diff --git a/src/lib/jogl/gluegen-rt-natives-windows-amd64.jar b/src/lib/jogl/gluegen-rt-natives-windows-amd64.jar index 992a56638..2ae552be1 100644 Binary files a/src/lib/jogl/gluegen-rt-natives-windows-amd64.jar and b/src/lib/jogl/gluegen-rt-natives-windows-amd64.jar differ diff --git a/src/lib/jogl/gluegen-rt.jar b/src/lib/jogl/gluegen-rt.jar index 2025bf878..51cd1a882 100644 Binary files a/src/lib/jogl/gluegen-rt.jar and b/src/lib/jogl/gluegen-rt.jar differ diff --git a/src/lib/jogl/jogl-all-natives-windows-amd64.jar b/src/lib/jogl/jogl-all-natives-windows-amd64.jar index d8f66a16a..7b8dcff73 100644 Binary files a/src/lib/jogl/jogl-all-natives-windows-amd64.jar and b/src/lib/jogl/jogl-all-natives-windows-amd64.jar differ diff --git a/src/lib/jogl/jogl-all.jar b/src/lib/jogl/jogl-all.jar index dc83f61bb..ab93476ac 100644 Binary files a/src/lib/jogl/jogl-all.jar and b/src/lib/jogl/jogl-all.jar differ diff --git a/src/processManager/library/AgentScraper.java b/src/processManager/library/AgentScraper.java index 05ef09e94..5f45e6e11 100644 --- a/src/processManager/library/AgentScraper.java +++ b/src/processManager/library/AgentScraper.java @@ -3,6 +3,7 @@ import java.util.LinkedList; import java.util.List; +import linearAlgebra.Vector; import org.w3c.dom.Element; import agent.Agent; @@ -12,6 +13,8 @@ import processManager.ProcessDeparture; import referenceLibrary.AspectRef; import surface.Point; +import surface.Surface; +import surface.Voxel; import utility.Helper; @@ -19,7 +22,8 @@ * Simple process that removes agents above a certain height. * This can be used to maintain a maximum thickness for a biofilm. * - * Author - Tim Foster trf896@student.bham.ac.uk + * Author - Tim Foster trf896@student.bham.ac.uk, + * Bastiaan Cockx @BastiaanCockx (baco@dtu.dk), DTU, Denmark. * */ @@ -29,6 +33,8 @@ public class AgentScraper extends ProcessDeparture { private String MAX_THICKNESS = AspectRef.maxThickness; private double _maxThickness; + + private boolean _centerPointRemoval; public void init( Element xmlElem, EnvironmentContainer environment, AgentContainer agents, String compartmentName) @@ -38,29 +44,48 @@ public void init( Element xmlElem, EnvironmentContainer environment, this._maxThickness = Helper.setIfNone( this.getDouble( MAX_THICKNESS ), agents.getShape().getDimensionLengths()[1] ); + + this._centerPointRemoval = Helper.setIfNone( + this.getBoolean( AspectRef.centerPointRemoval ), + false ); } - + + /** + * + * @return List of agents to be removed + * + * TODO: currently the agent scraper always considers dimension [1] for scraping, if this is made settable by the + * user, the scraper can also be used for other model configurations. + */ @Override public LinkedList agentsDepart() { LinkedList departures = new LinkedList(); - - List allAgents = this._agents.getAllAgents(); - - for ( Agent a : allAgents ) - { - List points = ((Body) a.getValue(AspectRef.agentBody)). - getPoints(); - for (Point p: points) - { - if (p.getPosition()[1] > this._maxThickness) - { - departures.add(a); - break; + + /* scrape agents based on their mass point position */ + if(this._centerPointRemoval) { + List allAgents = this._agents.getAllAgents(); + + for (Agent a : allAgents) { + List points = ((Body) a.getValue(AspectRef.agentBody)). + getPoints(); + for (Point p : points) { + if (p.getPosition()[1] > this._maxThickness) { + departures.add(a); + break; + } } } } - + /* scrape agents based on agent-region collision */ + else { + double[] dimLengths = this._agents.getShape().getDimensionLengths(); + double[] lowerBounds = Vector.zeros(dimLengths); + lowerBounds[1] += this._maxThickness; + /* note that in this specific case we don't need additional steps to confirm actual collision as voxels is + identical to it's bounding box and we are looking at the full depth and with of the domain */ + departures.addAll( this._agents.treeSearch(new Voxel(lowerBounds,dimLengths),0.0) ); + } return departures; } diff --git a/src/processManager/library/Analysis.java b/src/processManager/library/Analysis.java new file mode 100644 index 000000000..046f03b99 --- /dev/null +++ b/src/processManager/library/Analysis.java @@ -0,0 +1,110 @@ +package processManager.library; + +import compartment.AgentContainer; +import compartment.EnvironmentContainer; +import org.w3c.dom.Element; + +import analysis.FilteredTable; +import analysis.quantitative.Raster; +import dataIO.CsvExport; +import dataIO.Log; +import dataIO.Log.Tier; +import referenceLibrary.AspectRef; +import utility.Helper; +import idynomics.Idynomics; +import linearAlgebra.Vector; +import processManager.ProcessManager; + +/** + * + * @author Bastiaan Cockx @BastiaanCockx (baco@env.dtu.dk), DTU, Denmark. + * + */ +public class Analysis extends ProcessManager { + + + public static String FILE_PREFIX = AspectRef.filePrefix; + + /** + * The CSV exporter. + */ + protected CsvExport _csvExport = new CsvExport(); + + /** + * The prefix for the file output path. + */ + protected String _prefix; + + protected String[] header = new String[]{ + "#", + "time" + }; + + + /* *********************************************************************** + * CONSTRUCTORS + * **********************************************************************/ + + @Override + public void init(Element xmlElem, EnvironmentContainer environment, + AgentContainer agents, String compartmentName) + { + super.init(xmlElem, environment, agents, compartmentName); + + this._prefix = this.getString(FILE_PREFIX); + + /* Initiate new file. */ + this._csvExport.createCustomFile(this._prefix); + + this._csvExport.writeLine( getHeader() + Raster.getHeader() ); + + } + + + /* *********************************************************************** + * STEPPING + * **********************************************************************/ + + @Override + protected void internalStep() + { + Raster raster = new Raster( this._agents ); + + raster.rasterize( this.getDouble( AspectRef.rasterScale ) ); + + double[] time = new double[] { + Idynomics.simulator.timer.getCurrentIteration(), + this.getTimeForNextStep() }; + + String line = Vector.toString( time ) + "," + raster.toString(); + this._csvExport.writeLine( line ); + + /* output table summary to log/console */ + Log.out(Tier.EXPRESSIVE, "Structural analysis:\n" + + getHeader() + "," + Raster.getHeader() + "\n" + line ); + } + + + public String getHeader() + { + + StringBuilder builder = new StringBuilder(); + for ( int i = 0; i < header.length; i++) + { + builder.append( header[i] ); + builder.append( Vector.DELIMITER ); + } + return builder.toString(); + } + + /** + * TODO this pm needs a post run call to properly close the file, + * alternatively we could open and close the file each time step. + * Doing neither should still release the file after the program is + * closed, but this is not a correct way of handling this. + */ + protected void postRun() + { + this._csvExport.closeFile(); + } + } diff --git a/src/processManager/library/AnalysisTrait.java b/src/processManager/library/AnalysisTrait.java new file mode 100644 index 000000000..e7bf8ca9b --- /dev/null +++ b/src/processManager/library/AnalysisTrait.java @@ -0,0 +1,198 @@ +package processManager.library; + +import java.util.Arrays; +import java.util.LinkedList; + +import compartment.AgentContainer; +import compartment.EnvironmentContainer; +import org.w3c.dom.Element; + + +import analysis.quantitative.Raster; +import dataIO.CsvExport; +import dataIO.Log; +import dataIO.Log.Tier; +import referenceLibrary.AspectRef; +import utility.Helper; +import idynomics.Idynomics; +import linearAlgebra.Vector; +import processManager.ProcessManager; + +/** + * FIXME AB and BA are inverted? + * @author Bastiaan Cockx @BastiaanCockx (baco@env.dtu.dk), DTU, Denmark. + * + */ +public class AnalysisTrait extends ProcessManager { + + public static String FILE_PREFIX = AspectRef.filePrefix; + + /** + * The CSV exporter. + */ + protected CsvExport _csvExport = new CsvExport(); + + /** + * The prefix for the file output path. + */ + protected String _prefix; + + protected String[] filters; + + protected int[] colocalizationSteps; + + protected String[] header = new String[]{ + "#", + "time" + }; + + + /* *********************************************************************** + * CONSTRUCTORS + * **********************************************************************/ + + @Override + public void init(Element xmlElem, EnvironmentContainer environment, + AgentContainer agents, String compartmentName) + { + super.init(xmlElem, environment, agents, compartmentName); + + this._prefix = this.getString(FILE_PREFIX); + + /* Initiate new file. */ + this._csvExport.createCustomFile(this._prefix); + + filters = this.getStringA( AspectRef.filterSet ); + + String steps = Helper.setIfNone( + this.getString( AspectRef.colocalizationSteps ) , "1" ); + this.colocalizationSteps = Vector.intFromString( steps ); + + this._csvExport.writeLine( getHeader() ); + } + + + /* *********************************************************************** + * STEPPING + * **********************************************************************/ + + @Override + protected void internalStep() + { + Raster raster = new Raster( this._agents ); + + raster.rasterize( this.getDouble( AspectRef.rasterScale ) ); + + double[] time = new double[] { + Idynomics.simulator.timer.getCurrentIteration(), + this.getTimeForNextStep() }; + + StringBuilder builder = new StringBuilder(); + builder.append( Vector.toString( time ) ); + String line = ""; + + for ( int i = 0; i < this.filters.length; i++) + { + builder.append(Vector.DELIMITER); + builder.append( raster.averageDiffusionDistance(filters[i])); + } + + LinkedList combList = combinations( filters ); + for ( int i = 0; i < combList.size(); i++) + { + int[] distAB = raster.distanceVector( + combList.get(i)[0], combList.get(i)[1]); + int[] distBA = raster.distanceVector( + combList.get(i)[1], combList.get(i)[0]); + + if( distAB != null ) { + builder.append(Vector.DELIMITER); + builder.append(raster.averageDist(distAB)); + } + else + { + builder.append(Vector.DELIMITER); + builder.append(Double.NaN); + } + + if( distBA != null ) { + builder.append( Vector.DELIMITER ); + builder.append( raster.averageDist( distBA ) ); + } + else + { + builder.append(Vector.DELIMITER); + builder.append(Double.NaN); + } + + builder.append( Vector.DELIMITER ); + for ( int j = 0; j < colocalizationSteps.length; j++) + builder.append( + (( distBA != null && distAB != null) ? + Vector.toString( raster.colocalization( + distAB, distBA, colocalizationSteps[j] ) ) + : Double.NaN+Vector.DELIMITER+Double.NaN) + + (j < colocalizationSteps.length-1 ? Vector.DELIMITER : "" ) ); + + line = builder.toString().substring( 0, builder.length()-1 ); + } + + + this._csvExport.writeLine( line ); + + /* output table summary to log/console */ + Log.out(Tier.EXPRESSIVE, "Trait analysis:\n" + + getHeader() + "\n" + builder.toString() ); + } + + public LinkedList combinations( String[] input ) + { + LinkedList out = new LinkedList(); + for ( int i = 1; i < input.length; i++) + out.add( new String[] { input[0], input[i] } ); + if( input.length > 2 ) + out.addAll( combinations( + Arrays.copyOfRange( input, 1, input.length ) ) ); + return out; + } + + public String getHeader() + { + + StringBuilder builder = new StringBuilder(); + for ( int i = 0; i < header.length; i++) + { + builder.append( header[i] ); + builder.append( Vector.DELIMITER ); + } + for ( int i = 0; i < this.filters.length; i++) + { + builder.append( "average diff " + filters[i] ); + builder.append(Vector.DELIMITER); + } + LinkedList combList = combinations( filters ); + for ( int i = 0; i < combList.size(); i++) + { + builder.append( "average codist AB " + combList.get(i)[0] + " " + combList.get(i)[1] + + ", BA,"); + for ( int j = 0; j < colocalizationSteps.length; j++) + { + builder.append( colocalizationSteps[j] + "AB, " + + colocalizationSteps[j] + "BA," ); + } + } + String comb = builder.toString().substring( 0, builder.length()-1 ); + return comb; + } + + /** + * TODO this pm needs a post run call to properly close the file, + * alternatively we could open and close the file each time step. + * Doing neither should still release the file after the program is + * closed, but this is not a correct way of handling this. + */ + protected void postRun() + { + this._csvExport.closeFile(); + } +} diff --git a/src/processManager/library/GraphicalOutput.java b/src/processManager/library/GraphicalOutput.java index 254b32dad..b079bd90a 100644 --- a/src/processManager/library/GraphicalOutput.java +++ b/src/processManager/library/GraphicalOutput.java @@ -2,10 +2,7 @@ import static grid.ArrayType.CONCN; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import idynomics.Idynomics; import org.w3c.dom.Element; @@ -261,8 +258,10 @@ else if (_shape instanceof CylindricalShape) /* * ^^ */ - - for ( Agent a: _agents.getAllLocatedAgents() ) + List sortedAgents = this._agents.getAllLocatedAgents(); + Collections.sort(sortedAgents, new Agent.AgentComparator()); + + for ( Agent a: sortedAgents ) if ( a.isAspect(BODY) ) { List surfaces = ((Body) a.getValue(BODY)).getSurfaces(); diff --git a/src/referenceLibrary/AspectRef.java b/src/referenceLibrary/AspectRef.java index 10aba7670..741c37fd4 100644 --- a/src/referenceLibrary/AspectRef.java +++ b/src/referenceLibrary/AspectRef.java @@ -15,8 +15,7 @@ public class AspectRef { - - public static String[] getAllOptions() + public static String[] getAllOptions() { Field[] fields = AspectRef.class.getFields(); String[] options = new String[fields.length]; @@ -560,7 +559,21 @@ public static String[] getAllOptions() */ public static final String regionDepth = "regionDepth"; - + /** + * specify target compartment by name. + */ + public static final String compartmentName = "compartmentName"; + + /** + * Array of filters for spatial analysis + */ + public static final String filterSet = "filterSet"; + + /** + * set of distances to do colocalization analysis for. + */ + public static final String colocalizationSteps = "colocalizationSteps"; + /** * The name of a dimension (X, Y or Z) */ @@ -707,4 +720,6 @@ public static String[] getAllOptions() public static String youngsModulus = "youngsModulus"; public static String poissonRatio = "poissonRatio"; + + public static String centerPointRemoval = "centerPointRemoval"; } diff --git a/src/referenceLibrary/ClassRef.java b/src/referenceLibrary/ClassRef.java index 9d371f6e2..5af99784b 100644 --- a/src/referenceLibrary/ClassRef.java +++ b/src/referenceLibrary/ClassRef.java @@ -491,6 +491,12 @@ public static String path(String name) */ public final static String agentsArriveInChemostat = processManager.library.AgentsArriveInChemostat.class.getName(); + + public final static String analysis = + processManager.library.Analysis.class.getName(); + + public final static String analysisTrait = + processManager.library.AnalysisTrait.class.getName(); /* ************************************************************************ * IdynoMiCS main classes diff --git a/src/render/AgentMediator.java b/src/render/AgentMediator.java index 785db4d86..9586ceb91 100644 --- a/src/render/AgentMediator.java +++ b/src/render/AgentMediator.java @@ -5,12 +5,14 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Collections; import com.jogamp.opengl.GL2; import com.jogamp.opengl.GLAutoDrawable; import com.jogamp.opengl.glu.GLU; import com.jogamp.opengl.glu.GLUquadric; import com.jogamp.opengl.math.Quaternion; +import com.jogamp.opengl.math.Vec3f; import com.jogamp.opengl.util.gl2.GLUT; import agent.Agent; @@ -193,7 +195,7 @@ public void colStep() /** * assign agent container via the constructor - * @param agents + * @param c: Compartment to be rendered. */ public AgentMediator(Compartment c) { @@ -267,9 +269,11 @@ public void draw(GLAutoDrawable drawable) { * when we want to disable depth test we draw the domain here */ // draw(_shape); - + + List sortedAgents = this._agents.getAllLocatedAgents(); + Collections.sort(sortedAgents, new Agent.AgentComparator()); /* get the surfaces from the agents */ - for ( Agent a : this._agents.getAllLocatedAgents() ) + for ( Agent a : sortedAgents) { /* cycle through the agent surfaces */ @@ -578,10 +582,10 @@ private void glRotated(double[] direc){ Quaternion quat = new Quaternion(); /* this will create a quaternion, so that we rotate from looking * along the Z-axis (which is the default orientation) */ - quat.setLookAt(Vector.toFloat(direc), _orthoZ, _orthoX, _orthoY, _orthoZ); + quat.setLookAt( new Vec3f(Vector.toFloat(direc)), new Vec3f(_orthoZ), new Vec3f(_orthoX), new Vec3f(_orthoY), new Vec3f(_orthoZ)); /* transform the quaternion into a rotation matrix and apply it */ //TODO: is there a way to make openGL use the quaternion directly? - _gl.glMultMatrixf(quat.toMatrix(_rotTemp, 0), 0); + _gl.glMultMatrixf(quat.toMatrix(_rotTemp), 0); } private void drawVoxel(Shape shape, int[] coord) diff --git a/src/render/Render.java b/src/render/Render.java index 022d144cd..0c4e43ff5 100644 --- a/src/render/Render.java +++ b/src/render/Render.java @@ -133,7 +133,7 @@ public class Render implements GLEventListener, Runnable { private boolean _dispFps = false; private Font font = new Font("consolas", Font.PLAIN, 10); - private TextRenderer textRenderer = new TextRenderer(font); + /* * screendump */ @@ -171,6 +171,7 @@ public void display(GLAutoDrawable drawable) { } if ( this._dispFps ) { + TextRenderer textRenderer = new TextRenderer(font); textRenderer.setColor(Color.YELLOW); textRenderer.setSmoothing(true); gl.glLoadIdentity(); diff --git a/src/utility/Helper.java b/src/utility/Helper.java index 812748a40..a916cc955 100644 --- a/src/utility/Helper.java +++ b/src/utility/Helper.java @@ -296,7 +296,7 @@ else if ( input == null ) public static boolean confirmation(String input) { for ( String s : confirmations ) - if ( s == input ) + if ( input.equals(s) ) return true; return false; } @@ -309,7 +309,7 @@ public static boolean confirmation(String input) public static boolean rejection(String input) { for ( String s : rejections ) - if ( s == input ) + if ( input.equals(s) ) return true; return false; } @@ -776,7 +776,7 @@ public static boolean expressionParseable(String strParse) new Expression( strParse ); } catch (NumberFormatException | StringIndexOutOfBoundsException - | NullPointerException f) + | NullPointerException | StackOverflowError f) { return false; } @@ -794,7 +794,7 @@ public static boolean formatParseable(String strParse) new Expression( strParse ).format( Idynomics.unitSystem ); } catch (NumberFormatException | StringIndexOutOfBoundsException - | NullPointerException f) + | NullPointerException | StackOverflowError f) { return false; }