00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "situsio.h"
00037 #include "portable_fileio.h"
00038 #include "util.h"
00039
00040 using namespace EMAN;
00041
00042 const int SitusIO::SITUS_HEADER_LINES=2;
00043 const int SitusIO::FLOAT_SIZE = 12;
00044 const int SitusIO::NFLOAT_PER_LINE = 10;
00045 const char * SitusIO::OUTFORMAT = "%12.6f";
00046 const int SitusIO::LINE_LENGTH = 1024;
00047
00048 SitusIO::SitusIO(const string & situsname, IOMode rw) :
00049 filename(situsname), rw_mode(rw), situsfile(0),
00050 initialized(false), is_new_file(false),
00051 apix(0.0f), origx(0.0f), origy(0.0f), origz(0.0f),
00052 nx(0), ny(0), nz(0)
00053 {
00054 }
00055
00056 SitusIO::~SitusIO()
00057 {
00058 if (situsfile) {
00059 fclose(situsfile);
00060 situsfile = 0;
00061 }
00062 }
00063
00064 void SitusIO::init()
00065 {
00066 ENTERFUNC;
00067 if (initialized) {
00068 return;
00069 }
00070
00071 initialized = true;
00072 situsfile = sfopen(filename, rw_mode, &is_new_file);
00073
00074 if (!is_new_file) {
00075 char first_block[1024];
00076 fread(&first_block, sizeof(char), sizeof(first_block), situsfile);
00077 if (!is_valid(&first_block)) {
00078 throw ImageReadException(filename, "invalid SITUS file");
00079 }
00080
00081 char * buf = (char *)first_block;
00082 string line1 = Util::get_line_from_string(&buf);
00083
00084 sscanf(line1.c_str(), "%f %f %f %f %d %d %d", &apix, &origx, &origy, &origz, &nx, &ny, &nz);
00085 }
00086
00087 EXITFUNC;
00088 }
00089
00090 int SitusIO::read_data(float* data, int image_index, const EMAN::Region*, bool)
00091 {
00092 ENTERFUNC;
00093
00094 image_index = 0;
00095
00096 portable_fseek(situsfile, 0, SEEK_SET);
00097 EMUtil::jump_lines(situsfile, SITUS_HEADER_LINES);
00098
00099 int number_lines = nx*ny*nz / NFLOAT_PER_LINE + 1;
00100
00101 size_t index = 0;
00102 int nitems_in_line = 0;
00103 for (int i=0; i<number_lines; ++i) {
00104 char line[LINE_LENGTH];
00105 if (!fgets(line, sizeof(line), situsfile)) {
00106 printf("read situs file failed\n");
00107 }
00108
00109 nitems_in_line = (int) (strlen(line) / FLOAT_SIZE);
00110 char * pline = line;
00111 for (int j=0; j<nitems_in_line; ++j) {
00112 sscanf(pline, "%f", &data[index]);
00113 pline += FLOAT_SIZE;
00114 ++index;
00115 }
00116 }
00117
00118 EXITFUNC;
00119 return 0;
00120 }
00121
00122 int SitusIO::read_header(EMAN::Dict& dict, int, const EMAN::Region*, bool)
00123 {
00124 ENTERFUNC;
00125 init();
00126
00127 dict["nx"] = nx;
00128 dict["ny"] = ny;
00129 dict["nz"] = nz;
00130
00131 dict["apix_x"] = apix;
00132 dict["apix_y"] = apix;
00133 dict["apix_z"] = apix;
00134
00135 dict["origin_x"] = origx;
00136 dict["origin_y"] = origy;
00137 dict["origin_z"] = origz;
00138
00139 EXITFUNC;
00140 return 0;
00141 }
00142
00143 int SitusIO::write_header(const EMAN::Dict& dict, int, const EMAN::Region*, EMAN::EMUtil::EMDataType, bool)
00144 {
00145 ENTERFUNC;
00146 init();
00147
00148 apix = (float)dict["apix_x"];
00149 origx = (float)dict["origin_x"];
00150 origy = (float)dict["origin_y"];
00151 origz = (float)dict["origin_z"];
00152 nx = (int)dict["nx"];
00153 ny = (int)dict["ny"];
00154 nz = (int)dict["nz"];
00155
00156 char headerline[LINE_LENGTH];
00157 sprintf(headerline, "%.6f %.6f %.6f %.6f %d %d %d", apix, origx, origy, origz, nx, ny, nz);
00158
00159 if(!fputs(headerline, situsfile)) {
00160 printf("Write situs header failed\n");
00161 }
00162
00163 if(!fputs("\n\n", situsfile)) {
00164 printf("Write situs header failed\n");
00165 }
00166
00167 EXITFUNC;
00168 return 0;
00169 }
00170
00171 int SitusIO::write_data(float* data, int, const EMAN::Region*, EMAN::EMUtil::EMDataType, bool)
00172 {
00173 ENTERFUNC;
00174
00175 for (size_t index=0; index<(size_t)nx*ny*nz; ++index) {
00176 fprintf(situsfile, OUTFORMAT, data[index]);
00177 if((index+1)%NFLOAT_PER_LINE == 0) {
00178 fputs("\n", situsfile);
00179 }
00180 }
00181
00182 EXITFUNC;
00183 return 0;
00184 }
00185
00186 bool SitusIO::is_valid(const void *first_block)
00187 {
00188 ENTERFUNC;
00189 if (!first_block) {
00190 return false;
00191 }
00192
00193 char *buf = (char *)(first_block);
00194 string line1 = Util::get_line_from_string(&buf);
00195
00196 if(line1.size()==0) return false;
00197
00198 float apix, origx, origy, origz;
00199 int nx, ny, nz;
00200
00201 if(sscanf(line1.c_str(), "%f %f %f %f %d %d %d", &apix, &origx, &origy, &origz, &nx, &ny, &nz) != 7) return false;
00202
00203 if(apix<0.01 || apix>100) return false;
00204 if(nx<=0 || ny<0 || nz<0) return false;
00205
00206 EXITFUNC;
00207 return true;
00208 }
00209
00210 void SitusIO::flush()
00211 {
00212 fflush(situsfile);
00213 }
00214
00215 bool SitusIO::is_image_big_endian()
00216 {
00217 return ByteOrder::is_host_big_endian();
00218 }
00219
00220 bool SitusIO::is_complex_mode()
00221 {
00222 return false;
00223 }