/* * Copyright (c) 2005–2012 Goethe Center for Scientific Computing - Simulation and Modelling (G-CSC Frankfurt) * Copyright (c) 2012-2015 Goethe Center for Scientific Computing - Computational Neuroscience (G-CSC Frankfurt) * * This file is part of NeuGen. * * NeuGen is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * see: http://opensource.org/licenses/LGPL-3.0 * file://path/to/NeuGen/LICENSE * * NeuGen is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * This version of NeuGen includes copyright notice and attribution requirements. * According to the LGPL this information must be displayed even if you modify * the source code of NeuGen. The copyright statement/attribution may not be removed. * * Attribution Requirements: * * If you create derived work you must do the following regarding copyright * notice and author attribution. * * Add an additional notice, stating that you modified NeuGen. In addition * you must cite the publications listed below. A suitable notice might read * "NeuGen source code modified by YourName 2012". * * Note, that these requirements are in full accordance with the LGPL v3 * (see 7. Additional Terms, b). * * Publications: * * S. Wolf, S. Grein, G. Queisser. NeuGen 2.0 - * Employing NeuGen 2.0 to automatically generate realistic * morphologies of hippocapal neurons and neural networks in 3D. * Neuroinformatics, 2013, 11(2), pp. 137-148, doi: 10.1007/s12021-012-9170-1 * * * J. P. Eberhard, A. Wanner, G. Wittum. NeuGen - * A tool for the generation of realistic morphology * of cortical neurons and neural networks in 3D. * Neurocomputing, 70(1-3), pp. 327-343, doi: 10.1016/j.neucom.2006.01.028 * */ package org.neugen.slider; import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.imageio.ImageIO; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JScrollPane; import javax.swing.filechooser.FileFilter; import javax.vecmath.Point3f; import org.apache.log4j.Logger; import org.jdesktop.application.Application; import org.jdesktop.application.Task; import org.neugen.datastructures.Net; import org.neugen.datastructures.Segment; import org.neugen.gui.NeuGenView; import org.neugen.gui.SliderDialog; import org.neugen.makemovie.MovieMaker; import org.neugen.utils.Utils; /** * @author Alexander Wanner * @author Sergei Wolf */ public final class SliderGeneratorTask extends Task<Void, Void> { /** use to log messages */ private final static Logger logger = Logger.getLogger(SliderGeneratorTask.class.getName()); private Net net; public final class SliderImage extends JComponent { private static final long serialVersionUID = 1L; private Image img; private int width; private int height; public SliderImage(Image img, int width, int height) { super(); this.width = width; this.height = height; this.img = img; if (img != null) { repaint(); } } @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(img, 0, 0, width, height, this); } } public SliderGeneratorTask(Application application, Net net) { super(application); this.net = net; } @Override protected Void doInBackground() throws Exception { NeuGenView ngView = NeuGenView.getInstance(); SliderDialog sliderDialog = new SliderDialog(ngView.getFrame(), true); sliderDialog.setVisible(true); sliderDialog.setLocationRelativeTo(null); if (sliderDialog.getReturnStatus() == SliderDialog.RET_CANCEL) { return null; } Utils.del(new File("imagesSlider")); File dir = new File("imagesSlider"); boolean mkDir = dir.mkdir(); while(!mkDir) { mkDir = dir.mkdir(); } int imgWidth = sliderDialog.getImgWidth(); int imgHeight = sliderDialog.getImgHeight(); Point3f coordOrigin = sliderDialog.getCoordOrigin(); Point3f spacing = sliderDialog.getSpacing(); if (ngView != null) { ngView.outPrintln("Image directory: " + dir.getAbsolutePath()); ngView.outPrintln("The image width: " + imgWidth); ngView.outPrintln("The image height: " + imgHeight); ngView.outPrintln("The coordinate origin: " + coordOrigin.toString()); ngView.outPrintln("Spacing: " + spacing.toString()); } JScrollPane visualScrollPane = ngView.getVisualScrollPane(); visualScrollPane.setBorder(null); visualScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); visualScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); SegmentData d = new SegmentData(net); logger.info(d.getNumberOfSegments()); List<Segment> segments = d.getData(); CartGridGenerator<Float> gen = new CartGridGenerator<Float>(coordOrigin, spacing); for (Segment segment : segments) { gen.resolve(segment, 1.5f); } logger.info("grid size : " + gen.getGrid().getNDataPoints()); // Calculate the min/max int x,y,z { int mins[] = null, maxs[] = null; Map<Integer, Map<Integer, Map<Integer, Float>>> dataGrid = gen.getGrid().dataGrid; Set<Integer> keySet = dataGrid.keySet(); for (Integer zInt : keySet) { //logger.info("" + zInt + " " + dataGrid.get(zInt).size()); Map<Integer, Map<Integer, Float>> zLayer = dataGrid.get(zInt); Set<Integer> keySet2 = zLayer.keySet(); for (Integer xInt : keySet2) { Set<Entry<Integer, Float>> xLine = zLayer.get(xInt).entrySet(); for (Entry<Integer, Float> p : xLine) { int coord[] = new int[]{xInt, p.getKey(), zInt}; if (mins == null) { mins = Arrays.copyOf(coord, coord.length); maxs = Arrays.copyOf(coord, coord.length); } else { for (int i = 0; i < mins.length; ++i) { if (mins[i] > coord[i]) { mins[i] = coord[i]; } if (maxs[i] < coord[i]) { maxs[i] = coord[i]; } } } } } } if(mins == null || maxs == null) { return null; } //logger.info("mins " + new Point3i(mins).toString()); //logger.info("maxs " + new Point3i(maxs).toString()); { int width = maxs[0] - mins[0]; int height = maxs[1] - mins[1]; //if(width > imgWidth) width = imgWidth; //if(height > imgHeight) height = imgHeight; BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics graphics = bufferedImage.getGraphics(); List<File> vFiles = new ArrayList<File>(); for (Integer zInt = mins[2]; zInt < maxs[2] + 1; ++zInt) { //logger.info("z=" + zInt); Map<Integer, Map<Integer, Float>> layer0 = dataGrid.get(zInt); if (layer0 == null) { continue; } for (Integer xInt : layer0.keySet()) { Map<Integer, Float> lineX = layer0.get(xInt); for (Integer yInt : lineX.keySet()) { graphics.drawLine(xInt - mins[0], yInt - mins[1], xInt - mins[0], yInt - mins[1]); } } String dirPath = dir.getAbsolutePath(); File file = new File(dirPath + "/z" + zInt + ".jpg"); ImageIO.write(bufferedImage, "jpg", file); visualScrollPane.getViewport().add(new SliderImage(bufferedImage, imgWidth, imgHeight)); visualScrollPane.validate(); visualScrollPane.repaint(); float progress = Math.abs((float) (zInt)) / ((float) maxs[2]); try { setProgress(progress); } catch (IllegalArgumentException ae) { logger.error(ae); } vFiles.add(file); } ngView.outPrintln("Number of images: " + dir.list().length); /* * GENERATE VIDEO */ width = imgWidth; height = imgHeight; int frameRate = 60; File[] files = vFiles.toArray(new File[0]); try { MovieMaker movieMaker = new MovieMaker(width, height, frameRate, new File("slider.mov"), files); movieMaker.makeMovie(); } catch (Exception ex) { logger.error(ex); } ngView.outPrintln("end"); } } return null; } @Override protected void succeeded(Void result) { NeuGenView ngView = NeuGenView.getInstance(); ngView.getVisualScrollPane().getViewport().removeAll(); ngView.getVisualScrollPane().validate(); ngView.getVisualScrollPane().repaint(); ngView.getVisualScrollPane().setBorder(javax.swing.BorderFactory.createTitledBorder("Visualization")); ngView.enableButtons(); System.gc(); ngView.outPrintln(Utils.getMemoryStatus()); } }