private double[] compute2DCoordinates(double[] point3D, SimpleMatrix pMatrix) { // Compute coordinates in projection data. SimpleVector homogeneousPoint = SimpleOperators.multiply(pMatrix, new SimpleVector(point3D[0], point3D[1], point3D[2], 1)); // Transform to 2D coordinates double coordU = homogeneousPoint.getElement(0) / homogeneousPoint.getElement(2); double coordV = homogeneousPoint.getElement(1) / homogeneousPoint.getElement(2); // double pxlSize = config.getGeometry().getPixelDimensionX(); return new double[] {coordU, coordV}; }
public void setData(int x, int y, int z, DarkFieldPCA myPCA) { SimpleMatrix eigenVectors = myPCA.getEigenVectors(); SimpleVector eigenValues = myPCA.getEigenValues(); for (int i = 0; i < fieldList.size(); i++) { SimpleVector eigenVec = eigenVectors.getCol(i); double eigenVal = eigenValues.getElement(i); eigenVec = eigenVec.multipliedBy(eigenVal); fieldList.get(i).setVector(x, y, z, eigenVec); } // /** // * Threshold that checks, if 3 component of eigenvalues is too small // * If 3 component is too small, don't consider it as a fiber orientation // * and ignore it // */ // double th = 1E-10; // SimpleVector fiberDir; // if(myPCA.getEigenValues().getElement(2)<th){ // fiberDir = new SimpleVector(3); // }else{ // fiberDir = myPCA.getEigenVectors().getCol(2).normalizedL2(); // fiberDir.multiplyBy(myPCA.getEigenValues().getElement(2)); // } }
public static void printSimpleVector(SimpleVector B) { int n = B.getLen(); for (int i = 0; i < n; i++) { System.out.print(B.getElement(i) + "\t"); } System.out.print("\n"); }
private void followRay( SimpleVector pos, SimpleVector dir, double energyEV, FloatProcessor imp, int scatterCount, double totalDistance) { if (energyEV <= 1 || scatterCount > 20000) { System.out.println("energy low, times scattered: " + scatterCount); return; } // follow ray until next interaction point SimpleVector oldPos = pos.clone(); double dist = sampler.getDistanceUntilNextInteractionCm(material, energyEV); pos.add(dir.multipliedBy(dist)); pathlengths.add(dist); // draw the entire path // imp.drawLine((int)(scale*oldPos.getElement(0)), (int)(scale*oldPos.getElement(1)), // (int)(scale*pos.getElement(0)), (int)(scale*pos.getElement(1))); // draw interaction points only imp.drawDot((int) (scale * pos.getElement(0)), (int) (scale * pos.getElement(1))); // choose compton or photoelectric effect double photo = material.getAttenuation(energyEV / 1000, AttenuationType.PHOTOELECTRIC_ABSORPTION); double compton = material.getAttenuation(energyEV / 1000, AttenuationType.INCOHERENT_ATTENUATION); if (sampler.random() * (photo + compton) <= photo) { // photoelectric absorption energyEV = 0; // System.out.println("absorbed after " + scatterCount + " collisions"); xs.add(pos.getElement(0)); ys.add(pos.getElement(1)); zs.add(pos.getElement(2)); return; } else { // compton scattering energyEV = sampler.sampleComptonScattering(energyEV, dir); // send new ray followRay(pos, dir, energyEV, imp, scatterCount + 1, totalDistance + dist); } }
/** * @param x * @param y * @param z * @param vec - EigenValue is encoded in length of vector */ public void setVector(int x, int y, int z, SimpleVector vec) { // Check for inconsistency (different dimensions) assert (vec.getLen() == 3) : new Exception("Dimension of data vector has to be 3."); // Loop through every coordinate for (int i = 0; i < 3; i++) { super.setAtIndex(x, y, z, i, (float) vec.getElement(i)); } }
/** * Method to calculate alpha and t as indices from the radon transformed image of a view. * Neccessary are the inverse projection image (as SimpleMatrix) and the epipolar plane E * * @param E: epipolar plane E as SimpleVector (4 entries) * @return: line integral value as double */ private double getValueByAlphaAndT(SimpleVector E) { // compute corresponding epipolar lines // // (epipolar lines are of 3x1 = 3x4 * 4x1) SimpleVector l_kappa = SimpleOperators.multiply(this.P_Inverse.transposed(), E); // init the coordinate shift // int t_u = this.projectionWidth / 2; int t_v = this.projectionHeight / 2; // compute angle alpha and distance to origin t // double l0 = l_kappa.getElement(0); double l1 = l_kappa.getElement(1); double l2 = l_kappa.getElement(2); double alpha_kappa_RAD = Math.atan2(-l0, l1) + Math.PI / 2; double t_kappa = -l2 / Math.sqrt(l0 * l0 + l1 * l1); // correct the coordinate shift // t_kappa -= t_u * Math.cos(alpha_kappa_RAD) + t_v * Math.sin(alpha_kappa_RAD); // correct some alpha falling out of the radon window // if (alpha_kappa_RAD < 0) { alpha_kappa_RAD *= -1.0; } else if (alpha_kappa_RAD > Math.PI) { alpha_kappa_RAD = 2.0 * Math.PI - alpha_kappa_RAD; } // write back to l_kappa // l_kappa.setElementValue(0, Math.cos(alpha_kappa_RAD)); l_kappa.setElementValue(1, Math.sin(alpha_kappa_RAD)); l_kappa.setElementValue(2, -t_kappa); // calculate x and y coordinates for derived radon transformed image // double x = t_kappa * this.lineIncrement + 0.5 * this.radonWidth; double y = alpha_kappa_RAD * this.angleIncrement; // get intensity value out of radon transformed image // // (interpolation needed) return InterpolationOperators.interpolateLinear(this.radon, x, y); }
/** * Constructs the triangle corresponding to the i-th face in a mesh given the connectivity * information fcs and the vertices vtc and adds it to the CompoundShape. * * @param vtc The vertices of the mesh. * @param fcs The faces of the mesh, i.e connectivity information. * @param i The index of the face to be constructed. */ private void addTriangleAtIndex(CompoundShape cs, SimpleMatrix vtc, SimpleMatrix fcs, int i) { SimpleVector face = fcs.getRow(i); SimpleVector dirU = vtc.getRow((int) face.getElement(1)); dirU.subtract(vtc.getRow((int) face.getElement(0))); double l2 = dirU.normL2(); SimpleVector dirV = vtc.getRow((int) face.getElement(2)); dirV.subtract(vtc.getRow((int) face.getElement(0))); if (dirV.normL2() < l2) { l2 = dirV.normL2(); } double nN = General.crossProduct(dirU.normalizedL2(), dirV.normalizedL2()).normL2(); if (l2 < Math.sqrt(CONRAD.DOUBLE_EPSILON) || nN < Math.sqrt(CONRAD.DOUBLE_EPSILON)) { } else { Triangle t = new Triangle( new PointND(vtc.getRow((int) face.getElement(0))), new PointND(vtc.getRow((int) face.getElement(1))), new PointND(vtc.getRow((int) face.getElement(2)))); cs.add(t); } }
/** @param pathFiberVTK */ public void writeToVectorField(String pathFiberVTK) { ArrayList<Index3D> indexListe = new ArrayList<Index3D>(); for (int x = 0; x < imgSizeX; x++) { for (int y = 0; y < imgSizeY; y++) { for (int z = 0; z < imgSizeZ; z++) { // Get EigenVec of smallest eigenValue SimpleVector direction = fieldList.get(2).getSimpleVectorAtIndex(x, y, z); double length = direction.normL2(); if (length != 0) { Index3D curIndex = new Index3D(x, y, z); indexListe.add(curIndex); } } } } try { FileOutputStream foStream = new FileOutputStream(pathFiberVTK); BufferedWriter bufWriter = new BufferedWriter(new OutputStreamWriter(foStream)); bufWriter.write("# vtk DataFile Version 2.0"); bufWriter.write(System.getProperty("line.separator")); bufWriter.write("Unstructured Grid Example"); bufWriter.write(System.getProperty("line.separator")); bufWriter.write("ASCII"); bufWriter.write(System.getProperty("line.separator")); bufWriter.write("DATASET UNSTRUCTURED_GRID"); bufWriter.write(System.getProperty("line.separator")); // TODO Not sure why that bufWriter.write("POINTS " + indexListe.size() + " float"); bufWriter.write(System.getProperty("line.separator")); // First write positions for (int poinIdx = 0; poinIdx < indexListe.size(); poinIdx++) { Index3D index3D = indexListe.get(poinIdx); bufWriter.write(index3D.x + " " + index3D.y + " " + index3D.z); bufWriter.write(System.getProperty("line.separator")); } bufWriter.write("CELLS " + indexListe.size() + " " + 2 * indexListe.size()); bufWriter.write(System.getProperty("line.separator")); int indCells = 0; for (int poinIdx = 0; poinIdx < indexListe.size(); poinIdx++) { bufWriter.write("1 " + indCells); bufWriter.write(System.getProperty("line.separator")); indCells = indCells + 1; } bufWriter.write("CELL_TYPES " + indexListe.size()); bufWriter.write(System.getProperty("line.separator")); for (int pointIdx = 0; pointIdx < indexListe.size(); pointIdx++) { bufWriter.write("1"); bufWriter.write(System.getProperty("line.separator")); } bufWriter.write("POINT_DATA " + indexListe.size()); bufWriter.write(System.getProperty("line.separator")); bufWriter.write("SCALARS eigenValues float 3"); bufWriter.write(System.getProperty("line.separator")); bufWriter.write("LOOKUP_TABLE default"); bufWriter.write(System.getProperty("line.separator")); // Write scalars for (int pointIdx = 0; pointIdx < indexListe.size(); pointIdx++) { Index3D coordIdx = indexListe.get(pointIdx); SimpleVector vec1 = fieldList.get(0).getSimpleVectorAtIndex(coordIdx.x, coordIdx.y, coordIdx.z); SimpleVector vec2 = fieldList.get(1).getSimpleVectorAtIndex(coordIdx.x, coordIdx.y, coordIdx.z); SimpleVector vec3 = fieldList.get(2).getSimpleVectorAtIndex(coordIdx.x, coordIdx.y, coordIdx.z); bufWriter.write(vec1.normL2() + " " + vec2.normL2() + " " + vec3.normL2()); bufWriter.write(System.getProperty("line.separator")); } bufWriter.write("SCALARS scalarDirection float 1"); bufWriter.write(System.getProperty("line.separator")); bufWriter.write("LOOKUP_TABLE default"); bufWriter.write(System.getProperty("line.separator")); // Write scalars for (int pointIdx = 0; pointIdx < indexListe.size(); pointIdx++) { Index3D coordIdx = indexListe.get(pointIdx); SimpleVector curEigVec = fieldList.get(2).getSimpleVectorAtIndex(coordIdx.x, coordIdx.y, coordIdx.z); curEigVec = curEigVec.absoluted(); if (curEigVec.max() == curEigVec.getElement(0)) { bufWriter.write("0"); } else if (curEigVec.max() == curEigVec.getElement(1)) { bufWriter.write("0.5"); } else { bufWriter.write("1"); } bufWriter.write(System.getProperty("line.separator")); } for (int eigIdx = 0; eigIdx < 3; eigIdx++) { bufWriter.write("VECTORS eigenVector" + eigIdx + " float"); // Write scalars for (int pointIdx = 0; pointIdx < indexListe.size(); pointIdx++) { Index3D coordIdx = indexListe.get(pointIdx); SimpleVector curEigVec = fieldList.get(eigIdx).getSimpleVectorAtIndex(coordIdx.x, coordIdx.y, coordIdx.z); bufWriter.write(System.getProperty("line.separator")); bufWriter.write( curEigVec.getElement(0) + " " + curEigVec.getElement(1) + " " + "" + curEigVec.getElement(2)); } bufWriter.write(System.getProperty("line.separator")); } bufWriter.flush(); foStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
public Grid2D raytraceScene(PrioritizableScene phantomScene, Projection projection) { Trajectory geom = Configuration.getGlobalConfiguration().getGeometry(); // Grid2D slice = new Grid2D(geom.getDetectorWidth(), geom.getDetectorHeight()); Grid2D slice = detector.createDetectorGrid(geom.getDetectorWidth(), geom.getDetectorHeight(), projection); rayTracer.setScene(phantomScene); // Second rule of optimization is: Optimize later. PointND raySource = new PointND(0, 0, 0); raySource.setCoordinates(projection.computeCameraCenter()); StraightLine castLine = new StraightLine(raySource, new SimpleVector(0, 0, 0)); SimpleVector centerPixDir = null; if (accurate) { centerPixDir = projection.computePrincipalAxis(); } // SimpleVector prinpoint = trajectory.getProjectionMatrix(sliceNumber).getPrincipalPoint(); double xcorr = 0; // trajectory.getDetectorWidth()/2 - prinpoint.getElement(0); double ycorr = 0; // trajectory.getDetectorHeight()/2 - prinpoint.getElement(1); double length = trajectory.getSourceToDetectorDistance(); Edge environmentEdge = new Edge(new PointND(0), new PointND(length)); ArrayList<PhysicalObject> fallBackBackground = new ArrayList<PhysicalObject>(1); SimpleVector pixel = new SimpleVector(0, 0); boolean negate = false; for (int y = 0; y < trajectory.getDetectorHeight(); y++) { for (int x = 0; x < trajectory.getDetectorWidth(); x++) { pixel.setElementValue(0, x - xcorr); pixel.setElementValue(1, y - ycorr); SimpleVector dir = projection.computeRayDirection(pixel); if ((y == 0) && (x == 0)) { // Check that ray direction is towards origin. double max = 0; int index = 0; for (int i = 0; i < 3; i++) { if (Math.abs(dir.getElement(i)) > max) { max = Math.abs(dir.getElement(i)); index = i; } } double t = -raySource.get(index) / dir.getElement(index); if (t < 0) negate = true; } if (negate) dir.negate(); castLine.setDirection(dir); ArrayList<PhysicalObject> segments = rayTracer.castRay(castLine); if (accurate) { double dirCosine = SimpleOperators.multiplyInnerProd(centerPixDir, dir); length = trajectory.getSourceToDetectorDistance() / dirCosine; } if (segments == null) { fallBackBackground.clear(); segments = fallBackBackground; } else { if (accurate) { environmentEdge = new Edge(new PointND(0), new PointND(length - getTotalSegmentsLength(segments))); } } environment.setShape(environmentEdge); segments.add(environment); /* old code: double integral = absorptionModel.evaluateLineIntegral(segments); slice.putPixelValue(x, y, integral); */ detector.writeToDetector(slice, x, y, segments); } } return slice; }
@Override public Grid2D applyToolToImage(Grid2D imageProcessor) { FloatProcessor imp = new FloatProcessor(imageProcessor.getWidth(), imageProcessor.getHeight()); imp.setPixels(imageProcessor.getBuffer()); if (!initBead) initializeBead(); ImageProcessor imp1 = imp.duplicate(); // original double[][] beadMean3D = config.getBeadMeanPosition3D(); // [beadNo][x,y,z] double[] uv = new double[1]; SimpleMatrix pMatrix = config.getGeometry().getProjectionMatrix(imageIndex).computeP(); // [projection #][bead #][u, v, state[0: initial, 1: registered, 2: updated by hough searching]] double[][][] beadPosition2D = config.getBeadPosition2D(); int noBeadRegistered = 0; double[][] xy1 = new double[WeightBearingBeadPositionBuilder.beadNo][2]; // original double[][] xy2 = new double[WeightBearingBeadPositionBuilder.beadNo] [2]; // warped (mapped to the mean), control points, reference double[][] xy1_hat = new double[WeightBearingBeadPositionBuilder.beadNo][2]; // original double[][] xy2_hat = new double[WeightBearingBeadPositionBuilder.beadNo][2]; // original // double distanceReferenceToCurrentBead = 0; for (int i = WeightBearingBeadPositionBuilder.currentBeadNo; i >= 0; i--) { if (beadMean3D[i][0] != 0 || beadMean3D[i][1] != 0 || beadMean3D[i][2] != 0) { // assume bead 3d is registered. uv = compute2DCoordinates(beadMean3D[i], pMatrix); // find bead location if registered by txt: state 1 if (beadPosition2D[imageIndex][i][2] == 1) { noBeadRegistered++; if (isDisplay) { imp1.setValue(2); imp1.drawLine( (int) Math.round(beadPosition2D[imageIndex][i][0] - 10), (int) Math.round(beadPosition2D[imageIndex][i][1] - 10), (int) Math.round(beadPosition2D[imageIndex][i][0] + 10), (int) Math.round(beadPosition2D[imageIndex][i][1] + 10)); imp1.drawLine( (int) Math.round(beadPosition2D[imageIndex][i][0] - 10), (int) Math.round(beadPosition2D[imageIndex][i][1] + 10), (int) Math.round(beadPosition2D[imageIndex][i][0] + 10), (int) Math.round(beadPosition2D[imageIndex][i][1] - 10)); imp1.drawString( "Bead " + i + " (state:" + (int) beadPosition2D[imageIndex][i][2] + ")", (int) beadPosition2D[imageIndex][i][0], (int) beadPosition2D[imageIndex][i][1] - 10); } xy1[noBeadRegistered - 1][0] = beadPosition2D[imageIndex][i][0]; xy1[noBeadRegistered - 1][1] = beadPosition2D[imageIndex][i][1]; xy2[noBeadRegistered - 1][0] = uv[0]; xy2[noBeadRegistered - 1][1] = uv[1]; } else if (imageIndex != 0 && imageIndex != config.getGeometry().getNumProjectionMatrices() - 1) { if (beadPosition2D[imageIndex - 1][i][2] == 1 && beadPosition2D[imageIndex + 1][i][2] == 1) { noBeadRegistered++; double xMean = (beadPosition2D[imageIndex - 1][i][0] + beadPosition2D[imageIndex - 1][i][0]) / 2; double yMean = (beadPosition2D[imageIndex + 1][i][1] + beadPosition2D[imageIndex + 1][i][1]) / 2; if (isDisplay) { imp1.setValue(2); imp1.drawLine( (int) Math.round(xMean - 10), (int) Math.round(yMean - 10), (int) Math.round(xMean + 10), (int) Math.round(yMean + 10)); imp1.drawLine( (int) Math.round(xMean - 10), (int) Math.round(yMean + 10), (int) Math.round(xMean + 10), (int) Math.round(yMean - 10)); imp1.drawString("Bead " + i + " (state:" + "M)", (int) xMean, (int) yMean - 10); } xy1[noBeadRegistered - 1][0] = xMean; xy1[noBeadRegistered - 1][1] = yMean; xy2[noBeadRegistered - 1][0] = uv[0]; xy2[noBeadRegistered - 1][1] = uv[1]; } } // mean projected bead // imp1.drawLine((int) Math.round(uv[0]-10), (int) Math.round(uv[1]), (int) // Math.round(uv[0]+10), (int) Math.round(uv[1])); // imp1.drawLine((int) Math.round(uv[0]), (int) Math.round(uv[1]-10), (int) // Math.round(uv[0]), (int) Math.round(uv[1]+10)); } } if (isDisplay) { for (int x = 0; x < config.getGeometry().getDetectorWidth(); x += 50) imp1.drawLine(x, 0, x, config.getGeometry().getDetectorHeight()); for (int y = 0; y < config.getGeometry().getDetectorHeight(); y += 50) imp1.drawLine(0, y, config.getGeometry().getDetectorWidth(), y); } if (isCornerIncluded) { xy1[noBeadRegistered + 0][0] = 0; xy1[noBeadRegistered + 0][1] = 0; xy2[noBeadRegistered + 0][0] = 0; xy2[noBeadRegistered + 0][1] = 0; xy1[noBeadRegistered + 1][0] = 0; xy1[noBeadRegistered + 1][1] = config.getGeometry().getDetectorHeight(); xy2[noBeadRegistered + 1][0] = 0; xy2[noBeadRegistered + 1][1] = config.getGeometry().getDetectorHeight(); xy1[noBeadRegistered + 2][0] = config.getGeometry().getDetectorWidth(); xy1[noBeadRegistered + 2][1] = 0; xy2[noBeadRegistered + 2][0] = config.getGeometry().getDetectorWidth(); xy2[noBeadRegistered + 2][1] = 0; xy1[noBeadRegistered + 3][0] = config.getGeometry().getDetectorWidth(); xy1[noBeadRegistered + 3][1] = config.getGeometry().getDetectorHeight(); xy2[noBeadRegistered + 3][0] = config.getGeometry().getDetectorWidth(); xy2[noBeadRegistered + 3][1] = config.getGeometry().getDetectorHeight(); noBeadRegistered = noBeadRegistered + 4; } boolean fScaling = true; double minX = Double.MAX_VALUE; double maxX = 0; double minY = Double.MAX_VALUE; double maxY = 0; double c = 0; if (fScaling) { // ----- scaling to reduce condition # of A matrix for (int i = 0; i < noBeadRegistered; i++) { minX = Math.min(minX, xy1[i][0]); maxX = Math.max(maxX, xy1[i][0]); minY = Math.min(minY, xy1[i][1]); maxY = Math.max(maxY, xy1[i][1]); } c = Math.max(maxX - minX, maxY - minY); for (int i = 0; i < noBeadRegistered; i++) { xy1_hat[i][0] = (xy1[i][0] - minX) / c; xy1_hat[i][1] = (xy1[i][1] - minY) / c; xy2_hat[i][0] = (xy2[i][0] - minX) / c; xy2_hat[i][1] = (xy2[i][1] - minY) / c; } } else { xy1_hat = xy1; xy2_hat = xy2; } ImageProcessor imp2 = imp1.duplicate(); // warped /* * A*x = b * Matrix A = (n + 3) * (n + 3); * n (noBeadRegistered + 4): # of control points + 4 corner points (assume corner points are static) */ int n = noBeadRegistered + 3; SimpleMatrix A = new SimpleMatrix(n, n); SimpleVector x_x = new SimpleVector(n); SimpleVector x_y = new SimpleVector(n); SimpleVector b_x = new SimpleVector(n); SimpleVector b_y = new SimpleVector(n); double rij = 0; double valA = 0; double valb_x = 0; double valb_y = 0; // Matrix L formation // alpha: mean of distances between control points' xy-projections) is a constant only present // on the diagonal of K // lambda: TPS smoothing regularization coefficient double alpha = 0.0; double lambda = 1.6; // 1.6 for (int i = 0; i < noBeadRegistered; i++) { // i= # of row for (int j = i; j < noBeadRegistered; j++) { // j= # of column alpha += Math.sqrt( Math.pow(xy2_hat[i][0] - xy2_hat[j][0], 2) + Math.pow(xy2_hat[i][1] - xy2_hat[j][1], 2)); } } alpha = alpha / Math.pow(noBeadRegistered, 2); for (int i = 0; i < n; i++) { // i= # of row for (int j = i; j < n; j++) { // j= # of column if (i < 3 && j < 3) valA = 0; else if (i >= 3 && j >= 3 && i == j) { valA = Math.pow(alpha, 2) * lambda; // valA = lambda; if (imageIndex < 10) System.out.println("Regularization = " + valA + ", lambda= " + lambda); } else if (i == 0 && j >= 0) valA = 1; else if (i == 1 && j >= 3) valA = xy1_hat[j - 3][0]; else if (i == 2 && j >= 3) valA = xy1_hat[j - 3][1]; else { rij = Math.pow(xy1_hat[j - 3][0] - xy1_hat[i - 3][0], 2) + Math.pow(xy1_hat[j - 3][1] - xy1_hat[i - 3][1], 2); if (rij == 0) valA = 0; else valA = rij * Math.log(rij); } A.setElementValue(i, j, valA); A.setElementValue(j, i, valA); } if (i < 3) { valb_x = 0; valb_y = 0; } else { // valb_x = xy2_hat[i-3][0]-xy1_hat[i-3][0]; // valb_y = xy2_hat[i-3][1]-xy1_hat[i-3][1]; valb_x = xy2[i - 3][0] - xy1[i - 3][0]; valb_y = xy2[i - 3][1] - xy1[i - 3][1]; // if (imageIndex > 150 && imageIndex < 170) // System.out.println("Idx" + imageIndex + ",Elevation" + (i-3) + ": " + valb_x + "---" // + valb_y); } b_x.setElementValue(i, valb_x); b_y.setElementValue(i, valb_y); } // System.out.println("A condition number=" + A.conditionNumber(MatrixNormType.MAT_NORM_L1)); // System.out.println("A condition number=" + A.conditionNumber(MatrixNormType.MAT_NORM_LINF)); x_x = Solvers.solveLinearSysytemOfEquations(A, b_x); x_y = Solvers.solveLinearSysytemOfEquations(A, b_y); if (fScaling) { // ----- pixel space coefficients a, b scaling back double tmpA0 = x_x.getElement(0) - x_x.getElement(1) * (minX / c) - x_x.getElement(2) * (minY / c); for (int j = 0; j < noBeadRegistered; j++) { tmpA0 -= Math.log(c) * 2 * x_x.getElement(j + 3) * (Math.pow(xy1_hat[j][0], 2) + Math.pow(xy1_hat[j][1], 2)); } x_x.setElementValue(0, tmpA0); tmpA0 = x_y.getElement(0) - x_y.getElement(1) * (minX / c) - x_y.getElement(2) * (minY / c); for (int j = 0; j < noBeadRegistered; j++) { tmpA0 -= Math.log(c) * 2 * x_y.getElement(j + 3) * (Math.pow(xy1_hat[j][0], 2) + Math.pow(xy1_hat[j][1], 2)); } x_y.setElementValue(0, tmpA0); x_x.setElementValue(1, x_x.getElement(1) / c); x_y.setElementValue(1, x_y.getElement(1) / c); x_x.setElementValue(2, x_x.getElement(2) / c); x_y.setElementValue(2, x_y.getElement(2) / c); for (int i = 3; i < n; i++) { x_x.setElementValue(i, x_x.getElement(i) / Math.pow(c, 2)); x_y.setElementValue(i, x_y.getElement(i) / Math.pow(c, 2)); } // ----- pixel space coefficients a, b scaling back end } double devU = 0; double devV = 0; // Do warping // if (imageIndex == 0) { for (int y = 0; y < config.getGeometry().getDetectorHeight(); y++) { // for (int y=252; y<253; y++) { for (int x = 0; x < config.getGeometry().getDetectorWidth(); x++) { // for (int x=606; x<607; x++) { devU = x_x.getElement(0) + x_x.getElement(1) * x + x_x.getElement(2) * y; devV = x_y.getElement(0) + x_y.getElement(1) * x + x_y.getElement(2) * y; for (int i = 0; i < noBeadRegistered; i++) { rij = Math.pow(xy1[i][0] - x, 2) + Math.pow(xy1[i][1] - y, 2); if (rij > 0) { devU += x_x.getElement(i + 3) * rij * Math.log(rij); devV += x_y.getElement(i + 3) * rij * Math.log(rij); } } // devU = 0; // devV = 0; imp2.setf(x, y, (float) imp1.getInterpolatedValue(x - devU, y - devV)); // System.out.println("x, y=" + x + ", " + y + "\t" + devU + ", " + devV); // maxDevU = Math.max(maxDevU, devU); // maxDevV = Math.max(maxDevV, devV); } } // Error estimate after transformation // for (int i=0; i<= WeightBearingBeadPositionBuilder.currentBeadNo; i++){ // // if (beadMean3D[i][0] != 0 || beadMean3D[i][1] != 0 || beadMean3D[i][2] != 0){ // assume // bead 3d is registered. // // // find bead location if registered by txt: state 1 // if (beadPosition2D[imageIndex][i][2] == 1){ // // // Projected Reference // uv = compute2DCoordinates(beadMean3D[i], pMatrix); // double x = uv[0]; // double y = uv[1]; // // bead detected position in 2d // // Transform to 2D coordinates, time variant position // //beadPosition2D[imageIndex][i][0]; // //beadPosition2D[imageIndex][i][1]; // // devU = x_x.getElement(0) + x_x.getElement(1)*x + x_x.getElement(2)*y; // devV = x_y.getElement(0) + x_y.getElement(1)*x + x_y.getElement(2)*y; // for (int j=0; j<noBeadRegistered; j++){ // rij = Math.pow(xy1[j][0]-x, 2) + Math.pow(xy1[j][1]-y, 2); // if (rij > 0) { // devU += x_x.getElement(j+3)*rij*Math.log(rij); // devV += x_y.getElement(j+3)*rij*Math.log(rij); // } // } // // distanceReferenceToCurrentBead += // Math.sqrt(Math.pow(uv[0]-(beadPosition2D[imageIndex][i][0]+devU), // 2)+Math.pow(uv[1]-(beadPosition2D[imageIndex][i][1]+devV), 2)); // // } // } // } // System.out.println("Euclidean distance\t" + imageIndex + "\t" + // distanceReferenceToCurrentBead/noBeadRegistered); // } if (isDisplay) { for (int i = WeightBearingBeadPositionBuilder.currentBeadNo; i >= 0; i--) { if (beadMean3D[i][0] != 0 || beadMean3D[i][1] != 0 || beadMean3D[i][2] != 0) { // assume bead 3d is registered. uv = compute2DCoordinates(beadMean3D[i], pMatrix); imp2.setValue(2); // mean projected bead imp2.drawLine( (int) Math.round(uv[0] - 10), (int) Math.round(uv[1]), (int) Math.round(uv[0] + 10), (int) Math.round(uv[1])); imp2.drawLine( (int) Math.round(uv[0]), (int) Math.round(uv[1] - 10), (int) Math.round(uv[0]), (int) Math.round(uv[1] + 10)); } } } Grid2D result = new Grid2D((float[]) imp2.getPixels(), imp2.getWidth(), imp2.getHeight()); return result; }
private void visualizeKleinNishina(double energyJoule) { int gridWidth = 600; int gridHeight = 500; double maxAngle = 360; Grid2D grid = new Grid2D(gridWidth, gridHeight); FloatProcessor fp = new FloatProcessor(grid.getWidth(), grid.getHeight()); fp.setPixels(grid.getBuffer()); // find max value double max = 0; for (int i = 0; i < maxAngle; ++i) { double value = XRayTracerSampling.comptonAngleProbability(energyJoule, Math.toRadians(i)); if (value > max) { max = value; } } fp.drawLine((int) 0, grid.getHeight() / 2, grid.getWidth(), grid.getHeight() / 2); fp.drawLine(grid.getWidth() / 2, 0, grid.getWidth() / 2, grid.getHeight()); fp.drawOval((grid.getWidth() - grid.getHeight()) / 2, 0, grid.getHeight(), grid.getHeight()); double lastX = 0; double lastY = 0; // draw angle distribution for (int i = 0; i < maxAngle; ++i) { double value = XRayTracerSampling.comptonAngleProbability(energyJoule, Math.toRadians(i)); SimpleMatrix m = Rotations.createBasicZRotationMatrix(Math.toRadians(i)); SimpleVector v = new SimpleVector(((value / max) * ((double) grid.getHeight() / 2.d)), 0, 0); SimpleVector r = SimpleOperators.multiply(m, v); double x = grid.getWidth() / 2 + r.getElement(0); double y = grid.getHeight() / 2 + r.getElement(1); if (i > 0) fp.drawLine((int) lastX, (int) lastY, (int) x, (int) y); lastX = x; lastY = y; } grid.show( "Normalized Klein-Nishina cross-section as a function of scatter angle (" + energyJoule / eV + "eV)"); grid = new Grid2D(gridWidth, gridHeight); fp = new FloatProcessor(grid.getWidth(), grid.getHeight()); fp.setPixels(grid.getBuffer()); // draw histogram with rejection sampling of the klein-nishina // distribution int[] angles = new int[grid.getWidth()]; for (int i = 0; i < numSamples; ++i) { double angle = Math.toDegrees(sampler.getComptonAngleTheta(energyJoule)); int pos = (int) (angle * grid.getWidth() / 360.d); angles[pos] += 1; } double max2 = 0; for (int i = 0; i < angles.length; ++i) { if (angles[i] > max2) { max2 = angles[i]; } } for (int i = 0; i < angles.length; ++i) { double x = i; double y = ((angles[i]) * (grid.getHeight() / (max2))); fp.drawLine((int) x, (int) grid.getHeight(), (int) x, grid.getHeight() - (int) y); } // draw klein-nishina probability function lastX = 0; lastY = 0; for (int i = 0; i < maxAngle; ++i) { double value = XRayTracerSampling.comptonAngleProbability(energyJoule, Math.toRadians(i)); double x = (i * (grid.getWidth() / 360.f)); double y = grid.getHeight() - ((value) * (grid.getHeight() / (max))); fp.drawLine((int) lastX, (int) lastY, (int) x, (int) y); lastX = x; lastY = y; } grid.show( "Energy: " + energyJoule / eV + "eV; x-axis: angle[0-360]; y-axis: probability[0-max]"); }
/** * method to calculate a mapping K from two source positions C0, C1 to a plane C0 (C1) is the * source position from the first (second) view */ public void createMappingToEpipolarPlane() { // set up source matrices // SimpleVector C0 = this.view1.C; SimpleVector C1 = this.view2.C; // compute Pluecker coordinates // double L01 = C0.getElement(0) * C1.getElement(1) - C0.getElement(1) * C1.getElement(0); double L02 = C0.getElement(0) * C1.getElement(2) - C0.getElement(2) * C1.getElement(0); double L03 = C0.getElement(0) * C1.getElement(3) - C0.getElement(3) * C1.getElement(0); double L12 = C0.getElement(1) * C1.getElement(2) - C0.getElement(2) * C1.getElement(1); double L13 = C0.getElement(1) * C1.getElement(3) - C0.getElement(3) * C1.getElement(1); double L23 = C0.getElement(2) * C1.getElement(3) - C0.getElement(3) * C1.getElement(2); // construct B (6x1) // SimpleVector B = new SimpleVector(L01, L02, L03, L12, L13, L23); // compute infinity point in direction of B // SimpleVector N = new SimpleVector(-L03, -L13, -L23, 0); // compute plane E0 containing B and X0=(0,0,0,1) // SimpleVector E0 = SimpleOperators.getPlueckerJoin(B, new SimpleVector(0, 0, 0, 1)); // find othonormal basis from plane normals // // (vectors are of 3x1) SimpleVector a2 = new SimpleVector(E0.getElement(0), E0.getElement(1), E0.getElement(2)); SimpleVector a3 = new SimpleVector(N.getElement(0), N.getElement(1), N.getElement(2)); // set vectors to unit length a2.normalizeL2(); a3.normalizeL2(); // calculate cross product to get the last basis vector // SimpleVector a1 = General.crossProduct(a2, a3).negated(); // (a1 is already of unit length -> no normalization needed) // set up assembly matrix A (4x3) // SimpleMatrix A = new SimpleMatrix(4, 3); A.setSubColValue(0, 0, a1); A.setSubColValue(0, 1, a2); A.setSubColValue(0, 2, C0); // store mapping matrix K (4x3 = 4x4 * 4x3) // this.K = SimpleOperators.multiplyMatrixProd(SimpleOperators.getPlueckerMatrixDual(B), A); }