Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

dm3io.cpp

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00033  *
00034  * */
00035 
00036 #include <cstring>
00037 
00038 #include "dm3io.h"
00039 #include "portable_fileio.h"
00040 #include "geometry.h"
00041 
00042 using namespace EMAN;
00043 using namespace EMAN::Gatan;
00044 
00045 const char *TagTable::IMAGE_WIDTH_TAG = "Dimensions #0";
00046 const char *TagTable::IMAGE_HEIGHT_TAG = "Dimensions #1";
00047 const char *TagTable::IMAGE_DATATYPE_TAG = "DataType";
00048 const char *TagTable::IMAGE_THUMB_INDEX_TAG = "ImageIndex";
00049 
00050 TagTable::TagTable()
00051         :       img_index(0), is_big_endian(true)
00052 {
00053 }
00054 
00055 TagTable::~TagTable()
00056 {
00057         for (unsigned int i = 0; i < data_list.size(); i++) {
00058                 if (data_list[i]) {
00059                         delete[]data_list[i];
00060                         data_list[i] = 0;
00061                 }
00062         }
00063 }
00064 
00065 
00066 void TagTable::add(const string & name, const string & value)
00067 {
00068         const char *value_str = value.c_str();
00069 
00070         if (name == IMAGE_WIDTH_TAG) {
00071                 x_list.push_back(atoi(value_str));
00072         }
00073         else if (name == IMAGE_HEIGHT_TAG) {
00074                 y_list.push_back(atoi(value_str));
00075         }
00076         else if (name == IMAGE_DATATYPE_TAG) {
00077                 datatype_list.push_back(atoi(value_str));
00078         }
00079         else if (name == IMAGE_THUMB_INDEX_TAG) {
00080                 set_thumb_index(atoi(value_str));
00081         }
00082         else {
00083                 tags[name] = value;
00084         }
00085 }
00086 
00087 void TagTable::add_data(char *data)
00088 {
00089         if (!data) {
00090                 throw NullPointerException("DM3 data is NULL");
00091         }
00092         else {
00093                 data_list.push_back(data);
00094         }
00095 }
00096 
00097 string TagTable::get_string(const string & name)
00098 {
00099         return tags[name];
00100 }
00101 
00102 int TagTable::get_int(const string & name)
00103 {
00104         return atoi(tags[name].c_str());
00105 }
00106 
00107 float TagTable::get_float(const string & name)
00108 {
00109         return static_cast < float >(atof(tags[name].c_str()));
00110 }
00111 
00112 double TagTable::get_double(const string & name)
00113 {
00114         return atof(tags[name].c_str());
00115 }
00116 
00117 void TagTable::dump() const
00118 {
00119         map < string, string >::const_iterator p;
00120 
00121         for (p = tags.begin(); p != tags.end(); p++) {
00122 //              LOGDEBUG("  %s: %s", (*p).first.c_str(), (*p).second.c_str());
00123                 printf("  %s: %s\n", (*p).first.c_str(), (*p).second.c_str());
00124         }
00125 }
00126 
00127 int TagTable::get_xsize() const
00128 {
00129         return x_list[img_index];
00130 }
00131 
00132 int TagTable::get_ysize() const
00133 {
00134         return y_list[img_index];
00135 }
00136 
00137 int TagTable::get_datatype() const
00138 {
00139         return datatype_list[img_index];
00140 }
00141 
00142 char *TagTable::get_data() const
00143 {
00144         return data_list[img_index];
00145 }
00146 
00147 void TagTable::set_thumb_index(int i)
00148 {
00149         if (i != 0 && i != 1) {
00150                 throw OutofRangeException(0, 1, i, "image index");
00151         }
00152         else {
00153                 if (i == 0) {
00154                         img_index = 1;
00155                 }
00156                 else {
00157                         img_index = 0;
00158                 }
00159         }
00160 }
00161 
00162 
00163 TagData::TagData(FILE * data_file, TagTable * table, const string & tagname)
00164         :       in(data_file), tagtable(table), name(tagname), tag_type(UNKNOWN)
00165 {
00166 }
00167 
00168 TagData::~TagData()
00169 {
00170 }
00171 
00172 string TagData::read_native(bool is_value_stored)
00173 {
00174         size_t sz = typesize();
00175         char val_str[32];
00176 
00177         if (tag_type == SHORT) {
00178                 short val = 0;
00179                 fread(&val, sz, 1, in);
00180                 tagtable->become_host_endian(&val);
00181                 sprintf(val_str, "%d", val);
00182         }
00183         else if (tag_type == USHORT) {
00184                 unsigned short val = 0;
00185                 fread(&val, sz, 1, in);
00186                 tagtable->become_host_endian(&val);
00187                 sprintf(val_str, "%d", val);
00188         }
00189         else if (tag_type == INT) {
00190                 int val = 0;
00191                 fread(&val, sz, 1, in);
00192                 tagtable->become_host_endian(&val);
00193                 sprintf(val_str, "%d", val);
00194         }
00195         else if (tag_type == CHAR || tag_type == OCTET) {
00196                 char val = 0;
00197                 fread(&val, sz, 1, in);
00198                 sprintf(val_str, "%d", val);
00199         }
00200         else if (tag_type == BOOLEAN) {
00201                 bool val = false;
00202                 fread(&val, sz, 1, in);
00203                 tagtable->become_host_endian(&val);
00204                 sprintf(val_str, "%d", val);
00205         }
00206         else if (tag_type == UINT) {
00207                 unsigned int val = 0;
00208                 fread(&val, sz, 1, in);
00209                 tagtable->become_host_endian(&val);
00210                 sprintf(val_str, "%d", (int) val);
00211         }
00212         else if (tag_type == FLOAT) {
00213                 float val = 0;
00214                 fread(&val, sz, 1, in);
00215                 tagtable->become_host_endian(&val);
00216                 sprintf(val_str, "%f", val);
00217         }
00218         else if (tag_type == DOUBLE) {
00219                 double val = 0;
00220                 fread(&val, sz, 1, in);
00221                 tagtable->become_host_endian(&val);
00222                 sprintf(val_str, "%10e", val);
00223         }
00224         else {
00225                 LOGERR("invalid tag type: '%d'", tag_type);
00226                 exit(1);
00227         }
00228 
00229         if (is_value_stored) {
00230                 tagtable->add(name, val_str);
00231         }
00232 
00233         LOGVAR("value = '%s'", val_str);
00234 
00235         return string(val_str);
00236 }
00237 
00238 
00239 vector < int >TagData::read_array_types()
00240 {
00241         LOGVAR("TagData::read_array_types()");
00242 
00243         int array_type = 0;
00244         fread(&array_type, sizeof(array_type), 1, in);
00245 
00246         ByteOrder::become_big_endian(&array_type);
00247 
00248         LOGVAR("array data type = '%s'", Gatan::to_str((Type) array_type));
00249 
00250         vector < int >item_types;
00251 
00252         if (array_type == STRUCT) {
00253                 item_types = read_struct_types();
00254         }
00255         else if (array_type == ARRAY) {
00256                 item_types = read_array_types();
00257                 LOGERR("DM3: don't know how to handle this array type");
00258         }
00259         else {
00260                 item_types.push_back(array_type);
00261         }
00262 
00263         return item_types;
00264 }
00265 
00266 
00267 // string tag data are stored in unicode
00268 string TagData::read_string(int size)
00269 {
00270         if (size <= 0) {
00271                 return string("");
00272         }
00273 
00274         unsigned short *buf = new unsigned short[size];
00275         char *str = new char[size + 1];
00276 
00277         fread(buf, size * sizeof(unsigned short), 1, in);
00278         tagtable->become_host_endian < unsigned short >(buf, size);
00279 
00280         for (int i = 0; i < size; i++) {
00281                 str[i] = static_cast < char >(buf[i]);
00282         }
00283 
00284         str[size] = '\0';
00285         string str1 = string(str);
00286 
00287         if( str )
00288         {
00289                 delete[]str;
00290                 str = 0;
00291         }
00292         if( buf )
00293         {
00294                 delete[]buf;
00295                 buf = 0;
00296         }
00297 
00298         return str1;
00299 }
00300 
00301 
00302 int TagData::read_array_data(vector < int >item_types, bool nodata)
00303 {
00304         ENTERFUNC;
00305         if (item_types.size() == 0) {
00306                 LOGERR("DM3 item types cannot be empty");
00307                 return 1;
00308         }
00309 
00310         int err = 0;
00311         int array_size = 0;
00312 
00313         fread(&array_size, sizeof(array_size), 1, in);
00314         ByteOrder::become_big_endian(&array_size);
00315 
00316         LOGVAR("array size = %d\n", array_size);
00317 
00318         size_t item_size = 0;
00319         for (size_t i = 0; i < item_types.size(); i++) {
00320                 item_size += typesize(item_types[i]);
00321         }
00322 
00323         LOGVAR("%s array item size = %d\n", name.c_str(), item_size);
00324 
00325         size_t buf_size = item_size * array_size;
00326 
00327         if (item_types.size() == 1 && item_types[0] == USHORT && nodata) {
00328                 string val = read_string(array_size);
00329                 tagtable->add(name, val);
00330                 LOGVAR("value: %s", val.c_str());
00331         }
00332         else if (!nodata && name == "Data") {
00333                 char *data = new char[buf_size];
00334                 fread(data, buf_size, 1, in);
00335 
00336                 if (item_size == sizeof(short)) {
00337                         tagtable->become_host_endian((short *) data, array_size);
00338                 }
00339                 else if (item_size == sizeof(int)) {
00340                         tagtable->become_host_endian((int *) data, array_size);
00341                 }
00342                 else if (item_size == sizeof(double)) {
00343                         tagtable->become_host_endian((double *) data, array_size);
00344                 }
00345                 else {
00346                         LOGERR("cannot handle this type of DM3 image data");
00347                         return 1;
00348                 }
00349 
00350                 tagtable->add_data(data);
00351         }
00352         else {
00353                 portable_fseek(in, buf_size, SEEK_CUR);
00354         }
00355         EXITFUNC;
00356         return err;
00357 }
00358 
00359 vector < int >TagData::read_struct_types()
00360 {
00361         LOGVAR("TagData::read_struct_types()");
00362 
00363         unsigned int namelength = 0;
00364         unsigned int nfields = 0;
00365 
00366         fread(&namelength, sizeof(namelength), 1, in);
00367         ByteOrder::become_big_endian(&namelength);
00368 
00369         fread(&nfields, sizeof(nfields), 1, in);
00370         ByteOrder::become_big_endian(&nfields);
00371 
00372         LOGVAR("namelength = %d\n", namelength);
00373         LOGVAR("num fields = %d\n", nfields);
00374 
00375         vector < int >field_types;
00376 
00377         for (unsigned int i = 0; i < nfields; i++) {
00378                 fread(&namelength, sizeof(namelength), 1, in);
00379                 ByteOrder::become_big_endian(&namelength);
00380 
00381                 int field_type = 0;
00382                 fread(&field_type, sizeof(field_type), 1, in);
00383                 ByteOrder::become_big_endian(&field_type);
00384 
00385                 LOGVAR("%dth namelength = %d, type = '%s'",
00386                            i, namelength, Gatan::to_str((Type) field_type));
00387                 field_types.push_back(field_type);
00388         }
00389 
00390         return field_types;
00391 }
00392 
00393 
00394 
00395 int TagData::read_any(bool nodata)
00396 {
00397         int err = 0;
00398 
00399         fread(&tag_type, sizeof(tag_type), 1, in);
00400         ByteOrder::become_big_endian(&tag_type);
00401         LOGVAR("tag type = '%s'\n", Gatan::to_str((Type) tag_type));
00402 
00403         if (tag_type == ARRAY) {
00404                 vector < int >item_types = read_array_types();
00405                 err = read_array_data(item_types, nodata);
00406         }
00407         else if (tag_type == STRUCT) {
00408                 vector < int >field_types = read_struct_types();
00409 
00410                 for (unsigned int i = 0; i < field_types.size(); i++) {
00411                         tag_type = static_cast < Type > (field_types[i]);
00412                         string val = read_native(false);
00413                         char int_str[32];
00414                         sprintf(int_str, " #%d", i);
00415                         string fieldname = name + string(int_str);
00416                         tagtable->add(fieldname, val);
00417                 }
00418         }
00419         else if (tag_type == STRING) {
00420                 int str_sz = 0;
00421                 fread(&str_sz, sizeof(str_sz), 1, in);
00422                 ByteOrder::become_big_endian(&str_sz);
00423 
00424                 char *val = new char[str_sz + 1];
00425                 fread(val, str_sz, 1, in);
00426                 val[str_sz] = '\0';
00427                 string val_str = string(val);
00428                 if( val )
00429                 {
00430                         delete[]val;
00431                         val = 0;
00432                 }
00433 
00434                 tagtable->add(name, val_str);
00435         }
00436         else {
00437                 read_native(true);
00438         }
00439 
00440         return err;
00441 }
00442 
00443 int TagData::read(bool nodata)
00444 {
00445         LOGVAR("TagData::read()");
00446         int err = 0;
00447 
00448         const char *DATA_TYPE_MARK = "%%%%";
00449         const size_t mark_sz = strlen(DATA_TYPE_MARK);
00450         char *mark = new char[mark_sz + 1];
00451         fread(mark, mark_sz, 1, in);
00452         mark[mark_sz] = '\0';
00453 
00454         if (strcmp(mark, DATA_TYPE_MARK) != 0) {
00455                 LOGERR("data type label has been changed from '%s' to '%s'",
00456                            DATA_TYPE_MARK, mark);
00457                 return 1;
00458         }
00459 
00460         if( mark )
00461         {
00462                 delete[]mark;
00463                 mark = 0;
00464         }
00465 
00466         int encoded_types_size = 0;
00467         fread(&encoded_types_size, sizeof(int), 1, in);
00468         ByteOrder::become_big_endian(&encoded_types_size);
00469 
00470         LOGVAR("encoded types size = %d\n", encoded_types_size);
00471 
00472         err = read_any(nodata);
00473 
00474         return err;
00475 }
00476 
00477 
00478 size_t TagData::typesize() const
00479 {
00480         return typesize((int) tag_type);
00481 }
00482 
00483 size_t TagData::typesize(int t) const
00484 {
00485         size_t size = 0;
00486         Type type = static_cast < Type > (t);
00487 
00488         switch (type) {
00489         case SHORT:
00490                 size = sizeof(short);
00491                 break;
00492         case USHORT:
00493                 size = sizeof(unsigned short);
00494                 break;
00495         case INT:
00496                 size = sizeof(int);
00497                 break;
00498         case UINT:
00499                 size = sizeof(unsigned int);
00500                 break;
00501         case FLOAT:
00502                 size = sizeof(float);
00503                 break;
00504         case DOUBLE:
00505                 size = sizeof(double);
00506                 break;
00507         case BOOLEAN:
00508                 size = sizeof(bool);
00509                 break;
00510         case CHAR:
00511         case OCTET:
00512                 size = sizeof(char);
00513                 break;
00514         default:
00515                 LOGERR("no such type: '%d'\n", type);
00516                 break;
00517         }
00518 
00519         return size;
00520 }
00521 
00523 
00524 TagGroup::TagGroup(FILE * data_file, TagTable * table, const string & groupname)
00525         :       in(data_file), tagtable(table), name(groupname), entry_id(0)
00526 {
00527 }
00528 
00529 TagGroup::~TagGroup()
00530 {
00531 }
00532 
00533 int TagGroup::read(bool nodata)
00534 {
00535         LOGVAR("TagGroup::read()");
00536 
00537 
00538         int ntags = 0;
00539         portable_fseek(in, sizeof(char) * 2, SEEK_CUR);
00540         
00541         fread(&ntags, sizeof(ntags), 1, in);
00542         
00543         ByteOrder::become_big_endian(&ntags);
00544         
00545         LOGVAR("DM3: ntags = %d\n", ntags);
00546 
00547         int err = 0;
00548 
00549         for (int i = 0; i < ntags; i++) {
00550                 TagEntry tag_entry(in, tagtable, this);
00551                 err = tag_entry.read(nodata);
00552 
00553                 if (err) {
00554                         break;
00555                 }
00556         }
00557 
00558         return err;
00559 }
00560 
00561 string TagGroup::get_name() const
00562 {
00563         return name;
00564 }
00565 
00566 int TagGroup::get_entry_id()
00567 {
00568         int id = entry_id;
00569         entry_id++;
00570         return id;
00571 }
00572 
00573 
00574 
00576 
00577 TagEntry::TagEntry(FILE * data_file, TagTable * table, TagGroup * parent)
00578         :       in(data_file), tagtable(table), parent_group(parent), name("")
00579 {
00580 }
00581 
00582 TagEntry::~TagEntry()
00583 {
00584 }
00585 
00586 
00587 int TagEntry::read(bool nodata)
00588 {
00589         LOGVAR("TagEntry::read()");
00590         int err = 0;
00591         char tag_type = 0;
00592         char *tmp_name = 0;
00593 
00594         fread(&tag_type, sizeof(char), 1, in);
00595 
00596         if (tag_type != GROUP_TAG && tag_type != DATA_TAG) {
00597                 LOGERR("TagEntry::read() invalid tag type: %d", tag_type);
00598                 return 1;
00599         }
00600 
00601         short name_len = 0;
00602         fread(&name_len, sizeof(short), 1, in);
00603         ByteOrder::become_big_endian(&name_len);
00604 
00605         if (name_len != 0) {
00606                 tmp_name = new char[name_len + 1];
00607                 fread(tmp_name, name_len, 1, in);
00608                 tmp_name[name_len] = '\0';
00609         }
00610         else {
00611                 string parent_name = parent_group->get_name();
00612                 name_len = static_cast < short >(parent_name.size() + 4);
00613                 tmp_name = new char[name_len + 1];
00614                 sprintf(tmp_name, "%s #%d", parent_name.c_str(), parent_group->get_entry_id());
00615         }
00616 
00617         name = string(tmp_name);
00618         if( tmp_name )
00619         {
00620                 delete[]tmp_name;
00621                 tmp_name = 0;
00622         }
00623 
00624         LOGVAR("\ntag name: '%s', len: %d, type: '%s'",
00625                    name.c_str(), name_len, Gatan::to_str((EntryType) tag_type));
00626 
00627         if (tag_type == DATA_TAG) {
00628                 TagData tag_data(in, tagtable, name);
00629                 err = tag_data.read(nodata);
00630         }
00631         else if (tag_type == GROUP_TAG) {
00632                 TagGroup group(in, tagtable, name);
00633                 err = group.read(nodata);
00634         }
00635 
00636         return err;
00637 }
00638 
00639 
00641 
00642 DM3IO::DM3IO(const string & dm3_filename, IOMode rw)
00643         :       filename(dm3_filename), rw_mode(rw), dm3file(0), initialized(false)
00644 {
00645         is_big_endian = ByteOrder::is_host_big_endian();
00646         tagtable = new TagTable();
00647 }
00648 
00649 DM3IO::~DM3IO()
00650 {
00651         if (dm3file) {
00652                 fclose(dm3file);
00653                 dm3file = 0;
00654         }
00655         if (tagtable) {
00656                 delete tagtable;
00657                 tagtable = 0;
00658         }
00659 }
00660 
00661 void DM3IO::init()
00662 {
00663         ENTERFUNC;
00664         if (initialized) {
00665                 return;
00666         }
00667         initialized = true;
00668 
00669         if (rw_mode != READ_ONLY) {
00670                 throw ImageReadException(filename, "only support DM3 read-only");
00671         }
00672 
00673         dm3file = sfopen(filename, READ_ONLY);
00674 
00675         int buf[NUM_ID_INT];
00676         if (fread(buf, sizeof(buf), 1, dm3file) != 1) {
00677                 throw ImageReadException(filename, "read first block of DM3 file");
00678         }
00679 
00680         if (!is_valid(&buf)) {
00681                 throw ImageReadException(filename, "invalid DM3 file");
00682         }
00683 
00684         int byte_order = buf[2];
00685 
00686         if (byte_order == 0) {
00687                 is_big_endian = true;
00688         }
00689         else {
00690                 is_big_endian = false;
00691         }
00692 
00693         tagtable->set_endian(is_big_endian);
00694         ByteOrder::become_big_endian(buf, 3);
00695 
00696         LOGDEBUG("dm3 ver = %d, image size = %d, is_big_endian = %d",
00697                          buf[0], buf[1], (int) is_big_endian);
00698 
00699         EXITFUNC;
00700 }
00701 
00702 
00703 
00704 bool DM3IO::is_valid(const void *first_block)
00705 {
00706         ENTERFUNC;
00707 
00708         if (!first_block) {
00709                 return false;
00710         }
00711 
00712         const int *data = static_cast < const int *>(first_block);
00713 
00714         int img_ver = data[0];
00715         int img_size = data[1];
00716         int byte_order = data[2];
00717 
00718         ByteOrder::become_big_endian(&img_ver);
00719 
00720         if (img_ver != 3) {
00721                 return false;
00722         }
00723 
00724         ByteOrder::become_big_endian(&img_size);
00725         ByteOrder::become_big_endian(&byte_order);
00726 
00727         if (byte_order != 0 && byte_order != 1) {
00728                 return false;
00729         }
00730 
00731         return true;
00732 }
00733 
00734 bool DM3IO::is_image_big_endian()
00735 {
00736         init();
00737         return is_big_endian;
00738 }
00739 
00740 int DM3IO::read_header(Dict & dict, int image_index, const Region * area, bool)
00741 {
00742         ENTERFUNC;
00743         int err = 0;
00744 
00745         //single image format, index can only be zero
00746         if(image_index == -1) {
00747                 image_index = 0;
00748         }
00749         image_index = 0;
00750         check_read_access(image_index);
00751 
00752         portable_fseek(dm3file, NUM_ID_INT * sizeof(int), SEEK_SET);
00753         TagGroup root_group(dm3file, tagtable, "");
00754         root_group.read(true);
00755 
00756         int nx = tagtable->get_xsize();
00757         int ny = tagtable->get_ysize();
00758 
00759         check_region(area, IntSize(nx, ny));
00760         int xlen = 0, ylen = 0;
00761         EMUtil::get_region_dims(area, nx, &xlen, ny, &ylen);
00762 
00763         dict["nx"] = xlen;
00764         dict["ny"] = ylen;
00765         dict["nz"] = 1;
00766 
00767         dict["DM3.acq_date"] = tagtable->get_string("Acquisition Date");
00768         dict["DM3.acq_time"] = tagtable->get_string("Acquisition Time");
00769         dict["DM3.source"] = tagtable->get_string("Source");
00770         dict["DM3.exposure_number"] = tagtable->get_int("Exposure Number");
00771         dict["DM3.exposure_time"] = tagtable->get_double("Exposure (s)");
00772         dict["DM3.zoom"] = tagtable->get_double("Zoom");
00773         dict["DM3.antiblooming"] = tagtable->get_int("Antiblooming");
00774         dict["DM3.indicated_mag"] = tagtable->get_double("Indicated Magnification");
00775         dict["DM3.actual_mag"] = tagtable->get_double("Actual Magnification");
00776         dict["DM3.pixel_size"] = tagtable->get_double("Pixel Size (um) #0");
00777         dict["DM3.name"] = tagtable->get_string("Name");
00778 
00779         dict["DM3.voltage"] = tagtable->get_double("Voltage")/1000.0;
00780         dict["microscope_voltage"]=(float)dict["DM3.voltage"];
00781         dict["DM3.cs"] = tagtable->get_double("Cs(mm)");
00782         dict["microscope_cs"]=(float)dict["DM3.cs"];
00783 
00784         dict["DM3.frame_type"] = tagtable->get_string("Processing");
00785         dict["DM3.camera_x"] = tagtable->get_int("Active Size (pixels) #0");
00786         dict["DM3.camera_y"] = tagtable->get_int("Active Size (pixels) #1");
00787         dict["DM3.binning_x"] = tagtable->get_int("Binning #0");
00788         dict["DM3.binning_y"] = tagtable->get_int("Binning #1");
00789         dict["datatype"] = to_em_datatype(tagtable->get_datatype());
00790 
00791         if ((float)dict["DM3.actual_mag"] >0.0) {
00792                 float apix=10000.0*(float)dict["DM3.pixel_size"]/(float)dict["DM3.actual_mag"];
00793                 dict["apix_x"]=apix;
00794                 dict["apix_y"]=apix;
00795                 dict["apix_z"]=apix;
00796         }
00797 
00798 //tagtable->dump();
00799 
00800         EXITFUNC;
00801         return err;
00802 }
00803 
00804 int DM3IO::read_data(float *rdata, int image_index, const Region * area, bool)
00805 {
00806         ENTERFUNC;
00807         //single image format, index can only be zero
00808         image_index = 0;
00809         check_read_access(image_index, rdata);
00810 
00811         portable_fseek(dm3file, NUM_ID_INT * sizeof(int), SEEK_SET);
00812 
00813         TagGroup root_group(dm3file, tagtable, "");
00814         root_group.read(false);
00815         
00816         int nx = tagtable->get_xsize();
00817         int ny = tagtable->get_ysize();
00818 
00819         check_region(area, IntSize(nx, ny));
00820 
00821         int xlen = 0, ylen = 0, x0 = 0, y0 = 0;
00822         EMUtil::get_region_dims(area, nx, &xlen, ny, &ylen);
00823         EMUtil::get_region_origins(area, &x0, &y0);
00824 
00825         char *data = tagtable->get_data();
00826         int data_type = tagtable->get_datatype();
00827 
00828         int k = 0;
00829         
00830         for (int i = y0; i < y0 + ylen; i++) {
00831                 for (int j = x0; j < x0 + xlen; j++) {
00832                         switch (data_type) {
00833                         case Gatan::DataType::SIGNED_INT8_DATA:
00834                                 rdata[k] = (float) ((char *) data)[i * nx + j];
00835                                 break;
00836                         case Gatan::DataType::UNSIGNED_INT8_DATA:
00837                                 rdata[k] = (float) ((unsigned char *) data)[i * nx + j];
00838                                 break;
00839                         case Gatan::DataType::SIGNED_INT16_DATA:
00840                                 rdata[k] = (float) ((short *) data)[i * nx + j];
00841                                 break;
00842                         case Gatan::DataType::UNSIGNED_INT16_DATA:
00843                                 rdata[k] = (float) ((unsigned short *) data)[i * nx + j];
00844                                 break;
00845                         case Gatan::DataType::SIGNED_INT32_DATA:
00846                                 rdata[k] = (float) ((int *) data)[i * nx + j];
00847                                 break;
00848                         case Gatan::DataType::UNSIGNED_INT32_DATA:
00849                                 rdata[k] = (float) ((unsigned int *) data)[i * nx + j];
00850                                 break;
00851                         case Gatan::DataType::REAL4_DATA:
00852                                 rdata[k] = (float) ((float *) data)[i * nx + j];
00853                                 break;
00854                         default:
00855                                 string desc = string("unsupported DM3 data type") +
00856                                         string(Gatan::to_str((Gatan::DataType::GatanDataType) data_type));
00857                                 throw ImageReadException(filename, desc);
00858                         }
00859                         k++;
00860                 }
00861         }
00862         EXITFUNC;
00863         return 0;
00864 }
00865 
00866 bool DM3IO::is_complex_mode()
00867 {
00868         return false;
00869 }
00870 
00871 int DM3IO::write_header(const Dict &, int, const Region* , EMUtil::EMDataType, bool)
00872 {
00873         ENTERFUNC;
00874         LOGWARN("DM3 write is not supported.");
00875         EXITFUNC;
00876         return 1;
00877 }
00878 
00879 int DM3IO::write_data(float *, int, const Region* , EMUtil::EMDataType, bool)
00880 {
00881         ENTERFUNC;
00882         LOGWARN("DM3 write is not supported.");
00883         EXITFUNC;
00884         return 1;
00885 }
00886 
00887 void DM3IO::flush()
00888 {
00889 }
00890 
00891 int Gatan::to_em_datatype(int gatan_datatype)
00892 {
00893         DataType::GatanDataType type = static_cast < DataType::GatanDataType > (gatan_datatype);
00894         int t = 0;
00895 
00896         switch (type) {
00897         case Gatan::DataType::SIGNED_INT8_DATA:
00898                 t = EMUtil::EM_CHAR;
00899                 break;
00900         case Gatan::DataType::UNSIGNED_INT8_DATA:
00901                 t = EMUtil::EM_UCHAR;
00902                 break;
00903         case Gatan::DataType::SIGNED_INT16_DATA:
00904                 t = EMUtil::EM_SHORT;
00905                 break;
00906         case Gatan::DataType::UNSIGNED_INT16_DATA:
00907                 t = EMUtil::EM_USHORT;
00908                 break;
00909         case Gatan::DataType::SIGNED_INT32_DATA:
00910                 t = EMUtil::EM_INT;
00911                 break;
00912         case Gatan::DataType::UNSIGNED_INT32_DATA:
00913                 t = EMUtil::EM_UINT;
00914                 break;
00915         default:
00916                 t = EMUtil::EM_UNKNOWN;
00917         }
00918 
00919         return t;
00920 }
00921 
00922 
00923 const char *Gatan::to_str(TagData::Type type)
00924 {
00925         const char *str = "unknown";
00926 
00927         switch (type) {
00928         case TagData::SHORT:
00929                 str = "short";
00930                 break;
00931         case TagData::INT:
00932                 str = "int";
00933                 break;
00934         case TagData::USHORT:
00935                 str = "unsigned short";
00936                 break;
00937         case TagData::UINT:
00938                 str = "unsigned int";
00939                 break;
00940         case TagData::FLOAT:
00941                 str = "float";
00942                 break;
00943         case TagData::DOUBLE:
00944                 str = "double";
00945                 break;
00946         case TagData::BOOLEAN:
00947                 str = "boolean";
00948                 break;
00949         case TagData::CHAR:
00950                 str = "char";
00951                 break;
00952         case TagData::OCTET:
00953                 str = "octet";
00954                 break;
00955         case TagData::STRUCT:
00956                 str = "struct";
00957                 break;
00958         case TagData::STRING:
00959                 str = "string";
00960                 break;
00961         case TagData::ARRAY:
00962                 str = "array";
00963                 break;
00964         default:
00965                 str = "unknown";
00966         }
00967         return str;
00968 }
00969 
00970 const char *Gatan::to_str(TagEntry::EntryType type)
00971 {
00972         const char *str = "unknown";
00973 
00974         switch (type) {
00975         case TagEntry::GROUP_TAG:
00976                 str = "Group";
00977                 break;
00978         case TagEntry::DATA_TAG:
00979                 str = "Data";
00980                 break;
00981         default:
00982                 str = "unknown";
00983         }
00984         return str;
00985 }
00986 
00987 
00988 const char *Gatan::to_str(Gatan::DataType::GatanDataType type)
00989 {
00990         switch (type) {
00991         case Gatan::DataType::SIGNED_INT16_DATA:
00992                 return "SIGNED_INT16_DATA";
00993         case Gatan::DataType::REAL4_DATA:
00994                 return "REAL4_DATA";
00995         case Gatan::DataType::COMPLEX8_DATA:
00996                 return "COMPLEX8_DATA";
00997         case Gatan::DataType::OBSELETE_DATA:
00998                 return "OBSELETE_DATA";
00999         case Gatan::DataType::PACKED_DATA:
01000                 return "PACKED_DATA";
01001         case Gatan::DataType::UNSIGNED_INT8_DATA:
01002                 return "UNSIGNED_INT8_DATA";
01003         case Gatan::DataType::SIGNED_INT32_DATA:
01004                 return "SIGNED_INT32_DATA";
01005         case Gatan::DataType::RGB_DATA:
01006                 return "RGB_DATA";
01007         case Gatan::DataType::SIGNED_INT8_DATA:
01008                 return "SIGNED_INT8_DATA";
01009         case Gatan::DataType::UNSIGNED_INT16_DATA:
01010                 return "UNSIGNED_INT16_DATA";
01011         case Gatan::DataType::UNSIGNED_INT32_DATA:
01012                 return "UNSIGNED_INT32_DATA";
01013         case Gatan::DataType::REAL8_DATA:
01014                 return "REAL8_DATA";
01015         case Gatan::DataType::COMPLEX16_DATA:
01016                 return "COMPLEX16_DATA";
01017         case Gatan::DataType::BINARY_DATA:
01018                 return "BINARY_DATA";
01019         case Gatan::DataType::RGB_UINT8_0_DATA:
01020                 return "RGB_UINT8_0_DATA";
01021         case Gatan::DataType::RGB_UINT8_1_DATA:
01022                 return "RGB_UINT8_1_DATA";
01023         case Gatan::DataType::RGB_UINT16_DATA:
01024                 return "RGB_UINT16_DATA";
01025         case Gatan::DataType::RGB_FLOAT32_DATA:
01026                 return "RGB_FLOAT32_DATA";
01027         case Gatan::DataType::RGB_FLOAT64_DATA:
01028                 return "RGB_FLOAT64_DATA";
01029         case Gatan::DataType::RGBA_UINT8_0_DATA:
01030                 return "RGBA_UINT8_0_DATA";
01031         case Gatan::DataType::RGBA_UINT8_1_DATA:
01032                 return "RGBA_UINT8_1_DATA";
01033         case Gatan::DataType::RGBA_UINT8_2_DATA:
01034                 return "RGBA_UINT8_2_DATA";
01035         case Gatan::DataType::RGBA_UINT8_3_DATA:
01036                 return "RGBA_UINT8_3_DATA";
01037         case Gatan::DataType::RGBA_UINT16_DATA:
01038                 return "RGBA_UINT16_DATA";
01039         case Gatan::DataType::RGBA_FLOAT32_DATA:
01040                 return "RGBA_FLOAT32_DATA";
01041         case Gatan::DataType::RGBA_FLOAT64_DATA:
01042                 return "RGBA_FLOAT64_DATA";
01043         case Gatan::DataType::POINT2_SINT16_0_DATA:
01044                 return "POINT2_SINT16_0_DATA";
01045         case Gatan::DataType::POINT2_SINT16_1_DATA:
01046                 return "POINT2_SINT16_1_DATA";
01047         case Gatan::DataType::POINT2_SINT32_0_DATA:
01048                 return "POINT2_SINT32_0_DATA";
01049         case Gatan::DataType::POINT2_FLOAT32_0_DATA:
01050                 return "POINT2_FLOAT32_0_DATA";
01051         case Gatan::DataType::RECT_SINT16_1_DATA:
01052                 return "RECT_SINT16_1_DATA";
01053         case Gatan::DataType::RECT_SINT32_1_DATA:
01054                 return "RECT_SINT32_1_DATA";
01055         case Gatan::DataType::RECT_FLOAT32_1_DATA:
01056                 return "RECT_FLOAT32_1_DATA";
01057         case Gatan::DataType::RECT_FLOAT32_0_DATA:
01058                 return "RECT_FLOAT32_0_DATA";
01059         case Gatan::DataType::SIGNED_INT64_DATA:
01060                 return "SIGNED_INT64_DATA";
01061         case Gatan::DataType::UNSIGNED_INT64_DATA:
01062                 return "UNSIGNED_INT64_DATA";
01063         default:
01064                 break;
01065         }
01066         return "Unknown Type";
01067 }
01068 

Generated on Tue Jun 11 13:40:37 2013 for EMAN2 by  doxygen 1.3.9.1