/** TrakEM2 plugin for ImageJ(C). Copyright (C) 2005-2009 Albert Cardona and Rodney Douglas. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation (http://www.gnu.org/licenses/gpl.txt ) This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. You may contact Albert Cardona at acardona at ini.phys.ethz.ch Institute of Neuroinformatics, University of Zurich / ETH, Switzerland. **/ package ini.trakem2.utils; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; public class Montage { private HashMap<String,HashMap<String,Item>> ht; private ArrayList<Item> al; private int i_row_start = -1; private int i_row_end = -1; private int i_col_start = -1; private int i_col_end = -1; public Montage(String convention, boolean chars_are_columns) { convention = convention.toLowerCase(); al = new ArrayList<Item>(); ht = new HashMap<String,HashMap<String,Item>>(); // find out the start and end index of the char string that defines the chunks for the rows and cols in the name int start, end; start = convention.indexOf('c'); end = start + 1; if (convention.length() != end) { while (end < convention.length() && 'c' == convention.charAt(end)) { end++; } } if (chars_are_columns) { i_col_start = start; i_col_end = end; } else { i_row_start = start; i_row_end = end; } start = convention.indexOf('d'); end = start + 1; if (convention.length() != end) { while (end < convention.length() && 'd' == convention.charAt(end)) { end++; } } if (chars_are_columns) { i_row_start = start; i_row_end = end; } else { i_col_start = start; i_col_end = end; } //Utils.log2("Montage: i_row_start,end : " + i_row_start + "," + i_row_end + " i_col_start,end : " + i_col_start + "," + i_col_end); } public void addAll(String[] file_name) { for (int i=0; i<file_name.length; i++) { add(file_name[i]); } } public void add(String file_name) { Item item = new Item(file_name); al.add(item); HashMap<String,Item> ob = ht.get(item.s_col); if (null == ob) { HashMap<String,Item> rows = new HashMap<String,Item>(); rows.put(item.s_row, item); ht.put(item.s_col, rows); } else { ob.put(item.s_row, item); } } /** Returns an ArrayList of String[], which can be of unequal length, and each contain the file names of a column. First dimension is columns, second is rows. */ public ArrayList<String[]> getCols() { // TODO problem: if an image is missing in the middle of the grid, the column will be shifted up // It'd be better to identify col and row markers, and then fill in a grid pattern with them. If there are holes, so what ... but then, if images are of unequal size, that won't work .. // Whatever, it's fine as it is (and easy enough to fix manually when such a problem occurs) // get cols, and order them String[] cols = new String[ht.size()]; int i = 0; int max_col_len = 0; for (final String c : ht.keySet()) { cols[i] = c; int len = cols[i].length(); if (len > max_col_len) max_col_len = len; i++; } //fix length of col string: prepend '0' to any that is shorter than the longest for Arrays.sort() to work ok for (i=al.size()-1;i>-1; i--) { Item item = (Item)al.get(i); item.fixColLength(max_col_len); } Arrays.sort(cols); // you do it, java .. ArrayList<String[]> mon = new ArrayList<String[]>(); for (i=0; i<cols.length; i++) { HashMap<String,Item> ht_rows = ht.get(cols[i]); String[] rows = new String[ht_rows.size()]; int j = 0; int max_row_len = 0; for (final String r : ht_rows.keySet()) { rows[j] = r; int len = rows[j].length(); if (len > max_row_len) max_row_len = len; j++; } for (final Item item : ht_rows.values()) { item.fixRowLength(max_row_len); } Arrays.sort(rows); //ordering by whatever ordering there is, letters or numbers String[] ob_rows = new String[rows.length]; for (j=0; j<rows.length; j++) { ob_rows[j] = ((Item)ht_rows.get(rows[j])).file_name; } // add it mon.add(ob_rows); } return mon; } private class Item { String file_name; String s_col; String s_row; Item(String file_name) { this.file_name = file_name; this.s_col = file_name.substring(i_col_start, i_col_end); this.s_row = file_name.substring(i_row_start, i_row_end); } void fixColLength(int target_len) { int len = s_col.length(); while (target_len > len) { s_col = "0" + s_col; len++; } } void fixRowLength(int target_len) { int len = s_row.length(); while (target_len > len) { s_row = "0" + s_row; len++; } } } }