From 4086791f716b6ea641fb64abff0e340adf91188c Mon Sep 17 00:00:00 2001
From: brinn <brinn>
Date: Wed, 17 Jun 2009 18:11:17 +0000
Subject: [PATCH] refactor: database to have the "standard" experiment, sample
 and data_set dimensions

SVN: 11419
---
 .../ch/systemsx/cisd/yeastx/db/DBFactory.java |  39 ++++++
 .../systemsx/cisd/yeastx/db/DMDataSetDTO.java | 114 +++++++++++++++++
 .../cisd/yeastx/db/DMExperimentDTO.java       |  77 +++++++++++
 .../systemsx/cisd/yeastx/db/DMSampleDTO.java  | 105 +++++++++++++++
 .../systemsx/cisd/yeastx/db/IGenericDAO.java  |  59 +++++++++
 .../cisd/yeastx/eicml/ChromatogramDTO.java    |  10 +-
 .../cisd/yeastx/eicml/EICML2Database.java     |  17 ++-
 .../cisd/yeastx/eicml/EICML2TabConverter.java |   6 +-
 .../cisd/yeastx/eicml/EICMLParser.java        |   8 +-
 .../cisd/yeastx/eicml/EICMSRunDTO.java        |  49 +++++--
 .../cisd/yeastx/eicml/IEICMSRunDAO.java       |  29 +++--
 .../cisd/yeastx/etl/ML2DatabaseUploader.java  |   7 +-
 .../cisd/yeastx/fiaml/CentroidDTO.java        |  13 +-
 .../cisd/yeastx/fiaml/FIAML2Database.java     |  12 +-
 .../cisd/yeastx/fiaml/FIAMLParser.java        |   6 +-
 .../cisd/yeastx/fiaml/FIAMSRunDTO.java        |  49 +++++--
 .../cisd/yeastx/fiaml/FIAMSRunDataDTO.java    |  16 ---
 .../cisd/yeastx/fiaml/IFIAMSRunDAO.java       |  19 +--
 .../cisd/yeastx/fiaml/ProfileDTO.java         |  11 +-
 .../source/sql/postgresql/001/schema-001.sql  | 121 +++++++++++++-----
 .../systemsx/cisd/yeastx/eicml/EICMLTest.java |  10 +-
 .../systemsx/cisd/yeastx/fiaml/FIAMLTest.java |  14 +-
 22 files changed, 647 insertions(+), 144 deletions(-)
 create mode 100644 rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DMDataSetDTO.java
 create mode 100644 rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DMExperimentDTO.java
 create mode 100644 rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DMSampleDTO.java
 create mode 100644 rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/IGenericDAO.java

diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DBFactory.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DBFactory.java
index c49777bd2d3..b1e26701bab 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DBFactory.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DBFactory.java
@@ -70,4 +70,43 @@ public class DBFactory
         return context;
     }
 
+    /**
+     * Returns the data access object for the generic tables of the data mart.
+     */
+    public static IGenericDAO getDAO(Connection conn)
+    {
+        return QueryTool.getQuery(conn, IGenericDAO.class);
+    }
+
+    /**
+     * Creates the data set based on the information given in <var>dataSet</var>. The sample and
+     * experiment of the data set may already exist in the database. If they don't, they are created
+     * as well.
+     */
+    public static void createDataSet(IGenericDAO dao, DMDataSetDTO dataSet)
+    {
+        DMSampleDTO sample = dao.getSample(dataSet.getSample().getPermId());
+        if (sample == null)
+        {
+            DMExperimentDTO experiment = dao.getExperiment(dataSet.getExperiment().getPermId());
+            if (experiment == null)
+            {
+                experiment = dataSet.getExperiment();
+                final long experimentId = dao.addExperiment(experiment);
+                experiment.setId(experimentId);
+            }
+            sample = dataSet.getSample();
+            sample.setExperiment(experiment);
+            final long sampleId = dao.addSample(sample);
+            sample.setId(sampleId);
+            dataSet.setSample(sample); // make sure all the ids are set correctly.
+        } else
+        {
+            dataSet.setSample(sample);
+            sample.setExperiment(dao.getExperiment(sample.getExperimentId()));
+        }
+        long dataSetId = dao.addDataSet(dataSet);
+        dataSet.setId(dataSetId);
+    }
+
 }
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DMDataSetDTO.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DMDataSetDTO.java
new file mode 100644
index 00000000000..6d480c39103
--- /dev/null
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DMDataSetDTO.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.yeastx.db;
+
+import net.lemnik.eodsql.AutoGeneratedKeys;
+import net.lemnik.eodsql.ResultColumn;
+
+/**
+ * The generic information about a data set for the data mart.
+ * 
+ * @author Bernd Rinn
+ */
+public class DMDataSetDTO
+{
+    @AutoGeneratedKeys
+    private long id;
+
+    @ResultColumn("PERM_ID")
+    private String permId;
+
+    @ResultColumn("EXPE_ID")
+    private long experimentId;
+
+    @ResultColumn("SAMP_ID")
+    private long sampleId;
+
+    private DMSampleDTO sample;
+
+    public DMDataSetDTO()
+    {
+        // Bean compatibility.
+    }
+
+    public DMDataSetDTO(String dsPermId, String sampPermId, String sampName, String expePermId,
+            String expeName)
+    {
+        this.permId = dsPermId;
+        final DMExperimentDTO experiment = new DMExperimentDTO(expePermId, expeName);
+        this.sample = new DMSampleDTO(sampPermId, sampName);
+        sample.setExperiment(experiment);
+    }
+
+    public long getId()
+    {
+        return id;
+    }
+
+    public void setId(long id)
+    {
+        this.id = id;
+    }
+
+    public String getPermId()
+    {
+        return permId;
+    }
+
+    public void setPermId(String permId)
+    {
+        this.permId = permId;
+    }
+
+    public long getExperimentId()
+    {
+        return experimentId;
+    }
+
+    public void setExperimentId(long experimentId)
+    {
+        this.experimentId = experimentId;
+    }
+
+    public long getSampleId()
+    {
+        return sampleId;
+    }
+
+    public void setSampleId(long sampleId)
+    {
+        this.sampleId = sampleId;
+    }
+
+    public DMSampleDTO getSample()
+    {
+        return sample;
+    }
+
+    public void setSample(DMSampleDTO sample)
+    {
+        this.sample = sample;
+        this.sampleId = sample.getId();
+        this.experimentId = sample.getExperimentId();
+    }
+
+    public DMExperimentDTO getExperiment()
+    {
+        return sample.getExperiment();
+    }
+
+}
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DMExperimentDTO.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DMExperimentDTO.java
new file mode 100644
index 00000000000..3df4cd07c45
--- /dev/null
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DMExperimentDTO.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.yeastx.db;
+
+import net.lemnik.eodsql.AutoGeneratedKeys;
+import net.lemnik.eodsql.ResultColumn;
+
+/**
+ * The DTO for an experiment in the data mart.
+ *
+ * @author Bernd Rinn
+ */
+public class DMExperimentDTO
+{
+    @AutoGeneratedKeys
+    private long id;
+    
+    @ResultColumn("PERM_ID")
+    private String permId;
+    
+    private String name;
+
+    public DMExperimentDTO()
+    {
+        // Bean compatibility.
+    }
+    
+    public DMExperimentDTO(String permId, String name)
+    {
+        this.permId = permId;
+        this.name = name;
+    }
+    
+    public long getId()
+    {
+        return id;
+    }
+
+    public void setId(long id)
+    {
+        this.id = id;
+    }
+
+    public String getPermId()
+    {
+        return permId;
+    }
+
+    public void setPermId(String permId)
+    {
+        this.permId = permId;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+}
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DMSampleDTO.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DMSampleDTO.java
new file mode 100644
index 00000000000..e44efaa844d
--- /dev/null
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DMSampleDTO.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.yeastx.db;
+
+import net.lemnik.eodsql.AutoGeneratedKeys;
+import net.lemnik.eodsql.ResultColumn;
+
+/**
+ * The DTO for a sample in the data mart.
+ *
+ * @author Bernd Rinn
+ */
+public class DMSampleDTO
+{
+
+    @AutoGeneratedKeys
+    private long id;
+    
+    @ResultColumn("PERM_ID")
+    private String permId;
+    
+    private String name;
+
+    @ResultColumn("EXPE_ID")
+    private long experimentId;
+    
+    private DMExperimentDTO experiment;
+    
+    public DMSampleDTO()
+    {
+        // Bean compatibility.
+    }
+    
+    public DMSampleDTO(String permId, String name)
+    {
+        this.permId = permId;
+        this.name = name;
+    }
+
+    public long getId()
+    {
+        return id;
+    }
+
+    public void setId(long id)
+    {
+        this.id = id;
+    }
+
+    public String getPermId()
+    {
+        return permId;
+    }
+
+    public void setPermId(String permId)
+    {
+        this.permId = permId;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    public long getExperimentId()
+    {
+        return experimentId;
+    }
+
+    public void setExperimentId(long experimentId)
+    {
+        this.experimentId = experimentId;
+    }
+
+    public DMExperimentDTO getExperiment()
+    {
+        return experiment;
+    }
+
+    public void setExperiment(DMExperimentDTO experiment)
+    {
+        this.experiment = experiment;
+        this.experimentId = experiment.getId();
+    }
+    
+}
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/IGenericDAO.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/IGenericDAO.java
new file mode 100644
index 00000000000..e972e23b7a0
--- /dev/null
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/IGenericDAO.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.yeastx.db;
+
+import net.lemnik.eodsql.BaseQuery;
+import net.lemnik.eodsql.Select;
+
+/**
+ * Interface for the "generic" methods (i.e. experiment, sample and data set).
+ * 
+ * @author Bernd Rinn
+ */
+public interface IGenericDAO extends BaseQuery
+{
+
+    @Select("select * from EXPERIMENTS where PERM_ID = ?{1}")
+    public DMExperimentDTO getExperiment(String experimentPermId);
+
+    @Select("select * from EXPERIMENTS where ID = ?{1}")
+    public DMExperimentDTO getExperiment(long id);
+
+    @Select("insert into EXPERIMENTS (PERM_ID, NAME) values (?{1.permId}, ?{1.name}) returning ID")
+    public long addExperiment(DMExperimentDTO experiment);
+
+    @Select("select * from SAMPLES where PERM_ID = ?{1}")
+    public DMSampleDTO getSample(String samplePermId);
+
+    @Select("select * from SAMPLES where ID = ?{1}")
+    public DMSampleDTO getSample(long id);
+
+    @Select("insert into SAMPLES (PERM_ID, NAME, EXPE_ID) values (?{1.permId}, ?{1.name}, ?{1.experiment.id}) "
+            + "returning ID")
+    public long addSample(DMSampleDTO sample);
+
+    @Select("select * from DATA_SETS where PERM_ID = ?{1}")
+    public DMDataSetDTO getDataSet(String dataSetPermId);
+
+    @Select("select * from DATA_SETS where ID = ?{1}")
+    public DMDataSetDTO getDataSet(long id);
+
+    @Select("insert into DATA_SETS (PERM_ID, EXPE_ID, SAMP_ID) values "
+            + "(?{1.permId}, ?{1.experiment.id}, ?{1.sample.id}) returning ID")
+    public long addDataSet(DMDataSetDTO dataSet);
+
+}
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/ChromatogramDTO.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/ChromatogramDTO.java
index 6c80933a987..b8d32a4e23e 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/ChromatogramDTO.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/ChromatogramDTO.java
@@ -27,7 +27,7 @@ import org.apache.commons.lang.builder.ToStringBuilder;
 public class ChromatogramDTO
 {
     @AutoGeneratedKeys
-    private long chromId;
+    private long id;
 
     @ResultColumn("EIC_MS_RUN_ID")
     private long eicMsRunId;
@@ -60,14 +60,14 @@ public class ChromatogramDTO
         return eicMsRunId;
     }
 
-    public void setChromId(long chromId)
+    public void setId(long id)
     {
-        this.chromId = chromId;
+        this.id = id;
     }
 
-    public long getChromId()
+    public long getId()
     {
-        return chromId;
+        return id;
     }
 
     public void setQ1Mz(float q1Mz)
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICML2Database.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICML2Database.java
index 495444f0268..e82fe396aaa 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICML2Database.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICML2Database.java
@@ -31,6 +31,7 @@ import org.xml.sax.SAXException;
 
 import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
 import ch.systemsx.cisd.yeastx.db.DBFactory;
+import ch.systemsx.cisd.yeastx.db.DMDataSetDTO;
 import ch.systemsx.cisd.yeastx.eicml.EICMLParser.IChromatogramObserver;
 import ch.systemsx.cisd.yeastx.eicml.EICMLParser.IMSRunObserver;
 
@@ -63,21 +64,25 @@ public class EICML2Database
      * Method for uploading an <var>eicMLFile</var> to the database.
      */
     public static void uploadEicMLFile(final Connection conn, final File eicMLFile,
-            String dataSetPermId)
-            throws SQLException
+            final DMDataSetDTO dataSet) throws SQLException
     {
         final long[] eicMLId = new long[1];
         final List<ChromatogramDTO> chromatograms =
                 new ArrayList<ChromatogramDTO>(CHROMATOGRAM_BATCH_SIZE);
         try
         {
+            DBFactory.createDataSet(DBFactory.getDAO(conn), dataSet);
             final IEICMSRunDAO dao = getDAO(conn);
-            new EICMLParser(eicMLFile.getPath(), dataSetPermId, new IMSRunObserver()
+            new EICMLParser(eicMLFile.getPath(), new IMSRunObserver()
                 {
                     public void observe(EICMSRunDTO run)
                     {
-                        // add chromatograms from the last run to the database before setting the new run id
+                        // add chromatograms from the last run to the database before setting the
+                        // new run id
                         addChromatograms(dao, eicMLId[0], chromatograms, 1);
+                        run.setExperimentId(dataSet.getExperimentId());
+                        run.setSampleId(dataSet.getSampleId());
+                        run.setDataSetId(dataSet.getId());
                         eicMLId[0] = dao.addMSRun(run);
                     }
                 }, new IChromatogramObserver()
@@ -114,7 +119,9 @@ public class EICML2Database
             int permId = 0;
             for (String f : new File(dir).list(new EICMLFilenameFilter()))
             {
-                uploadEicMLFile(conn, new File(dir, f), Integer.toString(++permId));
+                uploadEicMLFile(conn, new File(dir, f), new DMDataSetDTO(
+                        Integer.toString(++permId), "sample1", "the sample name", "experiment1",
+                        "the experiment name"));
             }
         } finally
         {
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICML2TabConverter.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICML2TabConverter.java
index eb79da2ffcb..a03cda70915 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICML2TabConverter.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICML2TabConverter.java
@@ -41,7 +41,7 @@ public class EICML2TabConverter
         for (String f : new File(dir).list(new EICMLFilenameFilter()))
         {
             final String[] msRunName = new String[1];
-            new EICMLParser(dir + "/" + f, null, new EICMLParser.IMSRunObserver()
+            new EICMLParser(dir + "/" + f, new EICMLParser.IMSRunObserver()
                 {
                     public void observe(EICMSRunDTO run)
                     {
@@ -104,9 +104,9 @@ public class EICML2TabConverter
                             {
                                 out.println("endTime\t" + run.getEndTime());
                             }
-                            if (run.getEicMsRunId() >= 0)
+                            if (run.getId() >= 0)
                             {
-                                out.println("msRunId\t" + run.getEicMsRunId());
+                                out.println("msRunId\t" + run.getId());
                             }
                             out.close();
                         } catch (FileNotFoundException ex)
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICMLParser.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICMLParser.java
index 81264d39b27..833a2df1db7 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICMLParser.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICMLParser.java
@@ -70,8 +70,6 @@ public class EICMLParser extends DefaultHandler
     
     private StringBuilder buffer = new StringBuilder();
 
-    private String permIdOrNull;
-
     private EICMSRunDTO msRun;
 
     private ChromatogramDTO chromatogram;
@@ -84,13 +82,12 @@ public class EICMLParser extends DefaultHandler
 
     private final IChromatogramObserver chromatogramObserverOrNull;
 
-    public EICMLParser(String fileName, String permIdOrNull, IMSRunObserver msRunObserverOrNull,
+    public EICMLParser(String fileName, IMSRunObserver msRunObserverOrNull,
             IChromatogramObserver chromatogramObserverOrNull) throws ParserConfigurationException,
             SAXException, IOException
     {
         assert fileName != null;
 
-        this.permIdOrNull = permIdOrNull;
         this.msRunObserverOrNull = msRunObserverOrNull;
         this.chromatogramObserverOrNull = chromatogramObserverOrNull;
         parseDocument(fileName);
@@ -112,7 +109,6 @@ public class EICMLParser extends DefaultHandler
         if (MS_RUN.equals(name))
         {
             msRun = new EICMSRunDTO();
-            msRun.setDataSetPermId(permIdOrNull);
             parsingMsRun = true;
         } else if ("chromatogram".equals(name))
         {
@@ -164,7 +160,7 @@ public class EICMLParser extends DefaultHandler
             msRun.setChromCount(Integer.parseInt(value));
         } else if ("msRunId".equals(name) && value.length() > 0)
         {
-            msRun.setEicMsRunId(Long.parseLong(value));
+            msRun.setId(Long.parseLong(value));
         } else if ("startTime".equals(name) && value.length() > 0)
         {
             msRun.setStartTime(Float.parseFloat(value));
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICMSRunDTO.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICMSRunDTO.java
index 017d901d513..0fafb092ae2 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICMSRunDTO.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICMSRunDTO.java
@@ -29,11 +29,16 @@ import org.apache.commons.lang.builder.ToStringBuilder;
 public class EICMSRunDTO
 {
     @AutoGeneratedKeys
-    @ResultColumn("EIC_MS_RUN_ID")
-    private long eicMsRunId;
+    private long id;
 
-    @ResultColumn("DATA_SET_PERM_ID")
-    private String dataSetPermId;
+    @ResultColumn("DS_ID")
+    private long dataSetId;
+    
+    @ResultColumn("SAMP_ID")
+    private long sampleId;
+    
+    @ResultColumn("EXPE_ID")
+    private long experimentId;
     
     @ResultColumn("RAW_DATA_FILE_PATH")
     private String rawDataFilePath;
@@ -72,24 +77,44 @@ public class EICMSRunDTO
     @ResultColumn("END_TIME")
     private float endTime = Float.NaN;
 
-    public String getDataSetPermId()
+    public long getId()
+    {
+        return id;
+    }
+
+    public long getDataSetId()
+    {
+        return dataSetId;
+    }
+
+    public void setDataSetId(long dataSetId)
+    {
+        this.dataSetId = dataSetId;
+    }
+
+    public long getSampleId()
+    {
+        return sampleId;
+    }
+
+    public void setSampleId(long sampleId)
     {
-        return dataSetPermId;
+        this.sampleId = sampleId;
     }
 
-    public void setDataSetPermId(String permId)
+    public long getExperimentId()
     {
-        this.dataSetPermId = permId;
+        return experimentId;
     }
 
-    public long getEicMsRunId()
+    public void setExperimentId(long experimentId)
     {
-        return eicMsRunId;
+        this.experimentId = experimentId;
     }
 
-    public void setEicMsRunId(long eicMsRunId)
+    public void setId(long id)
     {
-        this.eicMsRunId = eicMsRunId;
+        this.id = id;
     }
 
     public String getRawDataFilePath()
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/IEICMSRunDAO.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/IEICMSRunDAO.java
index 5a4ef5883d6..9b751682628 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/IEICMSRunDAO.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/IEICMSRunDAO.java
@@ -31,18 +31,21 @@ import net.lemnik.eodsql.Update;
 public interface IEICMSRunDAO extends BaseQuery
 {
     final String ALL_EIC_MSRUN_COLUMNS =
-            "EIC_MS_RUNS.EIC_MS_RUN_ID, EIC_MS_RUNS.DATA_SET_PERM_ID, EIC_MS_RUNS.RAW_DATA_FILE_NAME, EIC_MS_RUNS.RAW_DATA_FILE_PATH, "
+            "EIC_MS_RUNS.ID, EIC_MS_RUNS.EXPE_ID, EIC_MS_RUNS.SAMP_ID, EIC_MS_RUNS.DS_ID, "
+                    + "EIC_MS_RUNS.RAW_DATA_FILE_NAME, EIC_MS_RUNS.RAW_DATA_FILE_PATH, "
                     + "EIC_MS_RUNS.ACQUISITION_DATE, EIC_MS_RUNS.INSTRUMENT_TYPE, EIC_MS_RUNS.INSTRUMENT_MANUFACTURER, "
                     + "EIC_MS_RUNS.INSTRUMENT_MODEL, EIC_MS_RUNS.METHOD_IONISATION, EIC_MS_RUNS.METHOD_SEPARATION, "
                     + "EIC_MS_RUNS.SET_ID, EIC_MS_RUNS.OPERATOR, "
                     + "EIC_MS_RUNS.START_TIME, EIC_MS_RUNS.END_TIME";
 
-    @Select("insert into EIC_MS_RUNS (DATA_SET_PERM_ID, RAW_DATA_FILE_NAME, RAW_DATA_FILE_PATH, ACQUISITION_DATE, "
+    @Select("insert into EIC_MS_RUNS (EXPE_ID, SAMP_ID, DS_ID, "
+            + "RAW_DATA_FILE_NAME, RAW_DATA_FILE_PATH, ACQUISITION_DATE, "
             + "INSTRUMENT_TYPE, INSTRUMENT_MANUFACTURER, INSTRUMENT_MODEL, METHOD_IONISATION, "
-            + "METHOD_SEPARATION, SET_ID, OPERATOR, START_TIME, END_TIME) values (?{1.dataSetPermId}, ?{1.rawDataFileName}, "
+            + "METHOD_SEPARATION, SET_ID, OPERATOR, START_TIME, END_TIME) values "
+            + "(?{1.experimentId}, ?{1.sampleId}, ?{1.dataSetId}, ?{1.rawDataFileName}, "
             + "?{1.rawDataFilePath}, ?{1.acquisitionDate}, ?{1.instrumentType}, "
             + "?{1.instrumentManufacturer}, ?{1.instrumentModel}, ?{1.methodIonisation}, "
-            + "?{1.methodSeparation}, ?{1.setId}, ?{1.operator}, ?{1.startTime}, ?{1.endTime}) returning EIC_MS_RUN_ID")
+            + "?{1.methodSeparation}, ?{1.setId}, ?{1.operator}, ?{1.startTime}, ?{1.endTime}) returning ID")
     public long addMSRun(EICMSRunDTO msRun);
 
     @Update(sql = "insert into EIC_CHROMATOGRAMS (EIC_MS_RUN_ID, Q1_MZ, Q3_LOW_MZ, Q3_HIGH_MZ, LABEL, POLARITY, RUN_TIMES, "
@@ -52,37 +55,37 @@ public interface IEICMSRunDAO extends BaseQuery
     public void addChromatograms(long EIC_MS_RUN_ID, List<ChromatogramDTO> chromatogram);
 
     @Select(sql = "select EIC_MS_RUNS.*,count(EIC_CHROMATOGRAMS.*) as chromCount from EIC_MS_RUNS "
-            + "left join EIC_CHROMATOGRAMS using(EIC_MS_RUN_ID) group by " + ALL_EIC_MSRUN_COLUMNS)
+            + "left join EIC_CHROMATOGRAMS on EIC_MS_RUN_ID = EIC_MS_RUNS.ID group by " + ALL_EIC_MSRUN_COLUMNS)
     public DataIterator<EICMSRunDTO> getMsRuns();
 
     @Select(sql = "select * from EIC_MS_RUNS where RAW_DATA_FILE_NAME=?{1}")
     public DataIterator<EICMSRunDTO> getMsRunsForRawDataFile(String rawDataFileName);
 
     @Select("select EIC_MS_RUNS.*, count(EIC_CHROMATOGRAMS.*) AS chromCount from EIC_MS_RUNS "
-            + "left join EIC_CHROMATOGRAMS using(EIC_MS_RUN_ID) where EIC_MS_RUNS.EIC_MS_RUN_ID=?{1} group by "
+            + "left join EIC_CHROMATOGRAMS on EIC_MS_RUN_ID = EIC_MS_RUNS.ID where EIC_MS_RUNS.EIC_MS_RUN_ID=?{1} group by "
             + ALL_EIC_MSRUN_COLUMNS)
     public EICMSRunDTO getMSRunById(long id);
 
     @Select("select EIC_MS_RUNS.*, count(EIC_CHROMATOGRAMS.*) AS chromCount from EIC_MS_RUNS "
-            + "left join EIC_CHROMATOGRAMS using(EIC_MS_RUN_ID) where EIC_MS_RUNS.DATA_SET_PERM_ID=?{1} group by "
+            + "left join EIC_CHROMATOGRAMS on EIC_MS_RUN_ID = eic_ms_run.id where EIC_MS_RUNS.DATA_SET_PERM_ID=?{1} group by "
             + ALL_EIC_MSRUN_COLUMNS)
     public EICMSRunDTO getMSRunByPermId(String permId);
 
-    @Select("select EIC_MS_RUNS.* FROM msrun LEFT JOIN EIC_CHROMATOGRAMS USING(EIC_MS_RUN_ID) "
-            + "where EIC_CHROMATOGRAMS.CHROM_ID = ?{1.chromId}")
+    @Select("select EIC_MS_RUNS.* FROM msrun LEFT JOIN EIC_CHROMATOGRAMS USING(ID) "
+            + "where EIC_CHROMATOGRAMS.ID = ?{1.id}")
     public EICMSRunDTO getMSRunForChromatogram(ChromatogramDTO chromatogram);
 
-    @Select("select EIC_CHROMATOGRAMS.* FROM EIC_CHROMATOGRAMS where CHROM_ID=?{1}")
+    @Select("select EIC_CHROMATOGRAMS.* FROM EIC_CHROMATOGRAMS where ID=?{1}")
     public ChromatogramDTO getChromatogramById(long id);
 
     @Select("select EIC_CHROMATOGRAMS.* FROM EIC_CHROMATOGRAMS where LABEL=?{1}")
     public ChromatogramDTO getChromatogramByLabel(String label);
 
-    @Select("select * FROM EIC_CHROMATOGRAMS where EIC_MS_RUN_ID=?{1.eicMsRunId}")
+    @Select("select * FROM EIC_CHROMATOGRAMS where EIC_MS_RUN_ID=?{1.id}")
     public DataIterator<ChromatogramDTO> getChromatogramsForRun(EICMSRunDTO msRun);
 
-    @Select(sql = "select CHROM_ID, EIC_MS_RUN_ID, Q1_MZ, Q3_LOW_MZ, Q3_HIGH_MZ, LABEL, POLARITY FROM EIC_CHROMATOGRAMS "
-            + "LEFT JOIN EIC_MS_RUNS USING(EIC_MS_RUN_ID) " + "where EIC_MS_RUN_ID=?{1.eicMsRunId}")
+    @Select(sql = "select ID, EIC_MS_RUN_ID, Q1_MZ, Q3_LOW_MZ, Q3_HIGH_MZ, LABEL, POLARITY FROM EIC_CHROMATOGRAMS "
+            + "LEFT JOIN EIC_MS_RUNS on EIC_MS_RUN_ID = EIC_MS_RUNS.ID where EIC_MS_RUN_ID=?{1.id}")
     public DataIterator<ChromatogramDTO> getChromatogramsForRunNoData(EICMSRunDTO msRun);
 
 }
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/etl/ML2DatabaseUploader.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/etl/ML2DatabaseUploader.java
index de01a35f5f6..b3ffcad6722 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/etl/ML2DatabaseUploader.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/etl/ML2DatabaseUploader.java
@@ -25,6 +25,7 @@ import org.apache.commons.io.FilenameUtils;
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
 import ch.systemsx.cisd.yeastx.db.DBFactory;
+import ch.systemsx.cisd.yeastx.db.DMDataSetDTO;
 import ch.systemsx.cisd.yeastx.eicml.EICML2Database;
 import ch.systemsx.cisd.yeastx.fiaml.FIAML2Database;
 
@@ -85,12 +86,14 @@ public class ML2DatabaseUploader
 
     private void translateEIC(File dataSet, String datasetPermId) throws SQLException
     {
-        EICML2Database.uploadEicMLFile(connection, dataSet, datasetPermId);
+        EICML2Database.uploadEicMLFile(connection, dataSet, new DMDataSetDTO(datasetPermId,
+                "sample perm id", "sample name", "experiment perm id", "eperiment name"));
     }
 
     private void translateFIA(File dataSet, String datasetPermId) throws SQLException
     {
-        FIAML2Database.uploadFiaMLFile(connection, dataSet, datasetPermId);
+        FIAML2Database.uploadFiaMLFile(connection, dataSet, new DMDataSetDTO(datasetPermId,
+                "sample perm id", "sample name", "experiment perm id", "experiment name"));
     }
 
     private static String getExtension(final File incomingDataSetPath)
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/CentroidDTO.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/CentroidDTO.java
index f386e4a744c..1a2d5d6ef2f 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/CentroidDTO.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/CentroidDTO.java
@@ -20,7 +20,7 @@ import net.lemnik.eodsql.AutoGeneratedKeys;
 import net.lemnik.eodsql.ResultColumn;
 
 /**
- * 
+ * The data transfer object for FIA centroids.
  *
  * @author Bernd Rinn
  */
@@ -28,20 +28,19 @@ public class CentroidDTO
 {
 
     @AutoGeneratedKeys
-    @ResultColumn("CENTROID_ID")
-    private long centroidId;
+    private long id;
     
     @ResultColumn("FIA_MS_RUN_ID")
     private long fiaMsRunId;
 
-    public long getCentroidId()
+    public long getId()
     {
-        return centroidId;
+        return id;
     }
 
-    public void setCentroidId(long centroidId)
+    public void setId(long id)
     {
-        this.centroidId = centroidId;
+        this.id = id;
     }
 
     public long getFiaMsRunId()
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAML2Database.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAML2Database.java
index f017266053b..2d0db836a53 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAML2Database.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAML2Database.java
@@ -25,6 +25,7 @@ import net.lemnik.eodsql.QueryTool;
 
 import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
 import ch.systemsx.cisd.yeastx.db.DBFactory;
+import ch.systemsx.cisd.yeastx.db.DMDataSetDTO;
 import ch.systemsx.cisd.yeastx.fiaml.FIAMLParser.IMSRunObserver;
 
 /**
@@ -81,15 +82,19 @@ public class FIAML2Database
      * Method for uploading an <var>fiaMLFile</var> to the database.
      */
     public static void uploadFiaMLFile(final Connection conn, final File fiaMLFile,
-            final String permId) throws SQLException
+            final DMDataSetDTO dataSet) throws SQLException
     {
         try
         {
+            DBFactory.createDataSet(DBFactory.getDAO(conn), dataSet);
             final IFIAMSRunDAO dao = getDAO(conn);
-            new FIAMLParser(fiaMLFile.getPath(), permId, new IMSRunObserver()
+            new FIAMLParser(fiaMLFile.getPath(), new IMSRunObserver()
                 {
                     public void observe(FIAMSRunDTO run, FIAMSRunDataDTO runData)
                     {
+                        run.setExperimentId(dataSet.getExperimentId());
+                        run.setSampleId(dataSet.getSampleId());
+                        run.setDataSetId(dataSet.getId());
                         final long fiaMsRunId = dao.addMSRun(run);
                         getDAO(conn).addProfiles(fiaMsRunId, profileChunk(runData));
                         getDAO(conn)
@@ -123,7 +128,8 @@ public class FIAML2Database
             for (String f : new File(dir).list(new FIAMLFilenameFilter()))
             {
                 System.out.println(f);
-                uploadFiaMLFile(conn, new File(dir, f), Integer.toString(++permId));
+                uploadFiaMLFile(conn, new File(dir, f), new DMDataSetDTO(Integer.toString(++permId),
+                        "sample perm id", "sample name", "experiment perm id", "experiment name"));
             }
         } finally
         {
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAMLParser.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAMLParser.java
index 14e07299200..39687b086c5 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAMLParser.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAMLParser.java
@@ -64,8 +64,6 @@ public class FIAMLParser extends DefaultHandler
 
     private StringBuilder buffer = new StringBuilder();
 
-    private String permIdOrNull;
-
     private FIAMSRunDTO msRun;
     
     private FIAMSRunDataDTO fiaRunData;
@@ -74,12 +72,11 @@ public class FIAMLParser extends DefaultHandler
 
     private final IMSRunObserver msRunObserverOrNull;
 
-    public FIAMLParser(String fileName, String permIdOrNull, IMSRunObserver msRunObserverOrNull)
+    public FIAMLParser(String fileName, IMSRunObserver msRunObserverOrNull)
             throws ParserConfigurationException, SAXException, IOException
     {
         assert fileName != null;
 
-        this.permIdOrNull = permIdOrNull;
         this.msRunObserverOrNull = msRunObserverOrNull;
         parseDocument(fileName);
     }
@@ -101,7 +98,6 @@ public class FIAMLParser extends DefaultHandler
         {
             msRun = new FIAMSRunDTO();
             fiaRunData = new FIAMSRunDataDTO();
-            msRun.setDataSetPermId(permIdOrNull);
             parsingMsRun = true;
         }
     }
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAMSRunDTO.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAMSRunDTO.java
index 59cf08f9131..4f0238310ad 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAMSRunDTO.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAMSRunDTO.java
@@ -29,11 +29,16 @@ import org.apache.commons.lang.builder.ToStringBuilder;
 public class FIAMSRunDTO
 {
     @AutoGeneratedKeys
-    @ResultColumn("FIA_MS_RUN_ID")
-    private long fiaMsRunId;
+    private long id;
 
-    @ResultColumn("DATA_SET_PERM_ID")
-    private String dataSetPermId;
+    @ResultColumn("DS_ID")
+    private long dataSetId;
+    
+    @ResultColumn("SAMP_ID")
+    private long sampleId;
+    
+    @ResultColumn("EXPE_ID")
+    private long experimentId;
     
     @ResultColumn("RAW_DATA_FILE_PATH")
     private String rawDataFilePath;
@@ -85,24 +90,44 @@ public class FIAMSRunDTO
         this.profileCount = profileCount;
     }
 
-    public String getDataSetPermId()
+    public long getId()
+    {
+        return id;
+    }
+
+    public void setId(long eicMsRunId)
+    {
+        this.id = eicMsRunId;
+    }
+
+    public long getDataSetId()
+    {
+        return dataSetId;
+    }
+
+    public void setDataSetId(long dataSetId)
+    {
+        this.dataSetId = dataSetId;
+    }
+
+    public long getSampleId()
     {
-        return dataSetPermId;
+        return sampleId;
     }
 
-    public void setDataSetPermId(String permId)
+    public void setSampleId(long sampleId)
     {
-        this.dataSetPermId = permId;
+        this.sampleId = sampleId;
     }
 
-    public long getFiaMsRunId()
+    public long getExperimentId()
     {
-        return fiaMsRunId;
+        return experimentId;
     }
 
-    public void setFiaMsRunId(long eicMsRunId)
+    public void setExperimentId(long experimentId)
     {
-        this.fiaMsRunId = eicMsRunId;
+        this.experimentId = experimentId;
     }
 
     public String getRawDataFilePath()
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAMSRunDataDTO.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAMSRunDataDTO.java
index 2e6e38d64f3..98b4d14e8b0 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAMSRunDataDTO.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/FIAMSRunDataDTO.java
@@ -16,8 +16,6 @@
 
 package ch.systemsx.cisd.yeastx.fiaml;
 
-import net.lemnik.eodsql.AutoGeneratedKeys;
-import net.lemnik.eodsql.ResultColumn;
 
 /**
  * A class that represents the data of a {@link FIAMSRunDTO}. 
@@ -27,10 +25,6 @@ import net.lemnik.eodsql.ResultColumn;
 public class FIAMSRunDataDTO
 {
     
-    @AutoGeneratedKeys
-    @ResultColumn("FIA_MS_RUN_ID")
-    private long fiaMsRunId;
-
     private float[] profileMz;
     
     private float[] profileIntensities;
@@ -41,16 +35,6 @@ public class FIAMSRunDataDTO
     
     private float[] centroidCorrelations;
 
-    public long getFiaMsRunId()
-    {
-        return fiaMsRunId;
-    }
-
-    public void setFiaMsRunId(long fiaMsRunId)
-    {
-        this.fiaMsRunId = fiaMsRunId;
-    }
-
     public float[] getProfileMz()
     {
         return profileMz;
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/IFIAMSRunDAO.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/IFIAMSRunDAO.java
index f885106c10a..f8de0f12da5 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/IFIAMSRunDAO.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/IFIAMSRunDAO.java
@@ -29,20 +29,22 @@ import net.lemnik.eodsql.Update;
 public interface IFIAMSRunDAO extends BaseQuery
 {
     final String ALL_FIA_MSRUN_COLUMNS =
-            "FIA_MS_RUNS.FIA_MS_RUN_ID, FIA_MS_RUNS.DATA_SET_PERM_ID, FIA_MS_RUNS.RAW_DATA_FILE_NAME, "
+            "FIA_MS_RUNS.ID, FIA_MS_RUNS.EXPE_ID, "
+                    + "FIA_MS_RUNS.SAMP_ID, FIA_MS_RUNS.DS_ID, FIA_MS_RUNS.RAW_DATA_FILE_NAME, "
                     + "FIA_MS_RUNS.RAW_DATA_FILE_PATH, FIA_MS_RUNS.ACQUISITION_DATE, "
                     + "FIA_MS_RUNS.INSTRUMENT_TYPE, FIA_MS_RUNS.INSTRUMENT_MANUFACTURER, "
                     + "FIA_MS_RUNS.INSTRUMENT_MODEL, FIA_MS_RUNS.METHOD_IONISATION, "
                     + "FIA_MS_RUNS.METHOD_SEPARATION, FIA_MS_RUNS.POLARITY, FIA_MS_RUNS.LOW_MZ, "
                     + "FIA_MS_RUNS.HIGH_MZ, FIA_MS_RUNS.INTERNAL_STANDARD, FIA_MS_RUNS.od, FIA_MS_RUNS.OPERATOR";
 
-    @Select("insert into FIA_MS_RUNS (DATA_SET_PERM_ID, RAW_DATA_FILE_NAME, RAW_DATA_FILE_PATH, ACQUISITION_DATE, "
-            + "INSTRUMENT_TYPE, INSTRUMENT_MANUFACTURER, INSTRUMENT_MODEL, METHOD_IONISATION, "
+    @Select("insert into FIA_MS_RUNS (EXPE_ID, SAMP_ID, DS_ID, RAW_DATA_FILE_NAME, RAW_DATA_FILE_PATH, "
+            + "ACQUISITION_DATE, INSTRUMENT_TYPE, INSTRUMENT_MANUFACTURER, INSTRUMENT_MODEL, METHOD_IONISATION, "
             + "METHOD_SEPARATION, POLARITY, LOW_MZ, HIGH_MZ, INTERNAL_STANDARD, od, OPERATOR) values "
-            + "(?{1.dataSetPermId}, ?{1.rawDataFileName}, ?{1.rawDataFilePath}, ?{1.acquisitionDate}, "
+            + "(?{1.experimentId}, ?{1.sampleId}, ?{1.dataSetId}, ?{1.rawDataFileName}, "
+            + "?{1.rawDataFilePath}, ?{1.acquisitionDate}, "
             + "?{1.instrumentType}, ?{1.instrumentManufacturer}, ?{1.instrumentModel}, "
             + "?{1.methodIonisation}, ?{1.methodSeparation}, ?{1.polarity}, ?{1.lowMz}, ?{1.highMz}, "
-            + "?{1.internalStandard}, ?{1.od}, ?{1.operator}) returning FIA_MS_RUN_ID")
+            + "?{1.internalStandard}, ?{1.od}, ?{1.operator}) returning ID")
     public long addMSRun(FIAMSRunDTO msRun);
 
     @Update(sql = "insert into FIA_CENTROIDS (FIA_MS_RUN_ID, MZ, INTENSITY, CORRELATION) "
@@ -55,13 +57,14 @@ public interface IFIAMSRunDAO extends BaseQuery
     public void addProfiles(long fiaMsRunId, Iterable<ProfileDTO> profiles);
 
     @Select(sql = "select FIA_MS_RUNS.*,count(FIA_PROFILES.*) as profileCount from FIA_MS_RUNS "
-            + "left join FIA_PROFILES using(FIA_MS_RUN_ID) group by " + ALL_FIA_MSRUN_COLUMNS)
+            + "left join FIA_PROFILES on FIA_MS_RUN_ID = FIA_MS_RUNS.ID group by "
+            + ALL_FIA_MSRUN_COLUMNS)
     public DataIterator<FIAMSRunDTO> getMsRuns();
 
-    @Select("select * from FIA_PROFILES where FIA_MS_RUN_ID=?{1.fiaMsRunId}")
+    @Select("select * from FIA_PROFILES where FIA_MS_RUN_ID=?{1.id}")
     public DataIterator<ProfileDTO> getProfilesForRun(FIAMSRunDTO msRun);
 
-    @Select("select * from FIA_CENTROIDS where FIA_MS_RUN_ID=?{1.fiaMsRunId}")
+    @Select("select * from FIA_CENTROIDS where FIA_MS_RUN_ID=?{1.id}")
     public DataIterator<CentroidDTO> getCentroidsForRun(FIAMSRunDTO msRun);
 
 }
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/ProfileDTO.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/ProfileDTO.java
index 3ec3aa44b2f..9cf92bc078a 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/ProfileDTO.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/fiaml/ProfileDTO.java
@@ -27,8 +27,7 @@ import net.lemnik.eodsql.ResultColumn;
 public class ProfileDTO
 {
     @AutoGeneratedKeys
-    @ResultColumn("PROFILE_ID")
-    private long profileId;
+    private long id;
     
     @ResultColumn("FIA_MS_RUN_ID")
     private long fiaMsRunId;
@@ -55,14 +54,14 @@ public class ProfileDTO
         return dto;
     }
     
-    public long getProfileId()
+    public long getId()
     {
-        return profileId;
+        return id;
     }
 
-    public void setProfileId(long profileId)
+    public void setId(long id)
     {
-        this.profileId = profileId;
+        this.id = id;
     }
 
     public long getFiaMsRunId()
diff --git a/rtd_yeastx/source/sql/postgresql/001/schema-001.sql b/rtd_yeastx/source/sql/postgresql/001/schema-001.sql
index dec8e9b3321..88321b4638e 100644
--- a/rtd_yeastx/source/sql/postgresql/001/schema-001.sql
+++ b/rtd_yeastx/source/sql/postgresql/001/schema-001.sql
@@ -4,6 +4,8 @@
 
 -- Create domain types section -------------------------------------------------
 
+CREATE DOMAIN TECH_ID AS BIGINT;
+
 CREATE DOMAIN CODE AS VARCHAR(40);
 
 CREATE DOMAIN FILE_NAME as VARCHAR(255);
@@ -18,9 +20,48 @@ CREATE DOMAIN CHAR as VARCHAR(1);
 
 -- Create tables section -------------------------------------------------
 
+-- Table EXPERIMENTS
+
+CREATE TABLE EXPERIMENTS (
+  ID BIGSERIAL NOT NULL,
+  PERM_ID CODE NOT NULL,
+  NAME LONG_LABEL NOT NULL,
+  PRIMARY KEY (ID),
+  UNIQUE (PERM_ID)
+);
+
+-- Table SAMPLES
+
+CREATE TABLE SAMPLES (
+  ID BIGSERIAL NOT NULL,
+  PERM_ID CODE NOT NULL,
+  NAME LONG_LABEL NOT NULL,
+  EXPE_ID TECH_ID NOT NULL,
+  PRIMARY KEY (ID),
+  UNIQUE (PERM_ID),
+  CONSTRAINT FK_SAMPLE_1 FOREIGN KEY (EXPE_ID) REFERENCES EXPERIMENTS (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+-- Table DATA_SETS
+
+CREATE TABLE DATA_SETS (
+  ID BIGSERIAL NOT NULL,
+  PERM_ID CODE NOT NULL,  
+  EXPE_ID TECH_ID NOT NULL,
+  SAMP_ID TECH_ID,
+  PRIMARY KEY (ID),
+  UNIQUE (PERM_ID),
+  CONSTRAINT FK_DATA_SET_1 FOREIGN KEY (EXPE_ID) REFERENCES EXPERIMENTS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT FK_DATA_SET_2 FOREIGN KEY (SAMP_ID) REFERENCES SAMPLES (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+-- Table EIC_MS_RUNS
+
 CREATE TABLE EIC_MS_RUNS (
-  EIC_MS_RUN_ID BIGSERIAL NOT NULL,
-  DATA_SET_PERM_ID CODE NOT NULL,
+  ID BIGSERIAL NOT NULL,
+  EXPE_ID TECH_ID NOT NULL,
+  SAMP_ID TECH_ID NOT NULL,
+  DS_ID TECH_ID NOT NULL,
   RAW_DATA_FILE_NAME FILE_NAME NOT NULL,
   RAW_DATA_FILE_PATH FILE_PATH DEFAULT NULL,
   ACQUISITION_DATE TIMESTAMP DEFAULT NULL,
@@ -30,16 +71,24 @@ CREATE TABLE EIC_MS_RUNS (
   METHOD_IONISATION SHORT_LABEL DEFAULT NULL,
   METHOD_SEPARATION LONG_LABEL DEFAULT NULL,
   OPERATOR SHORT_LABEL DEFAULT NULL,
-  SET_ID BIGINT DEFAULT NULL,
+  SET_ID TECH_ID DEFAULT NULL,
   START_TIME REAL NOT NULL,
   END_TIME REAL NOT NULL,
-  PRIMARY KEY (EIC_MS_RUN_ID),
-  UNIQUE(DATA_SET_PERM_ID)
+  PRIMARY KEY (ID),
+  CONSTRAINT FK_EIC_MS_RUN_1 FOREIGN KEY (EXPE_ID) REFERENCES EXPERIMENTS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT FK_EIC_MS_RUN_2 FOREIGN KEY (SAMP_ID) REFERENCES SAMPLES (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT FK_EIC_MS_RUN_3 FOREIGN KEY (DS_ID) REFERENCES DATA_SETS (ID) ON DELETE CASCADE ON UPDATE CASCADE
 );
 
+CREATE INDEX EIC_MS_RUNS_FK_DS_ID_IDX ON EIC_MS_RUNS(DS_ID);
+CREATE INDEX EIC_MS_RUNS_FK_SAMP_ID_IDX ON EIC_MS_RUNS(SAMP_ID);
+CREATE INDEX EIC_MS_RUNS_FK_EXPE_ID_IDX ON EIC_MS_RUNS(EXPE_ID);
+
+-- Table EIC_CHROMATOGRAMS
+
 CREATE TABLE EIC_CHROMATOGRAMS (
-  CHROM_ID BIGSERIAL NOT NULL,
-  EIC_MS_RUN_ID BIGINT NOT NULL,
+  ID BIGSERIAL NOT NULL,
+  EIC_MS_RUN_ID TECH_ID NOT NULL,
   Q1_MZ REAL NOT NULL,
   Q3_LOW_MZ REAL NOT NULL,
   Q3_HIGH_MZ REAL NOT NULL,
@@ -47,15 +96,19 @@ CREATE TABLE EIC_CHROMATOGRAMS (
   POLARITY CHAR DEFAULT NULL,
   RUN_TIMES TEXT NOT NULL,
   INTENSITIES TEXT NOT NULL,
-  PRIMARY KEY (CHROM_ID),
-  CONSTRAINT FK_CHROMATOGRAM_1 FOREIGN KEY (EIC_MS_RUN_ID) REFERENCES EIC_MS_RUNS (EIC_MS_RUN_ID) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (ID),
+  CONSTRAINT FK_EIC_CHROMATOGRAM_1 FOREIGN KEY (EIC_MS_RUN_ID) REFERENCES EIC_MS_RUNS (ID) ON DELETE CASCADE ON UPDATE CASCADE
 );
 
 CREATE INDEX EIC_CHROMATOGRAM_FK_IDX ON EIC_CHROMATOGRAMS(EIC_MS_RUN_ID);
 
+-- Table FIA_MS_RUNS
+
 CREATE TABLE FIA_MS_RUNS (
-  FIA_MS_RUN_ID BIGSERIAL NOT NULL,
-  DATA_SET_PERM_ID CODE,
+  ID BIGSERIAL NOT NULL,
+  EXPE_ID TECH_ID NOT NULL,
+  SAMP_ID TECH_ID NOT NULL,
+  DS_ID TECH_ID NOT NULL,
   RAW_DATA_FILE_NAME FILE_NAME NOT NULL,
   RAW_DATA_FILE_PATH FILE_PATH DEFAULT NULL,
   ACQUISITION_DATE TIMESTAMP DEFAULT NULL,
@@ -71,32 +124,38 @@ CREATE TABLE FIA_MS_RUNS (
   -- Is this a good name?
   OD REAL NOT NULL,
   OPERATOR SHORT_LABEL DEFAULT NULL,
-  PRIMARY KEY (FIA_MS_RUN_ID),
-  UNIQUE(DATA_SET_PERM_ID)
+  PRIMARY KEY (ID),
+  CONSTRAINT FK_FIA_MS_RUN_1 FOREIGN KEY (EXPE_ID) REFERENCES EXPERIMENTS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT FK_EIA_MS_RUN_2 FOREIGN KEY (SAMP_ID) REFERENCES SAMPLES (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT FK_EIA_MS_RUN_3 FOREIGN KEY (DS_ID) REFERENCES DATA_SETS (ID) ON DELETE CASCADE ON UPDATE CASCADE
 );
 
+-- Table FIA_PROFILES
+
 CREATE TABLE FIA_PROFILES (
-  PROFILE_ID BIGSERIAL NOT NULL,
-  FIA_MS_RUN_ID BIGINT NOT NULL,
+  ID BIGSERIAL NOT NULL,
+  FIA_MS_RUN_ID TECH_ID NOT NULL,
   LOW_MZ REAL NOT NULL,
   HIGH_MZ REAL NOT NULL,
   MZ TEXT NOT NULL,
   INTENSITIES TEXT NOT NULL,
-  PRIMARY KEY (PROFILE_ID),
-  CONSTRAINT FK_EIC_PROFILE_1 FOREIGN KEY (FIA_MS_RUN_ID) REFERENCES FIA_MS_RUNS (FIA_MS_RUN_ID) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (ID),
+  CONSTRAINT FK_FIA_PROFILE_1 FOREIGN KEY (FIA_MS_RUN_ID) REFERENCES FIA_MS_RUNS (ID) ON DELETE CASCADE ON UPDATE CASCADE
 );
 
 CREATE INDEX FIA_PROFILE_I_ID on FIA_PROFILES(FIA_MS_RUN_ID);
 CREATE INDEX FIA_PROFILE_I_ID_MZ on FIA_PROFILES(FIA_MS_RUN_ID, LOW_MZ, HIGH_MZ);
 
+-- Table FIA_CENTROIDS
+
 CREATE TABLE FIA_CENTROIDS (
-  CENTROID_ID BIGSERIAL NOT NULL,
-  FIA_MS_RUN_ID BIGINT NOT NULL,
+  ID BIGSERIAL NOT NULL,
+  FIA_MS_RUN_ID TECH_ID NOT NULL,
   MZ REAL NOT NULL,
   INTENSITY REAL NOT NULL,
   CORRELATION REAL NOT NULL,
-  PRIMARY KEY (CENTROID_ID),
-  CONSTRAINT FK_EIC_CENTROID_1 FOREIGN KEY (FIA_MS_RUN_ID) REFERENCES FIA_MS_RUNS (FIA_MS_RUN_ID) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (ID),
+  CONSTRAINT FK_FIA_CENTROID_1 FOREIGN KEY (FIA_MS_RUN_ID) REFERENCES FIA_MS_RUNS (ID) ON DELETE CASCADE ON UPDATE CASCADE
 );
 
 CREATE INDEX FIA_CENTROID_I_ID on FIA_CENTROIDS(FIA_MS_RUN_ID);
@@ -107,19 +166,19 @@ GRANT SELECT ON TABLE EIC_CHROMATOGRAMS TO GROUP metabol_readonly;
 GRANT SELECT ON TABLE FIA_MS_RUNS TO GROUP metabol_readonly;
 GRANT SELECT ON TABLE FIA_PROFILES TO GROUP metabol_readonly;
 GRANT SELECT ON TABLE FIA_CENTROIDS TO GROUP metabol_readonly;
-GRANT SELECT ON SEQUENCE EIC_MS_RUNS_EIC_MS_RUN_ID_SEQ TO GROUP metabol_readonly;
-GRANT SELECT ON SEQUENCE EIC_CHROMATOGRAMS_CHROM_ID_SEQ TO GROUP metabol_readonly;
-GRANT SELECT ON SEQUENCE FIA_MS_RUNS_FIA_MS_RUN_ID_SEQ TO GROUP metabol_readonly;
-GRANT SELECT ON SEQUENCE FIA_PROFILES_PROFILE_ID_SEQ TO GROUP metabol_readonly;
-GRANT SELECT ON SEQUENCE FIA_CENTROIDS_CENTROID_ID_SEQ TO GROUP metabol_readonly;
+GRANT SELECT ON SEQUENCE EIC_MS_RUNS_ID_SEQ TO GROUP metabol_readonly;
+GRANT SELECT ON SEQUENCE EIC_CHROMATOGRAMS_ID_SEQ TO GROUP metabol_readonly;
+GRANT SELECT ON SEQUENCE FIA_MS_RUNS_ID_SEQ TO GROUP metabol_readonly;
+GRANT SELECT ON SEQUENCE FIA_PROFILES_ID_SEQ TO GROUP metabol_readonly;
+GRANT SELECT ON SEQUENCE FIA_CENTROIDS_ID_SEQ TO GROUP metabol_readonly;
 
 GRANT ALL PRIVILEGES ON TABLE EIC_MS_RUNS TO GROUP metabol_readwrite;
 GRANT ALL PRIVILEGES ON TABLE EIC_CHROMATOGRAMS TO GROUP metabol_readwrite;
 GRANT ALL PRIVILEGES ON TABLE FIA_MS_RUNS TO GROUP metabol_readwrite;
 GRANT ALL PRIVILEGES ON TABLE FIA_PROFILES TO GROUP metabol_readwrite;
 GRANT ALL PRIVILEGES ON TABLE FIA_CENTROIDS TO GROUP metabol_readwrite;
-GRANT ALL PRIVILEGES ON SEQUENCE EIC_MS_RUNS_EIC_MS_RUN_ID_SEQ TO GROUP metabol_readwrite;
-GRANT ALL PRIVILEGES ON SEQUENCE EIC_CHROMATOGRAMS_CHROM_ID_SEQ TO GROUP metabol_readwrite;
-GRANT ALL PRIVILEGES ON SEQUENCE FIA_MS_RUNS_FIA_MS_RUN_ID_SEQ TO GROUP metabol_readwrite;
-GRANT ALL PRIVILEGES ON SEQUENCE FIA_PROFILES_PROFILE_ID_SEQ TO GROUP metabol_readwrite;
-GRANT ALL PRIVILEGES ON SEQUENCE FIA_CENTROIDS_CENTROID_ID_SEQ TO GROUP metabol_readwrite;
+GRANT ALL PRIVILEGES ON SEQUENCE EIC_MS_RUNS_ID_SEQ TO GROUP metabol_readwrite;
+GRANT ALL PRIVILEGES ON SEQUENCE EIC_CHROMATOGRAMS_ID_SEQ TO GROUP metabol_readwrite;
+GRANT ALL PRIVILEGES ON SEQUENCE FIA_MS_RUNS_ID_SEQ TO GROUP metabol_readwrite;
+GRANT ALL PRIVILEGES ON SEQUENCE FIA_PROFILES_ID_SEQ TO GROUP metabol_readwrite;
+GRANT ALL PRIVILEGES ON SEQUENCE FIA_CENTROIDS_ID_SEQ TO GROUP metabol_readwrite;
diff --git a/rtd_yeastx/sourceTest/java/ch/systemsx/cisd/yeastx/eicml/EICMLTest.java b/rtd_yeastx/sourceTest/java/ch/systemsx/cisd/yeastx/eicml/EICMLTest.java
index 2c9cb833495..c54dbab5eb7 100644
--- a/rtd_yeastx/sourceTest/java/ch/systemsx/cisd/yeastx/eicml/EICMLTest.java
+++ b/rtd_yeastx/sourceTest/java/ch/systemsx/cisd/yeastx/eicml/EICMLTest.java
@@ -25,6 +25,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.yeastx.db.AbstractDBTest;
+import ch.systemsx.cisd.yeastx.db.DMDataSetDTO;
 
 import static org.testng.AssertJUnit.*;
 
@@ -37,7 +38,7 @@ public class EICMLTest extends AbstractDBTest
 {
 
     private IEICMSRunDAO eicmlDAO;
-    
+
     @BeforeMethod(alwaysRun = true)
     public void setDAO() throws SQLException
     {
@@ -48,9 +49,10 @@ public class EICMLTest extends AbstractDBTest
     public void testUploadEicML() throws SQLException
     {
         EICML2Database.uploadEicMLFile(conn, new File("resource/examples/example.eicML"),
-                "some perm id");
+                new DMDataSetDTO("data set perm id", "sample perm id", "sample name",
+                        "experiment perm id", "experiment name"));
     }
-    
+
     @Test(dependsOnMethods = "testUploadEicML")
     public void testGetMsRuns()
     {
@@ -67,6 +69,6 @@ public class EICMLTest extends AbstractDBTest
             ++count;
         }
         assertEquals(22, count);
-        chromatograms.close();  // Shoudn't be necessary, just to be sure.
+        chromatograms.close(); // Shoudn't be necessary, just to be sure.
     }
 }
diff --git a/rtd_yeastx/sourceTest/java/ch/systemsx/cisd/yeastx/fiaml/FIAMLTest.java b/rtd_yeastx/sourceTest/java/ch/systemsx/cisd/yeastx/fiaml/FIAMLTest.java
index 9ef20b6e781..3ec406e2976 100644
--- a/rtd_yeastx/sourceTest/java/ch/systemsx/cisd/yeastx/fiaml/FIAMLTest.java
+++ b/rtd_yeastx/sourceTest/java/ch/systemsx/cisd/yeastx/fiaml/FIAMLTest.java
@@ -25,6 +25,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.yeastx.db.AbstractDBTest;
+import ch.systemsx.cisd.yeastx.db.DMDataSetDTO;
 
 import static org.testng.AssertJUnit.*;
 
@@ -47,9 +48,10 @@ public class FIAMLTest extends AbstractDBTest
     public void testUploadFiaML() throws SQLException
     {
         FIAML2Database.uploadFiaMLFile(conn, new File("resource/examples/example.fiaML"),
-                "some perm id");
+                new DMDataSetDTO("data set perm id", "sample perm id", "sample name",
+                        "experiment perm id", "experiment name"));
     }
-    
+
     @Test(dependsOnMethods = "testUploadFiaML")
     public void testGetMsRuns()
     {
@@ -63,8 +65,8 @@ public class FIAMLTest extends AbstractDBTest
         while (profiles.hasNext())
         {
             final ProfileDTO prof = profiles.next();
-            assertFalse(prof.getProfileId() == 0);
-            assertEquals(run.getFiaMsRunId(), prof.getFiaMsRunId());
+            assertFalse(prof.getId() == 0);
+            assertEquals(run.getId(), prof.getFiaMsRunId());
             ++count;
         }
         assertEquals(686, count);
@@ -74,8 +76,8 @@ public class FIAMLTest extends AbstractDBTest
         while (centroids.hasNext())
         {
             final CentroidDTO cent = centroids.next();
-            assertFalse(cent.getCentroidId() == 0);
-            assertEquals(run.getFiaMsRunId(), cent.getFiaMsRunId());
+            assertFalse(cent.getId() == 0);
+            assertEquals(run.getId(), cent.getFiaMsRunId());
             ++count;
         }
         assertEquals(556, count);
-- 
GitLab