use of org.vcell.util.CoordinateIndex in project vcell by virtualcell.
the class DataSetControllerImpl method interpolateFindNearFarIndex.
private VolumeIndexNearFar interpolateFindNearFarIndex(CartesianMesh mesh, int membraneIndex, boolean isInside, boolean isRegion) {
int volIndexNear = -1;
int volIndexFar = -1;
if (isInside) {
volIndexNear = mesh.getMembraneElements()[membraneIndex].getInsideVolumeIndex();
volIndexFar = volIndexNear + (volIndexNear - mesh.getMembraneElements()[membraneIndex].getOutsideVolumeIndex());
} else {
volIndexNear = mesh.getMembraneElements()[membraneIndex].getOutsideVolumeIndex();
volIndexFar = volIndexNear + (volIndexNear - mesh.getMembraneElements()[membraneIndex].getInsideVolumeIndex());
}
// Check if totally out of bounds
if (volIndexFar < 0 || volIndexFar > mesh.getNumVolumeElements()) {
volIndexFar = -1;
} else {
// Check if index wrapped
CoordinateIndex coordFar = mesh.getCoordinateIndexFromVolumeIndex(volIndexFar);
CoordinateIndex coordNear = mesh.getCoordinateIndexFromVolumeIndex(volIndexNear);
if (Math.abs(coordFar.x - coordNear.x) > 1 || Math.abs(coordFar.y - coordNear.y) > 1 || Math.abs(coordFar.z - coordNear.z) > 1) {
volIndexFar = -1;
} else {
// Check if in same region
if (mesh.getVolumeRegionIndex(volIndexNear) != mesh.getVolumeRegionIndex(volIndexFar)) {
volIndexFar = -1;
}
}
}
volIndexNear = (isRegion ? mesh.getVolumeRegionIndex(volIndexNear) : volIndexNear);
volIndexFar = (volIndexFar == -1 ? -1 : (isRegion ? mesh.getVolumeRegionIndex(volIndexFar) : volIndexFar));
return new VolumeIndexNearFar(volIndexNear, volIndexFar);
}
use of org.vcell.util.CoordinateIndex in project vcell by virtualcell.
the class DataSetControllerImpl method getSpatialNeighborData.
/**
* Insert the method's description here.
* Creation date: (2/10/2007 1:37:32 PM)
* @return double[]
*/
private double[] getSpatialNeighborData(CartesianMesh mesh, int volumeIndex, int numArgs, double time, Vector<SimDataHolder> dataSetList, double[] args) {
int regionIndex = mesh.getVolumeRegionIndex(volumeIndex);
double[] spatialNeighborData = args;
int argCount = numArgs;
for (int i = 0; i < 12; i += 1) {
int x = (i == 0 ? -1 : 0) + (i == 1 ? 1 : 0) + (i == 6 ? -2 : 0) + (i == 7 ? 2 : 0);
int y = (i == 2 ? -1 : 0) + (i == 3 ? 1 : 0) + (i == 8 ? -2 : 0) + (i == 9 ? 2 : 0);
int z = (i == 4 ? -1 : 0) + (i == 5 ? 1 : 0) + (i == 10 ? -2 : 0) + (i == 11 ? 2 : 0);
// for(int z=-1;z<=1;z+=2){
// for(int y=-1;y<=1;y+=2){
// for(int x=-1;x<=1;x+=2){
spatialNeighborData[argCount] = time;
argCount += 1;
//
CoordinateIndex ci = mesh.getCoordinateIndexFromVolumeIndex(volumeIndex);
ci.x += x;
ci.y += y;
ci.z += z;
if (ci.x >= 0 && ci.x < mesh.getSizeX() && ci.y >= 0 && ci.y < mesh.getSizeY() && ci.z >= 0 && ci.z < mesh.getSizeZ()) {
// Inside boundary of data
Coordinate coord = mesh.getCoordinate(ci);
int neighborVolumeIndex = mesh.getVolumeIndex(ci);
int neighborRegionIndex = mesh.getVolumeRegionIndex(neighborVolumeIndex);
if (neighborRegionIndex == regionIndex) {
spatialNeighborData[argCount] = coord.getX();
argCount += 1;
spatialNeighborData[argCount] = coord.getY();
argCount += 1;
spatialNeighborData[argCount] = coord.getZ();
argCount += 1;
for (int j = 0; j < numArgs - TXYZ_OFFSET; j++) {
SimDataHolder simDataHolder = dataSetList.elementAt(j);
if (simDataHolder.getVariableType().equals(VariableType.VOLUME)) {
spatialNeighborData[argCount] = simDataHolder.getData()[neighborVolumeIndex];
argCount += 1;
} else {
throw new RuntimeException("only VOLUME variables allowed in grad functions");
}
}
continue;
}
// else{//Outside the current region, mark neighbor as undefined
// for(int j=0;j<(numArgs-4);j+= 1){//four less because time and coordinate are inserted already
// spatialNeighborData[argCount] = Double.NaN;
// argCount+= 1;
// }
// }
}
// Outside boundary of data, mark neighbor as undefined
for (int j = 0; j < (numArgs - 1); j += 1) {
// one less because time is inserted already
spatialNeighborData[argCount] = Double.NaN;
argCount += 1;
}
// }
// }
// }
// }
}
return spatialNeighborData;
}
use of org.vcell.util.CoordinateIndex in project vcell by virtualcell.
the class SpatialSelectionVolume method sampleSymmetric.
/**
* Insert the method's description here.
* Creation date: (10/5/2004 7:19:49 AM)
*/
private SSHelper sampleSymmetric() throws Exception {
//
if (!isSymmetric()) {
return null;
}
SampledCurve ssCurve = getCurveSelectionInfo().getCurve().getSampledCurve();
Vector pointsV = ssCurve.getControlPointsVector();
if (pointsV.size() < 2) {
return null;
}
final int INDEX_SPACE_INCR = 100;
int[] indexes = new int[INDEX_SPACE_INCR];
int indexCounter = 0;
Vector snappedV = new Vector();
CoordinateIndex lastCI = null;
for (int i = 0; i < pointsV.size(); i += 1) {
if (i > 0) {
CoordinateIndex c1 = getMesh().getCoordinateIndexFromFractionalIndex(getMesh().getFractionalCoordinateIndex((Coordinate) pointsV.elementAt(i - 1)));
CoordinateIndex c2 = getMesh().getCoordinateIndexFromFractionalIndex(getMesh().getFractionalCoordinateIndex((Coordinate) pointsV.elementAt(i)));
int dx = c2.x - c1.x;
if (dx != 0) {
dx /= Math.abs(dx);
}
int dy = c2.y - c1.y;
if (dy != 0) {
dy /= Math.abs(dy);
}
int dz = c2.z - c1.z;
if (dz != 0) {
dz /= Math.abs(dz);
}
while (true) {
if (!c1.compareEqual(lastCI)) {
if (indexCounter == indexes.length) {
// Make more space
int[] temp = new int[indexes.length + INDEX_SPACE_INCR];
System.arraycopy(indexes, 0, temp, 0, indexes.length);
indexes = temp;
}
indexes[indexCounter] = getConvertedIndexFromCI(c1);
snappedV.add(getMesh().getCoordinate(c1));
indexCounter += 1;
}
if (c1.compareEqual(c2)) {
break;
}
c1.x += dx;
c1.y += dy;
c1.z += dz;
// sanity check to prevent infinite loop, this shouldn't happen
if (c1.x < 0 || c1.y < 0 || c1.z < 0 || c1.x >= getMesh().getSizeX() || c1.y >= getMesh().getSizeY() || c1.z >= getMesh().getSizeZ()) {
throw new Exception(this.getClass().getName() + ".sampleSymmetric failed");
}
}
;
lastCI = c2;
}
}
if (indexCounter > 0) {
return makeSSHelper(indexes, indexCounter, snappedV, false);
}
return null;
}
use of org.vcell.util.CoordinateIndex in project vcell by virtualcell.
the class SpatialSelectionVolume method isSymmetric.
/**
* Insert the method's description here.
* Creation date: (10/3/2004 12:54:59 PM)
* @return boolean
*/
private boolean isSymmetric() {
if (!(getCurveSelectionInfo().getCurve() instanceof SampledCurve)) {
return false;
}
SampledCurve ssCurve = getCurveSelectionInfo().getCurve().getSampledCurve();
Vector pointsV = ssCurve.getControlPointsVector();
if (pointsV.size() == 1) {
return true;
}
for (int i = 0; i < pointsV.size(); i += 1) {
if (i > 0) {
CoordinateIndex c1 = getMesh().getCoordinateIndexFromFractionalIndex(getMesh().getFractionalCoordinateIndex((Coordinate) pointsV.elementAt(i - 1)));
CoordinateIndex c2 = getMesh().getCoordinateIndexFromFractionalIndex(getMesh().getFractionalCoordinateIndex((Coordinate) pointsV.elementAt(i)));
int dx = Math.abs(c1.x - c2.x);
int dy = Math.abs(c1.y - c2.y);
int dz = Math.abs(c1.z - c2.z);
int symCount = 0;
if (dx != 0 && dy != 0 && dx != dy) {
symCount += 1;
}
if (dx != 0 && dz != 0 && dx != dz) {
symCount += 1;
}
if (dy != 0 && dz != 0 && dy != dz) {
symCount += 1;
}
if (symCount != 0) {
return false;
}
}
}
return true;
}
use of org.vcell.util.CoordinateIndex in project vcell by virtualcell.
the class SpatialSelectionVolume method resampleMeshBoundaries.
/**
* Insert the method's description here.
* Creation date: (10/6/2004 11:31:20 AM)
*/
private SSHelper resampleMeshBoundaries(int[] indexes, Coordinate[] wcV, boolean bRecenter) throws Exception {
if (wcV.length < 2) {
return null;
}
final int MEMBRANE_BOUNDARY = -1;
final int NON_MEMBRANE_BOUNDARY = -2;
final int MEMB_INDEX = 0;
final int IN_VOL = 1;
final int OUT_VOL = 2;
int newCount = 0;
int[] newIndexes = new int[indexes.length * 3];
int[][][] newCrossingMembraneIndex = new int[newIndexes.length][4][3];
Coordinate[] newWCV = new Coordinate[wcV.length * 3];
for (int i = 1; i < wcV.length; i += 1) {
CoordinateIndex ci1 = getCoordinateIndexFromWC(wcV[i]);
CoordinateIndex ci2 = getCoordinateIndexFromWC(wcV[i - 1]);
CoordinateIndex ci3 = null;
CoordinateIndex ci4 = null;
CoordinateIndex[][] faces = null;
if (areTouchingFace(ci1, ci2)) {
faces = new CoordinateIndex[][] { { ci1, ci2 } };
} else if (areTouching(ci1, ci2)) {
// must be a corner
// determine the 4 faces that coincide with this corner
int dx = ci2.x - ci1.x;
int dy = ci2.y - ci1.y;
int dz = ci2.z - ci1.z;
if (dx == 0 && dy != 0 && dz != 0) {
ci3 = new CoordinateIndex(ci1.x, ci1.y + dy, ci1.z);
ci4 = new CoordinateIndex(ci1.x, ci1.y, ci1.z + dz);
} else if (dx != 0 && dy == 0 && dz != 0) {
ci3 = new CoordinateIndex(ci1.x + dx, ci1.y, ci1.z);
ci4 = new CoordinateIndex(ci1.x, ci1.y, ci1.z + dz);
} else if (dx != 0 && dy != 0 && dz == 0) {
ci3 = new CoordinateIndex(ci1.x, ci1.y + dy, ci1.z);
ci4 = new CoordinateIndex(ci1.x + dx, ci1.y, ci1.z);
} else {
throw new Exception(this.getClass().getName() + ".resampleMeshBoundaries Couldn't adjust for corners");
}
faces = new CoordinateIndex[][] { { ci1, ci3 }, { ci1, ci4 }, { ci2, ci3 }, { ci2, ci4 } };
} else {
throw new Exception(this.getClass().getName() + ".resampleMeshBoundaries Expecting touching elements");
}
// System.out.println("p1="+i+" p2="+(i-1));
boolean[] bCrossMembraneArr = new boolean[faces.length];
java.util.Arrays.fill(bCrossMembraneArr, false);
int[][] crossMembraneIndexInOutArr = new int[bCrossMembraneArr.length][3];
Coordinate[] intersectArr = new Coordinate[faces.length];
int intersectNotNullCount = 0;
// Find out where the line segment between volume elements intersect the face(s)
for (int j = 0; j < faces.length; j += 1) {
crossMembraneIndexInOutArr[j][MEMB_INDEX] = -1;
crossMembraneIndexInOutArr[j][IN_VOL] = -1;
crossMembraneIndexInOutArr[j][OUT_VOL] = -1;
intersectArr[j] = lineMeshFaceIntersect3D(getMesh().getCoordinate(faces[j][0]), getMesh().getCoordinate(faces[j][1]), wcV[i], wcV[i - 1]);
intersectNotNullCount += (intersectArr[j] != null ? 1 : 0);
if (getMesh().getMembraneElements() != null) {
// Find out if this face is part of a Membrane
int vi1 = getMesh().getVolumeIndex(faces[j][0]);
int vi2 = getMesh().getVolumeIndex(faces[j][1]);
for (int k = 0; k < getMesh().getMembraneElements().length; k += 1) {
int inside = getMesh().getMembraneElements()[k].getInsideVolumeIndex();
int outside = getMesh().getMembraneElements()[k].getOutsideVolumeIndex();
if ((vi1 == inside && vi2 == outside) || (vi1 == outside && vi2 == inside)) {
bCrossMembraneArr[j] = true;
crossMembraneIndexInOutArr[j][MEMB_INDEX] = k;
crossMembraneIndexInOutArr[j][IN_VOL] = inside;
crossMembraneIndexInOutArr[j][OUT_VOL] = outside;
break;
}
}
}
// System.out.println("----- vi1="+vi1+" vi2="+vi2+" face="+j+" intersect="+intersectArr[j]+" bCrossMembrane="+bCrossMembraneArr[j]);
}
// we will use them later to determing the midpoint to adjust our data sample WorldCoordinates
if (i == 1) {
newIndexes[newCount] = indexes[0];
newWCV[newCount] = wcV[0];
newCount += 1;
}
if (faces.length == 1 && intersectNotNullCount == 1) {
// through face, use where it intersects and mark if has Membrane
newIndexes[newCount] = (bCrossMembraneArr[0] ? MEMBRANE_BOUNDARY : NON_MEMBRANE_BOUNDARY);
newCrossingMembraneIndex[newCount] = crossMembraneIndexInOutArr;
newWCV[newCount] = intersectArr[0];
newCount += 1;
} else if (faces.length == 4 && intersectNotNullCount == 4) {
// Through a corner, calculate the corner Coordinate and mark if has Membrane
Coordinate mc1 = getMesh().getCoordinate(ci1);
Coordinate mc2 = getMesh().getCoordinate(ci2);
Coordinate mc3 = getMesh().getCoordinate(ci3);
Coordinate mc4 = getMesh().getCoordinate(ci4);
Coordinate corner = new Coordinate((mc1.getX() + mc2.getX() + mc3.getX() + mc4.getX()) / 4.0, (mc1.getY() + mc2.getY() + mc3.getY() + mc4.getY()) / 4.0, (mc1.getZ() + mc2.getZ() + mc3.getZ() + mc4.getZ()) / 4.0);
newIndexes[newCount] = (bCrossMembraneArr[0] || bCrossMembraneArr[1] || bCrossMembraneArr[2] || bCrossMembraneArr[3] ? MEMBRANE_BOUNDARY : NON_MEMBRANE_BOUNDARY);
// newCrossingMembraneIndex[newCount] = crossMembraneIndexInOutArr;
newWCV[newCount] = corner;
newCount += 1;
} else {
throw new Exception(this.getClass().getName() + " Unexpected intersection result");
}
newIndexes[newCount] = indexes[i];
newWCV[newCount] = wcV[i];
newCount += 1;
}
// Count how many points we will finally end up with after markers are removed and
// including the points that will be added for membrane intersections
// also calculate the midpoints of the original data between the intersect points
// first and last
int finalCount = 2;
// Adjust distances to center between boundary markers (inersections)
for (int i = 0; i < newCount; i += 1) {
if (newIndexes[i] == MEMBRANE_BOUNDARY || newIndexes[i] == NON_MEMBRANE_BOUNDARY) {
if ((i + 2) < newCount) {
// if(bRecenter){
// Coordinate b0 = newWCV[i];
// Coordinate b1 = newWCV[i+2];
// newWCV[i+1] = new Coordinate((b0.getX()+b1.getX())/2.0,(b0.getY()+b1.getY())/2.0,(b0.getZ()+b1.getZ())/2.0);
// }else{
// TODO: why is this here, is this really what we want? ... A = A;
newWCV[i + 1] = newWCV[i + 1];
// }
finalCount += 1;
}
}
if (newIndexes[i] == MEMBRANE_BOUNDARY) {
finalCount += 2;
}
}
// Final pass, remove markers, add additional points at membrane intersections
int[] finalIndexes = new int[finalCount];
int[] finalCrossingMembrane = null;
Coordinate[] finalWC = new Coordinate[finalCount];
finalCount = 0;
for (int i = 0; i < newCount; i += 1) {
if (newIndexes[i] != MEMBRANE_BOUNDARY && newIndexes[i] != NON_MEMBRANE_BOUNDARY) {
// Get all original data points
finalIndexes[finalCount] = newIndexes[i];
finalWC[finalCount] = newWCV[i];
finalCount += 1;
} else if (newIndexes[i] == MEMBRANE_BOUNDARY) {
for (int j = 0; j < newCrossingMembraneIndex[i].length; j++) {
if (newCrossingMembraneIndex[i][j][MEMB_INDEX] != -1 && ((newCrossingMembraneIndex[i][j][IN_VOL] == newIndexes[i - 1] && newCrossingMembraneIndex[i][j][OUT_VOL] == newIndexes[i + 1]) || (newCrossingMembraneIndex[i][j][OUT_VOL] == newIndexes[i - 1] && newCrossingMembraneIndex[i][j][IN_VOL] == newIndexes[i + 1]))) {
if (finalCrossingMembrane == null) {
// make once only if needed
finalCrossingMembrane = new int[finalIndexes.length];
Arrays.fill(finalCrossingMembrane, -1);
}
finalCrossingMembrane[finalCount] = newCrossingMembraneIndex[i][j][MEMB_INDEX];
finalCrossingMembrane[finalCount + 1] = newCrossingMembraneIndex[i][j][MEMB_INDEX];
break;
}
}
// Add 2 new membrane intersection points, one for each side of the face
finalIndexes[finalCount] = newIndexes[i - 1];
// finalWC[finalCount] = offsetCoordinate(newWCV[i],newWCV[i-1]);
finalWC[finalCount] = newWCV[i];
finalCount += 1;
finalIndexes[finalCount] = newIndexes[i + 1];
// finalWC[finalCount] = offsetCoordinate(newWCV[i],newWCV[i+1]);
finalWC[finalCount] = newWCV[i];
finalCount += 1;
}
}
return new SSHelper(finalWC, finalIndexes, getVariableType(), finalCrossingMembrane);
}
Aggregations