Error with dicomwrite: Attribute has wrong data type.

6 views (last 30 days)
Hello! I am trying to anonymize dicom files by loading the original file with dicominfo and dicomread, changing some fields, and then writing the new file. However, I encountered the error below:
Error using dicom_add_attr>validate_data (line 118)
Attribute (7FE0,0010) has wrong data type.
Error in dicom_add_attr (line 103)
attr_str(pos).Data = validate_data(data, attr_str(pos), specificCharacterSet);
Error in dicom_convert_meta_to_attr (line 39)
attr = dicom_add_attr([], tag(1), tag(2), dictionary, specificCharacterSet, data, VR);
Error in dicom_convert_meta_to_attr>encode_item (line 151)
new_attr = dicom_convert_meta_to_attr(attr_names{p}, item_struct, dictionary, txfr, specificCharacterSet);
Error in dicom_convert_meta_to_attr>encode_SQ (line 125)
data = encode_item(SQ_struct.(items{p}), dictionary, txfr, specificCharacterSet);
Error in dicom_convert_meta_to_attr (line 26)
data = encode_SQ(metadata.(attr_name), dictionary, txfr, specificCharacterSet);
Error in dicom_copy_IOD (line 49)
new_attr = dicom_convert_meta_to_attr(attr_name, metadata, dictionary, options.txfr, specificCharacterSet);
Error in dicomwrite>write_message (line 277)
[attrs, status] = dicom_copy_IOD(X, map, ...
Error in dicomwrite (line 208)
[status, options] = write_message(X, filename, map, metadata, options);
I have also tried simply reading in the original file and writing out the new file (without changing any fields) -
>> y = dicomread('original.dcm');
>> x = dicominfo('original.dcm');
>> dicomwrite(y,'new.dcm',x,'WritePrivate',true,'CreateMode','Copy');
- but these actions produced the same error, as did using dicomanon. Any guidance would be much appreciated!
  6 Comments
Ralph Buchert
Ralph Buchert on 28 Jan 2021
Dear Theodore,
thank you so much. Removing IconImageSequence from the header solved my problem in all cases expect one. I'm very happy, thank you so much :-). Below please find my code, perhapy you find it useful.
With very best wishes
Ralph
function numScans = htpAnonymize(searchDir,anonDir,firstImageOnly)
% anonymize MRI dicom scans
% - works on all dicom data in searchDir and all its subdirectories
% - assumes that each directory containes (at most) one series
% - the anonymized serieses are copied to anonDir, one directory per series
% - generates the txt-file "Codes_<date>" in anonDir that lists IDs, the number of
% images in each series, the number of failures per series etc.
% - generates the log-file "AnonLog_<date>" in anonDir
% - ATTENTION: I did not manage to make sure that the last block of the SOPInstanceUID
% of the images belonging to the same sequence are consecutive numbers
% (neither 'keep' nor 'update' seems to work for SOPInstanceUID). As a consequence, some dicom
% viewers might not recognize that the anonymized images belong to the same series,
% although StudyInstanceUID and SeriesInstanceUID are equal for all images
% of the series ('update' works for StudyInstanceUID and SeriesInstanceUID)%
% - seems to work properly in about 90% of the cases.
% In the remaining 10% of the cases, there is either an error or a warning.
% most frequent error: "Attribute (7FE0,0010) has wrong data type" (= PixelData)
% In these cases (use dicomdisp):
% 0097588 2 (7FE0,0010) OW 4096 bytes - PixelData *Binary*
% 0101696 0 (7FE0,0010) OW 131072 bytes - PixelData []
% In 'normal' cases:
% 0009912 0 (7FE0,0010) OW 247808 bytes - PixelData []
% Solution (Theodore Turesky):
% The problem might be related to errorneous color info (suggesting % color but providing gray), try to
% remove IconImageSequence from the header.
% If this does not work, use another tool (e.g.,
% MicroDicom) to read and export the scan. Then try again.
% - if firstImageOnly == true, only the first dicom image in each subdirectory
% is anonymized. This might be usefull to check for errors and warnings
% before processing a large number of series
%
% Ralph Buchert, January 28, 2021, r.buchert@uke.de
%
values.PatientAddress = 'unknown';
if nargin < 1
searchDir = uigetdir('Select directory to be searched for DICOM data (including all subdirectories)');
end
if nargin < 2
anonDir = uigetdir('Select directory to write anonymized DICOM data');
end
if nargin < 3
firstImageOnly = false;
end
% get subdirs of searchDir
subdirs = genpath(searchDir);
semicolon = regexp(subdirs,';');
numSemicolon = max(size(semicolon));
dirs = {subdirs(1:semicolon(1)-1)};
for i = 1:numSemicolon-1
dirs = [dirs; subdirs(semicolon(i)+1:semicolon(i+1)-1)];
end
dirs = [dirs; subdirs(semicolon(numSemicolon)+1:length(subdirs))];
numDirs = size(dirs,1);
% prepare file for scan name codes
fnameCodes = strcat(anonDir,filesep,'Codes',strrep(strrep(datestr(now),' ','-'),':','-'),'.txt');
fid = fopen(fnameCodes,'w');
if fid == -1
error('ERROR(hptAnonymize): cannot open file to list codes\n\n');
end
fprintf(fid,'%s\t%s\t%s\t%s\t%s\t','original','code','numSlices','numFailures','numFailuresUnresolved');
fprintf(fid,'%s\t%s\t%s\t%s\t','manufacturer','model','fieldStrength','acquisitionDate');
fprintf(fid,'%s\t%s\n','sex','age');
fnameLog = strcat(anonDir,filesep,'AnonLog',strrep(strrep(datestr(now),' ','-'),':','-'),'.txt');
eval(['diary ' fnameLog]);
% do the work
numScans = 0;
for i = 1:numDirs
D = dir(dirs{i});
num_files = size(D,1);
numSlices = 0;
numFailures = 0;
numFailuresUnresolved = 0;
for j = 1:num_files
if (D(j).isdir ~= 1)
slice = strcat(dirs{i},filesep,D(j).name);
if firstImageOnly
condition = isdicom(slice) & (numSlices < 1);
else
condition = isdicom(slice);
end
if condition
numSlices = numSlices + 1;
if numSlices == 1
numScans = numScans + 1;
scan = dirs{i}(length(searchDir)+2:length(dirs{i}));
ind = findstr(dirs{i},filesep);
%newScan = sprintf('Scan%04d',str2num(dirs{i}(ind(length(ind)-1)+1:ind(length(ind))-1)));
newScan = sprintf('Scan%04d',numScans);
mkdir(anonDir,newScan);
newDir = strcat(anonDir,filesep,newScan);
values.StudyInstanceUID = dicomuid;
values.SeriesInstanceUID = dicomuid;
values.StudyID = sprintf('4711%04d',numScans);
values.PatientName.FamilyName = newScan;
values.PatientName.GivenName = newScan;
fprintf('\n\nCurrently working on %s\n\n',scan);
hdr = dicominfo(slice);
end
%anonSlice = strcat(newDir,filesep,D(j).name);
anonSlice = strcat(newDir,filesep,newScan,sprintf('Image%04d',numSlices-1),'.dcm');
try
dicomanon(slice,anonSlice,'keep', {'PatientAge', 'PatientSex', 'StudyDescription'},'update',values,'WritePrivate',false);
catch
numFailures = numFailures + 1;
values.IconImageSequence = [];
try
dicomanon(slice,anonSlice,'keep', {'PatientAge', 'PatientSex', 'StudyDescription'},'update',values,'WritePrivate',false);
catch
numFailuresUnresolved = numFailuresUnresolved+1;
end
rmfield(values,'IconImageSequence');
end
end
end
end
if numSlices > 0
fprintf(fid,'%s\t%s\t%d\t%d\t%d\t',scan,newScan,numSlices,numFailures,numFailuresUnresolved);
try
fprintf(fid,'%s\t',hdr.Manufacturer);
catch
fprintf(fid,'%s\t','na');
end
try
fprintf(fid,'%s\t',hdr.ManufacturerModelName);
catch
fprintf(fid,'%s\t','na');
end
try
fprintf(fid,'%3.1f\t',hdr.MagneticFieldStrength);
catch
fprintf(fid,'%s\t','na');
end
try
fprintf(fid,'%s\t',hdr.AcquisitionDate);
catch
fprintf(fid,'%s\t','na');
end
try
fprintf(fid,'%s\t',hdr.PatientSex);
catch
fprintf(fid,'%s\t','na');
end
try
fprintf(fid,'%s\n',hdr.PatientAge);
catch
fprintf(fid,'%s\n','na');
end
end
end
fclose(fid);
diary;
fprintf('\n\nDone\n\n');
end
Theodore Turesky
Theodore Turesky on 28 Jan 2021
Edited: Theodore Turesky on 28 Jan 2021
Looks great, Ralph! Thank you. Also, I want to credit Ross Mair for identifying the color problem and suggesting I remove the problematic tag.

Sign in to comment.

Accepted Answer

Theodore Turesky
Theodore Turesky on 28 Jan 2021
>> y = dicomread('original.dcm');
>> x = dicominfo('original.dcm');
>> x.PatientName = 'anon'; %you'll need to do something like this for every header field that you want to anonymize
>> x.IconImageSequence = []; % this is the key line for avoiding the attribute error
>> dicomwrite(y,'new.dcm',x,'WritePrivate',true,'CreateMode','Copy');

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!