/* * Eoulsan development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public License version 2.1 or * later and CeCILL-C. This should be distributed with the code. * If you do not have a copy, see: * * http://www.gnu.org/licenses/lgpl-2.1.txt * http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt * * Copyright for this code is held jointly by the Genomic platform * of the Institut de Biologie de l'École normale supérieure and * the individual authors. These should be listed in @author doc * comments. * * For more information on the Eoulsan project and its aims, * or to join the Eoulsan Google group, visit the home page * at: * * http://outils.genomique.biologie.ens.fr/eoulsan * */ package fr.ens.biologie.genomique.eoulsan.design; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import java.io.Serializable; import java.util.*; import fr.ens.biologie.genomique.eoulsan.core.FileNaming; /** * This class defines an experiment. * @author Xavier Bauquet * @since 2.0 */ public class Experiment implements Serializable { /** Serialization version UID. */ private static final long serialVersionUID = -2644491674956956116L; private static int instanceCount; private final Design design; private final String experimentId; private final int experimentNumber = ++instanceCount; private String experimentName = "Experiment" + experimentNumber; private final ExperimentMetadata metadata = new ExperimentMetadata(); private final List<ExperimentSample> samples = new ArrayList<>(); private final Set<String> sampleNames = new HashSet<>(); // // Getters // /** * Get the design related to the experiment. * @return the Design object related to the experiment */ public Design getDesign() { return this.design; } /** * get the experiment id. * @return the experiment id */ public String getId() { return experimentId; } /** * Get the experiment name. * @return the experiment name */ public String getName() { return experimentName; } /** * Get the experiment number. * @return the experiment number */ public int getNumber() { return experimentNumber; } /** * Get the experiment metadata. * @return the experiment metadata */ public ExperimentMetadata getMetadata() { return metadata; } /** * Get the samples of the experiment. * @return a list of ExperimentSample object */ public List<Sample> getSamples() { final List<Sample> result = new ArrayList<>(); for (ExperimentSample es : getExperimentSamples()) { result.add(es.getSample()); } return Collections.unmodifiableList(result); } /** * Get experiment samples list. * @return a list of ExperimentSample object */ public List<ExperimentSample> getExperimentSamples() { return Collections.unmodifiableList(samples); } /** * Get the experiment sample related to the sample. * @param sample the sample * @return an experiment sample object if exists or null */ public ExperimentSample getExperimentSample(final Sample sample) { for (ExperimentSample eSample : this.samples) { if (eSample.getSample() == sample) { return eSample; } } return null; } // // Setter // /** * Set the name of the experiment. * @param newExperimentName the new experiment name */ public void setName(String newExperimentName) { checkNotNull(newExperimentName, "newExperimentName argument cannot be null"); final String name = newExperimentName.trim(); // Do nothing if the new name is the old name if (name.equals(this.experimentName)) { return; } checkArgument(!this.design.containsExperimentName(name), "The sample name already exists in the design: " + name); this.experimentName = name; } // // Add // /** * Add a sample. * @param sample the sample to add * @return an experiment sample object */ public ExperimentSample addSample(final Sample sample) { checkNotNull(sample, "sample argument cannot be null"); checkArgument(!this.sampleNames.contains(sample.getId()), "The sample already exists in the experiment: " + sample.getId()); checkArgument(sample.getDesign() == this.design, "The sample to add to the experiment is not a sample of the design: " + sample.getId()); final ExperimentSample newExperimentSample = new ExperimentSample(sample); this.samples.add(newExperimentSample); this.sampleNames.add(sample.getId()); return newExperimentSample; } // // Remove // /** * Remove the sample. * @param sample the sample to remove */ public void removeSample(final Sample sample) { checkNotNull(sample, "sample argument cannot be null"); checkArgument(this.sampleNames.contains(sample.getId()), "The sample does not exists in the experiment: " + sample.getId()); checkArgument(sample.getDesign() == this.design, "The sample to remove to the experiment is not a sample of the design: " + sample.getId()); this.samples.remove(getExperimentSample(sample)); this.sampleNames.remove(sample.getId()); } // // Contains // /** * Test if the experiment contains a sample. * @param sample the sample to test * @return true if the sample is the experiment */ public boolean containsSample(final Sample sample) { checkNotNull(sample, "sample argument cannot be null"); return this.sampleNames.contains(sample.getId()); } // // Objects methods // @Override public String toString() { return com.google.common.base.Objects.toStringHelper(this) .add("experimentId", this.experimentId) .add("experimentNumber", this.experimentNumber) .add("experimentName", this.experimentName) .add("experimentMetadata", this.metadata) .add("experimentSamples", this.samples).toString(); } @Override public int hashCode() { return Objects.hash(this.experimentId, this.experimentNumber, this.experimentName, this.metadata, this.samples); } @Override public boolean equals(final Object o) { if (o == this) { return true; } if (!(o instanceof Experiment)) { return false; } final Experiment that = (Experiment) o; return Objects.equals(this.experimentId, that.experimentId) && Objects.equals(this.experimentName, that.experimentName) && Objects.equals(this.metadata, that.metadata) && Objects.equals(this.samples, that.samples); } // // Constructor // /** * @param design the design object * @param experimentId the experiment id */ Experiment(Design design, String experimentId) { checkNotNull(design, "design argument cannot be null"); checkNotNull(experimentId, "sampleId argument cannot be null"); checkArgument(FileNaming.isDataNameValid(experimentId), "The id of an experiment can only contains letters and digit: " + experimentId); this.design = design; this.experimentId = experimentId.trim(); } }