package edu.stanford.rsl.conrad.opencl; import com.jogamp.opencl.CLMemory.Mem; import edu.stanford.rsl.conrad.geometry.transforms.AffineTransform; import edu.stanford.rsl.conrad.numerics.SimpleMatrix; import edu.stanford.rsl.conrad.numerics.SimpleOperators; import edu.stanford.rsl.conrad.utils.Configuration; import edu.stanford.rsl.conrad.utils.XmlUtils; public class OpenCLDetectorMotionBackProjector extends OpenCLBackProjector{ /** * */ private static final long serialVersionUID = -7764566238080291654L; AffineTransform[] affDetMotion; public OpenCLDetectorMotionBackProjector () { super(); affDetMotion = null; } @Override public void configure() throws Exception{ super.configure(); affDetMotion = (AffineTransform[])XmlUtils.importFromXML(); if (affDetMotion==null || affDetMotion.length != Configuration.getGlobalConfiguration().getGeometry().getProjectionStackSize()) throw new Exception("Motion fields exceed the number of projections"); } public void configure(AffineTransform[] transf) throws Exception{ super.configure(); if (transf==null || transf.length != Configuration.getGlobalConfiguration().getGeometry().getProjectionStackSize()){ configured = false; throw new Exception("Motion fields exceed the number of projections"); } this.affDetMotion = transf; } @Override protected synchronized void initProjectionMatrix(int projectionNumber){ // load projection Matrix for current Projection. // if detector motion field exists, apply to projection matrix to do correction SimpleMatrix pMat; if (affDetMotion== null || affDetMotion.length <= projectionNumber) pMat = getGeometry().getProjectionMatrix(projectionNumber).computeP(); else{ SimpleMatrix affMotionH = new SimpleMatrix(3,3); affMotionH.setSubMatrixValue(0, 0, affDetMotion[projectionNumber].getRotation(2)); affMotionH.setSubColValue(0, 2, affDetMotion[projectionNumber].getTranslation(2)); affMotionH.setElementValue(2,2,1); pMat = SimpleOperators.multiplyMatrixProd(affMotionH, getGeometry().getProjectionMatrix(projectionNumber).computeP()); } float [] pMatFloat = new float[pMat.getCols() * pMat.getRows()]; for (int j = 0; j< pMat.getRows(); j++) { for (int i = 0; i< pMat.getCols(); i++) { pMatFloat[(j * pMat.getCols()) + i] = (float) pMat.getElement(j, i); } } // Obtain the global pointer to the view matrix from // the module if (projectionMatrix == null) projectionMatrix = context.createFloatBuffer(pMatFloat.length, Mem.READ_ONLY); projectionMatrix.getBuffer().put(pMatFloat); projectionMatrix.getBuffer().rewind(); commandQueue.putWriteBuffer(projectionMatrix, true).finish(); } @Override public String getName() { return "OpenCL Backprojector With Detector Motion"; } @Override public String getToolName(){ return "OpenCL Backprojector With Detector Motion"; } } /* * Copyright (C) 2010-2014 Martin Berger * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */