System Administrator Added MATIN utilities for Matlab  about 10 years ago

Commit id: 8d78482ec70e7f9f4689f19ab11502cd11a887cb

deletions | additions      

         

_site  *.h5  *.fig  *.mat  /Data  temp.yml  *~           

hh = 'something.h5';  delete(hh);  nms = {'/Dataset1/aggregate','/Dataset1/spatial','/Dataset1/Workflow1/aggregate', ...  '/Dataset2/aggregate','/Dataset2/spatial','/Dataset2/Workflow1/aggregate','/Dataset2/Workflow2/spatial'};  for dd = 1 : numel(nms);  dset = nms{dd};  if ~exist( hh,'file');  fo = H5F.create(hh);  else  fo = H5F.open(hh,'H5F_ACC_RDWR','H5P_DEFAULT');  end    try  gid=H5G.create(fo,fileparts(dset),'H5P_DEFAULT','H5P_DEFAULT','H5P_DEFAULT');H5G.close(gid);  s.link = 'http://www.theinternet.com';  h5writeatt( hh, fileparts(dset), 'location',s.link );  catch  disp('group exists')  end  H5F.close(fo);  % h5create(hh,dset,[1 1]);  S = struct('Var1',rand(1),'Huh',rand(1),'Pressure',rand(1));  h5writecompound( hh, nms{dd}, S);    end           

function h5writeattcompound( fn, dset, attname, DATA )  % An improved version of the matlab function h5write. Natively, h5write lacks the  % ability to write structures to HDF5 files.  %  % INPUTS:  % fn - file name where the data is written to.  % dset - name of the dataset in the HDF5 that the data is being stored as  % DATA - allows structures are all h5write native datatypes to be written.  % if DATA is a structure then the information is written as a  % compound datatype. The size of each field should be the same.  if isstruct( DATA )  if exist( fn, 'file')  fo = H5F.open(fn,'H5F_ACC_RDWR','H5P_DEFAULT');  else  fo = H5F.create(fn);  end  fields = fieldnames(DATA);  sz = size( getfield( DATA, fields{1}));  tid = H5T.create('H5T_COMPOUND',numel(fields)*8);    ii = 1;  H5T.insert(tid,fields{ii},(ii-1)*8,'H5T_NATIVE_DOUBLE');  ii = 2;  strType = H5T.copy( 'H5T_C_S1' );  H5T.set_size(strType, numel(getfield( DATA, fields{ii})) );  % DATA = setfield( DATA, fields{ii}, getfield( DATA, fields{ii} ) );    H5T.insert(tid,fields{ii},(ii-1)*8,strType);    sid = H5S.create_simple( numel(sz), fliplr(sz), fliplr(sz) );  % dset = horzcat(dset, num2str(round(rand(1)*1e5)));  did = H5D.open( fo, dset);  aid = H5A.create( did, attname, tid, sid, H5P.create('H5P_ATTRIBUTE_CREATE'));  H5A.write( aid, tid, DATA );  H5A.close(aid)  H5S.close(sid)  H5D.close(did)    H5T.close(tid)  H5F.close(fo);  elseif ischar(DATA)    if exist( fn, 'file')  fo = H5F.open(fn,'H5F_ACC_RDWR','H5P_DEFAULT');  else  fo = H5F.create(fn);  end  SDIM = size(DATA,2);  filetype = H5T.copy ('H5T_FORTRAN_S1');  H5T.set_size (filetype, SDIM );  memtype = H5T.copy ('H5T_C_S1');  H5T.set_size (memtype, SDIM );    % Create dataspace. Setting maximum size to [] sets the maximum  % size to be the current size.  %  dims = size(DATA,1);  space = H5S.create_simple (1,fliplr( dims), []);    %  % Create the attribute and write the string data to it.  %    if strcmp( dset, '/');  attr = H5A.create (fo, attname, filetype, space, 'H5P_DEFAULT');  H5A.write (attr, memtype, DATA');    else  did = H5D.open( fo, dset );  attr = H5A.create (fo, attname, filetype, space, 'H5P_DEFAULT');  H5A.write (attr, memtype, DATA');  H5D.close (did);  end    %  % Close and release resources.  %  H5A.close (attr);    H5S.close (space);  H5T.close (filetype);  H5T.close (memtype);  H5F.close ( fo );      else  h5writeatt( fn,dset, attname, DATA);  end  end           

function h5writecompound( fn, dset, DATA )  % An improved version of the matlab function h5write. Natively, h5write lacks the  % ability to write structures to HDF5 files.  %  % INPUTS:  % fn - file name where the data is written to.  % dset - name of the dataset in the HDF5 that the data is being stored as  % DATA - allows structures are all h5write native datatypes to be written.  % if DATA is a structure then the information is written as a  % compound datatype. The size of each field should be the same.  flds = fieldnames( DATA );  for ii = 1 : numel( flds )  switch class( getfield( DATA, flds{ii} ) )  case 'int8'  hdftype{ii} = 'H5T_STD_I8LE';  hdfbyte(ii) = 1;  case 'int16'  hdftype{ii} = 'H5T_STD_I16LE';  hdfbyte(ii) = 2;  case 'int32'  hdftype{ii} = 'H5T_STD_I32LE';  hdfbyte(ii) = 4;  case 'uint8'  hdftype{ii} = 'H5T_STD_I8LE';  hdfbyte(ii) = 1;  case 'int16'  hdftype{ii} = 'H5T_STD_I16LE';  hdfbyte(ii) = 2;  case 'uint32'  hdftype{ii} = 'H5T_STD_U32LE';  hdfbyte(ii) = 4;  otherwise  hdftype{ii} = 'H5T_NATIVE_DOUBLE';  hdfbyte(ii) = 8;  end  end  cumhdfbyte = [0 , cumsum(hdfbyte)];  if isstruct( DATA )  if exist( fn, 'file')  fo = H5F.open(fn,'H5F_ACC_RDWR','H5P_DEFAULT');  else  fo = H5F.create(fn);  end  fields = fieldnames(DATA);  sz = size( getfield( DATA, fields{1}));  tid = H5T.create('H5T_COMPOUND', sum(hdfbyte));  for ii = 1 : numel( fields )    H5T.insert(tid,fields{ii},cumhdfbyte(ii),hdftype{ii});  if ~all( sz == size( getfield( DATA, fields{ii})))  error('The size of the elements in the data structure must be the same. The data was not written.')  H5T.close(tid)  H5F.close(fo);  end  end    sid = H5S.create_simple( numel(sz), fliplr(sz), fliplr(sz) );  % dset = horzcat(dset, num2str(round(rand(1)*1e5)));  dset  did = H5D.create( fo, dset, tid, sid, 'H5P_DEFAULT');  H5D.write( did, tid, 'H5S_ALL', 'H5S_ALL', 'H5P_DEFAULT', DATA );  H5D.close(did)  H5S.close(sid)    else  h5create( fn,dset, DATA, size(DATA) );  end  end           

function S = AddTags( S,varargin );  if isfield(S,'tags')  S.tags = cat(1,S.tags, varargin{:});  else  S.tags = varargin{:};  end           

function YAML = attachDictionary( YAML, workflow, dictionary )  % if workflow is empty then work on the raw  % dict goes in the top level of YAML  %  % if workflow has a value then look for the workflow name  persistent crap  numel(crap)  if numel( workflow ) == 0;  cc = {'output'};  israw = true;  else  cc = {'workflow', 'output'};  israw = false;  end  % run over the aggregate values  if israw  YAML.dict = dictionary;  else  for ii = 1 : numel( YAML.aggregate )  if isfield( YAML.aggregate{ii}, 'workflow' )  for jj = 1 : numel( YAML.aggregate{ii}.workflow )  wf = fliplr( strtok( fliplr( YAML.aggregate{ii}.workflow{jj}.native ), '/' ) );  if strcmp( wf, workflow )  YAML.aggregate{ii}.workflow{jj}.dict = dictionary;  end  end  end  end    for ii = 1 : numel( YAML.spatial)  if isfield( YAML.spatial{ii}, 'workflow' )  for jj = 1 : numel( YAML.spatial{ii}.workflow )  wf = fliplr( strtok( fliplr( YAML.spatial{ii}.workflow{jj}.native ), '/' ) );  if strcmp( wf, workflow )  YAML.spatial{ii}.workflow{jj}.dict = dictionary;  end  end  end  end  end           

function [dict] = createDictionary( YAML, workflow, dictionary )  % if workflow is empty then work on the raw  % dict goes in the top level of YAML  %  % if workflow has a value then look for the workflow name  % Dictionary needs to output a structure that can write YAML to make the  % dictionary  %   % You can loop over this function is you have heterogenous outputs.  persistent spatialvars aggregatevars  if numel( workflow ) == 0;  cc = {'output'};  israw = true;  else  cc = {'workflow', 'output'};  israw = false;  end  if numel( spatialvars ) == 0 spatialvars = cell(0); end  if numel( aggregatevars ) == 0 aggregatevars = cell(0); end  % read the native variable names from a YAML structure  %%  if israw  for ii = 1 : numel( YAML.aggregate )  for jj = 1 : numel( YAML.aggregate{ii}.output )  aggregatevars = union( aggregatevars, YAML.aggregate{ii}.output{jj}.native );  end  end  for ii = 1 : numel( YAML.spatial )  for jj = 1 : numel( YAML.spatial{ii}.output )  spatialvars = union( aggregatevars, YAML.spatial{ii}.output{jj}.native );  end  end  else    for ii = 1 : numel( YAML.aggregate )  if isfield( YAML.aggregate{ii}, 'workflow' )  for jj = 1 : numel( YAML.aggregate{ii}.workflow )  wf = fliplr( strtok( fliplr( YAML.aggregate{ii}.workflow{jj}.native ), '/' ) );  if strcmp( wf, workflow )  for kk = 1 : numel( YAML.aggregate{ii}.workflow{jj}.output )  aggregatevars = union( aggvars, YAML.aggregate{ii}.workflow{jj}.output{kk}.native );  end  end  end  end  end    if isfield( YAML.spatial{ii}, 'workflow' )  for jj = 1 : numel( YAML.spatial{ii}.workflow )  wf = fliplr( strtok( fliplr( YAML.spatial{ii}.workflow{jj}.native ), '/' ) );  if strcmp( wf, workflow )  for kk = 1 : numel( YAML.spatial{ii}.workflow{jj}.output )  spatialvars = union( spatialvars, YAML.spatial{ii}.workflow{jj}.output{kk}.native );  end  end  end  end  end  assignin( 'base','spatialvars',spatialvars);  assignin( 'base','aggregatevars',aggregatevars);  %%  % Create dictionary YAML Matlab Structure  if numel( aggregatevars ) > 0 | numel( spatialvars ) > 0  dict.name = dictionary;  dict.description = '';  end  if numel( aggregatevars ) > 0  % Create a default group  dict.aggregate{1}.group{1}=struct(...  'name','DEFAULT', ...  'description','',...  'links',struct( 'url','','name','') ...  );  for ii = 1 : numel( aggregatevars );  dict.aggregate{1}.group{1+ii} = struct(...  'pretty', aggregatevars{ii},...  'native', aggregatevars{ii},...  'units','undefined',...  'description','',...  'links',struct( 'url','','name','') ...  );  end  end  if numel( spatialvars ) > 0  % Create a default group  dict.spatial{1}.group{1}=struct(...  'name','DEFAULT', ...  'description','',...  'links',struct( 'url','','name','') ...  );  for ii = 1 : numel( spatialvars );  dict.spatial{1}.group{1+ii} = struct(...  'pretty', spatialvars{ii},...  'native', spatialvars{ii},...  'units','undefined',...  'description','',...  'links',struct( 'url','','name','') ...  );  end  end           

function YAML = createDataset( H5 );  % H5 is an output structure from h5info'  % YAML is an output structure from ReadYAML'  % Dictionary information is attached with a separate function  H5 = xx;  YAML = struct( 'layout','dataset');  [~,YAML.title,~] = fileparts(xx.Filename);  YAML.description = [];  cc = {'Groups' 'Groups'};  for ii = 1 : numel( H5.Groups)  % This loop indexes the datasets    dsetname = H5.Groups(ii).Name; %dataset name    for dd = 1 : numel( H5.Groups(ii).Datasets );  % Whether the dataset can be queried will be a file option in the  % converter  field = H5.Groups(ii).Datasets(dd).Name;  switch field  % The index is on the number of datasets  case {'aggregate','Aggregate'}    if ~isfield( YAML, 'aggregate' )  [ YAML.aggregate{ii}.name YAML.aggregate{ii}.native ] = ...  deal( dsetname(2:end) );  end  YAML.aggregate{ii}.description = [];    if numel( fieldnames(YAML.aggregate{ii}) )==0 dsetid = 0;  else dsetid = numel(YAML.aggregate{ii}); end  % Read the aggregate values here    data = h5read( hh,strjoin( {dsetname, field},'/'));  for mm = 1 : numel(H5.Groups(ii).Datasets(dd).Datatype.Type.Member);  YAML.aggregate{ii}.output{mm}.native = ...  H5.Groups(ii).Datasets(dd).Datatype.Type.Member(mm).Name;  YAML.aggregate{ii}.output{mm}.value = ...  getfield( data, YAML.aggregate{ii}.output{mm}.native );  end  case {'spatial','Spatial'}  if ~isfield( YAML, 'spatial' )  [ YAML.spatial{ii}.name YAML.spatial{ii}.native ] = ...  deal( dsetname(2:end) );  end  YAML.spatial{ii}.description = [];    for mm = 1 : numel(H5.Groups(ii).Datasets(dd).Datatype.Type.Member);  YAML.spatial{ii}.output{mm}.native = ...  H5.Groups(ii).Datasets(dd).Datatype.Type.Member(mm).Name;  end  end  end    % cycle through additional workflows  for gg = 1 : numel( H5.Groups(ii).Groups );  dsetname = H5.Groups(ii).Groups(gg).Name; %dataset name  for dd = 1 : numel( H5.Groups(ii).Groups(gg).Datasets );  % Whether the dataset can be queried will be a file option in the  % converter  field = H5.Groups(ii).Groups(gg).Datasets(dd).Name;  switch field  % The index is on the number of datasets  case {'aggregate','Aggregate'}  if ~isfield(YAML.aggregate{ii},'workflow') || ...  numel( fieldnames(YAML.aggregate{ii}.workflow{gg}) )==0 dsetid = 0;  else dsetid = numel(YAML.aggregate{ii}.workflow{gg}); end  dsetid = dsetid+1;    if ~isfield( YAML.aggregate{ii}, 'workflow' )  [ YAML.aggregate{ii}.workflow{dsetid}.name YAML.aggregate{ii}.workflow{dsetid}.native ] = ...  deal( dsetname(2:end) );  end  YAML.aggregate{ii}.workflow{dsetid}.description = [];        data = h5read( hh,strjoin( {dsetname, field},'/'));  for mm = 1 : numel(H5.Groups(ii).Groups(gg).Datasets(dd).Datatype.Type.Member);  YAML.aggregate{ii}.workflow{dsetid}.output{mm}.native = ...  H5.Groups(ii).Groups(gg).Datasets(dd).Datatype.Type.Member(mm).Name;  YAML.aggregate{ii}.workflow{dsetid}.output{mm}.value = ...  getfield( data, YAML.aggregate{ii}.workflow{dsetid}.output{mm}.native );  end  case {'spatial','Spatial'}  if ~isfield(YAML.spatial{ii},'workflow') || ...  numel( fieldnames(YAML.spatial{ii}.workflow{gg}) )==0 dsetid = 0;  else dsetid = numel(YAML.spatial{ii}.workflow{gg}); end  dsetid = dsetid+1;    if ~isfield( YAML.spatial{ii}, 'worflow' )  [ YAML.spatial{ii}.workflow{dsetid}.name YAML.spatial{ii}.workflow{dsetid}.native ] = ...  deal( dsetname(2:end) );  end  YAML.spatial{ii}.workflow{dsetid}.description = [];  if numel( fieldnames(YAML.spatial{ii}.workflow{dsetid}) )==0 dsetid = 0;  else dsetid = numel(YAML.spatial{ii}.workflow{dsetid}); end    for mm = 1 : numel(H5.Groups(ii).Datasets(dd).Datatype.Type.Member);  YAML.spatial{ii}.workflow{dsetid}.output{mm}.native = ...  H5.Groups(ii).Datasets(dd).Datatype.Type.Member(mm).Name;  end  end  end  end    for aa = 1 : numel( H5.Groups(2).Attributes )  field = H5.Groups(2).Attributes(aa).Name;  switch field  case 'location'  YAML.location = H5.Groups(2).Attributes(aa).Value;  end  end  end           

function h5nm = BatchWrite( fn, Data, writeloc )  % Write a structure generated from a single Polymer MD output to an HDF5  % using h5writecomposite  if ~exist( 'writeloc', 'var');  writeloc = '.';  end  stripnm = @(x)regexprep( fliplr(strtok(fliplr(x),'/')),'dump.','');  h5nm = fullfile( writeloc, horzcat( stripnm(fn), '.h5' ) )  assignin( 'base','h5nm',h5nm)  if ~exist( h5nm,'file' )  h5 = H5F.create( h5nm );  H5F.close( h5 );  end  h5 = H5F.open( h5nm,'H5F_ACC_RDWR','H5P_DEFAULT' );  h5writeattcompound( h5nm, '/', 'SHA', strtok(evalc( 'git log --pretty=oneline')) );  h5writeattcompound( h5nm, '/', 'origin_file', fliplr(strtok(fliplr(fn),'/')) );  H5O.set_comment_by_name( h5, '/', 'Tony Fast updated these datasets.','H5P_DEFAULT');  for ii = 1 : numel( Data.Aggregate )    try  gid = H5G.create( h5, ['/',num2str(ii)],'H5P_DEFAULT','H5P_DEFAULT','H5P_DEFAULT' );  H5G.close( gid );  catch  warning('The group name already exists.');  end  h5writecompound( h5nm, ['/',num2str(ii),'/Aggregate'], Data.Aggregate(ii));  if all ( structfun( @(x)numel(x), Data.Spatial(ii)) == Data.Aggregate(ii).Natoms )  h5writecompound( h5nm, ['/',num2str(ii),'/Spatial'], Data.Spatial(ii));  end  end  H5F.close( h5 );           

function CreateThumbnails( vizdata,h5nm, postdir, imdir )  % Using the YAML portion of my Jekyll site, I am creating thumbnails based  % on the syntax given in the datapage viz.yml.  c = clock;  [p, f, ext] = fileparts( h5nm );  p = postdir  dataloc = sprintf( '%s/%i-%i-%i-%s.markdown',p,c(1),c(2),c(3),f);  vyml = ReadYaml(vizdata);  % Make it work right?  fo = fopen( dataloc );ct=0; while ~feof(fo) ct=ct+1;s{ct} = fgetl(fo);end; fclose(fo);  tfl = 'temp.yml';  fo = fopen( tfl,'w' ); for ii = 1 : numel( s) if ~all(s{ii}=='-') fprintf(fo,'%s\n',s{ii}); end;end;fclose(fo);  fo = fopen( tfl );ct=0; while ~feof(fo) ct=ct+1;s2{ct} = fgetl(fo);end; fclose(fo);  dyml = ReadYaml(tfl);  vars = {'X','Y','Z','C'};  lastim = 0;  for dd = 1 : numel(dyml.spatial)  imnm = sprintf('%s-*.png', f,lastim);  delete( fullfile( imdir, imnm ) );  for vv = 1 : numel( vyml )  sd = vyml{vv}.data{1};    nms = fieldnames( sd );    args = struct2cell(sd);    nargs = cellfun(@(x)numel(x), args );    cdid = find(cellfun( @(x)strcmp( x, 'Cdata'), nms )) ;  xyz = setdiff(1:numel(nms), cdid);  dims = max(2,sum(nargs(xyz)))  xyzi = xyz( nargs(xyz)>0 );  % if all the variable names are the same then it is gridded data  ispoint = numel( unique({args{xyzi}}) ) > 1;  isgridded = ~ispoint;    [ Xdata, Ydata, Zdata, Cdata ] = deal( [] );  for ii = xyzi  eval(sprintf('%s = struct2array(h5read( ''%s'', ''%s'', ''%s''));', nms{ii}, h5nm, dyml.spatial{dd}.native, args{ii} ));  end    if numel(args{cdid}) > 0  eval(sprintf('%s = struct2array(h5read( ''%s'', ''%s'', ''%s''));', 'Cdata', h5nm, dyml.spatial{dd}.native, args{cdid} ));  end    if numel(Cdata) > 0  xx = linspace( min(Cdata), max(Cdata), size(colormap,1));  co = colormap;  else  xx = [ 2 2];  co = 'c';  end    switch dims  case 2  if ispoint    for ii = 1 : (numel(xx)-1)  if numel(xx) == 2  b= ones(size(Xdata))==1;  else  b = Cdata>=xx(ii) & Cdata<=xx(ii+1);  end  plot( Xdata(b),Ydata(b),'ko','MarkerFaceColor',co(ii,:));  if ii == 1  hold on  end  end  hold off  else  pcolor( Cdata );  axis equal; axis tight;  end    case 3  if ispoint    for ii = 1 : (numel(xx)-1)  if numel(xx) == 2  b= ones(size(Xdata))==1;  else  b = Cdata>=xx(ii) & Cdata<=xx(ii+1);  end    plot3( Xdata(b),Ydata(b),Zdata(b),'ko','MarkerFaceColor',co(ii,:));  if ii == 1  hold on  end  end  hold off        end      otherwise  end  axis equal  if numel(Cdata) > 0  colorbar;  end  axis tight  set( gca,'Fontsize',14)    lastim = lastim + vv;    imnm = sprintf('%s-%i.png', f,lastim);  saveas(gcf,fullfile( imdir, imnm));  [IM ] = imread( fullfile( imdir, imnm) );  BIM = cat(3,all(IM == IM(1) ,3),all(IM == IM(end) ,3));  tr = find( ~all( BIM(:,:,1), 2), 1, 'first');  if numel( tr ) == 0 verttrim(1) = 1; else; verttrim(1) = tr; end  tr = find( ~all( BIM(:,:,2), 2), 1, 'last');  if numel( tr ) == 0 verttrim(2) = size(IM,1); else; verttrim(2) = tr; end  tr = find( ~all( BIM(:,:,1), 1), 1, 'first');  if numel( tr ) == 0 horztrim(1) = 1; else; horztrim(1) = tr; end  tr = find( ~all( BIM(:,:,2), 1), 1, 'last');  if numel( tr ) == 0 horztrim(2) = size(IM,2); else; horztrim(2) = tr; end  horztrim = [ 1 size(IM,2)];  verttrim = [ max( 1, verttrim(1)-20), min( size(IM,1), verttrim(2)+20)];  imwrite( IM( verttrim(1):verttrim(2), horztrim(1):horztrim(2),: ), fullfile( imdir, imnm));  dyml.spatial{dd}.viz{vv}.url= imnm;  dyml.spatial{dd}.viz{vv}.name= vyml{vv}.name;  dyml.spatial{dd}.viz{vv}.description= vyml{vv}.description;  % dyml.spatial{1}.viz{vv}.description = [];  end  lastim = lastim;  end  Struct2YMLMD( dyml, dataloc );           

function postout = H5toDict( h5nm, postout, source );  % From and HDF5 file, the native variables are stripped to make a metadata  % registry that can be dynamically changed.  if ~exist( 'postout','var')  postout = './_data/dictionary.yml';  end  % Initialize the file for writing  info = h5info( h5nm );    % Get root information  for rootid = 1 : numel( info.Groups ) % Iterate over the directories in the root    % Write Datasets  for dataid = 1 : numel( info.Groups( rootid ).Datasets )  T = info.Groups( rootid ).Datasets( dataid );  if strcmp( T.Name, 'Aggregate' )  % Get variable fields  if strcmp( T.Datatype.Class, 'H5T_COMPOUND' );  Agg.names = { T.Datatype.Type.Member.Name };  else  end  % Get attributes for fields  elseif strcmp( T.Name, 'Spatial' )  % Get variable fields  if strcmp( T.Datatype.Class, 'H5T_COMPOUND' );  Spa.names = { T.Datatype.Type.Member.Name };  else  end  % Get attributes for fields  % Get attibutes  % Get comment  else  end  end          for workid = 1 : info.Groups( rootid ).Groups  % Write Datasets  for dataid = 1 : numel( info.Groups( rootid ).Groups( workid ).Datasets )    end    end  end  c = clock;  [p, dnm, ext] = fileparts( postout );  dnm = 'A-Dictionary-Template';  dictout = fullfile( regexprep( p, 'data','posts'), sprintf( '%4i-%02i-%i-%s.markdown', c(1), c(2), c(3), dnm ));  [p, f, ext] = fileparts( h5nm );  % f = '~/my-awesome-site/_site/other';  fo = fopen( postout, 'w' );  fprintf(fo,'url: %s\n', sprintf( '%4i/%02i/%i/%s.html', c(1), c(2), c(3), dnm ) );  fprintf(fo,'short: %s\n', sprintf( '%s', dnm ) );  % Select the template  fprintf( fo, 'source : \n','');  fprintf( fo, ' - name: %s\n', source.name);  if isfield( source, 'url')  fprintf( fo, ' url: %s\n',source.url );  else  fprintf( fo, ' url: %s\n','');  end  fprintf( fo, 'converter : \n','');  fprintf( fo, ' - name: \n', mfilename);  fprintf( fo, ' sha: %s\n',strtok( evalc( 'git log --abbrev-commit --pretty=oneline' ) ));  if exist( 'Agg', 'var') & numel( Agg.names ) > 0   fprintf( fo, 'aggregate : \n','');  fprintf( fo, ' - group : \n');  fprintf( fo, ' - name : General\n');  fprintf( fo, ' description : \n');  for ii = 1 : numel( Agg.names )  fprintf( fo, ' - native : %s\n', Agg.names{ii});  fprintf( fo, ' pretty : %s\n', Agg.names{ii});  fprintf( fo, ' units : %s\n', '');  fprintf( fo, ' description : %s\n', '' );  fprintf( fo, ' links : %s\n', '' );  fprintf( fo, ' - url: %s\n', '' );  fprintf( fo, ' name: %s\n', '' );  end  end  if exist( 'Spa', 'var') & numel( Spa.names ) > 0   fprintf( fo, 'spatial : \n','');  fprintf( fo, ' - group : \n');  fprintf( fo, ' - name : General\n');  fprintf( fo, ' description : \n');  for ii = 1 : numel( Spa.names )  fprintf( fo, ' - native : %s\n', Spa.names{ii});  fprintf( fo, ' pretty : %s\n', Spa.names{ii});  fprintf( fo, ' units : %s\n', '');  fprintf( fo, ' description : %s\n', '' );  fprintf( fo, ' links : %s\n', '' );  fprintf( fo, ' - url: %s\n', '' );  fprintf( fo, ' name: %s\n', '' );  fprintf( fo, ' publish : %s\n', '' );  fprintf( fo, ' - isplot: %s\n', 'true' );  fprintf( fo, ' - isdisp: %s\n', 'true' );  end  end  fclose( fo );  fo = fopen( dictout, 'w' );  fprintf( fo,'---\nlayout: dictionary-template-final\ntitle: Dictionary Template\n---\n');  fclose(fo);  %%           

function postout = H5toDict( h5nm, postout, source );  if ~exist( 'postout','var')  postout = './_data/dictionary.yml';  end  % Initialize the file for writing  info = h5info( h5nm );    % Get root information  for rootid = 1 : numel( info.Groups ) % Iterate over the directories in the root    % Write Datasets  for dataid = 1 : numel( info.Groups( rootid ).Datasets )  T = info.Groups( rootid ).Datasets( dataid );  if strcmp( T.Name, 'Aggregate' )  % Get variable fields  if strcmp( T.Datatype.Class, 'H5T_COMPOUND' );  Agg.names = { T.Datatype.Type.Member.Name };  else  end  % Get attributes for fields  elseif strcmp( T.Name, 'Spatial' )  % Get variable fields  if strcmp( T.Datatype.Class, 'H5T_COMPOUND' );  Spa.names = { T.Datatype.Type.Member.Name };  else  end  % Get attributes for fields  % Get attibutes  % Get comment  else  end  end          for workid = 1 : info.Groups( rootid ).Groups  % Write Datasets  for dataid = 1 : numel( info.Groups( rootid ).Groups( workid ).Datasets )    end    end  end  c = clock;  [p, dnm, ext] = fileparts( postout );  dnm = 'A-Dictionary-Template';  dictout = fullfile( regexprep( p, 'data','posts'), sprintf( '%4i-%02i-%i-%s.markdown', c(1), c(2), c(3), dnm ));  [p, f, ext] = fileparts( h5nm );  % f = '~/my-awesome-site/_site/other';  postout  fo = fopen( postout, 'w' );  fprintf(fo,'url: %s\n', sprintf( '%4i/%02i/%i/%s.html', c(1), c(2), c(3), dnm ) );  fprintf(fo,'short: %s\n', sprintf( '%s', dnm ) );  % Select the template  fprintf( fo, 'source : \n','');  fprintf( fo, ' - name: %s\n', source.name);  fprintf( fo, ' url: %s\n',source.url );  fprintf( fo, 'converter : \n','');  fprintf( fo, ' - name: \n', mfilename);  fprintf( fo, ' sha: %s\n',strtok( evalc( 'git log --abbrev-commit --pretty=oneline' ) ));  if exist( 'Agg','var') && numel( Agg.names ) > 0   fprintf( fo, 'aggregate : \n','');  fprintf( fo, ' - group : \n');  fprintf( fo, ' - name : General\n');  fprintf( fo, ' description : \n');  for ii = 1 : numel( Agg.names )  fprintf( fo, ' - native : %s\n', Agg.names{ii});  fprintf( fo, ' pretty : %s\n', Agg.names{ii});  fprintf( fo, ' units : %s\n', '');  fprintf( fo, ' description : %s\n', '' );  fprintf( fo, ' links : %s\n', '' );  fprintf( fo, ' - url: %s\n', '' );  fprintf( fo, ' name: %s\n', '' );  end  end  if exist( 'Spa','var') && numel( Spa.names ) > 0   fprintf( fo, 'spatial : \n','');  fprintf( fo, ' - group : \n');  fprintf( fo, ' - name : General\n');  fprintf( fo, ' description : \n');  for ii = 1 : numel( Spa.names )  fprintf( fo, ' - native : %s\n', Spa.names{ii});  fprintf( fo, ' pretty : %s\n', Spa.names{ii});  fprintf( fo, ' units : %s\n', '');  fprintf( fo, ' description : %s\n', '' );  fprintf( fo, ' links : %s\n', '' );  fprintf( fo, ' - url: %s\n', '' );  fprintf( fo, ' name: %s\n', '' );  fprintf( fo, ' publish : %s\n', '' );  fprintf( fo, ' - isplot: %s\n', 'true' );  fprintf( fo, ' - isdisp: %s\n', 'true' );  end  end  fclose( fo );  fo = fopen( dictout, 'w' );  fprintf( fo,'---\nlayout: dictionary-template-final\ntitle: Dictionary Template\n---\n');  fclose(fo)  %%           

function postout = H5toDict( h5nm, dictdata, to_dir, source );  if ~exist( 'to_dir','var')  to_dir = './';  end  % Initialize the file for writing  info = h5info( h5nm );  % Get root information  %% Scrape metadata from the HDF5 file. Don't access any data yet.  h5 = H5F.open( h5nm )  description = H5O.get_comment_by_name( h5, '/','H5P_DEFAULT');  for rootid = 1 : numel( info.Groups ) % Iterate over the directories in the root    % Write Datasets  for dataid = 1 : numel( info.Groups( rootid ).Datasets )  T = info.Groups( rootid ).Datasets( dataid );  if strcmp( T.Name, 'Aggregate' )  % Get variable fields  if strcmp( T.Datatype.Class, 'H5T_COMPOUND' );  Agg{rootid}.name = info.Groups( rootid ).Name;  Agg{rootid}.vars = { T.Datatype.Type.Member.Name };  else  end  % Get attributes for fields  elseif strcmp( T.Name, 'Spatial' )  % Get variable fields  if strcmp( T.Datatype.Class, 'H5T_COMPOUND' );  Spa{rootid}.name = info.Groups( rootid ).Name;  Spa{rootid}.vars = { T.Datatype.Type.Member.Name };    H5O.get_comment_by_name(h5,info.Groups( rootid ).Name,'H5P_DEFAULT');  else  end  % Get attributes for fields  % Get attibutes  % Get comment  else  end  end          for workid = 1 : info.Groups( rootid ).Groups  % Write Datasets  for dataid = 1 : numel( info.Groups( rootid ).Groups( workid ).Datasets )    end    end  end  H5F.close(h5);  %% Parse Metadata and Dictionary to the datapage  dyml = ReadYaml(dictdata);  [p, f, ext] = fileparts( h5nm );  % f = '~/my-awesome-site/_site/other';  c = clock;  p = to_dir  postout = sprintf( '%s/%i-%i-%i-%s.markdown',p,c(1),c(2),c(3),f)  fo = fopen( postout, 'w' );  fprintf( fo, '---\n');  fprintf( fo, 'layout: dataset-template-final\n');  fprintf( fo, 'description: %s\n',description);  fprintf( fo, 'aggregate: \n','');  if exist( 'Agg','var')  for dd = 1 : numel( Agg );  fprintf( fo, ' - name: %s\n',regexprep( Agg{dd}.name, '/','Dataset '));  native = [Agg{dd}.name,'/Aggregate'];  fprintf( fo, ' native: %s\n',native);  fprintf( fo, ' vars: \n');  for gg = 1 : numel(dyml.aggregate)  for jj = 1 : numel(dyml.aggregate{gg}.group)  data = h5read( h5nm, native );  if isfield( dyml.aggregate{gg}.group{jj}, 'native' )  dyml.aggregate{gg}.group{jj}.native   if any( ismember( dyml.aggregate{gg}.group{jj}.native, Agg{dd}.vars ));  fprintf( fo, ' - native: %s\n', dyml.aggregate{gg}.group{jj}.native);  fprintf( fo, ' value: %f\n', getfield( data,dyml.aggregate{gg}.group{jj}.native) );  end  end  end  end  end  end  h5 = H5F.open( h5nm );   fprintf( fo, 'spatial: \n','');  if exist( 'Spa','var')  for dd = 1 : numel( Spa );  fprintf( fo, ' - name: %s\n',regexprep( Spa{dd}.name, '/','Dataset '));  native = [Spa{dd}.name,'/Spatial'];  fprintf( fo, ' native: %s\n',native);  desc = H5O.get_comment_by_name( h5, Spa{dd}.name,'H5P_DEFAULT');  fprintf( fo, ' description: %s\n',desc);  fprintf( fo, ' vars: \n');  for gg = 1 : numel(dyml.spatial)  for jj = 1 : numel(dyml.spatial{gg}.group)  if isfield( dyml.spatial{gg}.group{jj}, 'native' )  dyml.spatial{gg}.group{jj}.native   if any( ismember( dyml.spatial{gg}.group{jj}.native, Spa{dd}.vars ));  fprintf( fo, ' - native: %s\n', dyml.spatial{gg}.group{jj}.native);  end  end  end  end  end  end  fprintf( fo, '---\n');  fclose(fo);  H5F.close(h5);  return  % Select the template  fprintf( fo, 'source : \n','');  fprintf( fo, ' - name: \n', source.name);  fprintf( fo, ' url: %s\n',source.url );  fprintf( fo, 'converter : \n','');  fprintf( fo, ' - name: \n', mfilename);  fprintf( fo, ' sha: %s\n',strtok( evalc( 'git log --abbrev-commit --pretty=oneline' ) ));  if numel( Agg.names ) > 0   fprintf( fo, 'aggregate : \n','');  fprintf( fo, ' - group : \n');  fprintf( fo, ' - name : General\n');  fprintf( fo, ' description : \n');  for ii = 1 : numel( Agg.names )  fprintf( fo, ' - native : %s\n', Agg.names{ii});  fprintf( fo, ' pretty : %s\n', Agg.names{ii});  fprintf( fo, ' units : %s\n', '');  fprintf( fo, ' description : %s\n', '' );  fprintf( fo, ' links : %s\n', '' );  fprintf( fo, ' - url: %s\n', '' );  fprintf( fo, ' name: %s\n', '' );  end  end  if numel( Spa.names ) > 0   fprintf( fo, 'spatial : \n','');  fprintf( fo, ' - group : \n');  fprintf( fo, ' - name : General\n');  fprintf( fo, ' description : \n');  for ii = 1 : numel( Spa.names )  fprintf( fo, ' - native : %s\n', Spa.names{ii});  fprintf( fo, ' pretty : %s\n', Spa.names{ii});  fprintf( fo, ' units : %s\n', '');  fprintf( fo, ' description : %s\n', '' );  fprintf( fo, ' links : %s\n', '' );  fprintf( fo, ' - url: %s\n', '' );  fprintf( fo, ' name: %s\n', '' );  fprintf( fo, ' publish : %s\n', '' );  fprintf( fo, ' - isplot: %s\n', 'true' );  fprintf( fo, ' - isdisp: %s\n', 'true' );  end  end  fclose( fo );  %%           

function fn = Stuct2YMLMD( D, fn)  fo = fopen( fn,'w');  fprintf( fo,'---\n');  fldsii = cellfun(@(x)char(x),fieldnames( D )','UniformOutput',false);  recurseii = [];  indent = '';  for ii = 1 : numel( fldsii )  data = getfield( D, fldsii{ii} );  if ~iscell( data )  if ischar( data )  fprintf( fo,'%s%s: %s\n',indent,char(fldsii{ii}),data);  else  fprintf( fo,'%s%s: %f\n',indent,char(fldsii{ii}),data);  end  else  %%  indent = '';  fprintf( fo,'%s%s: \n',indent,char(fldsii{ii}));  for dd = 1 : numel( data)  indent = ' - ';  flddata = getfield( D, fldsii{ii},{dd} );  fldsjj = cellfun(@(x)char(x),fieldnames( flddata{1} )','UniformOutput',false);  for jj = 1 : numel(fldsjj)  data = getfield( flddata{1}, fldsjj{jj});  if ~iscell( data )  if ischar( data )  fprintf( fo,'%s%s: %s\n',indent,char(fldsjj{jj}),data);  else  fprintf( fo,'%s%s: %f\n',indent,char(fldsjj{jj}),data);  end  indent = regexprep(indent, '-',' ');  else  indent = ' ';  %%  fprintf( fo,'%s%s: \n',indent,char(fldsjj{jj}));  for ee = 1 : numel( data)  indent = ' - ';  flddatajj = getfield( flddata{1}, fldsjj{jj},{ee} );  fldskk = cellfun(@(x)char(x),fieldnames( flddatajj{1} )','UniformOutput',false);  for kk = 1 : numel(fldskk)  data = getfield( flddatajj{1}, fldskk{kk});  %%    if ~iscell( data )  if ischar( data )  fprintf( fo,'%s%s: %s\n',indent,char(fldskk{kk}),data);  else  fprintf( fo,'%s%s: %f\n',indent,char(fldskk{kk}),data);  end  indent = regexprep(indent, '-',' ');  else  indent = ' ';  %%  fprintf( fo,'%s%s: \n',indent,char(fldskk{kk}));  for ff = 1 : numel( data)  indent = ' - ';  flddatakk = getfield( flddatajj{1}, fldskk{kk},{ff} );  fldsll = cellfun(@(x)char(x),fieldnames( flddatakk{1} )','UniformOutput',false);  for ll = 1 : numel(fldsll)  data = getfield( flddatakk{1}, fldsll{ll});  %%    if ~iscell( data )  if ischar( data )  fprintf( fo,'%s%s: %s\n',indent,char(fldsll{ll}),data);  else  fprintf( fo,'%s%s: %f\n',indent,char(fldsll{ll}),data);  end  indent = regexprep(indent, '-',' ');  else  indent = ' ';  %%  fprintf( fo,'%s%s: \n',indent,char(fldsll{ll}));  for gg = 1 : numel( data)  indent = ' - ';  flddatall = getfield( flddatakk{1}, fldsll{ll},{gg} );  fldsmm = cellfun(@(x)char(x),fieldnames( flddatall{1} )','UniformOutput',false);  for mm = 1 : numel(fldsmm)  data = getfield( flddatamm{1}, fldskk{mm});  %%    if ~iscell( data )  if ischar( data )  fprintf( fo,'%s%s: %s\n',indent,char(fldsmm{mm}),data);  else  fprintf( fo,'%s%s: %f\n',indent,char(fldsmm{mm}),data);  end  indent = regexprep(indent, '-',' ');  else  indent = ' ';  %%      %%  end    %%  end  end      %%  end    %%  end  end  %%  end    %%  end  end    %%  end    end  end  % fldsjj = cellfun(@(x)char(x),fieldnames( D )','UniformOutput',false);  recurseii = [ recurseii, ii];  indent = '';    %%  end  end  fprintf( fo,'---\n');  fclose(fo);           

function DATA = h5read( fn, dset, FIELD )  % Reads from HDF5 filetypes. This function was specifically made to support partial reading of composite datatypes.   %   % INPUTS:  % fn - file name where the data is written to.  % dset - name of the dataset in the HDF5 that the data is being stored as  % FIELD - Name or Index of the composite field to be read from the datasset  % dset  fid = H5F.open( fn );  did = H5D.open(fid,dset);  tid = H5D.get_type(did);  tid2 = H5T.create('H5T_COMPOUND',H5T.get_size( tid ) );  N = H5T.get_nmembers(tid);  if nargin == 3  if isnumeric(FIELD)  index = FIELD;  index_on = true;  else  if ischar( FIELD)  FIELD = {FIELD};  end  nm = arrayfun(@(x)H5T.get_member_name(tid,x),[1:N]-1,'UniformOutput',false);    index = find( ismember( nm, FIELD) );  end  for ii = index-1  H5T.insert( tid2, nm{ii+1}, H5T.get_member_offset( tid, ii ),'H5T_NATIVE_DOUBLE');  end  else  index = 1:N;  tid2 = 'H5ML_DEFAULT';  end  %  DATA = H5D.read(did, tid2 , 'H5S_ALL', 'H5S_ALL', 'H5P_DEFAULT' );  H5D.close( did )  H5T.close( tid )  if nargin == 3  H5T.close( tid2 )  end  H5F.close(fid);           

function h5writeattcompound( fn, dset, attname, DATA )  % An improved version of the matlab function h5write. Natively, h5write lacks the  % ability to write structures to HDF5 files.  %  % INPUTS:  % fn - file name where the data is written to.  % dset - name of the dataset in the HDF5 that the data is being stored as  % DATA - allows structures are all h5write native datatypes to be written.  % if DATA is a structure then the information is written as a  % compound datatype. The size of each field should be the same.  if isstruct( DATA )  if exist( fn, 'file')  fo = H5F.open(fn,'H5F_ACC_RDWR','H5P_DEFAULT');  else  fo = H5F.create(fn);  end  fields = fieldnames(DATA);  sz = size( getfield( DATA, fields{1}));  tid = H5T.create('H5T_COMPOUND',numel(fields)*8);    ii = 1;  H5T.insert(tid,fields{ii},(ii-1)*8,'H5T_NATIVE_DOUBLE');  ii = 2;  strType = H5T.copy( 'H5T_C_S1' );  H5T.set_size(strType, numel(getfield( DATA, fields{ii})) );  % DATA = setfield( DATA, fields{ii}, getfield( DATA, fields{ii} ) );    H5T.insert(tid,fields{ii},(ii-1)*8,strType);    sid = H5S.create_simple( numel(sz), fliplr(sz), fliplr(sz) );  % dset = horzcat(dset, num2str(round(rand(1)*1e5)));  did = H5D.open( fo, dset);  aid = H5A.create( did, attname, tid, sid, H5P.create('H5P_ATTRIBUTE_CREATE'));  H5A.write( aid, tid, DATA );  H5A.close(aid)  H5S.close(sid)  H5D.close(did)    H5T.close(tid)  H5F.close(fo);  else  h5writeatt( fn,dset, attname, DATA);  end  end           

function h5writeattcompound( fn, dset, attname, DATA )  % An improved version of the matlab function h5write. Natively, h5write lacks the  % ability to write structures to HDF5 files.  %  % INPUTS:  % fn - file name where the data is written to.  % dset - name of the dataset in the HDF5 that the data is being stored as  % DATA - allows structures are all h5write native datatypes to be written.  % if DATA is a structure then the information is written as a  % compound datatype. The size of each field should be the same.  if isstruct( DATA )  if exist( fn, 'file')  fo = H5F.open(fn,'H5F_ACC_RDWR','H5P_DEFAULT');  else  fo = H5F.create(fn);  end  fields = fieldnames(DATA);  sz = size( getfield( DATA, fields{1}));  tid = H5T.create('H5T_COMPOUND',numel(fields)*8);    ii = 1;  H5T.insert(tid,fields{ii},(ii-1)*8,'H5T_NATIVE_DOUBLE');  ii = 2;  strType = H5T.copy( 'H5T_C_S1' );  H5T.set_size(strType, numel(getfield( DATA, fields{ii})) );  % DATA = setfield( DATA, fields{ii}, getfield( DATA, fields{ii} ) );    H5T.insert(tid,fields{ii},(ii-1)*8,strType);    sid = H5S.create_simple( numel(sz), fliplr(sz), fliplr(sz) );  % dset = horzcat(dset, num2str(round(rand(1)*1e5)));  did = H5D.open( fo, dset);  aid = H5A.create( did, attname, tid, sid, H5P.create('H5P_ATTRIBUTE_CREATE'));  H5A.write( aid, tid, DATA );  H5A.close(aid)  H5S.close(sid)  H5D.close(did)    H5T.close(tid)  H5F.close(fo);  elseif ischar(DATA)    if exist( fn, 'file')  fo = H5F.open(fn,'H5F_ACC_RDWR','H5P_DEFAULT');  else  fo = H5F.create(fn);  end  SDIM = size(DATA,2);  filetype = H5T.copy ('H5T_FORTRAN_S1');  H5T.set_size (filetype, SDIM );  memtype = H5T.copy ('H5T_C_S1');  H5T.set_size (memtype, SDIM );    % Create dataspace. Setting maximum size to [] sets the maximum  % size to be the current size.  %  dims = size(DATA,1);  space = H5S.create_simple (1,fliplr( dims), []);    %  % Create the attribute and write the string data to it.  %    if strcmp( dset, '/');  attr = H5A.create (fo, attname, filetype, space, 'H5P_DEFAULT');  H5A.write (attr, memtype, DATA');    else  did = H5D.open( fo, dset );  attr = H5A.create (fo, attname, filetype, space, 'H5P_DEFAULT');  H5A.write (attr, memtype, DATA');  H5D.close (did);  end    %  % Close and release resources.  %  H5A.close (attr);    H5S.close (space);  H5T.close (filetype);  H5T.close (memtype);  H5F.close ( fo );      else  h5writeatt( fn,dset, attname, DATA);  end  end           

function h5writecompound( fn, dset, DATA )  % An improved version of the matlab function h5write. Natively, h5write lacks the  % ability to write structures to HDF5 files.  %  % INPUTS:  % fn - file name where the data is written to.  % dset - name of the dataset in the HDF5 that the data is being stored as  % DATA - allows structures are all h5write native datatypes to be written.  % if DATA is a structure then the information is written as a  % compound datatype. The size of each field should be the same.  flds = fieldnames( DATA );  for ii = 1 : numel( flds )  switch class( getfield( DATA, flds{ii} ) )  case 'int8'  hdftype{ii} = 'H5T_STD_I8LE';  hdfbyte(ii) = 1;  case 'int16'  hdftype{ii} = 'H5T_STD_I16LE';  hdfbyte(ii) = 2;  case 'int32'  hdftype{ii} = 'H5T_STD_I32LE';  hdfbyte(ii) = 4;  case 'uint8'  hdftype{ii} = 'H5T_STD_I8LE';  hdfbyte(ii) = 1;  case 'int16'  hdftype{ii} = 'H5T_STD_I16LE';  hdfbyte(ii) = 2;  case 'uint32'  hdftype{ii} = 'H5T_STD_U32LE';  hdfbyte(ii) = 4;  otherwise  hdftype{ii} = 'H5T_NATIVE_DOUBLE';  hdfbyte(ii) = 8;  end  end  cumhdfbyte = [0 , cumsum(hdfbyte)];  if isstruct( DATA )  if exist( fn, 'file')  fo = H5F.open(fn,'H5F_ACC_RDWR','H5P_DEFAULT');  else  fo = H5F.create(fn);  end  fields = fieldnames(DATA);  sz = size( getfield( DATA, fields{1}));  tid = H5T.create('H5T_COMPOUND', sum(hdfbyte));  for ii = 1 : numel( fields )    H5T.insert(tid,fields{ii},cumhdfbyte(ii),hdftype{ii});  if ~all( sz == size( getfield( DATA, fields{ii})))  error('The size of the elements in the data structure must be the same. The data was not written.')  H5T.close(tid)  H5F.close(fo);  end  end    sid = H5S.create_simple( numel(sz), fliplr(sz), fliplr(sz) );  % dset = horzcat(dset, num2str(round(rand(1)*1e5)));  did = H5D.create( fo, dset, tid, sid, 'H5P_DEFAULT');  H5D.write( did, tid, 'H5S_ALL', 'H5S_ALL', 'H5P_DEFAULT', DATA );  H5D.close(did)  H5S.close(sid)    else  h5create( fn,dset, DATA, size(DATA) );  end  end           

function h5writemeta( fn, dset, attname, DATA )  % An improved version of the matlab function h5write. Natively, h5write lacks the  % ability to write structures to HDF5 files.  %  % INPUTS:  % fn - file name where the data is written to.  % dset - name of the dataset in the HDF5 that the data is being stored as  % DATA - allows structures are all h5write native datatypes to be written.  % if DATA is a structure then the information is written as a  % compound datatype. The size of each field should be the same.  if isstruct( DATA )  if exist( fn, 'file')  fo = H5F.open(fn,'H5F_ACC_RDWR','H5P_DEFAULT');  else  fo = H5F.create(fn);  end  fields = fieldnames(DATA);  sz = size( getfield( DATA, fields{1}));    nbytes = [ 8 50 128];  cnb = cumsum( nbytes );  tid = H5T.create('H5T_COMPOUND',cnb(end));    ii = 1;  H5T.insert(tid,fields{ii},0,'H5T_NATIVE_DOUBLE');  ii = 2;  strType = H5T.copy( 'H5T_C_S1' );  H5T.set_size(strType, cnb(ii-1) );  H5T.insert(tid,fields{ii},nbytes(ii),strType);  if numel( fields ) == 3   ii = 3;  strType = H5T.copy( 'H5T_C_S1' );  H5T.set_size(strType, cnb(ii-1) );  H5T.insert(tid,fields{ii},nbytes(ii),strType);  elseif numel(fields) > 3  error(sprintf('Invalid %s attribute.', attname ));  end  % DATA = setfield( DATA, fields{ii}, getfield( DATA, fields{ii} ) );        sid = H5S.create_simple( numel(sz), fliplr(sz), fliplr(sz) );  % dset = horzcat(dset, num2str(round(rand(1)*1e5)));  did = H5D.open( fo, dset);  aid = H5A.create( did, attname, tid, sid, H5P.create('H5P_ATTRIBUTE_CREATE'));  H5A.write( aid, tid, DATA );  H5A.close(aid)  H5S.close(sid)  H5D.close(did)    H5T.close(tid)  H5F.close(fo);  else  h5writeatt( fn,dset, attname, DATA);  end  end