001/* 002 * Copyright 2018 Leibniz-Institut für Analytische Wissenschaften – ISAS – e.V.. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package uk.ac.ebi.pride.jmztab2.utils.parser; 017 018import de.isas.mztab2.model.Assay; 019import de.isas.mztab2.model.Metadata; 020import de.isas.mztab2.model.Parameter; 021import de.isas.mztab2.model.StudyVariable; 022import java.util.*; 023import org.slf4j.Logger; 024import org.slf4j.LoggerFactory; 025import uk.ac.ebi.pride.jmztab2.model.IMZTabColumn; 026import uk.ac.ebi.pride.jmztab2.model.ISmallMoleculeColumn; 027import uk.ac.ebi.pride.jmztab2.model.MZTabColumnFactory; 028import uk.ac.ebi.pride.jmztab2.model.MZTabConstants; 029import uk.ac.ebi.pride.jmztab2.model.Section; 030import uk.ac.ebi.pride.jmztab2.model.SmallMoleculeColumn; 031import uk.ac.ebi.pride.jmztab2.model.SmallMoleculeColumn.Stable; 032import uk.ac.ebi.pride.jmztab2.utils.errors.FormatErrorType; 033import uk.ac.ebi.pride.jmztab2.utils.errors.LogicalErrorType; 034import uk.ac.ebi.pride.jmztab2.utils.errors.MZTabError; 035import uk.ac.ebi.pride.jmztab2.utils.errors.MZTabErrorList; 036import uk.ac.ebi.pride.jmztab2.utils.errors.MZTabException; 037 038/** 039 * Parse and validate Small Molecule header line into a {@link uk.ac.ebi.pride.jmztab2.model.MZTabColumnFactory}. 040 * 041 * @author qingwei 042 * @author ntoro 043 * @author nilshoffmann 044 * @since 10/02/13 045 * 046 */ 047public class SMHLineParser extends MZTabHeaderLineParser { 048 049 private static final Logger LOGGER = LoggerFactory.getLogger(SMHLineParser.class); 050 private Map<Integer, String> physPositionToOrder; 051 052 053 /** 054 * <p>Constructor for SMHLineParser.</p> 055 * 056 * @param context a {@link uk.ac.ebi.pride.jmztab2.utils.parser.MZTabParserContext} object. 057 * @param metadata a {@link de.isas.mztab2.model.Metadata} object. 058 */ 059 public SMHLineParser(MZTabParserContext context, Metadata metadata) { 060 super(context, MZTabColumnFactory.getInstance(Section.Small_Molecule_Header), metadata); 061 } 062 063 /** {@inheritDoc} */ 064 @Override 065 protected int parseColumns() throws MZTabException { 066 String header; 067 Integer physicalPosition; 068 069 ISmallMoleculeColumn column; 070 SortedMap<String, IMZTabColumn> columnMapping = factory.getColumnMapping(); 071 SortedMap<String, IMZTabColumn> optionalMapping = factory.getOptionalColumnMapping(); 072 SortedMap<String, IMZTabColumn> stableMapping = factory.getStableColumnMapping(); 073 074 physPositionToOrder = generateHeaderPhysPositionToOrderMap(items); 075 076 //Iterates through the tokens in the protein header 077 //It will identify the type of column and the position accordingly 078 for (physicalPosition = 1; physicalPosition < items.length; physicalPosition++) { 079 080 column = null; 081 header = items[physicalPosition]; 082 if (header.startsWith(MZTabConstants.ABUNDANCE_PREFIX)) { 083 checkAbundanceColumns(physicalPosition, physPositionToOrder.get(physicalPosition)); 084 } else if (header.startsWith(MZTabConstants.OPT_PREFIX)) { 085 checkOptColumnName(header); 086 } else { 087 try { 088 column = SmallMoleculeColumn.Stable.columnFor(header); 089 } catch(IllegalArgumentException iae) { 090 throw new MZTabException(new MZTabError(LogicalErrorType.ColumnNotValid,lineNumber,header,section.getName())); 091 } 092 } 093 094 if (column != null) { 095 if (!column.getOrder().equals(physPositionToOrder.get(physicalPosition))) { 096 column.setOrder(physPositionToOrder.get(physicalPosition)); 097 LOGGER.debug(column.toString()); 098 } 099 if(column.isOptional()){ 100 optionalMapping.put(column.getLogicPosition(), column); 101 } else { 102 stableMapping.put(column.getLogicPosition(), column); 103 } 104 columnMapping.put(column.getLogicPosition(), column); 105 } 106 } 107 return physicalPosition; 108 } 109 110 private Map<Integer, String> generateHeaderPhysPositionToOrderMap(String[] items) { 111 Integer physicalPosition; 112 Map<Integer, String> physicalPositionToOrder = new LinkedHashMap<>(); 113 int order = 0; 114 115 for (physicalPosition = 1; physicalPosition < items.length; physicalPosition++) { 116 if(physicalPositionToOrder.containsKey(physicalPosition)) { 117 throw new IllegalArgumentException("Physical position "+physicalPosition+" for item "+items[physicalPosition-1]+" is already assigned!"); 118 } 119 physicalPositionToOrder.put(physicalPosition, fromIndexToOrder(++order)); 120 } 121 return physicalPositionToOrder; 122 } 123 124 /** 125 * {@inheritDoc} 126 * 127 * The following optional columns are mandatory: 128 * 1. abundance_assay[1-n] 129 * 2. abundance_study_variable[1-m] 130 * 3. abundance_variation_study_variable[1-m] 131 * 132 * NOTICE: this method will be called at end of parse() function. 133 * @see MZTabHeaderLineParser#parse(int, String, MZTabErrorList) 134 * @see MZTabHeaderLineParser#parse(int, String, MZTabErrorList) 135 */ 136 @Override 137 protected void refine() throws MZTabException { 138 139 for (Stable columnHeader : SmallMoleculeColumn.Stable.values()) { 140 ISmallMoleculeColumn smc = Stable.columnFor(columnHeader); 141 if (factory.findColumnByHeader(smc.getHeader()) == null) { 142 throw new MZTabException(new MZTabError(FormatErrorType.StableColumn, lineNumber, smc.getHeader())); 143 } 144 } 145 146 Parameter smallMoleculeQuantificationUnit = Optional.ofNullable(metadata.getSmallMoleculeQuantificationUnit()).orElseThrow(() -> 147 new MZTabException(new MZTabError(LogicalErrorType.NoSmallMoleculeQuantificationUnit, lineNumber))); 148 149 if (metadata.getSmallMoleculeIdentificationReliability() == null) { 150 throw new MZTabException(new MZTabError(LogicalErrorType.NoSmallMoleculeIdentificationReliability, lineNumber)); 151 } 152 for (StudyVariable studyVariable : metadata.getStudyVariable()) { 153 String svLabel = "_"+Metadata.Properties.studyVariable+"[" + studyVariable.getId() + "]"; 154 refineOptionalColumn(Section.Small_Molecule_Header, "abundance" + svLabel); 155 refineOptionalColumn(Section.Small_Molecule_Header, "abundance_variation" + svLabel); 156 } 157 for (Assay assay : metadata.getAssay()) { 158 String assayLabel = "_"+Metadata.Properties.assay+"[" + assay.getId() + "]"; 159 refineOptionalColumn(Section.Small_Molecule_Header, "abundance" + assayLabel); 160 } 161 } 162}