001/*
002 * Copyright 2019 nils.hoffmann.
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 de.isas.lipidomics.domain;
017
018import de.isas.lipidomics.palinom.exceptions.ConstraintViolationException;
019import java.util.stream.Collectors;
020import lombok.Builder;
021import lombok.Data;
022import lombok.EqualsAndHashCode;
023
024/**
025 * An isomeric subspecies. Child of LipidStructuralSubspecies. Individual FAs,
026 * their sn positions, and the double bond positions are known.
027 *
028 * Example: PE(P-18:0/22:6(4Z,7Z,10Z,13Z,16Z,19Z))
029 *
030 * @author nils.hoffmann
031 * @see LipidStructuralSubspecies
032 */
033@Data
034@EqualsAndHashCode(callSuper = true)
035public class LipidIsomericSubspecies extends LipidStructuralSubspecies {
036
037    /**
038     * Creates a new LipidIsomericSubspecies.
039     *
040     * @param headGroup the head group for this lipid.
041     * @param fa the FattyAcids attached to this lipid.
042     */
043    @Builder(builderMethodName = "lipidIsomericSubspeciesBuilder")
044    public LipidIsomericSubspecies(HeadGroup headGroup, FattyAcid... fa) {
045        super(headGroup);
046        int nCarbon = 0;
047        int nHydroxyl = 0;
048        int nDoubleBonds = 0;
049        ModificationsList mods = new ModificationsList();
050        for (FattyAcid fas : fa) {
051            if (super.fa.containsKey(fas.getName())) {
052                throw new ConstraintViolationException(
053                        "FA names must be unique! FA with name " + fas.getName() + " was already added!");
054            } else {
055                super.fa.put(fas.getName(), fas);
056                nCarbon += fas.getNCarbon();
057                nHydroxyl += fas.getNHydroxy();
058                nDoubleBonds += fas.getNDoubleBonds();
059                mods.addAll(fas.getModifications());
060            }
061        }
062        super.info
063                = LipidSpeciesInfo.lipidSpeciesInfoBuilder().
064                        level(LipidLevel.ISOMERIC_SUBSPECIES).
065                        name(headGroup.getName()).
066                        position(-1).
067                        nCarbon(nCarbon).
068                        nHydroxy(nHydroxyl).
069                        nDoubleBonds(nDoubleBonds).
070                        lipidFaBondType(LipidFaBondType.getLipidFaBondType(headGroup, fa)).
071                        modifications(mods).
072                        build();
073    }
074
075    private String buildLipidIsomericSubstructureName(LipidLevel level, String headGroup, boolean isNormalized) {
076        StringBuilder sb = new StringBuilder();
077        String faStrings = getFa().values().stream().map((fa) -> {
078            return fa.buildSubstructureName(level);
079        }).collect(Collectors.joining("/"));
080        return sb.append(
081                buildSubspeciesHeadGroupString(headGroup, isNormalized)
082        ).append(faStrings).toString();
083    }
084
085    @Override
086    public String getLipidString(LipidLevel level, boolean normalizeHeadGroup) {
087        String headGroup = normalizeHeadGroup ? getNormalizedHeadGroup() : getHeadGroup().getName();
088        switch (level) {
089            case ISOMERIC_SUBSPECIES:
090                return buildLipidIsomericSubstructureName(level, headGroup, normalizeHeadGroup);
091            case STRUCTURAL_SUBSPECIES:
092            case MOLECULAR_SUBSPECIES:
093            case CATEGORY:
094            case CLASS:
095            case SPECIES:
096                return super.getLipidString(level, normalizeHeadGroup);
097            default:
098                LipidLevel thisLevel = getInfo().getLevel();
099                throw new ConstraintViolationException(getClass().getSimpleName() + " can not create a string for lipid with level " + thisLevel + " for level " + level + ": target level is more specific than this lipid's level!");
100        }
101    }
102
103    @Override
104    public String getLipidString(LipidLevel level) {
105        return this.getLipidString(level, false);
106    }
107
108    @Override
109    public String getNormalizedLipidString() {
110        return getLipidString(getInfo().getLevel(), true);
111    }
112
113    @Override
114    public String toString() {
115        return getLipidString();
116    }
117}