% table2admb(catchfile,surveyfiles,firstyear,lastyear, maxage, num_cohorts, outfilename) % % Conversion of ICES table data to the .dat format used by AD Model builder. % % Input: % % catchfile - string with path to ascii file containing catch data % surveyfiles - either string with path to ascii file containing % survey data, or cell array of such strings. % firstyear - first year of observation/estimation (e.g 1995) % lastyear - last year of observation (e.g 2001) % maxage - maximum age for cohort (after maxage is reached no more % computation is done for the cohort in question). % num_cohorts - number of cohorts to follow (e.g. 4) % % NOTE: first year, last year, num_cohorts and maxage should have % consistent values. We always include the cohort born in % firstyear, and at the moment always have cohorts born in % consecutive years. % % Output: % % outfilename - (Optional) string with filename of output file without suffix, % that is, outfilename = '../cod' will create ../cod.dat and % ../cod.pin. .pin-file generation may be omitted in the future. % If outfilename is not defined, then output is written to the % screen. % % % Written by Lennart Frimannslund, April 2010 % Test input variables if (in_maxage > in_lastyear-firstyear), fprintf(1,'Maxage = %i, but lastyear-firstyear = %i. Setting maxage to %i.\n',maxage,in_lastyear-firstyear,in_lastyear-firstyear); maxage = lastyear-firstyear; else, maxage = in_maxage; end; if (in_lastyear > firstyear + (num_cohorts-1) + maxage), fprintf(1,'Lastyear = %i, but firstyear = %i, num_cohorts = %i and maxage = %i.\nSetting lastyear to %i.\n', ... in_lastyear,firstyear,num_cohorts,maxage,firstyear + (num_cohorts-1) + maxage); lastyear = firstyear + (num_cohorts-1) + maxage; else, lastyear = in_lastyear; end; if (num_cohorts > lastyear-firstyear), fprintf(2,'Error: firstyear = %i, lastyear = %i, maxage = %i and num_cohorts = %i not consistent.\nExiting...\n', ... firstyear, lastyear, maxage,num_cohorts); end; % Read input files C = load(catchfile,'-ascii'); if (iscell(surveyfiles)), S = cell(length(surveyfiles),1); for (i=1:length(surveyfiles)), S{i} = load(surveyfiles{i},'-ascii'); end; else, S = load(surveyfiles,'-ascii'); end; % Create output file, or OVERWRITE it if it exists. if (exist('outfilename','var') == 0), fid = 1; else, try, fid = fopen([outfilename '.dat'],'w'); catch, disp(lasterr); fid = 1; end; end; % Print data to file, item by item % Headeer and number of cohorts fprintf(fid,'#Generated .dat-file with catch and acoustic/trawl data from ICES report.\n#\n#Number of cohorts\n'); fprintf(fid,'%i\n',num_cohorts); % Birth years fprintf(fid,'\n# Cohort birth years (Startaar)\n'); for (i=1:num_cohorts), fprintf(fid,'%4i ',firstyear+i-1); end; % Last year for each cohorst fprintf(fid,'\n\n# Last year of observation (Sluttaar)\n'); for (i=1:num_cohorts), fprintf(fid,'%4i ',min(firstyear+i-1+maxage,lastyear)); end; % Catch. Note that catch in the table is in thousands, but here we divide the volume by 1000 so that it is in millions fprintf(fid,'\n\n# Catch data IN MILLIONS. One cohort per row, one year per column.\n# First column is the birth year. Last column is not used by .tpl file\n# but must be present.\n'); youngest_age_caught = C(1,2); max_age_in_catch_table = max(C(1,:)); % Populate catch matrix, one cohort at a time for (i=1:num_cohorts), [this_birthyear_index] = find(C(:,1) == firstyear + i - 1); % Set catch to zero for age groups too young to be in the table for (j=0:youngest_age_caught - 1), fprintf(fid,'0.0 '); end; % Go diagonally in the catch table until either the end is reached or maxage is reached for (j=youngest_age_caught:min(max_age_in_catch_table,min(maxage,lastyear-firstyear - i + 1))), % Make sure we don't exceed size of table desired_row = this_birthyear_index+j-youngest_age_caught; if (desired_row <= size(C,1)), % Divide by 1000 since catch table data is in thousands, not millions fprintf(fid,'%f ',C(desired_row,j-youngest_age_caught+2)/1000); end; end; fprintf(fid,'\n'); end; % Surveys fprintf(fid,'\n# Survey section. Surveys included:\n#\n'); if (iscell(S)), for (i=1:length(S)), fprintf(fid,'# %s\n',surveyfiles{i}); end; fprintf(fid,'#\n\n# Number of surveys per year\n%i\n',length(S)); else, fprintf(fid,'# %s\n',surveyfiles); fprintf(fid,'#\n\n# Number of surveys per year\n1\n'); end; % For the surveys we don't yet know how many survey indices there will be, % even though the data format requires this number to come first. % We first write the survey data to a matrix of maximum possible size, and then to file if (iscell(S)), num_surveys = length(S); else, num_surveys = 1; end; I = zeros(num_cohorts*num_surveys*(lastyear-firstyear+1),4); num_survey_indices = 0; for (k=1:num_surveys), if (num_surveys == 1), this_survey = S; else, this_survey = S{k}; end; % Populate one cohort at a time for (i=1:num_cohorts), % Find the row in column 2 which corresponds to the current cohort this_cohort_row_in_col_2 = find( (this_survey(:,1) - this_survey(1,2) - (firstyear + (i-1)) ) == 0); last_legal_row = find(this_survey(:,1) == lastyear); last_legal_col = find(this_survey(1,:) == lastyear-firstyear - i + 1); max_j = min(last_legal_row-this_cohort_row_in_col_2,last_legal_col-2); % go diagonally, same as for catch. for (j=0:max_j), try, candidate_volume = this_survey(this_cohort_row_in_col_2+j,2+j); if (isfinite(candidate_volume)), % If we encounter an observation of zero (which will make the % objective function infinity), don't include it if (candidate_volume > 0.0), num_survey_indices = num_survey_indices + 1; I(num_survey_indices,:) = [ i this_survey(1,2+j) k candidate_volume]; end; end; % For debug purposes, report if our indices are out of bounds. Shouldn't happen anymore. catch, fprintf(1,'Survey table index exceeded. (i,j) = (%i,%i), but size S{%i} = (%i,%i).\n', ... this_cohort_row_in_col_2+j,this_cohort_row_in_col_2+1+j,k,size(this_survey,1),size(this_survey,2)); end; end; end; end; % Print everything to file fprintf(fid,'\n# Number of survey indices\n'); fprintf(fid,'%i \n',num_survey_indices); fprintf(fid,'\n# Survey table: (Cohort, age, survey_number, observed_volume)\n'); for (i=1:num_survey_indices), fprintf(fid,'%3i %3i %3i %f\n',I(i,1),I(i,2),I(i,3),I(i,4)); end; fprintf(fid,'# End of file'); % Done, close file if applicable if (fid ~= 1), fclose(fid); end; %return; % Make .pin-file too if (exist('outfilename','var') == 0), fid = 1; else, try, fid = fopen([outfilename '.pin'],'w'); catch, disp(lasterr); fid = 1; end; end; fprintf(fid,'\n\n# Autogenerated .pin file\n# N0\n'); for (i=1:num_cohorts), fprintf(fid,'%f ',1e3); end; fprintf(fid,'\n\n# q\n'); for (i=1:num_surveys), fprintf(fid,'%4.2f ',0.4); end; fprintf(fid,'\n\n# log(s)\n0.1\n\n# M\n0.2\n'); if (fid ~= 1), fclose(fid); end;