/* * Copyright (C) 2014 Andreas Maier * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */ package edu.stanford.rsl.conrad.opencl; import java.nio.FloatBuffer; import java.util.ArrayList; import java.util.HashMap; import com.jogamp.opencl.CLBuffer; import com.jogamp.opencl.CLCommandQueue; import com.jogamp.opencl.CLContext; import com.jogamp.opencl.CLDevice; import com.jogamp.opencl.CLMemory.Mem; import edu.stanford.rsl.conrad.data.numeric.Grid2D; import edu.stanford.rsl.conrad.data.numeric.MultiChannelGrid2D; import edu.stanford.rsl.conrad.phantom.AnalyticPhantom; import edu.stanford.rsl.conrad.physics.PhysicalObject; import edu.stanford.rsl.conrad.physics.materials.Material; public class OpenCLMaterialPathLengthPhantomRenderer extends OpenCLProjectionPhantomRenderer { ArrayList<Material> materials; String [] channelNames; protected HashMap<Material, CLBuffer<FloatBuffer>> mus; private CLBuffer<FloatBuffer> generateMuMap(CLContext context, CLDevice device, Material mat) { // absorption model // setting only the present material to 10 (due to the normalization in the drawing code. // this means we draw the path length in [mm]. CLBuffer<FloatBuffer> mu = context.createFloatBuffer(phantom.size() +1, Mem.READ_ONLY); mu.getBuffer().put((float) phantom.getBackgroundMaterial().getDensity()); for (PhysicalObject o: phantom){ float density = 0.0f; if (o.getMaterial().equals(mat)) density = 10.0f; mu.getBuffer().put(density); } mu.getBuffer().rewind(); device.createCommandQueue().putWriteBuffer(mu, false).finish().release(); return mu; } @Override protected void evaluateAbsorptionModel(int k) { MultiChannelGrid2D multiChannelGrid2D = new MultiChannelGrid2D(dimx, dimy, materials.size()); multiChannelGrid2D.setChannelNames(channelNames); for (int c = 0; c < materials.size(); c++){ // evaluate absorption model long time = System.nanoTime(); renderer.drawScreenMonochromatic(screenBuffer, mus.get(materials.get(c)), priorities); //render.drawScreen(screenBuffer); time = System.nanoTime() - time; System.out.println("path length screen buffer drawing took: "+(time/1000000)+"ms for " +materials.get(c)); CLCommandQueue clc = renderer.device.createCommandQueue(); clc.putReadBuffer(screenBuffer, true).finish(); clc.release(); float[] array = new float [dimx*dimy]; for (int j = 0; j < dimy; j++){ for (int i = 0; i < dimx; i++){ array[(j*dimx)+i] = screenBuffer.getBuffer().get(); } } screenBuffer.getBuffer().rewind(); // Save data to buffer Grid2D image = new Grid2D(array, dimx, dimy); multiChannelGrid2D.setChannel(c, image); screenBuffer.getBuffer().clear(); // its not the screenbuffer, copied TestOpenCL code } buffer.add(multiChannelGrid2D, k); // its not the buffer, deleted it } @Override public void release(){ super.release(); for (int i=mus.size()-1; i > -1; i--){ CLBuffer<FloatBuffer> buffer = mus.get(i); if (buffer != null){ mus.remove(i); buffer.release(); } } } @Override public void configure() throws Exception{ AnalyticPhantom phantom = AnalyticPhantom.getCurrentPhantom(); CLContext context = OpenCLUtil.createContext(); CLDevice device = context.getMaxFlopsDevice(); configure(phantom, context, device, false); materials = new ArrayList<Material>(); for (PhysicalObject o: phantom){ if (! materials.contains(o.getMaterial())) materials.add(o.getMaterial()); } mus = new HashMap<Material, CLBuffer<FloatBuffer>>(); for (int i = 0; i< materials.size(); i++){ mus.put(materials.get(i), generateMuMap(context, device, materials.get(i))); } channelNames = new String[materials.size()]; for (int i=0; i < materials.size(); i ++){ channelNames[i]=materials.get(i).getName(); } configured = true; } @Override public String getBibtexCitation() { String bibtex = "@Article{Maier12-FSO,\n" + " author = {Maier, A. and Hofmann, H.G. and Schwemmer, C. and Hornegger, J. and Keil, A. and Fahrig, R.},\n" + " title = {Fast simulation of x-ray projections of spline-based surfaces using an append buffer},\n" + " journal = {Physics in Medicine and Biology},\n" + " volume = {57},\n" + " number = {19},\n" + " pages = {6193-6210},\n" + " year = {2012}\n" + "}"; return bibtex; } @Override public String getMedlineCitation() { String medline = "Maier A, Hofmann HG, Schwemmer C, Hornegger J, Keil A, Fahrig R. Fast simulation of x-ray projections of spline-based surfaces using an append buffer. Phys Med Biol. 57(19):6193-210. 2012"; return medline; } @Override public String toString() { return "OpenCL Material Path Length Renderer"; } }