All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.actelion.research.chem.io.DWARFileCreator Maven / Gradle / Ivy

There is a newer version: 2024.11.2
Show newest version
/*
* Copyright (c) 1997 - 2016
* Actelion Pharmaceuticals Ltd.
* Gewerbestrasse 16
* CH-4123 Allschwil, Switzerland
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
*    list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
* 3. Neither the name of the the copyright holder nor the
*    names of its contributors may be used to endorse or promote products
*    derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

package com.actelion.research.chem.io;

import com.actelion.research.chem.Canonizer;
import com.actelion.research.chem.StereoMolecule;

import java.io.BufferedWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.TreeMap;

import static com.actelion.research.chem.io.CompoundTableConstants.NEWLINE_STRING;
import static com.actelion.research.chem.io.CompoundTableConstants.TAB_STRING;

public class DWARFileCreator {
	private BufferedWriter mWriter;
	private DWARFileParser mMasterCopyParser;
	private String[] mRow;
	private ArrayList mColumnTitleList;
	private TreeMap mColumnPropertiesMap;

	/**
	 * Use a DWARFileCreator for writing native DataWarrior files without a CompoundTableModel.
	 * (if you have a populated CompoundTableModel, use the CompoundTableSaver instead).
	 * You may provide a freshly instantiated DWARFileParser as master copy that will provide header,
	 * explanation text, macros, column properties, and runtime properties for the new file.
	 * To use the DWARFileCreator you need to follow these steps:
* - instantiate a new DWARFileCreator for a new output file
* - optionally call setMasterCopy()
* - define individual columns with addStructureColumn(), addDescriptorColumn(), and addAlphanumericalColumn()
* - add custom column properties, if you need to with addColumnProperty() * - call writeHeader() once to create the file and write file & table headers
* - for every row call setRowStructure() and setRowValue() for cell values and then writeCurrentRow()
* - if you didn't call setMasterCopy(), then optionally call writeTemplate() to add runtime properties
* - call writeEnd() to close the file
* @param writer make sure that it encodes as UTF-8 */ public DWARFileCreator(BufferedWriter writer) { mWriter = writer; mColumnTitleList = new ArrayList(); } /** * If the file to be created shall resemble another DataWarrior file regarding file * explanation, macro content, columns names, column properties, runtime properties (template), * then one may define a master copy with this method that serves as a blue print. * @param parser DWARFileParser initialized with MODE_BUFFER_HEAD_AND_TAIL */ public void setMasterCopy(DWARFileParser parser) { mMasterCopyParser = parser; ArrayList headAndTail = mMasterCopyParser.getHeadOrTail(); for (String title:headAndTail.get(headAndTail.size()-1).split("\\t")) mColumnTitleList.add(title); } /** * This adds a column to host canonical structure representations (idcodes). * This call allocates the column and defines proper column properties. * If you want DataWarrior to show structure in this column with the original * atom coordinates, you need to also add a column for the encoded atom coordinates. * Otherwise DataWarrior would generate 2D-coordinates for the structures atoms * on the fly. * @param name * @param idColumnName null or column title of other column that hold a compound identifier * @return new structure column index */ public int addStructureColumn(String name, String idColumnName) { int structureColumn = mColumnTitleList.size(); String title = makeUnique(name); mColumnTitleList.add(title); addColumnProperty(structureColumn, "specialType", "idcode"); if (idColumnName != null) addColumnProperty(structureColumn, "idColumn", idColumnName); return structureColumn; } /** * Creates a new column to hold encoded 2-dimensional atom coordinates for the structures * stored in the associated structure column. A structure column may not have more than one * associated 2-dimensional atom coordinate column. * This call allocates the column and defines proper column properties. * @param structureColumn * @return new coordinate column index */ public int add2DCoordinatesColumn(int structureColumn) { return addStructureChildColumn("idcoordinates2D", "idcoordinates2D", structureColumn); } /** * Creates a new column to hold encoded 3-dimensional atom coordinates for the structures * stored in the associated structure column. A structure column may have multiple * associated 3-dimensional atom coordinate columns. * This call allocates the column and defines proper column properties. * @param name 3D-coordinate column names are used to distinguish multiple 3D-coordinate sets * @param structureColumn * @return new coordinate column index */ public int add3DCoordinatesColumn(String name, int structureColumn) { return addStructureChildColumn("idcoordinates3D", name, structureColumn); } /** * Creates a new column to hold a chemical descriptor for the structures * stored in the associated structure column. A structure column may have multiple * associated descriptor columns, provided that these have distinct types. * This call allocates the column and defines proper column properties. * @param descriptorShortName name used to identify the descriptor type, e.g. 'FragFp' * @param structureColumn * @return new descriptor column index */ public int addDescriptorColumn(String descriptorShortName, String descriptorVersion, int structureColumn) { int column = addStructureChildColumn(descriptorShortName, descriptorShortName, structureColumn); addColumnProperty(column, "version", descriptorVersion); return column; } private int addStructureChildColumn(String specialType, String name, int structureColumn) { int column = mColumnTitleList.size(); mColumnTitleList.add(makeUnique(name)); addColumnProperty(column, "parent", mColumnTitleList.get(structureColumn)); addColumnProperty(column, "specialType", specialType); return column; } /** * Creates a new standard column to hold any alphanumerical content. * @param name * @return */ public int addAlphanumericalColumn(String name) { mColumnTitleList.add(makeUnique(name)); return mColumnTitleList.size()-1; } /** * This method may be used to define column properties, e.g. to associate the column * with an URL for identifier lookups, to define a data range, or other special DataWarrior * related features. * @param column * @param key * @param value */ public void addColumnProperty(int column, String key, String value) { if (mColumnPropertiesMap == null) mColumnPropertiesMap = new TreeMap(); Properties cp = mColumnPropertiesMap.get(column); if (cp == null) { cp = new Properties(); mColumnPropertiesMap.put(column, cp); } cp.setProperty(key, value); } /** * This method, when called after calling setMasterCopy() or after completing * defining columns, returns the list of defined column names in the correct order. * Especially, when using a master copy, this method informs about the expected columns * and their order to be used for adding the data. * @return manually defined column titles or from master copy, if used */ public String[] getColumnTitles() { return mColumnTitleList.toArray(new String[0]); } /** * This method, when called after calling setMasterCopy() or after completing * defining columns, returns the column properties of the given column. * @return manually defined column properties or from master copy, if used */ public Properties getColumnProperties(String columnTitle) { if (mMasterCopyParser != null) { return mMasterCopyParser.getColumnProperties(columnTitle); } else { for (int i=0; i"); mWriter.newLine(); mWriter.write(""); mWriter.newLine(); if (rowCount > 0) { mWriter.write(""); mWriter.newLine(); } mWriter.write(""); mWriter.newLine(); writeColumnPropertiesAndTitles(); } else { for (String line:mMasterCopyParser.getHeadOrTail()) { if (line.trim().matches("")) { if (rowCount < 0) continue; line = ""; } if (line.trim().matches("")) { line = ""; } mWriter.write(line); mWriter.newLine(); } } mRow = new String[mColumnTitleList.size()]; } private void writeColumnPropertiesAndTitles() throws IOException { if (mColumnPropertiesMap != null) { mWriter.write(""); mWriter.newLine(); for (int column:mColumnPropertiesMap.keySet()) { mWriter.write(""); mWriter.newLine(); Properties cp = mColumnPropertiesMap.get(column); for (String key:cp.stringPropertyNames()) { String value = cp.getProperty(key); mWriter.write(""); mWriter.newLine(); } } mWriter.write(""); mWriter.newLine(); } boolean isFirst = true; for (int i=0; i properties) throws IOException { if (properties != null && properties.size() != 0) { mWriter.write(CompoundTableConstants.cPropertiesStart); mWriter.newLine(); for (String propertyLine:properties) { mWriter.write(propertyLine); mWriter.newLine(); } mWriter.write(CompoundTableConstants.cPropertiesStart); mWriter.newLine(); } } public void writeEnd() throws IOException { if (mMasterCopyParser != null) { while (mMasterCopyParser.advanceToNext()); for (String line:mMasterCopyParser.getHeadOrTail()) { mWriter.write(line); mWriter.newLine(); } } mWriter.close(); } /** * Checks column name for uniqueness and modifies it if needed to be unique. * @param name desired column name * @return */ private String makeUnique(String name) { if (name == null || name.trim().length() == 0) { name = "Column 1"; } else { name = name.trim().replaceAll("[\\x00-\\x1F]", "_"); } while (columnNameExists(name)) { int index = name.lastIndexOf(' '); if (index == -1) name = name + " 2"; else { try { int suffix = Integer.parseInt(name.substring(index+1)); name = name.substring(0, index+1) + (suffix+1); } catch (NumberFormatException nfe) { name = name + " 2"; } } } return name; } private boolean columnNameExists(String name) { for (String existing:mColumnTitleList) if (name.equalsIgnoreCase(existing)) return true; return false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy