/*
* 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";
}
}