SaveArff.m 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. % SaveArff.m
  2. %
  3. % Function to save ARFF data to file.
  4. %
  5. % input:
  6. % arffFile - name of the file to save data
  7. % data - data to write in arff file
  8. % metadata - metadata struct in
  9. % attributes - nx2 cell array holding the attribute names
  10. % relation - relation described in the file
  11. % comments - (optional) nx1 cell array containing one comment line per cell
  12. function SaveArff(arffFile, data, metadata, attributes, relation, comments)
  13. if (nargin < 6)
  14. comments = {};
  15. end
  16. % check input
  17. assert(isfield(metadata,'width_px'), 'metadata should contain "width_px" field');
  18. assert(isfield(metadata,'height_px'), 'metadata should contain "height_px" field');
  19. assert(isfield(metadata,'width_mm'), 'metadata should contain "width_mm" field');
  20. assert(isfield(metadata,'height_mm'), 'metadata should contain "height_mm" field');
  21. assert(isfield(metadata,'distance_mm'), 'metadata should contain "distance_mm" field');
  22. assert(size(relation,2)>0, 'relation should not be empty');
  23. assert(size(attributes,1)==size(data,2), 'attribute number should be the same with data');
  24. % start writing
  25. fid = fopen(arffFile, 'w+');
  26. % write relation
  27. fprintf(fid, '@RELATION %s\n\n', relation);
  28. % write metadata
  29. fprintf(fid, '%%@METADATA width_px %d\n', metadata.width_px);
  30. fprintf(fid, '%%@METADATA height_px %d\n', metadata.height_px);
  31. fprintf(fid, '%%@METADATA width_mm %.2f\n', metadata.width_mm);
  32. fprintf(fid, '%%@METADATA height_mm %.2f\n', metadata.height_mm);
  33. fprintf(fid, '%%@METADATA distance_mm %.2f\n\n', metadata.distance_mm);
  34. % write metadata extras. Those are data that vary between experiments
  35. for i=1:size(metadata.extra,1)
  36. fprintf(fid, '%%@METADATA %s %s\n', metadata.extra{i,1}, metadata.extra{i,2});
  37. end
  38. % print an empty line
  39. fprintf(fid, '\n');
  40. % write attributes and get their type
  41. % 1 = integer
  42. % 2 = numeric
  43. % -1 = other
  44. numAtts = size(attributes,1);
  45. attType = -1*ones(numAtts,1);
  46. numMaps = cell(numAtts,1);
  47. for i=1:numAtts
  48. fprintf(fid, '@ATTRIBUTE %s %s\n', attributes{i,1}, attributes{i,2});
  49. [isNom, ~, numericMap] = IsNomAttribute(attributes{i,2});
  50. % get type
  51. if (strcmpi(attributes{i,2},'integer')==1)
  52. attType(i) = 1;
  53. elseif (strcmpi(attributes{i,2},'numeric')==1)
  54. attType(i) = 2;
  55. elseif (isNom)
  56. attType(i) = 3;
  57. numMaps{i,1} = numericMap;
  58. end
  59. end
  60. % write comments if they exist
  61. if (~isempty(comments))
  62. fprintf(fid, '\n');
  63. for i=1:length(comments)
  64. comment = comments{i};
  65. % check if % is the first character
  66. if (length(comment)>0 && comment(1)~='%')
  67. comment = ['%' comment];
  68. end
  69. fprintf(fid, '%s\n', comment);
  70. end
  71. end
  72. % write data keyword
  73. fprintf(fid,'\n@DATA\n');
  74. numEntries = size(data,1);
  75. % transpose data in order to allow one line writing because fprintf handles
  76. % matrices column wise when writing in file
  77. data = num2cell(data');
  78. nomIndices = find(attType==3);
  79. for nomInd=nomIndices'
  80. if (isempty(nomInd))
  81. break;
  82. end
  83. for ind=1:numEntries
  84. %data{ind, nomInd} = numMaps{nomInd,1}(data{ind, nomInd});
  85. data{nomInd, ind} = numMaps{nomInd,1}(data{nomInd, ind});
  86. end
  87. end
  88. writeFormat = '';
  89. for ind=1:numAtts
  90. if (attType(ind) == 1)
  91. writeFormat = [writeFormat '%d'];
  92. elseif (attType(ind) == 2)
  93. writeFormat = [writeFormat '%.2f'];
  94. elseif (attType(ind) == 3)
  95. writeFormat = [writeFormat '%s'];
  96. else
  97. error(['Attribute type "' num2str(attType(ind)) '" is not recognised']);
  98. end
  99. if (ind<numAtts)
  100. writeFormat = [writeFormat ','];
  101. end
  102. end
  103. writeFormat = [writeFormat '\n'];
  104. % One line writing almost halves the writing time
  105. fprintf(fid, writeFormat, data{:});
  106. %for ind=1:numEntries
  107. % fprintf(fid, writeFormat, data{ind,:});
  108. %end
  109. % close file
  110. fclose(fid);
  111. end