ncarray/0000775000175000017500000000000013017312002011770 5ustar abarthabarthncarray/INDEX0000664000175000017500000000101013017311667012572 0ustar abarthabarthncarray >> ncArray ncArray ncArray ncCatArray nccoord nctimeunits ncreadtime cached_decompress @ncArray/coord @ncArray/ncArray @ncArray/subsasgn @ncArray/subsref ncBaseArray @BaseArray/BaseArray @BaseArray/end @BaseArray/full @BaseArray/isnumeric @BaseArray/max @BaseArray/mean @BaseArray/min @BaseArray/moment @BaseArray/numel @BaseArray/prod @BaseArray/reduce @BaseArray/size @BaseArray/std @BaseArray/sum @BaseArray/sumsq @BaseArray/var Test script test_ncarrayncarray/DESCRIPTION0000664000175000017500000000064213017311667013520 0ustar abarthabarthName: ncarray Version: 1.0.4 Date: 2016-11-29 Author: Alexander Barth Maintainer: Alexander Barth Title: ncarray Description: Access a single or a collection of NetCDF files as a multi-dimensional array Categories: IO Depends: octave (>= 3.4.0), netcdf (>= 1.0.2), statistics (>= 1.0.6) License: GPLv2+ Url: http://modb.oce.ulg.ac.be/mediawiki/index.php/ncArray ncarray/COPYING0000664000175000017500000004307713017311667013056 0ustar abarthabarth GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ncarray/NEWS0000664000175000017500000000304713017311667012513 0ustar abarthabarthSummary of important user-visible changes for ncarray 1.0.4: ------------------------------------------------------------ ** Avoid obsolete strmatch function ** Use a tolerance in test script (bug #49391) Summary of important user-visible changes for ncarray 1.0.3: ------------------------------------------------------------ ** use lower-case package name as upper-case latters in the package name can cause troubles wiht pkg. ** new functions nctimeunits and ncreadtime for handling time variables. Summary of important user-visible changes for ncArray 1.0.2: ------------------------------------------------------------ ** new function: nansum, nanvar, nanstd: mean, variance, standard deviation ignoring NaNs ** ncarray nows depends on package netcdf (instead of octcdf) ** Add missing dependency to statistics ** Avoid obsolete isequalwithequalnans functions Summary of important user-visible changes for ncArray 1.0.1: ------------------------------------------------------------ ** new function: nanmean: mean ignoring NaNs ** new function: load: load data based on a coordinate range or a single value (only 1-dimensional coordinates are currently supported) ** CACHED_DECOMPRESS_DIR defaults now to a directory inside the system temporary directory (/tmp on Linux) ** add support for xz compression ** optimization of assignement operator ** add units and standard_name in nccoord Summary of important user-visible changes for ncArray 1.0.0: ------------------------------------------------------------ ** Initial release ncarray/inst/0000775000175000017500000000000013017311667012765 5ustar abarthabarthncarray/inst/ncCatArray.m0000664000175000017500000001326413017311667015200 0ustar abarthabarth% Create an array that represent a concatenated NetCDF variables. % % C = ncCatArray(dim,filenames,varname) % C = ncCatArray(dim,pattern,varname) % C = ncCatArray(dim,filenamefun,varname,range) % C = ncCatArray(...,'property',value) % % create a concatenated array from variables (varname) in a list of % netcdf files along dimension dim.Individual elements can be accessed by % subscribs, e.g. C(2,3) and the corrsponding subset of the appropriate file is loaded % % This list of netcdf files can be specified as a cell array (filenames), % shell wildcard pattern (e.g. file_*.nc) or a function handle % filenamefun. In this later case, this i-th filename is % filenamefun(range(i)). % % Properties: % 'SameAttributes': false or true (default). If SameAttribute is true, % the variables' NetCDF attribute of all files are assumed to be the same. % Only the attributes of the first file is loaded in this case. % % Example: % % data = ncCatArray(3,{'file-20120708.nc','file-20120709.nc'},'SST') % % data = ncCatArray(3,'file-*.nc','SST') % % data = ncCatArray(3,@(t) ['file-' datestr(t,'yyyymmdd') '.nc'],'SST',... % datenum(2012,07,08):datenum(2012,07,09)); % % Note: in Octave the glob function is used to determine files matching the % shell wildcard pattern, while in Matlab rdir is used. The function rdir % is available from Matlab exchange under BSD license % (http://www.mathworks.com/matlabcentral/fileexchange/19550). % % see also cache_decompress, ncArray % Web: http://modb.oce.ulg.ac.be/mediawiki/index.php/ncArray % Author: Alexander Barth (barth.alexander@gmail.com) % function data = ncCatArray(dim,pattern,varname,varargin) catdimname = '_cat_dim'; SameAttributes = true; range = []; [reg, prop] = parseparams(varargin); if length(reg) == 1 range = reg{1}; end for i = 1:2:length(prop) if strcmp(prop{i},'SameAttributes') SameAttributes = prop{i+1}; elseif strcmp(prop{i},'range') range = prop{i+1}; else error(['unknown property value ' prop{i}]); end end % file names if iscell(pattern) filenames = pattern; elseif ischar(pattern) try filenames = glob(pattern); catch try d = rdir(pattern); filenames = {d(:).name}; catch error(['The function rdir or glob (octave) is not available. '... 'rdir can be installed from '... 'http://www.mathworks.com/matlabcentral/fileexchange/19550']); end end if isempty(filenames) error('ncArray:nomatch','no file found matching %s',pattern); end elseif isa(pattern, 'function_handle') filenames = cell(1,length(range)); for i=1:length(range) filenames{i} = pattern(range(i)); end end if isempty(range) range = 1:length(filenames); end % get all file information finfos = cell(length(filenames),1); if SameAttributes % assume all files have the same ncinfo as the first one tmp = ncinfo(cached_decompress(filenames{1})); for i=1:length(filenames) finfos{i} = tmp; end % octave allows the following, but not matlab %finfos(:) = tmp; else for i=1:length(filenames) finfos{i} = ncinfo(cached_decompress(filenames{i})); end end var = arr(dim,filenames,varname,finfos); [dims,coord] = nccoord(finfos{1},varname); % add new dimension to coord if arrays are contatenated over a new dimension % and if coord information already exist if (dim > length(dims)) && ~isempty(coord) % concatenate is new dimension dims{dim} = catdimname; coord(dim).dims = {catdimname}; coord(dim).val = range; coord(dim).name = catdimname; end for i=1:length(coord) %test if value is already defined, if yes do nothing if isfield(coord(i),'val') if ~isempty(coord(i).val) continue end end % the number of the dimension might be different % find in coord(i).dims the index of the dimension called dims{dim} % for example we concatenate over time, then two situations can arrise % the coordinate variable lon can dependent on time (dimc is not empty) % or it does not depdent on time (dimc is empty) dimc = find(strcmp(coord(i).dims,dims{dim})); if isempty(dimc) vinfo = varinfo(finfos{1},coord(i).name); coord(i).val = ncBaseArray(filenames{1},coord(i).name,'vinfo',vinfo); else % coordinates do also depend on the dimension over which we concatenate %i,coord(i).name,dimc,dims{dim} coord(i).val = arr(dimc,filenames,coord(i).name,finfos); end %if dim > length(coord(i).dims) % coord(i).dims{dim} = catdimname; %end end data = ncArray(var,dims,coord); end function CA = arr(dim,filenames,varname,finfos) arrays = cell(1,length(filenames)); for i=1:length(filenames) vinfo = varinfo(finfos{i},varname); arrays{i} = ncBaseArray(filenames{i},varname,'vinfo',vinfo); end CA = CatArray(dim,arrays); end function vinfo = varinfo(fileinfo,varname) index = find(strcmp({fileinfo.Variables(:).Name},varname)); vinfo = fileinfo.Variables(index); end % Copyright (C) 2012,2013 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/ncarray_example_file.m0000664000175000017500000000362213017311667017317 0ustar abarthabarth% create an example NetCDF file with the name filename and given data function ncarray_example_file(filename,data) dtype = 'double'; sz = size(data); % Variables nccreate(filename,'lon','Format','classic','Datatype',dtype,... 'Dimensions',{'x',sz(1), 'y',sz(2)}); ncwriteatt(filename,'lon','long_name','Longitude') ncwriteatt(filename,'lon','units','degrees_east') nccreate(filename,'lat','Datatype',dtype,'Dimensions',{'x',sz(1), 'y',sz(2)}); ncwriteatt(filename,'lat','long_name','Latitude') ncwriteatt(filename,'lat','units','degrees_north') nccreate(filename,'time','Datatype',dtype,'Dimensions',{'time',1}); ncwriteatt(filename,'time','long_name','Time') ncwriteatt(filename,'time','units','days since 1858-11-17 00:00:00 GMT') nccreate(filename,'SST','Datatype',dtype,'Dimensions',... {'x',sz(1), 'y',sz(2), 'time',1}); ncwriteatt(filename,'SST','missing_value',single(9999)) ncwriteatt(filename,'SST','_FillValue',single(9999)) ncwriteatt(filename,'SST','units','degC') ncwriteatt(filename,'SST','long_name','Sea Surface Temperature') ncwriteatt(filename,'SST','coordinates','lat lon') ncwrite(filename,'SST',data); % Copyright (C) 2012,2013,2015 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/ncarray_example.m0000664000175000017500000000201413017311667016312 0ustar abarthabarth % Tutorial for using ncArray % It is advised to run this script in an empty directory. % It will delete and overwrite files named file1.nc, file2.nc and file3.nc. % size of the example data (2x3) n = 3; m = 2; % create 3 files (file1.nc, file2.nc,...) with a 2x3 variable called SST data = zeros(n,m); disp('create example files: file1.nc, file2.nc, file3.nc') for i = 1:3 data(:) = i; files{i} = sprintf('file%d.nc',i); delete(files{i}); ncarray_example_file(files{i},data); end % Using ncArray SST = ncArray('file1.nc','SST'); disp('load the entire file') data = SST(:,:,:); disp('get the attribute units') units = SST.units; disp('load a particular value'); data = SST(3,2,1); % Using ncCatArray disp('concatenate the files over the 3rd dimension (here time)') SST = ncCatArray(3,{'file1.nc','file2.nc','file3.nc'},'SST'); % or just % SST = ncCatArray(3,'file*.nc','SST'); disp('load all 3 files'); data = SST(:,:,:); disp('load a particular value (1,2,1) of the 3rd file'); data = SST(1,2,3); ncarray/inst/nccoord.m0000664000175000017500000000676713017311667014612 0ustar abarthabarth% Coordinates of a NetCDF variable. % % [dims,coord] = nccoord(filename,varname) % get coordinates of the variable varname in the % netcdf file called filename. The netcdf is assumed to % follow the CF convention. % dims is a cell-array of the dimensions of varname % coord is an array of structures with the field 'name' % for the variable name, 'dims' with a cell-array of the % netcdf dimensions, the units and NetCDF-CF standard name. % % coord is an empty structure if no coordinate information have been % found. % TODO: use a predictable order for coord: % lon, lat, depth, time, ensemble,... % Author: Alexander Barth (barth.alexander@gmail.com) function [dims,coord] = nccoord(filename,varname) if ischar(filename) finfo = ncinfo(filename); else finfo = filename; end % get variable info index = find(strcmp({finfo.Variables(:).Name},varname)); vinfo = finfo.Variables(index); % determine coordinates % using CF convention dims = {vinfo.Dimensions(:).Name}; % create empty coord array with the fields name and dims coord = struct('name',{},'dims',{},'standard_name',{},... 'units',{},'positive',{}); % check the coordinate attribute if ~isempty(vinfo.Attributes) index = find(strcmp('coordinates',{vinfo.Attributes(:).Name})); if ~isempty(index) tmp = strsplit(vinfo.Attributes(index).Value,' '); % order should not be siginficant for i=length(tmp):-1:1 coord = addcoord(coord,tmp{i},finfo); end end end % check for coordinate dimensions for i=1:length(dims) % check if variable with the same name than the dimension exist index = find(strcmp(dims{i},{finfo.Variables(:).Name}),1); if ~isempty(index) coord = addcoord(coord,dims{i},finfo); end end end function coord = addcoord(coord,name,finfo) % check if coordinate is aleady in the list if isempty(find(strcmp(name,{coord(:).name}),1)) % check if name is variable index = find(strcmp(name,{finfo.Variables(:).Name})); if ~isempty(index) vinfo = finfo.Variables(index); c.name = name; d = vinfo.Dimensions; c.dims = {d(:).Name}; c.standard_name = []; c.units = []; c.positive = []; % get standard_name attribute if present i = find(strcmp('standard_name',{vinfo.Attributes(:).Name})); if ~isempty(i) c.standard_name = vinfo.Attributes(i).Value; end % get units attribute if present i = find(strcmp('units',{vinfo.Attributes(:).Name})); if ~isempty(i) c.units = vinfo.Attributes(i).Value; end % get positive attribute if present i = find(strcmp('positive',{vinfo.Attributes(:).Name})); if ~isempty(i) c.positive = vinfo.Attributes(i).Value; end coord(end+1) = c; end end end % Copyright (C) 2012, 2013, 2015 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/cached_decompress.m0000664000175000017500000000760413017311667016605 0ustar abarthabarth% Decompress a file using a cache. % % [fname,success] = cached_decompress(filename) % % Input: % filename: name of the file which is possibly compressed % % Output: % fname: the filename of the uncompressed file % % Global variables: % CACHED_DECOMPRESS_DIR (default is the result of tempname) % cache directory of decompressed files % CACHED_DECOMPRESS_LOG_FID (default 1): file id for log message % CACHED_DECOMPRESS_MAX_SIZE (default 1e10): maximum size of cache in bytes. function fname = cached_decompress(url) global CACHED_DECOMPRESS_DIR global CACHED_DECOMPRESS_LOG_FID global CACHED_DECOMPRESS_MAX_SIZE if startswith(url,'http:') || ... ~(endswith(url,'.gz') || endswith(url,'.bz2') || endswith(url,'.xz')) % opendap url or not compressed file fname = url; return end cache_dir = CACHED_DECOMPRESS_DIR; if isempty(cache_dir) cache_dir = tempname; CACHED_DECOMPRESS_DIR = cache_dir; mkdir(cache_dir); fprintf('creating directory %s for temporary files.\n',cache_dir); end %if exist(cache_dir,'dir') ~= 7 % error(['cache directory for compressed files does not exist. '... % 'Please create the directory %s or change le value of the '... % 'global variable CACHED_DECOMPRESS_DIR'],cache_dir); %end % where to print logs? default to screen fid = CACHED_DECOMPRESS_LOG_FID; if (isempty(fid)) fid = 1; end % form filename for cache fname = url; fname = strrep(fname,'/','_SLASH_'); fname = strrep(fname,'*','_STAR_'); fname = strrep(fname,'\','_BSLASH_'); fname = strrep(fname,':','_COLON_'); fname = fullfile(cache_dir,fname); % test if in cache if exist(fname,'file') ~= 2 if endswith(url,'.gz') cmd = 'gunzip --stdout -'; elseif endswith(url,'.bz2') cmd = 'bunzip2 --stdout -'; elseif endswith(url,'.xz') cmd = 'unxz --stdout -'; else cmd = 'cat'; end if startswith(url,'ftp://') syscmd('curl --silent "%s" | %s > "%s"',url,cmd,fname); else syscmd('%s < "%s" > "%s"',cmd,url,fname); end else % fprintf(fid,'retrieve from cache %s\n',url); end % check cache size d=dir(cache_dir); cashe_size = sum([d.bytes]); max_cache_size = CACHED_DECOMPRESS_MAX_SIZE; if isempty(max_cache_size) max_cache_size = 1e10; end if (cashe_size > max_cache_size) % look for oldest files fdate = zeros(1,length(d)); for i=1:length(d); fdate(i) = datenum(d(i).date); end [fdate,index] = sort(fdate,'descend'); d=d(index); cum_size = cumsum([d(:).bytes]); todelete = find(cum_size > max_cache_size); for i=todelete if (d(i).isdir == 0) fprintf(fid,'clean cashe: delete %s\n', d(i).name); delete(fullfile(cache_dir,d(i).name)); end end end end function t = startswith(s,ext) if length(ext) <= length(s) t = strcmp(s(1:length(ext)),ext); else t = 0; end end function t = endswith(s,ext) if length(ext) <= length(s) t = strcmp(s(end-length(ext)+1:end),ext); else t = 0; end end function syscmd(varargin) cmd = sprintf(varargin{:}); %disp(cmd) status = 0; [status, output] = system(cmd); disp(output); if status ~= 0 error(['command "' cmd '" failed: ' output]); end end % Copyright (C) 2012-2013, 2015 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/private/0000775000175000017500000000000013017311667014437 5ustar abarthabarthncarray/inst/private/strsplit.m0000664000175000017500000000221713017311667016503 0ustar abarthabarth% parts = strsplit(name,sep); % % A simple strsplit implementation. % % Once a strsplit becomes widespread in octave and Matlab, % this file can be deleted. % % This file is preferred over octave's strsplit, because it is compatible % with the Matlab interpreter. function parts = strsplit(name,sep); ind = find(name == sep); parts = cell(length(ind)+1,1); ind = [0 ind length(name)+1]; for i=1:length(parts) parts{i} = name(ind(i)+1:ind(i+1)-1); end % Copyright (C) 2013 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/private/assertAlmostEqual.m0000664000175000017500000000073013017311667020266 0ustar abarthabarth% this function is necessary because of the limitation of matlab function assertAlmostEqual(observed,expected) % tolerance for testing tol = 1e-10; % for compatibility with matlab which does not have % assert (OBSERVED, EXPECTED, TOL) assert(max(abs(observed(:) - expected(:))) < tol) % for octave prior to 3.8.0 if isempty(which('isequaln')) isequaln = @(x,y) isequalwithequalnans(x,y); end % check also NaNS assert(isequal(isnan(observed),isnan(expected))) end ncarray/inst/@BaseArray/0000775000175000017500000000000013017311667014736 5ustar abarthabarthncarray/inst/@BaseArray/nanvar.m0000664000175000017500000000273313017311667016406 0ustar abarthabarth% Compute the variance (ignoring NaNs). % V = var (X, OPT, DIM) % Compute the variance along dimension DIM. % If OPT is equal to 1, then the variance is bias-corrected. function s = nanvar(self,opt,varargin) if nargin == 1 opt = 0; elseif isempty(opt) opt = 0; end nm = nanmean(self,varargin{:}); [s,n] = reduce(self,@funred, ... @(x) funelem(x,nm),varargin{:}); if isempty(s) s = 0; else total = s{1}; count = s{2}; if opt == 0 s = total./(count-1); else s = total./count; end end end function x = funelem(x,nm) % make sure x is not an ncArray x = full(x); mask = isnan(x) | isnan(nm); diff = zeros(size(x)); diff(mask) = x(mask) - nm(mask); x = {diff.^2, ~mask}; end function s = funred(x,y) s = {x{1} + y{1}, x{2} + y{2}} ; end % Copyright (C) 2013 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/reduce.m0000664000175000017500000000251413017311667016365 0ustar abarthabarth% Reduce array using callback fundtions. % [S,N] = reduce(SELF,FUNRED,FUNELEM,DIM) % Reduce array using the function FUNRED applied to all elements % after the function FUNELEM was applied along dimension DIM. function [s,n] = reduce(self,funred,funelem,dim) sz = size(self); if nargin == 3 dim = find(sz ~= 1,1); if isempty(dim) dim = 1; end end idx.type = '()'; nd = length(sz); idx.subs = cell(1,nd); for i=1:nd idx.subs{i} = ':'; end n = size(self,dim); if n == 0 s = []; else idx.subs{dim} = 1; s = funelem(subsref(self,idx)); for i=2:n idx.subs{dim} = i; s = funred(s,funelem(subsref(self,idx))); end end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/nanstd.m0000664000175000017500000000177013017311667016410 0ustar abarthabarth% Compute the standard deviation (ignoring NaNs). % S = nanstd (X, OPT, DIM) % Compute the standard deviation along dimension DIM. NaNs are treated as absent % values. % If OPT is equal to 1, then the standard deviation is bias-corrected. function s = nanstd(self,varargin) s = sqrt(nanvar(self,varargin{:})); % Copyright (C) 2013 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/nansum.m0000664000175000017500000000264413017311667016423 0ustar abarthabarth% Compute the sum (ignoring NaNs). % [s,count] = sum (X, DIM) % Compute the sum along dimension DIM. % The variable s is the sum and count the number of values summed. function [total,count] = nansum(self,varargin) % s will be a cell element containing % {the sum, the count of elements different from NaN} % this is necessary to avoid 2 calls to reduce [s,n] = reduce(self,... @(x,y) funred(x,y),... @(x) funelem(x),... varargin{:}); if isempty(s) s = 0; else total = s{1}; count = s{2}; end end function x = funelem(x) % make sure x is not an ncArray x = full(x); m = isnan(x); x(m) = 0; x = {x,~m}; end function s = funred(x,y) s = {x{1} + y{1}, x{2} + y{2}} ; end % Copyright (C) 2013 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/end.m0000664000175000017500000000142613017311667015665 0ustar abarthabarth% Return last index along a dimension. function e = end(self,k,n) e = size(self,k); % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/min.m0000664000175000017500000000164013017311667015700 0ustar abarthabarth% Compute the minimum. % S = min (X, [], DIM) % Compute the minimum along dimension DIM. function s = min(self,B,varargin) assert(isempty(B)) funred = @min; funelem = @(x) x; s = reduce(self,funred,funelem,varargin{:}); % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/std.m0000664000175000017500000000147513017311667015715 0ustar abarthabarth% Compute the standard deviation. % S = std (X, OPT, DIM) function s = std(self,varargin) s = sqrt(var(self,varargin{:})); % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/sumsq.m0000664000175000017500000000166213017311667016271 0ustar abarthabarth% Compute the sum squared. % S = sumsq (X, DIM) % Compute the sum squared along dimension DIM. function s = sumsq(self,varargin) funred = @plus; funelem = @(x) x.^2; s = reduce(self,funred,funelem,varargin{:}); if isempty(s) s = 1; end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/prod.m0000664000175000017500000000166613017311667016071 0ustar abarthabarth% Compute the product. % P = prod (X, DIM) % Compute the product of all elements along dimension DIM. function s = prod(self,varargin) funred = @times; funelem = @(x) x; s = reduce(self,funred,funelem,varargin{:}); if isempty(s) s = 1; end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/numel.m0000664000175000017500000000012313017311667016230 0ustar abarthabarth% Number of elements. % n = numel(A) function n = numel(self) n = prod(self.sz); ncarray/inst/@BaseArray/moment.m0000664000175000017500000000202513017311667016412 0ustar abarthabarth% Compute the central moment. % M = moment (X, ORDER, DIM) % compute the central moment of the given order along dimension DIM. function s = moment(self,order,varargin) m = mean(self,varargin{:}); funred = @plus; funelem = @(x) (x-m).^order; [s,n] = reduce(self,funred,funelem,varargin{:}); if isempty(s) s = NaN; else s = s/n; end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/BaseArray.m0000664000175000017500000000207013017311667016764 0ustar abarthabarth% Create a BaseArray. % BA = BaseArray(SZ) % Create a BaseArray of size SZ. BaseArray is an abstract class. % Derived classes should implement the methods subsref and subsasgn. % BaseArray implements several reduction methods such as sum, prod and mean. % SZ should have least two elements. % function retval = BaseArray(sz) self.sz = sz; retval = class(self,'BaseArray'); % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/mean.m0000664000175000017500000000166313017311667016042 0ustar abarthabarth% Compute the mean. % s = mean (X, DIM) % Compute the mean along dimension DIM. function s = mean(self,varargin) funred = @plus; funelem = @(x) x; [s,n] = reduce(self,funred,funelem,varargin{:}); if isempty(s) s = 0; else s = s/n; end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/length.m0000664000175000017500000000161613017311667016401 0ustar abarthabarth% len = length(A) % Return the "length" of the object A. For matrix objects, the % length is the number of rows or columns, whichever is greater. function len = length(self) len = max(size(self)); % Copyright (C) 2013 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/nanmean.m0000664000175000017500000000267213017311667016540 0ustar abarthabarth% Compute the mean (ignoring NaNs). % s = mean (X, DIM) % Compute the mean along dimension DIM. function [s,total,count] = nanmean(self,varargin) % s will be a cell element containing % {the sum, the count of elements different from NaN} % this is necessary to avoid 2 calls to reduce [s,n] = reduce(self,... @(x,y) funred(x,y),... @(x) funelem(x),... varargin{:}); if isempty(s) s = 0; else total = s{1}; count = s{2}; s = NaN*zeros(size(total)); nonz = count ~= 0; s(nonz) = total(nonz) ./ count(nonz); end end function x = funelem(x) % make sure x is not an ncArray x = full(x); m = isnan(x); x(m) = 0; x = {x,~m}; end function s = funred(x,y) s = {x{1} + y{1}, x{2} + y{2}} ; end % Copyright (C) 2013 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/size.m0000664000175000017500000000163313017311667016071 0ustar abarthabarth% Size of array. % sz = size(self,dim) function sz = size(self,dim) sz = self.sz; if length(sz) == 1 sz = [sz 1]; end if nargin == 2 if dim > length(sz) sz = 1; else sz = sz(dim); end end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/isnumeric.m0000664000175000017500000000143713017311667017117 0ustar abarthabarth% Test if array is numeric. % isn = isnumeric(self) function isn = isnumeric(self) isn = true; % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/var.m0000664000175000017500000000221713017311667015706 0ustar abarthabarth% Compute the variance. % V = var (X, OPT, DIM) % Compute the variance along dimension DIM. % If OPT is equal to 1, then the variance is bias-corrected. function s = var(self,opt,varargin) if nargin == 1 opt = 0; elseif isempty(opt) opt = 0; end m = mean(self,varargin{:}); funred = @plus; funelem = @(x) (x-m).^2; [s,n] = reduce(self,funred,funelem,varargin{:}); if isempty(s) s = 0; else if opt == 0 s = s/(n-1); else s = s/n; end end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/max.m0000664000175000017500000000164013017311667015702 0ustar abarthabarth% Compute the maximum. % S = max (X, [], DIM) % Compute the maximum along dimension DIM. function s = max(self,B,varargin) assert(isempty(B)) funred = @max; funelem = @(x) x; s = reduce(self,funred,funelem,varargin{:}); % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/sum.m0000664000175000017500000000163313017311667015723 0ustar abarthabarth% Compute the sum. % S = sum (X, DIM) % Compute the sum along dimension DIM. function s = sum(self,varargin) funred = @plus; funelem = @(x) x; s = reduce(self,funred,funelem,varargin{:}); if isempty(s) s = 0; end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@BaseArray/full.m0000664000175000017500000000153113017311667016056 0ustar abarthabarth% Make full (dense) array. function F = full(self); n = length(self.sz); idx.type = '()'; for i=1:n idx.subs{i} = ':'; end F = subsref(self,idx); % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/ncreadtime.m0000664000175000017500000000061013017311667015253 0ustar abarthabarth% Read a time variable as serial day number. % % t = ncreadtime(filename,varname) % % Read a time variable called varname from the file called filename as serial % day number (days since 31 December 1 BC, as datenum). function t = ncreadtime(filename,varname) t = double(ncread(filename,varname)); units = ncreadatt(filename,varname,'units'); [t0,f] = nctimeunits(units); t = f*t + t0; ncarray/inst/@CatArray/0000775000175000017500000000000013017311667014573 5ustar abarthabarthncarray/inst/@CatArray/display.m0000664000175000017500000000140713017311667016420 0ustar abarthabarthfunction display(self) for i=1:self.na display(self.arrays{i}) end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@CatArray/subsref.m0000664000175000017500000000465313017311667016432 0ustar abarthabarthfunction B = subsref(self,idx) % handle case with a single subscript % for example CA(234) if strcmp(idx.type,'()') && length(idx.subs) == 1 % indices of elements in B ind = idx.subs{1}; if strcmp(ind,':') ind = [1:numel(self)]'; end % output array B = zeros(size(ind)); B(:) = NaN; if self.overlap % transform linear index ind to subscript subs subs = cell(1,self.nd); [subs{:}] = ind2sub(size(self),ind); % make a nice array length(ind) by self.nd subs = cell2mat(subs); % get every element idxe.type = '()'; idxe.subs = cell(1,self.nd); for i=1:length(ind) idxe.subs = mat2cell(subs(i,:),1,ones(1,self.nd)); B(i) = subsref_canonical(self,idxe); end else % assume all arrays does not overlap for j=1:self.na sel = self.bounds(j) < ind & ind <= self.bounds(j+1); B(sel) = self.arrays{j}(ind(sel) - self.bounds(j)); end end elseif strcmp(idx.type,'.') % load attributes from first array B = subsref(self.arrays{1},idx); else B = subsref_canonical(self,idx); end end % for this function we assume that idx.subs has the same dimension than % the array function B = subsref_canonical(self,idx) [idx_global,idx_local,sz] = idx_global_local_(self,idx); B = zeros(sz); B(:) = NaN; for j=1:self.na % get subset from j-th array subset = subsref(self.arrays{j},idx_local{j}); % set subset in global array B % this is slow, why? %B = subsasgn(B,idx_global{j},subset); % however this quite fast idxa = idx_global{j}.subs; B(idxa{:}) = subset; end end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@CatArray/CatArray.m0000664000175000017500000000477413017311667016473 0ustar abarthabarth% C = CatArray(dim,{array1,array2,...}) % % Create a concatenated array from a cell-list of arrays. Individual % elements can be accessed by subscribs, e.g.: % C(2,3) function retval = CatArray(dim,arrays) self.dim = dim; self.arrays = arrays; self.na = length(arrays); % number of dimensions self.nd = length(size(arrays{1})); if dim > self.nd self.nd = dim; end self.size = ones(self.na,self.nd); self.start = ones(self.na,self.nd); % get size of all arrays for i=1:self.na tmp = size(arrays{i}); self.size(i,1:length(tmp)) = tmp; end % check if dimensions are consistent ncd = 1:self.nd ~= dim; for i=2:self.na if ~all(self.size(i,ncd) == self.size(1,ncd)) error('Array number %d has inconsistent dimension',i); end end % start index of each sub-array for i=2:self.na self.start(i,:) = self.start(i-1,:); self.start(i,dim) = self.start(i,dim) + self.size(i-1,dim); end self.end = self.start + self.size - 1; self.sz = self.size(1,:); self.sz(dim) = sum(self.size(:,dim)); self.overlap = false; self.bounds = [0; cumsum(prod(self.size,2))]; retval = class(self,'CatArray',BaseArray(self.sz)); % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@CatArray/subsasgn.m0000664000175000017500000000173313017311667016602 0ustar abarthabarthfunction self = subsasgn(self,idx,x) [idx_global,idx_local,sz] = idx_global_local_(self,idx); for j=1:self.na % get subset from global array x subset = subsref(x,idx_global{j}); % set subset in j-th array subsasgn(self.arrays{j},idx_local{j},subset); end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@CatArray/idx_global_local_.m0000664000175000017500000000404713017311667020373 0ustar abarthabarth% private method function [idx_global,idx_local,sz] = idx_global_local_(self,idx) assert(strcmp(idx.type,'()')) n = length(size(self)); % number of indices must be equal to dimension assert(length(idx.subs) == n) lb = ones(1,n); % lower bound ub = ones(1,n); % upper bound sz = ones(1,n); % size % transform all colons to index range for i=1:n if strcmp(idx.subs{i},':') idx.subs{i} = 1:self.sz(i); end lb(i) = min(idx.subs{i}); ub(i) = max(idx.subs{i}); sz(i) = length(idx.subs{i}); end %sz = ub-lb+1; idx_local = cell(1,self.na); idx_global = cell(1,self.na); % loop over all arrays for j=1:self.na idx_local{j} = idx; idx_global{j} = idx; % loop over all dimensions for i=1:n % rebase subscribt at self.start(j,i) tmp = idx.subs{i} - self.start(j,i) + 1; % only indeces within bounds of the j-th array sel = 1 <= tmp & tmp <= self.size(j,i); % index for getting the data from the local j-th array idx_local{j}.subs{i} = tmp(sel); % index for setting the data in the global B array %idx_global{j}.subs{i} = idx.subs{i}(sel) - lb(i)+1; if sum(sel) == 0 idx_global{j}.subs{i} = []; else idx_global{j}.subs{i} = (1:sum(sel)) + find(sel,1,'first') - 1; end end end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@ncBaseArray/0000775000175000017500000000000013017311667015257 5ustar abarthabarthncarray/inst/@ncBaseArray/display.m0000664000175000017500000000143313017311667017103 0ustar abarthabarthfunction display(self) disp([self.varname ' from ' self.filename]); %self.vinfo %self.dims % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@ncBaseArray/subsref.m0000664000175000017500000000502513017311667017110 0ustar abarthabarthfunction x = subsref(self,idx) assert(length(idx) == 1) if strcmp(idx.type,'()') % load data if strcmp(idx.type,'()') && length(idx.subs) == 1 ... && length(idx.subs) < self.nd % reference like A([2 3 1 5]) if self.tooBigToLoad % number of elements in x ind = idx.subs{1}; % transform index to subscript subs = cell(1,self.nd); [subs{:}] = ind2sub(size(self),ind); % make a nice array length(ind) by self.nd subs = cell2mat(subs); % output array x = zeros(size(ind)); x(:) = NaN; % get every element % can be quite slow idxe.type = '()'; idxe.subs = cell(1,self.nd); for i=1:length(ind) idxe.subs = mat2cell(subs(i,:),1,ones(1,self.nd)); x(i) = subsref(self,idxe); end else % load full array tmp = full(self); x = subsref(tmp,idx); end else [start, count, stride] = ncsub(self,idx); if any(count == 0) x = zeros(count); else x = ncread(cached_decompress(self.filename),self.varname,... start,count,stride); end end elseif strcmp(idx.type,'.') % load attribute name = idx.subs; % strmatch is obsolete % index = strmatch(name,{self.vinfo.Attributes(:).Name}); index = find(strcmp(name,{self.vinfo.Attributes(:).Name})); if isempty(index) error('variable %s has no attribute called %s',self.varname,name); else x = self.vinfo.Attributes(index).Value; end else error('not supported'); end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@ncBaseArray/ncBaseArray.m0000664000175000017500000000526613017311667017640 0ustar abarthabarth% V = ncBaseArray(filename,varname) % V = ncBaseArray(filename,varname,'property',value,...) % create a ncBaseArray that can be accessed as a normal matlab array. % Ths object is a helper object. Users should normally call ncArray. % % For read access filename can be compressed if it has the extensions % ".gz", ".bz2" or ".xz". It use the function cache_decompress to cache to % decompressed files. % % Data is loaded by ncread and saved by ncwrite. Values equal to _FillValue % are thus replaced by NaN and the scaling (add_offset and % scale_factor) is applied during loading and saving. % % Properties: % 'tooBigToLoad': if tooBigToLoad is set to true, then only the minimum % data will be loaded. However this can be quite slow. % 'vinfo': result from ncinfo can be specified if it is already known. % % Example: % % Loading the variable (assuming V is 3 dimensional): % % x = V(1,1,1); % load element 1,1,1 % x = V(:,:,:); % load the complete array % x = V(); x = full(V) % loads also the complete array % % Saving data in the netcdf file: % V(1,1,1) = x; % save x in element 1,1,1 % V(:,:,:) = x; % % Attributes % units = V.units; % get attribute called "units" % V.units = 'degree C'; % set attributes; % % Note: use the '.()' notation if the attribute has a leading underscore % (due to a limitation in the matlab parser): % % V.('_someStrangeAttribute') = 123; % % see also cache_decompress function retval = ncBaseArray(filename,varname,varargin) self.tooBigToLoad = false; self.vinfo = []; prop = varargin; for i=1:2:length(prop) if strcmp(prop{i},'tooBigToLoad') self.tooBigToLoad = prop{i+1}; elseif strcmp(prop{i},'vinfo') self.vinfo = prop{i+1}; end end self.filename = filename; self.varname = varname; if isempty(self.vinfo) self.vinfo = ncinfo(cached_decompress(filename),varname); end self.sz = self.vinfo.Size; self.dims = self.vinfo.Dimensions; self.nd = length(self.dims); % number of netcdf dimensions retval = class(self,'ncBaseArray',BaseArray(self.sz)); end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@ncBaseArray/subsasgn.m0000664000175000017500000000162313017311667017264 0ustar abarthabarthfunction self = subsasgn(self,idxs,x) %idx idx = idxs(1); assert(strcmp(idx.type,'()')) [start, count, stride] = ncsub(self,idx); if all(count ~= 0) ncwrite(self.filename,self.varname,x,start,stride); end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@ncBaseArray/ncsub.m0000664000175000017500000000450213017311667016550 0ustar abarthabarthfunction [start, count, stride] = ncsub(self,idx) assert(strcmp(idx.type,'()')) % number of dimension (including singleton dimensions) %n = length(size(self)); n = self.nd; % number of subscripts ns = length(idx.subs); if ns == 0 % load all start = ones(1,n); count = self.sz; stride = ones(1,n); else start = ones(1,ns); count = ones(1,ns); stride = ones(1,ns); % sz is the size padded by 1 if more indices are given than n sz = ones(1,ns); sz(1:length(self.sz)) = self.sz; for i=1:ns if isempty(idx.subs{i}) count(i) = 0; elseif strcmp(idx.subs{i},':') count(i) = sz(i); else tmp = idx.subs{i}; if length(tmp) == 1 start(i) = tmp; else % check if indexes are at regular intervals test = tmp(1):tmp(2)-tmp(1):tmp(end); if size(tmp,2) == 1 % tmp is a row vector, make test also a row vector test = test'; end if all(tmp == test) start(i) = tmp(1); stride(i) = tmp(2)-tmp(1); count(i) = (tmp(end)-tmp(1))/stride(i) +1; else error('indeces not at regular intervals'); end end end end assert(all(count(n+1:end) == 1 | count(n+1:end) == 0)) assert(all(start(n+1:end) == 1)) if ~any(count == 0) count = count(1:n); start = start(1:n); stride = stride(1:n); end end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/test_ncarray.m0000664000175000017500000002153513017311667015647 0ustar abarthabarth% Test ncBaseArray, ncCatArray and ncArray. function test_ncarray() varname = 'SST'; tmpdir = tempname; mkdir(tmpdir); tmpfname = tempname(tmpdir); refdata = {}; for i = 1:3 files{i} = fullfile(tmpdir,sprintf('file%d.nc',i)); refdata{i} = randn(220,144); ncarray_example_file(files{i},refdata{i}); end filename = files{1}; % test ncread/ncwrite copyfile(files{1},tmpfname); SST_ref = ncread(files{1},'SST'); ncwrite(tmpfname,'SST',zeros(size(SST_ref))); test = ncread(tmpfname,'SST'); assert(all(test(:) == 0)) ncwrite(tmpfname,'SST',SST_ref); test = ncread(tmpfname,'SST'); assertAlmostEqual(test,SST_ref) %%% test ncBaseArray % reading copyfile(files{2},tmpfname); SST = ncBaseArray(tmpfname,varname); test = SST(:,:,:); SST_ref = ncread(tmpfname,varname); assertAlmostEqual(test,SST_ref) assert(isempty(SST(:,:,:,[]))); assertAlmostEqual(SST_ref, SST(:,:,:,1)) ind = floor(numel(SST_ref) * rand(100,1))+1; assertAlmostEqual(SST(ind),SST_ref(ind)) % writing r = round(randn(size(SST))); SST(:,:,:) = r; SST_ref = ncread(tmpfname,varname); assertAlmostEqual(r,SST_ref); SST(:,:,:) = 3 * r; SST_ref = ncread(tmpfname,varname); assertAlmostEqual(3 * r,SST_ref); %%% test ncArray % reading copyfile(files{2},tmpfname); SST = ncArray(tmpfname,varname); test = SST(:,:,:); SST_ref = ncread(tmpfname,varname); assertAlmostEqual(test,SST_ref) assert(isempty(SST(:,:,:,[]))); assertAlmostEqual(SST_ref, SST(:,:,:,1)) ind = floor(numel(SST_ref) * rand(100,1))+1; assertAlmostEqual(SST(ind),SST_ref(ind)) assertAlmostEqual(SST_ref(1,:,:), SST(1,:,:)) % sum nanmeanSST = nanmean(SST); nanmeanSSTref = nanmean(SST_ref); assertAlmostEqual(nanmeanSST, nanmeanSSTref) %momentSST = moment(SST,2,1); %momentSSTref = moment(SST_ref,2,1); %assertAlmostEqual(momentSST, momentSSTref) sumSST = sum(SST,1); sumSSTref = sum(SST_ref,1); assertAlmostEqual(sumSST, sumSSTref) sumSST = sum(SST,2); sumSSTref = sum(SST_ref,2); assertAlmostEqual(sumSST, sumSSTref) sumSST = sum(SST,3); sumSSTref = sum(SST_ref,3); assertAlmostEqual(sumSST, sumSSTref) sumSST = sum(SST); sumSSTref = sum(SST_ref); assertAlmostEqual(sumSST, sumSSTref) prodSST = prod(SST); prodSSTref = prod(SST_ref); assertAlmostEqual(prodSST, prodSSTref) % only for octave %sumsqSST = sumsq(SST); %sumsqSSTref = sumsq(SST_ref); % does not work in matlab %assertAlmostEqual(sumsqSST, sumsqSSTref) meanSST = mean(SST); meanSSTref = mean(SST_ref); assertAlmostEqual(meanSST, meanSSTref) varSST = var(SST); varSSTref = var(SST_ref); assertAlmostEqual(varSST, varSSTref) varSST = var(SST,1); varSSTref = var(SST_ref,1); assertAlmostEqual(varSST, varSSTref) varSST = var(SST,[],2); varSSTref = var(SST_ref,[],2); assertAlmostEqual(varSST, varSSTref) stdSST = std(SST); stdSSTref = std(SST_ref); assertAlmostEqual(stdSST, stdSSTref) stdSST = std(SST,1); stdSSTref = std(SST_ref,1); assertAlmostEqual(stdSST, stdSSTref) stdSST = std(SST,[],2); stdSSTref = std(SST_ref,[],2); assertAlmostEqual(stdSST, stdSSTref) maxSST = max(SST,[],2); maxSSTref = max(SST_ref,[],2); assertAlmostEqual(maxSST, maxSSTref) minSST = min(SST,[],2); minSSTref = min(SST_ref,[],2); assertAlmostEqual(minSST, minSSTref) % writing r = round(randn(size(SST))); SST(:,:,:) = r; SST_ref = ncread(tmpfname,varname); assertAlmostEqual(r,SST_ref); SST(:,:,:) = 3 * r; SST_ref = ncread(tmpfname,varname); assertAlmostEqual(3 * r,SST_ref); %%% CatArray % reading CA = CatArray(3,{... ncArray(filename,varname),... ncArray(files{2},varname),... ncArray(files{3},varname)... }); assert(isequaln(size(CA),[220 144 3])) SST_ref = ncread(filename,'SST'); tmp2 = CA(:,:,1); assertAlmostEqual(SST_ref,tmp2) SST_test = CA(:,:,2); SST_ref = ncread(files{2},'SST'); assertAlmostEqual(SST_test,SST_ref) CA2 = CatArray(4,{... ncArray(files{1},varname),... ncArray(files{2},varname),... ncArray(files{3},varname)... }); SST_test = CA2(:,:,:,2); assertAlmostEqual(SST_test,SST_ref) CA2 = ncCatArray(3,{... files{1},... files{2},... files{3}},... varname); SST_test = CA2(:,:,2); assertAlmostEqual(SST_test,SST_ref) CA2 = ncCatArray(3,fullfile(tmpdir,'file*nc'),varname); SST_test = CA2(:,:,2); assertAlmostEqual(SST_test,SST_ref) CA2 = ncCatArray(3,... @(i) fullfile(tmpdir,sprintf('file%d.nc',i)),... varname,... 1:3); SST_test = CA2(:,:,2); assertAlmostEqual(SST_test,SST_ref) SST_ref = cat(3,... ncread(files{1},'SST'),... ncread(files{2},'SST'),... ncread(files{3},'SST')); assertAlmostEqual(CA2(:,:,:),SST_ref) assertAlmostEqual(CA2(:,:,1),SST_ref(:,:,1)) assertAlmostEqual(CA2(3:5:50,3:5:100,1),SST_ref(3:5:50,3:5:100,1)) assertAlmostEqual(CA2(3:5:50,3:5:100,2),SST_ref(3:5:50,3:5:100,2)) assertAlmostEqual(CA2(3:5:50,3:5:100,3),SST_ref(3:5:50,3:5:100,3)) assertAlmostEqual(CA2(3:5:50,3:5:100,end),SST_ref(3:5:50,3:5:100,end)) assertAlmostEqual(CA2(50,100,1:3),SST_ref(50,100,1:3)) assertAlmostEqual(CA2(3:5:50,3:5:100,1:2:3),SST_ref(3:5:50,3:5:100,1:2:3)) assertAlmostEqual(CA2(3:5:50,3:5:end,1:2:3),SST_ref(3:5:50,3:5:end,1:2:3)) assertAlmostEqual(CA2(3:5:50,3:5:end,:),SST_ref(3:5:50,3:5:end,:)) % access with linear index assertAlmostEqual(CA2(:),SST_ref(:)) assertAlmostEqual(CA2(1:10),SST_ref(1:10)) assertAlmostEqual(CA2(1:2:10),SST_ref(1:2:10)) ind = floor(numel(SST_ref) * rand(100,1))+1; assertAlmostEqual(CA2(ind),SST_ref(ind)) meanSST = mean(CA2,3); meanSSTref = mean(SST_ref,3); %assertAlmostEqual(meanSST, meanSSTref) diff = meanSST -meanSSTref; assert(max(diff(:)) < 1e-6) % writing for i=1:3 list{i} = tempname; copyfile(filename,list{i}); end CA2 = ncCatArray(3,list,varname); r = round(randn(size(CA2))); CA2(:,:,:) = r; check = ncread(list{2},varname); assertAlmostEqual(check,r(:,:,2)) r2 = round(randn(size(CA2))); r(3:5:50,3:5:end,:) = r2(3:5:50,3:5:end,:); CA2(3:5:50,3:5:end,:) = r2(3:5:50,3:5:end,:); assertAlmostEqual(CA2(:,:,:),r) r(end-1,3:5:end,1:2:3) = 2*r2(end-1,3:5:end,1:2:3); CA2(end-1,3:5:end,1:2:3) = 2*r2(end-1,3:5:end,1:2:3); assertAlmostEqual(CA2(:,:,:),r) if 1 % test ncArray (constructor: ncArray(var,dims,coord) SST = ncBaseArray(filename,varname); SST_ref = ncread(filename,varname); lon_ref = ncread(filename,'lon'); coord(1).val = ncBaseArray(filename,'lon'); coord(1).dims = {'x','y'}; coord(2).val = ncBaseArray(filename,'lat'); coord(2).dims = {'x','y'}; coord(3).val = ncBaseArray(filename,'time'); coord(3).dims = {'time'}; data = ncArray(SST,{'x','y','time'},coord); [x,y,t] = data(:,:,:).coord; assertAlmostEqual(data(:,:,:),SST_ref) assertAlmostEqual(x,lon_ref) assertAlmostEqual(data(),SST_ref) [x,y,t] = data().coord; assertAlmostEqual(x,lon_ref) assertAlmostEqual(data(1:3:end,:,:),SST_ref(1:3:end,:,:)) [x,y,t] = data(1:3:end,:,:).coord; assertAlmostEqual(x,lon_ref(1:3:end,:)) % test ncArray (constructor: ncData(filename,varname) SST = ncArray(filename,varname); [x,y,t] = data(:,:,:).coord; assertAlmostEqual(data(:,:,:),SST_ref) assertAlmostEqual(x,lon_ref) assertAlmostEqual(data(),SST_ref) [x,y,t] = data().coord; assertAlmostEqual(x,lon_ref) assertAlmostEqual(data(1:3:end,:,:),SST_ref(1:3:end,:,:)) [x,y,t] = data(1:3:end,:,:).coord; assertAlmostEqual(x,lon_ref(1:3:end,:)) %assert(strcmp(SST.units,'degC')) assert(strcmp(SST.('units'),'degC')) end % read compressed data zname = [tmpfname '.gz']; system(['gzip --stdout ' tmpfname ' > ' zname]); %zname = [tmpfname '.xz']; %system(['xz --stdout ' tmpfname ' > ' zname]); SST = ncArray(zname,'SST'); SST_ref = ncread(tmpfname,'SST'); assertAlmostEqual(SST(),SST_ref) CA2 = ncCatArray(3,fullfile(tmpdir,'file*nc'),varname); SST_test = CA2(:,:,2); SST_ref = ncread(files{2},'SST'); assertAlmostEqual(SST_test,SST_ref) assert(strcmp(CA2.('units'),'degC')); test_ncarray_nan % clean-up d = dir(tmpdir); for i = 1:length(d) if ~strcmp(d(i).name,'.') && ~strcmp(d(i).name,'..') delete(fullfile(tmpdir,d(i).name)); end end rmdir(tmpdir); [t0,f] = nctimeunits('days since 1770-01-01 00:00:00'); assert(t0 == datenum(1770,01,01)); assert(f == 1); disp('All tests passed.') end % Copyright (C) 2012, 2015 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@ncArray/0000775000175000017500000000000013017311667014464 5ustar abarthabarthncarray/inst/@ncArray/load.m0000664000175000017500000000353313017311667015565 0ustar abarthabarth% [val,coord1,coord2,...] = load(self,'coord_name1',range1,'coord_name2',range2,...) % Load a subset of a variable based on range of coordiante variables. % The names of the coordinates (coord_name1, coord_name2,...) coorespond to the standard_name attribute. % Only 1-dimensional coordinates are currently supported. % Time units are converted to "datenum". % % % Example % [temp,lon,lat,depth,time] = load(self,'longitude',[0 10],'latitude',[0 10]) function varargout = load(self,varargin) c = coord(self); for i = 1:length(c) c(i).v = full(c(i).val); % per default take all data along a dimension c(i).index = ':'; % convert time units if ~isempty(strfind(c(i).units,'since')) [t0,f] = nctimeunits(c(i).units); c(i).v = f*double(c(i).v) + t0; end % change vertical axis to positive up if strcmp(c(i).positive,'down') c(i).v = -double(c(i).v); end c(i).sub = c(i).v; end % loop over all constraints for i = 1:2:length(varargin) name = varargin{i}; j = find(strcmp(name,{c.standard_name})); if isempty(j) warning(['no coordinate has the standard_name ' name ... '. Try to use variable names.']); j = find(strcmp(name,{c.name})); if isempty(j) error(['no coordinate has the name ' name '.']); end end range = varargin{i+1}; if numel(range) == 1 dist = abs(c(j).v - range); [mindist,i] = min(dist); %i %mindist %c(j).v(i) %datevec(c(j).v(i)) else i = find(range(1) < c(j).v & c(j).v < range(end)); i = min(i):max(i); end c(j).index = i; c(j).sub = c(j).v(i); end idx = substruct('()',{c.index}); %idx data = subsref (self,idx); varargout = {data,c.sub}; % i = 1; % mask = xr(1) <= x & x <= xr(2); % l = find(mask); % [ij{:}] = ind2sub(size(mask),l); % for j=1:len % mins(j) = min(ij{j}); % maxs(j) = max(ij{j}); ncarray/inst/@ncArray/display.m0000664000175000017500000000212213017311667016304 0ustar abarthabarthfunction display(self) sz = size(self); tmp = sprintf('%dx',sz); fprintf('Size: %s\n',tmp(1:end-1)) c = coord(self); fprintf('Coordinates:\n') for i = 1:length(c) tmp = sprintf('%dx',size(c(i).val)); stdname = c(i).standard_name; if isempty(stdname) stdname = ''; end fprintf(' Name: %15s; standard name: %25s; size %10s\n',... c(i).name,stdname,tmp(1:end-1)); end % Copyright (C) 2013 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@ncArray/subsref.m0000664000175000017500000000411213017311667016311 0ustar abarthabarth% Subscripted element selection operation. % out = subsref (A, idx) % Perform the subscripted element selection operation according to the subscript specified by idx. % A slice of the NetCDF variable can be load by using A(index1,index2,...) and attributes % can be loaded by A.attribute_name or A.('attribute_name') % If index selection is followed by struct selection 'coord', then the coordinates corresponding to the % slice are loaded: % For example, the coordinate of element A(4,3) are: % [lon,lat] = A(4,3).coord; function varargout = subsref(self,idx) if strcmp(idx(1).type,'()') % no subscripts mean that we load all () -> (:,:,...) if isempty(idx(1).subs) for i=1:self.nd idx(1).subs{i} = ':'; end end end % catch expressions like: % data(:,:,:).coord if length(idx) == 2 && strcmp(idx(2).type,'.') && strcmp(idx(2).subs,'coord') for i=1:length(self.coord) % get indeces of the dimensions of the i-th coordinate which are also % coordinate of the variable % replace dummy by ~ once older version have died [dummy,j] = intersect(self.dims,self.coord(i).dims); j = sort(j); idx_c.type = '()'; idx_c.subs = idx(1).subs(j); varargout{i} = subsref(self.coord(i).val,idx_c); end else % pass subsref to underlying ncBaseArray varargout{1} = subsref(self.var,idx); end % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@ncArray/coord.m0000664000175000017500000000150713017311667015753 0ustar abarthabarth% Get coordinate. % c = coord(A) % Get a array of structures with the coordinate of ncArray A. function c = coord(self) c = self.coord; % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@ncArray/ncArray.m0000664000175000017500000000507213017311667016245 0ustar abarthabarth% Create an array representing a NetCDF variable. % % V = ncArray(filename,varname) % V = ncArray(filename,varname,'property',value,...) % create a ncArray that can be accessed as a normal array. % % For read access filename can be compressed if it has the extensions % ".gz" or ".bz2". It use the function cache_decompress to cache to % decompressed files. % % Data is loaded by ncread and saved by ncwrite. Values equal to _FillValue % are thus replaced by NaN and the scaling (add_offset and % scale_factor) is applied during loading and saving. % % % Example: % % Loading the variable (assuming V is 3 dimensional): % % x = V(1,1,1); % load element 1,1,1 % x = V(:,:,:); % load the complete array % x = V(); x = full(V) % loads also the complete array % % Saving data in the netcdf file: % V(1,1,1) = x; % save x in element 1,1,1 % V(:,:,:) = x; % % Attributes % units = V.units; % get attribute called "units" % V.units = 'degree C'; % set attributes; % % Note: use the '.()' notation if the attribute has a leading underscore % (due to a limitation in the matlab parser): % % V.('_someStrangeAttribute') = 123; % % see also cache_decompress, ncCatArray % Web: http://modb.oce.ulg.ac.be/mediawiki/index.php/ncArray % hidded constructor signature: % data = ncArray(var,dims,coord); % is used to create data with coordinate values by ncCatArray function retval = ncArray(varargin) if ischar(varargin{1}) filename = varargin{1}; varname = varargin{2}; var = ncBaseArray(filename,varname); [dims,coord] = nccoord(cached_decompress(filename),varname); for i=1:length(coord) coord(i).val = ncBaseArray(filename,coord(i).name); end else var = varargin{1}; dims = varargin{2}; coord = varargin{3}; end self.var = var; self.dims = dims; self.nd = length(self.dims); self.coord = coord; retval = class(self,'ncArray',BaseArray(size(self.var))); % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@ncArray/subsasgn.m0000664000175000017500000000175213017311667016474 0ustar abarthabarth% Subscripted assignment. % subsasgn (A, idx, rhs) % Perform the subscripted assignment operation according to the subscript specified by idx. % A slice of the NetCDF variable can be saved by using A(index1,index2,...) = rhs; function self = subsasgn(self,idx,x) self = subsasgn(self.var,idx,x); % Copyright (C) 2012 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/@ncArray/dims.m0000664000175000017500000000147113017311667015601 0ustar abarthabarth% Get dimension names % c = dims(A) % Get cell-array of dimension names ncArray A. function c = dims(self) c = self.dims; % Copyright (C) 2013 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/test_ncarray_nan.m0000664000175000017500000000331213017311667016474 0ustar abarthabarth% Test ncBaseArray, ncCatArray and ncArray. function test_ncarray_nan() % for octave prior to 3.8.0 if isempty(which('isequaln')) isequaln = @(x,y) isequalwithequalnans(x,y); end varname = 'SST'; tmpdir = tempname; mkdir(tmpdir); tmpfname = tempname(tmpdir); dataref = randn(220,144,3); %dataref(rand(size(dataref)) > 0.7) = NaN; dataref(50:80,30:90,1:2) = NaN; for i = 1:3 files{i} = fullfile(tmpdir,sprintf('file%d.nc',i)); ncarray_example_file(files{i},dataref(:,:,i)); end data = ncCatArray(3,files,varname); reddata = nanmean(data,3); reddataref = nanmean(dataref,3); assertAlmostEqual(reddata, reddataref) reddata = nansum(data,3); reddataref = nansum(dataref,3); assertAlmostEqual(reddata, reddataref) reddata = nanvar(data,[],3); reddataref = nanvar(dataref,[],3); diff = reddata - reddataref; assert(max(diff(:)) < 1e-6) reddata = nanstd(data,[],3); reddataref = nanstd(dataref,[],3); diff = reddata - reddataref; assert(max(diff(:)) < 1e-6) % clean-up for i = 1:3 delete(files{i}); end rmdir(tmpdir); % Copyright (C) 2013 Alexander Barth % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; If not, see . ncarray/inst/nctimeunits.m0000664000175000017500000000403613017311667015510 0ustar abarthabarth% Parse netCDF time unit. % % [t0,f] = nctimeunits(u) % % Parse the netCDF time unit u and returns the time offset (days since 31 % December 1 BC, as datenum) and scaling factor f (in days). % See the netCDF CF convention for the structure of the time units. % http://cfconventions.org/Data/cf-conventions/cf-conventions-1.6/build/cf-conventions.html#time-coordinate % Also: http://www.unidata.ucar.edu/software/thredds/current/netcdf-java/CDM/CalendarDateTime.html function [t0,f] = nctimeunits(u) % years in days for udunits % http://cfconventions.org/Data/cf-conventions/cf-conventions-1.6/build/cf-conventions.html#time-coordinate year_in_days = 365.242198781; l = strfind(u,'since'); if length(l) ~= 1 error(['time units sould expect one "since": "' u '"']); end period = strtrim(lower(u(1:l-1))); reference_date = strtrim(u(l+6:end)); if strcmp(period,'millisec') || strcmp(period,'msec') f = 1/(24*60*60*1000); elseif strcmp(period,'second') || strcmp(period,'seconds') ... || strcmp(period,'s') || strcmp(period,'sec') f = 1/(24*60*60); elseif strcmp(period,'minute') || strcmp(period,'minutes') ... || strcmp(period,'min') f = 1/(24*60); elseif strcmp(period,'hour') || strcmp(period,'hours') ... || strcmp(period,'hr') f = 1/24; elseif strcmp(period,'day') || strcmp(period,'days') f = 1; elseif strcmp(period,'week') || strcmp(period,'weeks') f = 1/(24*60*60*7); elseif strcmp(period,'year') || strcmp(period,'years') ... strcmp(period,'yr') f = year_in_days; elseif strcmp(period,'month') || strcmp(period,'months') ... strcmp(period,'mon') f = year_in_days/12; else error(['unknown units "' period '"']); end if strcmp(reference_date,'1900-01-01 00:00:0.0') t0 = datenum(1900,1,1); else try t0 = datenum(reference_date,'yyyy-mm-dd HH:MM:SS'); catch try t0 = datenum(reference_date,'yyyy-mm-ddTHH:MM:SS'); catch try t0 = datenum(reference_date,'yyyy-mm-dd'); catch error(['date format is not recogized ' reference_date]) end end end end