1 dnl Copyright (C) 2013 The Meme Factory, Inc. http://www.meme.com/
3 dnl This file is part of Gombe-MI.
5 dnl Gombe-MI is free software; you can redistribute it and/or modify
6 dnl it under the terms of the GNU General Public License as published by
7 dnl the Free Software Foundation; either version 3 of the License, or
8 dnl (at your option) any later version.
10 dnl This program is distributed in the hope that it will be useful,
11 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
12 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 dnl GNU General Public License for more details.
15 dnl You should have received a copy of the GNU General Public License
16 dnl along with Gombe-MI. If not, see <http://www.gnu.org/licenses/>.
18 dnl Function to convert group composition from access table structure
19 dnl to new table structure.
21 dnl Karl O. Pinc <kop@meme.com>
24 include(`copyright.m4')
25 include(`constants.m4')
27 include(`macros.m4')dnl
29 dnl Reset our search path so we pick up the conversion schema.
30 define(`gmi_function_search_path', `prepared_data, gombemi, pg_temp')
33 CREATE OR REPLACE FUNCTION prepared_data.convert_access_gc(fromdate DATE
38 gmi_function_set_search_path
40 -- Copy access data group comp structures into new gombemi data structures.
42 -- GPL_notice(` --', `2013', `The Meme Factory, Inc. http://www.meme.com/')
44 -- Syntax: select convert_access_gc(fromdate, todate);
47 -- fromdate Date to start copy (inclusive)
48 -- todate Date to stop copy (inclusive)
51 -- One-off program. Once it works we won't run it again.
53 -- Copies a day a a time.
55 -- Stops as soon as a transaction fails.
60 this_gcstatus fieldfollows.gcstatus%TYPE;
63 this_sheetid sheets.sheetid%TYPE;
64 this_ffid fieldfollows.ffid%TYPE;
68 this_follow_5_minute RECORD;
69 this_follow_5_minute_group RECORD;
71 this_uncertain BOOLEAN;
74 these_chimpids VARCHAR(gmi_animid_len)[];
76 this_chimpid raw_groupmembers.chimpid%TYPE;
82 WHERE fromdate <= follow.follow_date
83 AND follow.follow_date <= todate
84 ORDER BY follow.follow_date, follow.follow_id
86 -- Find the follows.gcstatus of the follow.
87 SELECT crfp.group_blank
90 WHERE crfp.follow_date = this_follow.follow_date
91 AND crfp.focal_mom = this_follow.mother_id;
94 RAISE EXCEPTION integrity_constraint_violation USING
95 MESSAGE = 'Cannot lookup gcstatus (group_blank) for follow on cross_reference_for_program'
96 , DETAIL = 'Value (Follow_id) = ('
97 || this_follow.follow_id
98 || '): Value (date) = ('
99 || this_follow.follow_date
100 || '): Mother = (' || this_follow.mother_id
104 IF this_gcstatus IS NULL THEN
105 RAISE EXCEPTION integrity_constraint_violation USING
106 MESSAGE = 'gcstatus (group_blank) for follow on cross_reference_forprogram is wrong'
107 , DETAIL = 'Value (Follow_id) = ('
108 || this_follow.follow_id
109 || '): Value (date) = ('
110 || this_follow.follow_date
111 || '): Mother = (' || this_follow.mother_id
112 || '): group_blank is NULL';
116 FOR this_follow_5_minute
119 WHERE follow_5_minute.follow_id = this_follow.follow_id
120 ORDER BY follow_5_minute.interval_time DESC
124 -- tableid | Page_id | Interval_number | Interval_time | Mother_feeding | Food_part_initials | Food_name | Infant_feeding | Strange_chimp | Other_animals | Interval_id
125 -- 1 | 11/08/2010_GM_01 | 1 | 2010-11-08 09:00:00 | - | | | - | | | 11/08/2010_GM_01_01
127 -- Check for already converted.
128 IF this_follow_5_minute.done THEN
129 RAISE EXCEPTION 'Date %: Mom %: Interval_ID %: follow_5_minute row already converted'
130 , this_follow.follow_date
131 , this_follow.mother_id
132 , this_follow_5_minute.interval_id;
136 -- Technically, it's the page/collector that's unique. But
137 -- in the access data it's enough to have a unique page.
138 SELECT sheets.sheetid, sheets.ffid
139 INTO this_sheetid, this_ffid
141 JOIN followparts ON (followparts.followid = follows.followid)
142 JOIN followroles ON (followroles.role = followparts.role)
143 JOIN intervals ON (intervals.followid = follows.followid)
144 JOIN sheets ON (sheets.sheetid = intervals.sheetid)
145 WHERE follows.date = this_follow.follow_date
146 AND followparts.chimpid
147 = convert_animid(this_follow.mother_id,
148 this_follow.follow_date)
149 AND followroles.function = 'gmi_mom'
150 AND sheets.page = SPLIT_PART(this_follow_5_minute.page_id
154 GET DIAGNOSTICS rows_found = ROW_COUNT;
156 WHEN rows_found = 0 THEN
157 RAISE EXCEPTION 'Follow_id %: Interval_id %: Page_id %: Unable to find row on SHEETS for this follow for this page to match follow_5_minute row'
158 , this_follow.follow_id
159 , this_follow_5_minute.interval_id
160 , this_follow_5_minute.page_id;
162 WHEN rows_found > 1 THEN
163 RAISE EXCEPTION 'Follow_id %: Interval_id %: Page_id %: More than one SHEETS row found for this follow for this page to match follow_5_minute row'
164 , this_follow.follow_id
165 , this_follow_5_minute.interval_id
166 , this_follow_5_minute.page_id;
172 -- Intepret the other_animals column.
174 WHEN this_follow_5_minute.other_animals = 'Y' THEN
176 WHEN this_follow_5_minute.other_animals = '?' THEN
178 WHEN this_follow_5_minute.other_animals IS NULL THEN
179 this_baboons = FALSE;
181 RAISE EXCEPTION 'Follow_id %: Interval_id %: Page_id %: Other_animals %: Unknown value for other_animals for this follow_5_minute_group'
182 , this_follow.follow_id
183 , this_follow_5_minute.interval_id
184 , this_follow_5_minute.page_id
185 , this_follow_5_minute.other_animals;
189 -- Create the RAW_GROUPS row.
190 INSERT INTO raw_groups (time, baboons, sheetid)
191 VALUES (this_follow_5_minute.interval_time
195 -- Interpret the strange_chimp flag.
196 IF this_follow_5_minute.strange_chimp IS NOT NULL THEN
197 CASE this_follow_5_minute.strange_chimp
199 this_uncertain := FALSE;
201 this_uncertain := TRUE;
203 RAISE EXCEPTION 'Follow_id %: Interval_id %: Page_id %: Strange_chimp %: Unknown value for strange_chimp for this follow_5_minute'
204 , this_follow.follow_id
205 , this_follow_5_minute.interval_id
206 , this_follow_5_minute.page_id
207 , this_follow_5_minute.strange_chimp;
211 -- Insert raw_groupmembers row.
212 INSERT INTO raw_groupmembers (rgid
217 VALUES (CURRVAL('raw_groups_rgid_seq'::regclass)
219 , 'G' -- is this right?
224 -- Remember the chimpids in the group comp.
225 -- Don't worrry about MGE since she's never a mom or infant.
226 these_chimpids := ARRAY[]::VARCHAR(gmi_animid_len)[];
229 FOR this_follow_5_minute_group
231 FROM follow_5_minute_group
232 WHERE follow_5_minute_group.interval_id
233 = this_follow_5_minute.interval_id
234 ORDER BY follow_5_minute_group.chimp_id
237 -- Check for already converted.
238 IF this_follow_5_minute_group.done THEN
239 RAISE EXCEPTION 'Date %: Mom %: Interval_ID %: Chimp_id %: follow_5_minute_group row already converted'
240 , this_follow.follow_date
241 , this_follow.mother_id
242 , this_follow_5_minute.interval_id
243 , this_follow_5_minute_group.chimp_id;
247 -- follow_5_minute_left_group:
248 -- tableid | Interval_id | Position_number | Chimp_id | Present | Position_id
249 -- 1 | 11/03/2010_GA_01_01 | 1 | FD | Y | 11/03/2010_GA_01_01_01
251 -- follow_5_minute_right_group:
252 -- tableid | Interval_id | Position_number | Chimp_id | Present | Position_id
253 -- 1 | 01/01/1997_SA_01_02 | 16 | SW | Y | 01/01/1997_SA_01_02_16
255 -- Interpret the present flag.
256 CASE this_follow_5_minute_group.present
258 this_uncertain = FALSE;
260 this_uncertain = TRUE;
262 RAISE EXCEPTION 'Follow_id %: Interval_id %: Page_id %: Animid %: Present %: Unknown value for present for this follow_5_minute_group individual'
263 , this_follow.follow_id
264 , this_follow_5_minute.interval_id
265 , this_follow_5_minute.page_id
266 , this_follow_5_minute_group.animid
267 , this_follow_5_minute_group.present;
271 -- Remember the chimpid.
272 these_chimpids[i] := convert_animid(
273 this_follow_5_minute_group.chimp_id
274 , this_follow.follow_date);
276 -- Insert raw_groupmembers row.
277 INSERT INTO raw_groupmembers (rgid
282 VALUES (CURRVAL('raw_groups_rgid_seq'::regclass)
284 , 'G' -- is this right?
288 -- Note follow 5 minute group converted.
289 UPDATE follow_5_minute_group
291 WHERE tableid = this_follow_5_minute_group.tableid;
294 END LOOP; -- over follow_5_minute_group
296 -- Go through the members of the group comp and make sure
297 -- the data is correct.
299 FOREACH this_chimpid IN ARRAY these_chimpids LOOP
300 -- Ensure the mom is in the group comp.
301 PERFORM mom_in_gc(this_chimpid
302 , CURRVAL('raw_groups_rgid_seq'::regclass)::INT
303 , this_follow.follow_date);
304 -- Ensure that young infants are in the group comp.
305 PERFORM infants_in_gc(this_chimpid
306 , CURRVAL('raw_groups_rgid_seq'::regclass)::INT
307 , this_follow.follow_date);
308 -- Ensure all social partners are in the group comp.
309 PERFORM add_social_partners(
311 , CURRVAL('raw_groups_rgid_seq'::regclass)::INT);
314 -- Note follow 5 minute converted.
315 UPDATE follow_5_minute
317 WHERE tableid = this_follow_5_minute.tableid;
319 -- We got a group comp for the follow.
321 END LOOP; -- over follow_5_minute
324 IF this_gcstatus = 'N' THEN
325 RAISE EXCEPTION integrity_constraint_violation USING
326 MESSAGE = 'gcstatus (group_blank) for follow on cross_reference_forprogram is wrong'
327 , DETAIL = 'Value (Follow_id) = ('
328 || this_follow.follow_id
329 || '): Value (date) = ('
330 || this_follow.follow_date
331 || '): Mother = (' || this_follow.mother_id
332 || '): group_blank = (' || this_gcstatus
333 || '): Group compositions exist for this follow';
336 -- Give the follow a status.
338 SET gcstatus = this_gcstatus
339 WHERE ffid = this_ffid;
341 ELSE -- didn't find any group comp.
342 IF this_gcstatus != 'N' THEN
343 RAISE EXCEPTION integrity_constraint_violation USING
344 MESSAGE = 'gcstatus (group_blank) for follow on cross_reference_forprogram is wrong'
345 , DETAIL = 'Value (Follow_id) = ('
346 || this_follow.follow_id
347 || '): Value (date) = ('
348 || this_follow.follow_date
349 || '): Mother = (' || this_follow.mother_id
350 || '): group_blank = (' || this_gcstatus
351 || '): No group composition exists for this follow';
355 -- Keep track of how many follows we converted.
356 converted := converted + 1;
365 grant_func_priv(`prepared_data.convert_access_gc(DATE, DATE)')