From 6c6dd7de38910765e666892f94ead825534e4bd3 Mon Sep 17 00:00:00 2001
From: tpylak <tpylak>
Date: Mon, 29 Nov 2010 12:22:16 +0000
Subject: [PATCH] LMS-1883 controlled vocabulary features - data model

SVN: 18917
---
 screening/source/sql/postgresql/008/data.sql  | 275 ++++++++++++++++++
 .../source/sql/postgresql/008/schema-008.sql  | 236 +++++++++++++++
 .../008/upload-screening-metadata.sh          |   2 +
 .../migration/migration-007-008.sql           |  18 ++
 4 files changed, 531 insertions(+)
 create mode 100644 screening/source/sql/postgresql/008/data.sql
 create mode 100644 screening/source/sql/postgresql/008/schema-008.sql
 create mode 100755 screening/source/sql/postgresql/008/upload-screening-metadata.sh
 create mode 100644 screening/source/sql/postgresql/migration/migration-007-008.sql

diff --git a/screening/source/sql/postgresql/008/data.sql b/screening/source/sql/postgresql/008/data.sql
new file mode 100644
index 00000000000..f08222c48c2
--- /dev/null
+++ b/screening/source/sql/postgresql/008/data.sql
@@ -0,0 +1,275 @@
+-- Note that these data has to be loaded manually into the openBIS Core database.
+
+-- TODO: this sql should be converted to a generic sql without refering to technical ids. 
+-- Now the ids should be updated if some new records will be added in the generic data.
+
+--
+-- PostgreSQL database dump
+--
+
+SET statement_timeout = 0;
+SET client_encoding = 'UTF8';
+SET standard_conforming_strings = off;
+SET check_function_bodies = false;
+SET client_min_messages = warning;
+SET escape_string_warning = off;
+
+SET search_path = public, pg_catalog;
+
+--
+-- Data for Name: controlled_vocabularies; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY controlled_vocabularies (id, code, description, registration_timestamp, pers_id_registerer, is_managed_internally, is_internal_namespace, dbin_id, modification_timestamp, is_chosen_from_list, source_uri) FROM stdin;
+2	PLATE_GEOMETRY	The geometry or dimensions of a plate	2008-06-17 16:38:30.723292+02	1	t	t	1	2009-11-27 16:02:26.451046+01	t	\N
+3	MICROSCOPE	Microscope used in an experiment.	2009-11-29 23:55:18.978884+01	1	f	f	1	2009-12-17 01:50:54.68+01	t	\N
+\.
+
+
+--
+-- Data for Name: controlled_vocabulary_terms; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY controlled_vocabulary_terms (id, code, registration_timestamp, covo_id, pers_id_registerer, label, description, ordinal) FROM stdin;
+3	384_WELLS_16X24	2008-06-17 16:38:30.723292+02	2	1	384 Wells, 16x24	\N	1
+4	96_WELLS_8X12	2008-06-17 16:38:31.101031+02	2	1	96 Wells, 8x12	\N	2
+5	1536_WELLS_32X48	2008-06-17 16:38:31.101031+02	2	1	1536 Wells, 32x48	\N	3
+6	BD_PATHWAY_855	2009-11-29 23:55:18.978884+01	3	1	\N	\N	1
+7	MD_IMAGEXPRESS_MICROLIVE	2009-11-29 23:55:18.978884+01	3	1	\N	\N	2
+8	MD_IMAGEXPRESS_MICRO_2	2009-11-29 23:55:18.978884+01	3	1	\N	\N	3
+\.
+
+
+--
+-- Data for Name: data_set_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY data_set_types (id, code, description, dbin_id, modification_timestamp) FROM stdin;
+3	HCS_IMAGE_ANALYSIS_DATA	Data derived from analysis of HCS images	1	2009-11-27 16:02:26.451046+01
+2	HCS_IMAGE	HCS raw images acquired by microscopes	1	2009-11-27 16:02:26.451046+01
+4	HCS_ANALYSIS_PER_GENE	Image analysis data aggregated per gene.	1	2009-12-16 16:59:50.743029+01
+\.
+
+
+--
+-- Data for Name: material_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY material_types (id, code, description, dbin_id, modification_timestamp) FROM stdin;
+1	VIRUS	Virus	1	2009-11-27 16:02:26.451046+01
+2	CELL_LINE	Cell Line or Cell Culture. The growing of cells under controlled conditions.	1	2009-11-27 16:02:26.451046+01
+3	GENE	Gene	1	2009-11-27 16:02:26.451046+01
+4	SIRNA	siRNA nucleotide	1	2009-11-27 16:02:26.451046+01
+5	CONTROL	Control of a control layout	1	2009-11-27 16:02:26.451046+01
+6	BACTERIUM	Bacterium	1	2009-11-27 16:02:26.451046+01
+7	COMPOUND	Compound	1	2009-11-27 16:02:26.451046+01
+\.
+
+
+--
+-- Data for Name: property_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY property_types (id, code, description, label, daty_id, registration_timestamp, pers_id_registerer, covo_id, is_managed_internally, is_internal_namespace, dbin_id, maty_prop_id) FROM stdin;
+3	NUCLEOTIDE_SEQUENCE	A sequence of nucleotides	Nucleotide Sequence	1	2008-02-28 13:03:03.358532+01	1	\N	f	f	1	\N
+4	REFSEQ	NCBI Reference Sequence code, applicable to sequences of type: DNA, RNA, protein	RefSeq	1	2008-02-28 13:03:03.358532+01	1	\N	f	f	1	\N
+13	MICROSCOPE	 	Microscope	7	2009-11-29 23:57:05.85618+01	1	3	f	f	1	\N
+7	INHIBITOR_OF	Inhibitor Of	Inhibitor Of	8	2009-11-27 16:02:45.060699+01	1	\N	f	f	1	3
+11	SIRNA	siRNA	siRNA	8	2009-11-29 23:56:19.39967+01	1	\N	f	f	1	4
+12	CONTROL	Control	Control	8	2009-11-29 23:56:37.355313+01	1	\N	f	f	1	5
+6	PLATE_GEOMETRY	Plate Geometry	Plate Geometry	7	2008-06-17 16:38:30.723292+02	1	2	t	t	1	\N
+15	NUMBER_OF_CHANNEL	 	Channels	3	2009-12-17 10:56:17.239319+01	1	\N	f	f	1	\N
+16	LIBRARY_ID	Library id	Id from the master plate library	1	2008-02-28 13:03:03.358532+01	1	\N	f	f	1	\N
+\.
+
+
+--
+-- Data for Name: data_set_type_property_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY data_set_type_property_types (id, dsty_id, prty_id, is_mandatory, is_managed_internally, pers_id_registerer, registration_timestamp, section, ordinal) FROM stdin;
+\.
+
+
+--
+-- Data for Name: experiment_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY experiment_types (id, code, description, dbin_id, modification_timestamp) FROM stdin;
+2	COMPOUND_HCS	Compound High Content Screening	1	2009-11-27 16:02:26.451046+01
+1	SIRNA_HCS	Small Interfering RNA High Content Screening	1	2009-11-27 16:02:26.451046+01
+\.
+
+
+--
+-- Data for Name: experiment_type_property_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY experiment_type_property_types (id, exty_id, prty_id, is_mandatory, is_managed_internally, pers_id_registerer, registration_timestamp, section, ordinal) FROM stdin;
+1	1	1	t	t	1	2008-06-17 16:38:49.023295+02	\N	1
+2	2	1	t	t	1	2008-06-17 16:38:49.301922+02	\N	1
+5	1	13	f	f	1	2009-12-17 10:54:01.261178+01	\N	2
+\.
+
+
+--
+-- Data for Name: file_format_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY file_format_types (id, code, description, dbin_id) FROM stdin;
+7	PNG	\N	1
+8	CSV	files with values separated by comma or semicolon	1
+9	JPG	\N	1
+\.
+
+
+--
+-- Data for Name: filters; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY filters (id, dbin_id, name, description, registration_timestamp, pers_id_registerer, modification_timestamp, expression, is_public, grid_id) FROM stdin;
+9	1	Infection index	\N	2009-12-16 21:19:19.012657+01	1	2009-12-16 22:41:56.863+01	float(row.col('colIndex_5')) > float(${threshold})	t	data-set-reporting-gridplate-image-analysis-merger
+8	1	Total number of cells	\N	2009-12-16 21:18:05.161964+01	1	2009-12-16 22:42:31.707+01	int(row.col('colIndex_3')) > int(${threshold})	t	data-set-reporting-gridplate-image-analysis-merger
+7	1	Number of infected cells	\N	2009-12-16 21:17:40.765083+01	1	2009-12-16 22:42:46.052+01	int(row.col('colIndex_4')) > int(${threshold})	t	data-set-reporting-gridplate-image-analysis-merger
+\.
+
+
+--
+-- Data for Name: material_type_property_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY material_type_property_types (id, maty_id, prty_id, is_mandatory, registration_timestamp, pers_id_registerer, is_managed_internally, section, ordinal) FROM stdin;
+10	4	7	t	2009-11-27 16:02:45.060699+01	1	f	\N	4
+9	5	1	f	2008-02-28 13:03:03.358532+01	1	f	\N	1
+8	4	1	f	2008-02-28 13:03:03.358532+01	1	f	\N	3
+6	4	3	t	2008-02-28 13:03:03.358532+01	1	f	\N	1
+12	4	16	f	2008-02-28 13:03:03.358532+01	1	f	\N	1
+5	3	1	f	2008-02-28 13:03:03.358532+01	1	f	\N	2
+3	7	1	t	2008-02-28 13:03:03.358532+01	1	f	\N	1
+2	6	1	t	2008-02-28 13:03:03.358532+01	1	f	\N	1
+1	1	1	t	2008-02-28 13:03:03.358532+01	1	f	\N	1
+\.
+
+
+--
+-- Data for Name: sample_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY sample_types (id, code, description, dbin_id, is_listable, generated_from_depth, part_of_depth, modification_timestamp, is_auto_generated_code, generated_code_prefix) FROM stdin;
+3	PLATE	Cell Plate	1	t	2	0	2009-11-27 16:02:26.451046+01	f	S
+7	SIRNA_WELL	\N	1	f	0	1	2009-11-27 19:42:03.483115+01	f	O
+8	CONTROL_WELL	\N	1	f	0	1	2009-11-27 19:42:25.791288+01	f	C
+9	LIBRARY	\N	1	f	0	0	2009-11-27 19:42:25.791288+01	f	L
+\.
+
+
+--
+-- Data for Name: sample_type_property_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY sample_type_property_types (id, saty_id, prty_id, is_mandatory, is_managed_internally, pers_id_registerer, registration_timestamp, is_displayed, section, ordinal) FROM stdin;
+8	7	11	f	f	1	2009-11-29 23:57:38.268212+01	t	\N	1
+9	8	12	f	f	1	2009-11-29 23:57:49.098187+01	t	\N	1
+10	3	6	f	f	1	2009-11-30 01:28:20.972263+01	t	\N	1
+\.
+
+--
+-- PostgreSQL database dump complete
+--
+
+--------------------------------------------------
+-- update sequences values
+--------------------------------------------------
+
+select setval('controlled_vocabulary_id_seq', 100);
+select setval('cvte_id_seq', 100);
+select setval('property_type_id_seq', 100);
+select setval('file_format_type_id_seq', 100);
+select setval('filter_id_seq', 100);
+select setval('experiment_type_id_seq', 100);
+select setval('sample_type_id_seq', 100);
+select setval('data_set_type_id_seq', 100);
+select setval('material_type_id_seq', 100);
+select setval('etpt_id_seq', 100);
+select setval('stpt_id_seq', 100);
+select setval('mtpt_id_seq', 100);
+
+
+--------------------------------------------------
+-- create a gene property and assign it to sirna well
+--------------------------------------------------
+
+insert into property_types(
+	id, 
+	code, description, label, 
+	daty_id,
+	pers_id_registerer,
+	dbin_id,
+	maty_prop_id) 
+values(
+		nextval('PROPERTY_TYPE_ID_SEQ'), 
+		'GENE','Inhibited gene','Gene',
+		(select id from data_types where code = 'MATERIAL'), 
+		(select id from persons where user_id ='system'), 
+		(select id from database_instances where is_original_source = 'T'), 
+		(select id from material_types where code = 'GENE')
+	);
+	
+insert into sample_type_property_types( 
+  id,
+  saty_id,
+  prty_id,
+  is_mandatory,
+  pers_id_registerer,
+  ordinal
+) values(
+		nextval('stpt_id_seq'), 
+		(select id from sample_types where code = 'SIRNA_WELL'),
+		(select id from property_types where code = 'GENE'),
+		false,
+		(select id from persons where user_id ='system'),
+		(select max(ordinal)+1 from sample_type_property_types 
+			where saty_id = (select id from sample_types where code = 'SIRNA_WELL'))
+	);
+
+
+--------------------------------------------------
+-- Create gene property: gene_symbols
+--------------------------------------------------
+
+
+	insert into property_types
+		(id
+		,code
+		,description
+		,label
+		,daty_id
+		,pers_id_registerer
+		,dbin_id)
+	values 
+		(nextval('PROPERTY_TYPE_ID_SEQ')
+		,'GENE_SYMBOLS'
+		,'Gene symbols'
+		,'Gene symbols'
+		,(select id from data_types where code ='VARCHAR')
+		,(select id from persons where user_id ='system')
+		,(select id from database_instances where is_original_source = 'T')
+	);
+		
+	insert into material_type_property_types( 
+	  id,
+	  maty_id,
+	  prty_id,
+	  is_mandatory,
+	  pers_id_registerer,
+	  ordinal
+	) values(
+			nextval('mtpt_id_seq'), 
+			(select id from material_types where code = 'GENE'),
+			(select id from property_types where code = 'GENE_SYMBOLS'),
+			false,
+			(select id from persons where user_id ='system'),
+			(select max(ordinal)+1 from material_type_property_types 
+				where maty_id = (select id from material_types where code = 'GENE'))
+		);
+
diff --git a/screening/source/sql/postgresql/008/schema-008.sql b/screening/source/sql/postgresql/008/schema-008.sql
new file mode 100644
index 00000000000..b9135854165
--- /dev/null
+++ b/screening/source/sql/postgresql/008/schema-008.sql
@@ -0,0 +1,236 @@
+
+/* ---------------------------------------------------------------------- */
+/* Domains                                                                */
+/* ---------------------------------------------------------------------- */
+
+CREATE DOMAIN TECH_ID AS BIGINT;
+
+CREATE DOMAIN CODE AS VARCHAR(40);
+
+CREATE DOMAIN NAME AS VARCHAR(80);
+
+CREATE DOMAIN DESCRIPTION AS VARCHAR(200);
+
+CREATE DOMAIN FILE_PATH as VARCHAR(1000);
+
+CREATE DOMAIN COLOR_COMPONENT AS VARCHAR(40) CHECK (VALUE IN ('RED', 'GREEN', 'BLUE'));
+
+CREATE DOMAIN BOOLEAN_CHAR AS BOOLEAN DEFAULT FALSE;
+
+/* ---------------------------------------------------------------------- */
+/* Tables                                                                 */
+/* ---------------------------------------------------------------------- */
+
+CREATE TABLE EXPERIMENTS (
+  ID BIGSERIAL NOT NULL,
+  PERM_ID CODE NOT NULL,
+  IMAGE_TRANSFORMER_FACTORY BYTEA,
+
+  PRIMARY KEY (ID),
+  UNIQUE (PERM_ID)
+);
+
+CREATE TABLE CONTAINERS (
+  ID BIGSERIAL NOT NULL,
+  PERM_ID CODE NOT NULL,
+
+  SPOTS_WIDTH INTEGER,
+  SPOTS_HEIGHT INTEGER,
+  
+  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
+);
+
+CREATE INDEX CONTAINERS_EXPE_IDX ON CONTAINERS(EXPE_ID);
+
+CREATE TABLE SPOTS (
+  ID BIGSERIAL NOT NULL,
+	
+	-- position in the container, one-based
+  X INTEGER, 
+  Y INTEGER, 
+  CONT_ID TECH_ID NOT NULL,
+  
+  PRIMARY KEY (ID),
+  CONSTRAINT FK_SPOT_1 FOREIGN KEY (CONT_ID) REFERENCES CONTAINERS (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX SPOTS_CONT_IDX ON SPOTS(CONT_ID);
+-- allows to select one spot of the container quicker
+CREATE INDEX SPOTS_COORDS_IDX ON SPOTS(CONT_ID, X, Y);
+
+CREATE TABLE DATA_SETS (
+  ID BIGSERIAL NOT NULL,
+  PERM_ID CODE NOT NULL,
+  
+	FIELDS_WIDTH INTEGER,
+	FIELDS_HEIGHT INTEGER,	
+  
+  CONT_ID TECH_ID NOT NULL,
+  -- a redundant information if there are timepoint or depth stack data for any spots in this dataset
+  IS_MULTIDIMENSIONAL BOOLEAN_CHAR NOT NULL,
+  
+  PRIMARY KEY (ID),
+  UNIQUE (PERM_ID),
+  CONSTRAINT FK_DATA_SET_1 FOREIGN KEY (CONT_ID) REFERENCES CONTAINERS (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX DATA_SETS_CONT_IDX ON DATA_SETS(CONT_ID);
+
+CREATE TABLE CHANNELS (
+    ID BIGSERIAL  NOT NULL,
+    
+    CODE NAME NOT NULL,
+    LABEL NAME NOT NULL,
+    DESCRIPTION DESCRIPTION,
+    WAVELENGTH INTEGER,
+    IMAGE_TRANSFORMER_FACTORY BYTEA,
+
+    DS_ID TECH_ID,
+    EXP_ID TECH_ID,
+    
+    PRIMARY KEY (ID),
+    CONSTRAINT FK_CHANNELS_1 FOREIGN KEY (DS_ID) REFERENCES DATA_SETS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT FK_CHANNELS_2 FOREIGN KEY (EXP_ID) REFERENCES EXPERIMENTS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT CHANNELS_DS_EXP_ARC_CK CHECK ((DS_ID IS NOT NULL AND EXP_ID IS NULL) OR (DS_ID IS NULL AND EXP_ID IS NOT NULL)),
+    
+    CONSTRAINT CHANNELS_UK_1 UNIQUE(CODE, DS_ID),
+    CONSTRAINT CHANNELS_UK_2 UNIQUE(CODE, EXP_ID)
+);
+
+CREATE INDEX CHANNELS_DS_IDX ON CHANNELS(DS_ID);
+
+CREATE TABLE CHANNEL_STACKS (
+    ID BIGSERIAL  NOT NULL,
+		
+		-- x and y are kind of a two dimensional sequence number, some use case may only use x and leave y alone
+		X INTEGER,
+		Y INTEGER,
+		-- we use the fixed dimension meters here
+		Z_in_M REAL,
+		-- we use the fixed dimension seconds here
+		T_in_SEC REAL,
+
+    DS_ID TECH_ID	NOT NULL,
+		SPOT_ID TECH_ID	NOT NULL,
+
+    PRIMARY KEY (ID),
+    CONSTRAINT FK_CHANNEL_STACKS_1 FOREIGN KEY (SPOT_ID) REFERENCES SPOTS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT FK_CHANNEL_STACKS_2 FOREIGN KEY (DS_ID) REFERENCES DATA_SETS (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX CHANNEL_STACKS_DS_IDX ON CHANNEL_STACKS(DS_ID);
+CREATE INDEX CHANNEL_STACKS_SPOT_IDX ON CHANNEL_STACKS(SPOT_ID);
+CREATE INDEX CHANNEL_STACKS_DIM_IDX ON CHANNEL_STACKS(X, Y, Z_in_M, T_in_SEC);
+
+CREATE TABLE IMAGES (
+    ID BIGSERIAL  NOT NULL,
+   
+    PATH	FILE_PATH NOT NULL,
+    PAGE	INTEGER,
+    COLOR	COLOR_COMPONENT,
+    
+    PRIMARY KEY (ID)
+);
+
+CREATE TABLE ACQUIRED_IMAGES (
+    ID BIGSERIAL  NOT NULL,
+   
+		IMG_ID   TECH_ID NOT NULL,
+		THUMBNAIL_ID  TECH_ID,
+
+    CHANNEL_STACK_ID  TECH_ID NOT NULL,
+    CHANNEL_ID  TECH_ID NOT NULL,
+
+    PRIMARY KEY (ID),
+    CONSTRAINT FK_IMAGES_1 FOREIGN KEY (CHANNEL_STACK_ID) REFERENCES CHANNEL_STACKS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT FK_IMAGES_2 FOREIGN KEY (CHANNEL_ID) REFERENCES CHANNELS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT FK_IMAGES_3 FOREIGN KEY (IMG_ID) REFERENCES IMAGES (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT FK_IMAGES_4 FOREIGN KEY (THUMBNAIL_ID) REFERENCES IMAGES (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX IMAGES_CHANNEL_STACK_IDX ON ACQUIRED_IMAGES(CHANNEL_STACK_ID);
+CREATE INDEX IMAGES_CHANNEL_IDX ON ACQUIRED_IMAGES(CHANNEL_ID);
+CREATE INDEX IMAGES_IMG_IDX ON ACQUIRED_IMAGES(IMG_ID);
+CREATE INDEX IMAGES_THUMBNAIL_IDX ON ACQUIRED_IMAGES(THUMBNAIL_ID);
+
+CREATE TABLE EVENTS (
+  LAST_SEEN_DELETION_EVENT_ID TECH_ID NOT NULL
+);
+
+/* ---------------------------------------------------------------------- */
+/* FEATURE VECTORS                                                        */
+/* ---------------------------------------------------------------------- */ 
+
+CREATE TABLE FEATURE_DEFS (
+    ID BIGSERIAL  NOT NULL,
+    
+    CODE NAME NOT NULL,
+    LABEL NAME NOT NULL,
+    DESCRIPTION DESCRIPTION,
+		-- If true then there are some vocabulary terms connected with this feature definition
+		-- and the value matrix references FEATURE_VOCABULARY_TERMS.SEQUENCE_NUMBER
+    HAS_VOCABULARY_VALUES BOOLEAN_CHAR NOT NULL,
+    
+    DS_ID  TECH_ID NOT NULL,
+    
+    PRIMARY KEY (ID),
+    CONSTRAINT FK_FEATURE_DEFS_1 FOREIGN KEY (DS_ID) REFERENCES DATA_SETS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT FEATURE_DEFS_UK_1 UNIQUE(CODE, DS_ID)
+);
+
+CREATE INDEX FEATURE_DEFS_DS_IDX ON FEATURE_DEFS(DS_ID);
+
+CREATE TABLE FEATURE_VOCABULARY_TERMS (
+	ID BIGSERIAL  NOT NULL,
+
+  CODE NAME NOT NULL,
+	-- If FEATURE_DEFS referenced with FD_ID has HAS_VOCABULARY_VALUES == true 
+  -- then the sequence number is referenced in the FEATURE_VALUES.VALUES matrix
+	SEQUENCE_NUMBER INTEGER NOT NULL,
+	FD_ID  TECH_ID NOT NULL,
+
+	PRIMARY KEY (ID),
+	CONSTRAINT FK_FEATURE_VOCABULARY_TERMS_1 FOREIGN KEY (FD_ID) REFERENCES FEATURE_DEFS (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX FEATURE_VOCABULARY_TERMS_FD_IDX ON FEATURE_VOCABULARY_TERMS(FD_ID);
+
+CREATE TABLE FEATURE_VALUES (
+    ID BIGSERIAL  NOT NULL,
+		
+		-- we use the fixed dimension meters here
+		Z_in_M REAL,
+		-- we use the fixed dimension seconds here
+		T_in_SEC REAL,
+		-- serialized 2D matrix with values for each spot
+		VALUES BYTEA NOT NULL,
+		
+		FD_ID  TECH_ID NOT NULL,
+		
+		PRIMARY KEY (ID),
+		CONSTRAINT FK_FEATURE_VALUES_1 FOREIGN KEY (FD_ID) REFERENCES FEATURE_DEFS (ID) ON DELETE CASCADE ON UPDATE CASCADE
+    -- This constaint does not make any sense. Leave it out for now.
+    -- CONSTRAINT FEATURE_VALUES_UK_1 UNIQUE(Z_in_M, T_in_SEC)
+);
+
+CREATE INDEX FEATURE_VALUES_FD_IDX ON FEATURE_VALUES(FD_ID);
+CREATE INDEX FEATURE_VALUES_Z_AND_T_IDX ON FEATURE_VALUES(Z_in_M, T_in_SEC);
+
+
+/* ---------------------------------------------------------------------- */
+/* FUNCTIONS AND TRIGGERS                                                 */
+/* ---------------------------------------------------------------------- */ 
+
+CREATE OR REPLACE FUNCTION DELETE_UNUSED_IMAGES() RETURNS trigger AS $$
+BEGIN
+   delete from images where id = OLD.img_id or id = OLD.thumbnail_id;
+   RETURN NEW;
+END;
+$$ LANGUAGE 'plpgsql';
+
+CREATE TRIGGER UNUSED_IMAGES AFTER DELETE ON ACQUIRED_IMAGES
+    FOR EACH ROW EXECUTE PROCEDURE DELETE_UNUSED_IMAGES();
\ No newline at end of file
diff --git a/screening/source/sql/postgresql/008/upload-screening-metadata.sh b/screening/source/sql/postgresql/008/upload-screening-metadata.sh
new file mode 100755
index 00000000000..1a8a1969f1e
--- /dev/null
+++ b/screening/source/sql/postgresql/008/upload-screening-metadata.sh
@@ -0,0 +1,2 @@
+DB=$1
+psql -U postgres -d openbis_$DB -f data.sql
diff --git a/screening/source/sql/postgresql/migration/migration-007-008.sql b/screening/source/sql/postgresql/migration/migration-007-008.sql
new file mode 100644
index 00000000000..82b39b18b06
--- /dev/null
+++ b/screening/source/sql/postgresql/migration/migration-007-008.sql
@@ -0,0 +1,18 @@
+-- Migration from 007 to 008
+
+ALTER TABLE feature_defs ADD COLUMN HAS_VOCABULARY_VALUES BOOLEAN_CHAR NOT NULL;
+
+CREATE TABLE FEATURE_VOCABULARY_TERMS (
+	ID BIGSERIAL  NOT NULL,
+
+  CODE NAME NOT NULL,
+	-- If FEATURE_DEFS referenced with FD_ID has HAS_VOCABULARY_VALUES == true 
+  -- then the sequence number is referenced in the FEATURE_VALUES.VALUES matrix
+	SEQUENCE_NUMBER INTEGER NOT NULL,
+	FD_ID  TECH_ID NOT NULL,
+
+	PRIMARY KEY (ID),
+	CONSTRAINT FK_FEATURE_VOCABULARY_TERMS_1 FOREIGN KEY (FD_ID) REFERENCES FEATURE_DEFS (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX FEATURE_VOCABULARY_TERMS_FD_IDX ON FEATURE_VOCABULARY_TERMS(FD_ID);
-- 
GitLab