/* * Copyright (c) 2003-2012 Fred Hutchinson Cancer Research Center * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fhcrc.cpl.viewer.commandline.modules; import org.fhcrc.cpl.toolbox.ApplicationContext; import org.fhcrc.cpl.toolbox.commandline.arguments.*; import org.fhcrc.cpl.toolbox.filehandler.TabLoader; import org.fhcrc.cpl.toolbox.commandline.CommandLineModuleExecutionException; import org.fhcrc.cpl.toolbox.commandline.CommandLineModule; import org.apache.log4j.Logger; import java.io.*; import java.util.*; /** * Command linemodule for plotting the mass calibration of a feature file */ public class CollapseSpreadsheetRowsCLM extends BaseViewerCommandLineModuleImpl implements CommandLineModule { protected static Logger _log = Logger.getLogger(CollapseSpreadsheetRowsCLM.class); protected String collapseColumnName = null; protected File inFile; protected File outFile; protected String separatorString = ";"; protected List<String> otherColsToCollapse = new ArrayList<String>(); protected boolean shouldCollapseToUnique = false; public CollapseSpreadsheetRowsCLM() { init(); } protected void init() { mCommandName = "collapsespreadsheetrows"; mShortDescription = "collapse multiple rows in a spreadsheet with the same value for collapsecolumn"; CommandLineArgumentDefinition[] argDefs = { createUnnamedFileArgumentDefinition(true,"input spreadsheet"), new StringArgumentDefinition("collapsecolumn", true, "column to split on"), new FileToWriteArgumentDefinition("out", false, "output file"), new StringArgumentDefinition("separator", false, "String to split on", separatorString), new StringListArgumentDefinition("othercolstocollapse", false, "other columns to collapse (rather than keep one value). Any column NOT on this list " + "must have only one unique value, or an error is thrown."), new BooleanArgumentDefinition("collapsetounique", false, "for other columns, collapse into unique values.", false), }; addArgumentDefinitions(argDefs); } public void assignArgumentValues() throws ArgumentValidationException { inFile = getUnnamedFileArgumentValue(); collapseColumnName = getStringArgumentValue("collapsecolumn"); separatorString = getStringArgumentValue("separator"); outFile = getFileArgumentValue("out"); otherColsToCollapse = getStringListArgumentValue("othercolstocollapse"); if (otherColsToCollapse == null) otherColsToCollapse = new ArrayList<String>(); if (!otherColsToCollapse.isEmpty()) { ApplicationContext.infoMessage("collapsing other columns:"); for (String col : otherColsToCollapse) ApplicationContext.infoMessage("\t" + col); } shouldCollapseToUnique = getBooleanArgumentValue("collapsetounique"); } /** * do the actual work */ public void execute() throws CommandLineModuleExecutionException { PrintWriter outPW = null; try { outPW = new PrintWriter(outFile); TabLoader loader = new TabLoader(inFile); List<TabLoader.ColumnDescriptor> columns = new ArrayList<TabLoader.ColumnDescriptor>(); StringBuffer headerLine = new StringBuffer(); boolean firstColumn = true; for (TabLoader.ColumnDescriptor column : loader.getColumns()) { columns.add(column); if (firstColumn) firstColumn = false; else headerLine.append("\t"); headerLine.append(column.name); } outPW.println(headerLine.toString()); outPW.flush(); Map<String, List<Map>> keyRowsMap = new HashMap<String, List<Map>>(); Map[] rowsAsMaps = (Map[])loader.load(); int lineNum = 0; for (Map row : rowsAsMaps) { lineNum++; Object collapseVal = row.get(collapseColumnName); if (collapseVal == null) { throw new CommandLineModuleExecutionException("Null collapse value for line " + lineNum); } String key = collapseVal.toString(); List<Map> rows = keyRowsMap.get(key); if (rows == null) { rows = new ArrayList<Map>(); keyRowsMap.put(key, rows); } rows.add(row); } for (String key : keyRowsMap.keySet()) { StringBuffer lineBuf = new StringBuffer(); List<Map> rows = keyRowsMap.get(key); boolean firstCol = true; for (TabLoader.ColumnDescriptor column : loader.getColumns()) { String valString = ""; if (key.equals(collapseColumnName)) valString = key; else { if (shouldCollapseToUnique) { Set<String> uniqueValsThisCol = new HashSet<String>(); for (Map row : rows) { String val = ""; if (row.containsKey(column.name) && row.get(column.name) != null) val = row.get(column.name).toString(); uniqueValsThisCol.add(val); } boolean firstVal = true; for (String val : uniqueValsThisCol) { if (!firstVal) valString = valString + separatorString; valString = valString + val; firstVal = false; } } else { List<String> allValsThisCol = new ArrayList<String>(); for (Map row : rows) { String val = ""; if (row.containsKey(column.name) && row.get(column.name) != null) val = row.get(column.name).toString(); allValsThisCol.add(val); } if (otherColsToCollapse.contains(column.name)) { boolean firstVal = true; for (String val : allValsThisCol) { if (!firstVal) valString = valString + separatorString; valString = valString + val; firstVal = false; } } else { Set<String> uniqueVals = new HashSet<String> (allValsThisCol); if (uniqueVals.size() > 1 && uniqueVals.contains("")) { uniqueVals.remove(""); } if (uniqueVals.size() > 1) { boolean firstVal = true; for (String val : uniqueVals) { if (!firstVal) valString = valString + separatorString; valString = valString + val; } // ApplicationContext.infoMessage("Vals:"); // for (String val : uniqueVals) // ApplicationContext.infoMessage("\t" + val); // throw new CommandLineModuleExecutionException("Key " + key + ", col " + column.name + // ", vals: " + uniqueVals.size()); } else { valString = uniqueVals.iterator().next(); } } } } lineBuf.append(firstCol ? "" : "\t"); lineBuf.append(valString); firstCol = false; } outPW.println(lineBuf.toString()); outPW.flush(); } } catch (Exception e) { throw new CommandLineModuleExecutionException(e); } finally { if (outPW != null) outPW.close(); } } }