Search in sources :

Example 16 with SubVolume

use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.

the class DistanceMapGenerator method computeDistanceMaps.

public static SubvolumeSignedDistanceMap[] computeDistanceMaps(Geometry geometry, VCImage subvolumeHandleImage, boolean bCellCentered, boolean insideOnly) throws ImageException {
    double[] samplesX = new double[subvolumeHandleImage.getNumX()];
    double[] samplesY = new double[subvolumeHandleImage.getNumY()];
    double[] samplesZ = new double[subvolumeHandleImage.getNumZ()];
    ISize sampleSize = new ISize(subvolumeHandleImage.getNumX(), subvolumeHandleImage.getNumY(), subvolumeHandleImage.getNumZ());
    byte[] pixels = subvolumeHandleImage.getPixels();
    boolean[] ignoreMask = new boolean[sampleSize.getXYZ()];
    Origin origin = geometry.getOrigin();
    Extent extent = geometry.getExtent();
    RayCaster.sampleXYZCoordinates(sampleSize, origin, extent, samplesX, samplesY, samplesZ, bCellCentered);
    ArrayList<SubvolumeSignedDistanceMap> distanceMaps = new ArrayList<SubvolumeSignedDistanceMap>();
    int count = 0;
    for (SubVolume subVolume : geometry.getGeometrySpec().getSubVolumes()) {
        // 
        // find surfaces that bound the current SubVolume
        // 
        ArrayList<Surface> surfaces = new ArrayList<Surface>();
        for (GeometricRegion geometricRegion : geometry.getGeometrySurfaceDescription().getGeometricRegions()) {
            if (geometricRegion instanceof SurfaceGeometricRegion) {
                SurfaceGeometricRegion surfaceGeometricRegion = (SurfaceGeometricRegion) geometricRegion;
                for (GeometricRegion adjacentRegion : ((SurfaceGeometricRegion) geometricRegion).getAdjacentGeometricRegions()) {
                    if (adjacentRegion instanceof VolumeGeometricRegion && ((VolumeGeometricRegion) adjacentRegion).getSubVolume() == subVolume) {
                        surfaces.add(geometry.getGeometrySurfaceDescription().getSurfaceCollection().getSurface(surfaceGeometricRegion));
                    }
                }
            }
        }
        // find unsigned distances in a narrow band for surfaces that bound this SubVolume (expensive)
        // values outside the band are assumed to be initialized to MAX_NUMBER
        long t1 = System.currentTimeMillis();
        double[] distanceMap = localUnsignedDistanceMap(surfaces, samplesX, samplesY, samplesZ, 3);
        long t2 = System.currentTimeMillis();
        System.out.println("          Distance to triangle:   " + (int) ((t2 - t1) / 1000) + " sec.");
        // extend signed distance map using fast marching method from narrow band to all points.
        // will do it in 2 steps, positive growth first towards inside, then change the sign of the whole
        // distance map, then positive growth towards the exterior
        // this way, the interior distances will end negative and the exterior distances positive
        // 2 step growth saves memory and reduces the number of elements present at any given time in the binary
        // heap (binary heap manipulation is the most time consuming factor and it depends on the # of elements)
        Arrays.fill(ignoreMask, true);
        int subvolumeHandle = subVolume.getHandle();
        for (int i = 0; i < ignoreMask.length; i++) {
            if (pixels[i] == subvolumeHandle) {
                // inside
                ignoreMask[i] = false;
            } else {
                // outside
                if (distanceMap[i] < MAX_NUMBER) {
                    // make negative the part of narrow band which is outside
                    distanceMap[i] = -distanceMap[i];
                }
            }
        }
        // // step 1, we compute distances for the points "inside"
        // // the points outside are cold (we don't compute their distances this step)
        double deltaX = samplesX[1] - samplesX[0];
        double deltaY = samplesY[1] - samplesY[0];
        double deltaZ = samplesZ[1] - samplesZ[0];
        FastMarchingMethodHA fmm = new FastMarchingMethodHA(samplesX.length, samplesY.length, samplesZ.length, deltaX, deltaY, deltaZ, distanceMap, ignoreMask);
        fmm.march();
        if (!insideOnly) {
            // sign change of the half-completed distance map, the "interior" will become negative as it should be
            for (int i = 0; i < distanceMap.length; i++) {
                if (distanceMap[i] < MAX_NUMBER) {
                    distanceMap[i] = -distanceMap[i];
                }
            }
            // step 2, we compute distances for the points "outside"
            // no cold points (points we don't care about) this time, they are already frozen
            fmm = new FastMarchingMethodHA(samplesX.length, samplesY.length, samplesZ.length, deltaX, deltaY, deltaZ, distanceMap, null);
            fmm.march();
        } else {
            // sign change of the half-completed distance map, the "interior" will become negative as it should be
            for (int i = 0; i < distanceMap.length; i++) {
                if (distanceMap[i] < MAX_NUMBER) {
                    if (pixels[i] != subvolumeHandle) {
                        // need to filter out the part of the narrow band which is not inside
                        distanceMap[i] = MAX_NUMBER;
                    } else {
                        distanceMap[i] = -distanceMap[i];
                    }
                }
            }
        }
        // try {		// save some points in a VisIt compatible format
        // int xm = samplesX.length;
        // int ym = samplesY.length;
        // BufferedWriter out = new BufferedWriter(new FileWriter("c:\\TEMP\\2D_circle" + count + ".3D"));
        // out.write("x y z value\n");
        // 
        // for(int j=0; j<distanceMap.length; j++) {
        // int x = getX(j,xm,ym);
        // int y = getY(j,xm,ym);
        // int z = getZ(j,xm,ym);
        // if(distanceMap[j] < MAX_NUMBER) {
        // if((j%2 == 0 || j%3 == 0)  && (distanceMap[j] <= -2)) {
        // out.write(x + " " + y + " " + z + " " + (int)(distanceMap[j]*10) + "\n");
        // } else if((j%17 == 0 || j%23 == 0) && (distanceMap[j] <= 0.5) && (distanceMap[j] > -2)) {
        // out.write(x + " " + y + " " + z + " " + (int)(distanceMap[j]*10) + "\n");
        // } else if((j%31 == 0 || j%41 == 0) && (distanceMap[j] > 0.5)) {
        // out.write(x + " " + y + " " + z + " " + (int)(distanceMap[j]*10) + "\n");
        // }
        // }
        // if(distanceMap[j] < MAX_NUMBER) {
        // if(j%2 == 0) {
        // out.write(x + " " + y + " " + z + " " + (int)(distanceMap[j]*100) + "\n");
        // }
        // }
        // if(x==50 && y==50 && z==25) {		// on the surface
        // out.write(x + " " + y + " " + z + " " + (int)(distanceMap[j]*100) + "\n");
        // }
        // if(x==0 && y==0 && z==0) {
        // out.write(x + " " + y + " " + z + " " + 0 + "\n");
        // }
        // if(x==100 && y==100 && z==100) {
        // out.write(x + " " + y + " " + z + " " + 0 + "\n");
        // }
        // 
        // }
        // out.close();
        // } catch (IOException e) {
        // }
        SubvolumeSignedDistanceMap subvolumeSignedDistanceMap = new SubvolumeSignedDistanceMap(subVolume, samplesX, samplesY, samplesZ, distanceMap);
        distanceMaps.add(subvolumeSignedDistanceMap);
        count++;
    }
    return distanceMaps.toArray(new SubvolumeSignedDistanceMap[distanceMaps.size()]);
}
Also used : Origin(org.vcell.util.Origin) Extent(org.vcell.util.Extent) ISize(org.vcell.util.ISize) ArrayList(java.util.ArrayList) SubVolume(cbit.vcell.geometry.SubVolume) FastMarchingMethodHA(cbit.vcell.render.FastMarchingMethodHA)

Example 17 with SubVolume

use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.

the class GeometrySurfaceDescription method refreshSurfaceClasses.

private void refreshSurfaceClasses() {
    if (getGeometricRegions() == null) {
        return;
    }
    boolean bChanged = false;
    ArrayList<SurfaceClass> surfaceClasses = new ArrayList<SurfaceClass>();
    for (int i = 0; i < getGeometricRegions().length; i++) {
        if (getGeometricRegions()[i] instanceof SurfaceGeometricRegion) {
            SurfaceGeometricRegion surfaceRegion = (SurfaceGeometricRegion) getGeometricRegions()[i];
            GeometricRegion[] adjacentRegions = surfaceRegion.getAdjacentGeometricRegions();
            if (adjacentRegions.length != 2) {
                throw new RuntimeException("found a Surface Region with " + adjacentRegions.length + " adjacent regions, expected 2");
            }
            if (adjacentRegions[0] instanceof VolumeGeometricRegion && adjacentRegions[1] instanceof VolumeGeometricRegion) {
                VolumeGeometricRegion volumeRegion0 = (VolumeGeometricRegion) adjacentRegions[0];
                SubVolume subVolume0 = volumeRegion0.getSubVolume();
                VolumeGeometricRegion volumeRegion1 = (VolumeGeometricRegion) adjacentRegions[1];
                SubVolume subVolume1 = volumeRegion1.getSubVolume();
                Set<SubVolume> subvolumes = new HashSet<SubVolume>();
                subvolumes.add(subVolume0);
                subvolumes.add(subVolume1);
                SurfaceClass surfaceClass = (fieldSurfaceClasses == null ? null : getSurfaceClass(subVolume0, subVolume1));
                if (surfaceClass == null) {
                    bChanged = true;
                    surfaceClass = new SurfaceClass(subvolumes, null, SurfaceClass.createName(subVolume0.getName(), subVolume1.getName()));
                }
                boolean bFound = false;
                for (int j = 0; j < surfaceClasses.size(); j++) {
                    if (surfaceClass.compareEqual(surfaceClasses.get(j))) {
                        bFound = true;
                        break;
                    }
                }
                if (!bFound) {
                    surfaceClasses.add(surfaceClass);
                }
            }
        }
    }
    if (bChanged || fieldSurfaceClasses.getCurrentValue() == null || fieldSurfaceClasses.getCurrentValue().length != surfaceClasses.size()) {
        try {
            setSurfaceClasses(surfaceClasses.toArray(new SurfaceClass[surfaceClasses.size()]));
        } catch (PropertyVetoException e) {
            e.printStackTrace();
            throw new RuntimeException("SurfaceClass refresh error: " + e.getMessage(), e);
        }
    }
}
Also used : SurfaceClass(cbit.vcell.geometry.SurfaceClass) ArrayList(java.util.ArrayList) PropertyVetoException(java.beans.PropertyVetoException) SubVolume(cbit.vcell.geometry.SubVolume) AnalyticSubVolume(cbit.vcell.geometry.AnalyticSubVolume) HashSet(java.util.HashSet)

Example 18 with SubVolume

use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.

the class GeometrySurfaceDescription method propertyChange.

/**
 * This method gets called when a bound property is changed.
 * @param evt A PropertyChangeEvent object describing the event source
 *   	and the property that has changed.
 */
public void propertyChange(java.beans.PropertyChangeEvent evt) {
    if (evt.getSource() == this && evt.getPropertyName().equals("volumeSampleSize")) {
        ISize oldValue = (ISize) evt.getOldValue();
        ISize newValue = (ISize) evt.getNewValue();
        if (!oldValue.compareEqual(newValue)) {
            try {
                // nobody listens to this, updateAll() will propagate changes
                getRegionImage0().setDirty();
                getSurfaceCollection0().setDirty();
                fieldGeometricRegions.setDirty();
            } catch (Exception e) {
                e.printStackTrace(System.out);
            }
        }
    }
    if (evt.getSource() == this && evt.getPropertyName().equals("filterCutoffFrequency")) {
        Double oldValue = (Double) evt.getOldValue();
        Double newValue = (Double) evt.getNewValue();
        if (!oldValue.equals(newValue)) {
            try {
                getSurfaceCollection0().setDirty();
                fieldGeometricRegions.setDirty();
            } catch (Exception e) {
                e.printStackTrace(System.out);
            }
        }
    }
    if (evt.getSource() == this && evt.getPropertyName().equals(PROPERTY_NAME_GEOMETRIC_REGIONS)) {
        refreshSurfaceClasses();
    }
    if (evt.getSource() == getGeometry().getGeometrySpec() && (evt.getPropertyName().equals("extent") || evt.getPropertyName().equals("origin"))) {
        Matchable oldExtentOrOrigin = (Matchable) evt.getOldValue();
        Matchable newExtentOrOrigin = (Matchable) evt.getNewValue();
        if (!Compare.isEqual(oldExtentOrOrigin, newExtentOrOrigin)) {
            try {
                // nobody listens to this, updateAll() will propagate changes
                getRegionImage0().setDirty();
                getSurfaceCollection0().setDirty();
                fieldGeometricRegions.setDirty();
            } catch (Exception e) {
                e.printStackTrace(System.out);
            }
        }
    }
    if (evt.getSource() instanceof AnalyticSubVolume && evt.getPropertyName().equals("expression")) {
        Expression oldExpression = (Expression) evt.getOldValue();
        Expression newExpression = (Expression) evt.getNewValue();
        if (!Compare.isEqual(oldExpression, newExpression)) {
            try {
                // nobody listens to this, updateAll() will propagate changes
                getRegionImage0().setDirty();
                getSurfaceCollection0().setDirty();
                fieldGeometricRegions.setDirty();
            } catch (Exception e) {
                e.printStackTrace(System.out);
            }
        }
    }
    if (evt.getSource() instanceof CSGObject && evt.getPropertyName().equals(CSGObject.PROPERTY_NAME_ROOT)) {
        try {
            // nobody listens to this, updateAll() will propagate changes
            getRegionImage0().setDirty();
            getSurfaceCollection0().setDirty();
            fieldGeometricRegions.setDirty();
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
    }
    if (evt.getSource() instanceof SubVolume && evt.getPropertyName().equals("name")) {
        String oldName = (String) evt.getOldValue();
        String newName = (String) evt.getNewValue();
        if (!Compare.isEqual(oldName, newName)) {
            try {
                fieldGeometricRegions.setDirty();
            } catch (Exception e) {
                e.printStackTrace(System.out);
            }
        }
    }
    if (evt.getSource() == getGeometry().getGeometrySpec() && evt.getPropertyName().equals("subVolumes")) {
        SubVolume[] oldValue = (SubVolume[]) evt.getOldValue();
        SubVolume[] newValue = (SubVolume[]) evt.getNewValue();
        // 
        for (int i = 0; oldValue != null && i < oldValue.length; i++) {
            oldValue[i].removePropertyChangeListener(this);
        }
        for (int i = 0; newValue != null && i < newValue.length; i++) {
            newValue[i].addPropertyChangeListener(this);
        }
        // 
        if (oldValue == null || newValue == null || !Compare.isEqualStrict(oldValue, newValue)) {
            try {
                // nobody listens to this, updateAll() will propagate changes
                getRegionImage0().setDirty();
                getSurfaceCollection0().setDirty();
                fieldGeometricRegions.setDirty();
            } catch (Exception e) {
                e.printStackTrace(System.out);
            }
        } else if (fieldGeometricRegions.getCurrentValue() != null && oldValue != newValue) {
            // 
            for (int i = 0; i < newValue.length; i++) {
                SubVolume subVolume = newValue[i];
                for (int j = 0; j < fieldGeometricRegions.getCurrentValue().length; j++) {
                    if (fieldGeometricRegions.getCurrentValue()[j] instanceof VolumeGeometricRegion) {
                        VolumeGeometricRegion volumeRegion = (VolumeGeometricRegion) fieldGeometricRegions.getCurrentValue()[j];
                        // 
                        if (volumeRegion.getSubVolume().compareEqual(subVolume) && volumeRegion.getSubVolume() != subVolume) {
                            volumeRegion.setSubVolume(subVolume);
                        }
                    }
                }
            }
        }
    }
}
Also used : Expression(cbit.vcell.parser.Expression) ISize(org.vcell.util.ISize) SubVolume(cbit.vcell.geometry.SubVolume) AnalyticSubVolume(cbit.vcell.geometry.AnalyticSubVolume) CSGObject(cbit.vcell.geometry.CSGObject) AnalyticSubVolume(cbit.vcell.geometry.AnalyticSubVolume) ImageException(cbit.image.ImageException) ExpressionException(cbit.vcell.parser.ExpressionException) PropertyVetoException(java.beans.PropertyVetoException) GeometryException(cbit.vcell.geometry.GeometryException) Matchable(org.vcell.util.Matchable)

Example 19 with SubVolume

use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.

the class RayCaster method sampleGeometry.

public static VCImage sampleGeometry(Geometry geometry, ISize sampleSize, boolean bCellCentered) throws ImageException, PropertyVetoException, GeometryException, ExpressionException {
    int numX = sampleSize.getX();
    int numY = sampleSize.getY();
    int numZ = sampleSize.getZ();
    Origin origin = geometry.getOrigin();
    Extent extent = geometry.getExtent();
    SurfaceCollection surfaceCollection = geometry.getGeometrySurfaceDescription().getSurfaceCollection();
    int surfaceCount = surfaceCollection.getSurfaceCount();
    // 
    if (surfaceCount == 0 && geometry.getGeometrySpec().getNumSubVolumes() == 1) {
        byte[] pixels = new byte[numX * numY * numZ];
        SubVolume subVolume = geometry.getGeometrySpec().getSubVolumes()[0];
        Arrays.fill(pixels, (byte) subVolume.getHandle());
        VCImageUncompressed vcImage = new VCImageUncompressed(null, pixels, extent, numX, numY, numZ);
        return vcImage;
    }
    VolumeSamples volumeSamples = volumeSampleSurface(surfaceCollection, sampleSize, origin, extent, bCellCentered);
    // for each mask bit, find union of masks which contain that bit ... iterate until no change.
    HashSet<Long> uniqueMasks = volumeSamples.getUniqueMasks();
    ArrayList<Long> consensusMaskArray = new ArrayList<Long>(uniqueMasks);
    // boolean bChanged = true;
    // while (bChanged){
    // bChanged = false;
    // for (int i=0;i<consensusMaskArray.size();i++){
    // for (int j=i+1;j<consensusMaskArray.size();j++){
    // if ((((long)consensusMaskArray.get(i)) & ((long)consensusMaskArray.get(j))) != 0L && (((long)consensusMaskArray.get(i))!=((long)consensusMaskArray.get(j)))){
    // long merged = consensusMaskArray.get(i) | consensusMaskArray.get(j);
    // if ((((merged<<1) & merged)==0L) &&  (((merged>>1) & merged)==0L)){
    // System.out.println("++++++++++++++++++++++++++++++++ merged "+Long.toBinaryString(consensusMaskArray.get(i))+" with "+Long.toBinaryString(consensusMaskArray.get(j))+" to get "+Long.toBinaryString(merged));
    // consensusMaskArray.set(i, merged);
    // consensusMaskArray.set(j, merged);
    // bChanged = true;
    // }
    // }
    // }
    // }
    // }
    /*
		for (Long l : consensusMaskArray) {
			System.out.println("++++++++++++++++++++++++++++++++ final mask "+Long.toBinaryString(l));
		}
		*/
    HashSet<Long> consensusSet = new HashSet<Long>(consensusMaskArray);
    byte[] pixels = new byte[numX * numY * numZ];
    setSurfaceMasks(geometry.getGeometrySurfaceDescription().getSurfaceCollection());
    for (long mask : consensusSet) {
        // for this consensus mask, find the subvolume that is associated
        SubVolume subvolume = getSubvolume(geometry, mask);
        if (subvolume == null) {
            throw new RuntimeException("could not reconcile volume samples with original geometry");
        }
        byte pixelValue = (byte) subvolume.getHandle();
        for (int i = 0; i < volumeSamples.getNumXYZ(); i++) {
            if ((volumeSamples.getMask(i) & mask) != 0) {
                pixels[i] = (byte) pixelValue;
            }
        }
    }
    VCImageUncompressed vcImage = new VCImageUncompressed(null, pixels, extent, numX, numY, numZ);
    return vcImage;
}
Also used : Origin(org.vcell.util.Origin) Extent(org.vcell.util.Extent) ArrayList(java.util.ArrayList) VCImageUncompressed(cbit.image.VCImageUncompressed) SubVolume(cbit.vcell.geometry.SubVolume) ImageSubVolume(cbit.vcell.geometry.ImageSubVolume) HashSet(java.util.HashSet)

Example 20 with SubVolume

use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.

the class GeometryClassLegendShape method paintSelf.

@Override
public void paintSelf(Graphics2D g, int absPosX, int absPosY) {
    // draw elipse
    if (geometryClass instanceof SubVolume) {
        SubVolume subVolume = (SubVolume) geometryClass;
        Color fillColor = getSubvolumeColor(subVolume);
        g.setColor(fillColor);
        g.fill3DRect(absPosX + 1, absPosY + 1, 2 * radius - 1, 2 * radius - 1, true);
        g.setColor(forgroundColor);
        g.draw3DRect(absPosX, absPosY, 2 * radius, 2 * radius, true);
    } else if (geometryClass instanceof SurfaceClass) {
        SurfaceClass surfaceClass = (SurfaceClass) geometryClass;
        Set<SubVolume> adjacentSubVolumes = surfaceClass.getAdjacentSubvolumes();
        Iterator<SubVolume> iterator = adjacentSubVolumes.iterator();
        SubVolume subVolume1 = iterator.next();
        SubVolume subVolume2 = iterator.next();
        Color fillColor1 = null;
        Color fillColor2 = null;
        // make same choice each time so that repaint don't flicker
        if (subVolume1.getName().compareTo(subVolume2.getName()) > 0) {
            fillColor1 = getSubvolumeColor(subVolume1);
            fillColor2 = getSubvolumeColor(subVolume2);
        } else {
            fillColor1 = getSubvolumeColor(subVolume2);
            fillColor2 = getSubvolumeColor(subVolume1);
        }
        g.setColor(fillColor1);
        g.fill3DRect(absPosX + 1, absPosY + 1, radius, 2 * radius - 1, true);
        g.setColor(fillColor2);
        g.fill3DRect(absPosX + 1 + radius, absPosY + 1, radius - 1, 2 * radius - 1, true);
        g.setColor(forgroundColor);
        g.draw3DRect(absPosX, absPosY, 2 * radius, 2 * radius, true);
    }
    int textX = getLabelPos().x + absPosX;
    int textY = getLabelPos().y + absPosY;
    g.setColor(forgroundColor);
    if (getLabel() != null && getLabel().length() > 0) {
        g.drawString(getLabel(), textX, textY);
    }
    return;
}
Also used : Set(java.util.Set) SurfaceClass(cbit.vcell.geometry.SurfaceClass) SubVolume(cbit.vcell.geometry.SubVolume) Color(java.awt.Color) Iterator(java.util.Iterator) Point(java.awt.Point)

Aggregations

SubVolume (cbit.vcell.geometry.SubVolume)84 SurfaceClass (cbit.vcell.geometry.SurfaceClass)42 Expression (cbit.vcell.parser.Expression)33 AnalyticSubVolume (cbit.vcell.geometry.AnalyticSubVolume)26 ImageSubVolume (cbit.vcell.geometry.ImageSubVolume)22 GeometryClass (cbit.vcell.geometry.GeometryClass)21 ArrayList (java.util.ArrayList)21 Geometry (cbit.vcell.geometry.Geometry)20 MathDescription (cbit.vcell.math.MathDescription)17 SpeciesContext (cbit.vcell.model.SpeciesContext)17 PropertyVetoException (java.beans.PropertyVetoException)17 CompartmentSubDomain (cbit.vcell.math.CompartmentSubDomain)16 CompartmentSubVolume (cbit.vcell.geometry.CompartmentSubVolume)15 Model (cbit.vcell.model.Model)15 ImageException (cbit.image.ImageException)14 VCImage (cbit.image.VCImage)14 Feature (cbit.vcell.model.Feature)14 Structure (cbit.vcell.model.Structure)14 MembraneSubDomain (cbit.vcell.math.MembraneSubDomain)13 ExpressionException (cbit.vcell.parser.ExpressionException)13