funkalicious 0.1

grid1.c

Go to the documentation of this file.
00001 /*
00002 ** grid1.c
00003 ** 
00004 
00005     Copyright (C) 2009 Joseph Pingenot
00006 
00007     This program is free software: you can redistribute it and/or modify
00008     it under the terms of the GNU Affero General Public License as published by
00009     the Free Software Foundation, either version 3 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU Affero General Public License for more details.
00016 
00017     You should have received a copy of the GNU Affero General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 
00020 ** Made by (Johnny Q. Hacker)
00021 ** Login   <solarion@borkborkbork>
00022 ** 
00023 ** Started on  Mon Nov 23 16:18:25 2009 Johnny Q. Hacker
00024 ** Last update Sun May 12 01:17:25 2002 Speed Blue
00025 */
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <glib-2.0/glib.h>
00029 #include <gio/gio.h>
00030 #include <libdotcode/dotcode_generic.h>
00031 #include <libdotcode/grid1.h>
00032 #include <libdotcode/read_binary_data.h>
00033 #include <libdotcode/matdb.h>
00034 #include <libdotcode/matdb-dotcode.h>
00035 #include "gcc_hints.h"
00036 
00037 #define DOTCODE_GRID1_GERROR_DOMAIN 9132
00038 
00039 hotfunc ___const ___always_inline long unsigned int get_assignment_index(int x, int y, int z, int Nx, int Ny) {
00040     return x + Nx*(y + Ny*(z));
00041 }
00042 
00043 long unsigned int dotcode_grid1_get_assignment_index(int x, int y, int z, int Nx, int Ny) {
00044   return get_assignment_index(x, y, z, Nx, Ny);
00045 }
00046 
00047 /*Just a stub for now*/
00048 GError* dotcode_grid1_write_to_GFile(GFile* f, const struct dotcode_grid1* grid) {
00049   return g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_NOTIMPLEMENTED, "dotcode::grid1::write_to_GFile: ERROR: this functionality is not yet implemented.");
00050 }
00051 void dotcode_grid1_free(struct dotcode_grid1* grid) {
00052   g_strfreev(grid->materials);
00053   if(grid->assignments != NULL) free(grid->assignments);
00054   free(grid);
00055 }
00056 
00057 
00058 
00059 struct dotcode_grid1* dotcode_grid1_get_from_gfile(GFile* f, GError **error) {
00060   struct dotcode_grid1* grid = (struct dotcode_grid1*)malloc(sizeof(struct dotcode_grid1));
00061   if(grid == NULL) {
00062     *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_MALLOCFAIL, "dotcode::grid1::get_from_GFile: Failed to allocate a new struct dotcode_grid1");
00063     return NULL;
00064   }
00065   GError *e = NULL;
00066   GFileInputStream *fis = g_file_read(f, NULL, &e);
00067   if((e != NULL) || (fis == NULL)) {
00068     if(e == NULL) {
00069       char* str = g_file_get_uri(f);
00070       *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to open the grid file (%s), but no further error was given.\n", str);
00071       g_free(str);
00072     }else{
00073       *error = e;
00074     }
00075     free(grid);
00076     return NULL;
00077   }
00078   /*The file is now open.*/
00079   char endian;
00080   gsize sz;
00081   if((!g_input_stream_read_all((GInputStream*)fis, &endian, 1, &sz, NULL, &e)) || (sz != 1)) {
00082     if(e == NULL) {
00083       *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read endianness from the stream: didn't get a single byte; got %lu", (long unsigned int)sz);
00084     }else{
00085       *error = e;
00086     }
00087     free(grid);
00088     return NULL;
00089   }
00090   gboolean little_endian;
00091   switch(endian) {
00092   case 'l':
00093     little_endian = TRUE;
00094     break;
00095   case 'b':
00096     little_endian = FALSE;
00097     break;
00098   default:
00099     *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read endianness from the stream: got invalid character (%d)", (int)endian);
00100     free(grid);
00101     return NULL;
00102   }
00103   e = NULL;
00104   char *grid1_string = dotcode_read_sstring(little_endian, (GInputStream*)fis, &e);
00105   if((grid1_string == NULL) || (e != NULL)) {
00106     if(e == NULL) {
00107     *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read \"Grid1\" sstring from input stream.\n");
00108     }else{
00109       *error = e;
00110     }
00111     free(grid);
00112     return NULL;
00113   }
00114   if(g_strcmp0(grid1_string, "Grid1")) {
00115     *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failure reading grid1 stream: string (%s) did not match expected string (%s)\n", grid1_string, "Grid1");
00116     free(grid);
00117     return NULL;
00118   }
00119   e = NULL;
00120   free(grid1_string);
00121   grid1_string = dotcode_read_sstring(little_endian, (GInputStream*)fis, &e);
00122   if((grid1_string == NULL) || (e != NULL)) {
00123     if(e == NULL) {
00124     *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read \"1\" sstring from input stream.\n");
00125     }else{
00126       *error = e;
00127     }
00128     free(grid);
00129     return NULL;
00130   }
00131   if(g_strcmp0(grid1_string, "1")) {
00132     *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failure reading grid1 stream: string (%s) did not match expected string (%s)\n", grid1_string, "1");
00133     free(grid);
00134     return NULL;
00135   }
00136   free(grid1_string);
00137   /*Read in ignored int, Nxyz, and number of materials*/
00138   int N_materials = -1;
00139   for(int i=0; i<5; i++) {
00140     e = NULL;
00141     int j =  dotcode_read_int(little_endian, (GInputStream*)fis, &e);
00142     if(e != NULL) {
00143       *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read header int %d from input stream. (error=%s)", i, e->message);
00144       g_error_free(e);
00145       free(grid);
00146       return NULL;
00147     }
00148     if((i > 0) && (i < 4)) {
00149       grid->N[i-1]=j;
00150     }else if(i==4) {
00151       N_materials = j;
00152     }
00153   }
00154   /*Set up the materials storage.*/
00155   grid->materials = (char**)malloc((N_materials+1)*sizeof(char*));
00156   if(grid->materials == NULL) {
00157     *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_MALLOCFAIL, "dotcode::grid1::get_from_GFile: Failed to allocate material name storage.\n");
00158     free(grid);
00159     return NULL;
00160   }
00161   /*allocate storage for the unsigned chars.*/
00162   grid->assignments = (unsigned char*)malloc(sizeof(unsigned char)*(grid->N[0])*(grid->N[1])*(grid->N[2]));
00163   if(grid->assignments == NULL) {
00164     *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_MALLOCFAIL, "dotcode::grid1::get_from_GFile: Failed to allocate material assignment storage.\n");
00165     free(grid->materials);
00166     free(grid);
00167     return NULL;
00168   }
00169   /*Set the last pointer to NULL to indicate the last one.*/
00170   (grid->materials)[N_materials] = NULL;
00171   /*Now read in N_materials materials*/
00172   #ifdef DEBUG3
00173   fprintf(stderr, "N_materials=%d:", N_materials);
00174   #endif
00175   for(int i=0; i<N_materials; i++) {
00176     e = NULL;
00177     (grid->materials)[i] = dotcode_read_sstring(little_endian, (GInputStream*)fis, &e);
00178     if(e != NULL) {
00179       *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read %d-th material sstring in header (error=%s)", i, e->message);
00180       g_error_free(e);
00181       for(int j=0; j<i; j++) {
00182   free(grid->materials[j]);
00183       }
00184       free(grid->assignments);
00185       free(grid);
00186       return NULL;
00187     }
00188     #ifdef DEBUG3
00189     fprintf(stderr, "%s, ", grid->materials[i]);
00190     #endif
00191   }
00192   #ifdef DEBUG3
00193   fprintf(stderr, "\n");
00194   #endif
00195   /*We read in another, identical-number-of-sstrings section that's ignored.*/
00196   for(int i=0; i<N_materials; i++) {
00197     e = NULL;
00198     free(dotcode_read_sstring(little_endian, (GInputStream*)fis, &e));
00199     if(e != NULL) {
00200       *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read %d-th ignored sstring in header (error=%s)", i, e->message);
00201       g_error_free(e);
00202       g_strfreev(grid->materials);
00203       free(grid->assignments);
00204       free(grid);
00205       return NULL;
00206     }
00207   }
00208   /*We now read in 3 ignored ints*/
00209   for(int i=0; i<3; i++) {
00210     e = NULL;
00211     dotcode_read_int(little_endian, (GInputStream*)fis, &e);
00212     if(e != NULL) {
00213       *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read ignored header int %d from input stream (error=%s)", i, e->message);
00214       g_error_free(e);
00215       g_strfreev(grid->materials);
00216       free(grid->assignments);
00217       free(grid);
00218       return NULL;
00219     }
00220   }
00221   /*And 15 float8s, which starts with 12 ignored ones and then 3 that have the grid spacings*/
00222   for(int i=0; i<15; i++) {
00223     double j =  dotcode_read_float8(little_endian, (GInputStream*)fis, &e);
00224     #ifdef DEBUG3
00225     fprintf(stderr, "%d=%g\n", i, j);
00226     #else
00227     j=j;
00228     #endif
00229     if(e != NULL) {
00230       *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read header double %d from input stream (error=%s)", i, e->message);
00231       g_error_free(e);
00232       g_strfreev(grid->materials);
00233       free(grid->assignments);
00234       free(grid);
00235       return NULL;
00236     }
00237   }
00238   for(int j=0; j<3; j++) {
00239     for(int i=0; i<grid->N[j]; i++) {
00240       double val =  dotcode_read_float8(little_endian, (GInputStream*)fis, &e);
00241       if(e != NULL) {
00242         *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read header double %d from input stream (error=%s)", i, e->message);
00243   g_error_free(e);
00244   g_strfreev(grid->materials);
00245   free(grid->assignments);
00246   free(grid);
00247   return NULL;
00248       }
00249       /*There are a sequence of floats which we assume will be the
00250        *same (same grid spacing for each grid site along a given
00251        *direction; otherwise, we'd need a list of dx[3][N[i]] to store
00252        *the grid site lengths
00253        */
00254       if(i != 0) {
00255   /*Precision is irrelevant; we put the bits in there, and they
00256     should be the same for every point along the axis*/
00257   if(grid->dx[j] != val) {
00258     *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Error while processing dx[%d]: set value is %g, but the %dth value is %g", j, grid->dx[j], i, val);
00259     g_error_free(e);
00260     g_strfreev(grid->materials);
00261     free(grid->assignments);
00262     free(grid);
00263     return NULL;
00264   }
00265       }else{
00266   grid->dx[j] = val;
00267       }
00268       #ifdef DEBUG3
00269       fprintf(stderr, "dx[%d](%d/%d)=%g(%g)\n", j, i, grid->N[j], grid->dx[j], val);
00270       #endif
00271     }
00272   }
00273 
00274   /*We now have a giant array of unsigned chars, but we can just read them in all at once.*/
00275 
00276   e = NULL;
00277   if((!g_input_stream_read_all((GInputStream*)fis, grid->assignments, (grid->N[0])*(grid->N[1])*(grid->N[2]), &sz, NULL, &e)) || (sz != (grid->N[0])*(grid->N[1])*(grid->N[2]))) {
00278     if(e == NULL) {
00279       *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read material assignments (%lu bytes) from the stream: got %lu bytes", (long unsigned int)(grid->N[0])*(grid->N[1])*(grid->N[2]), (long unsigned int)sz );
00280     }else{
00281       *error = e;
00282     }
00283     g_strfreev(grid->materials);
00284     free(grid->assignments);
00285     free(grid);
00286     return NULL;
00287   }
00288 
00289   /*Close the file; we're done*/
00290   g_input_stream_close((GInputStream*)fis, NULL, &e);
00291   /*Be paranoid. An error here means we have corrupted data somewhere.
00292     It seems likely to me that this will be true. And paranoia when it comes
00293     to data integrity is Good. In fact, I should probably look into HDF
00294     checksumming.*/
00295   if(e != NULL) {
00296     g_strfreev(grid->materials);
00297     free(grid->assignments);
00298     free(grid);
00299     *error = e;
00300     return NULL;
00301   }
00302   return grid;
00303 }
00304 
00305 
00306 double* dotcode_grid1_get_property_grid(const struct dotcode_grid1* grid, const struct matdb *mdb, const char* property, GError **err) {
00307   double* props = (double*)malloc((grid->N[0])*(grid->N[1])*(grid->N[2])*sizeof(double));
00308   if(props == NULL) {
00309     *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_MALLOCFAIL, "libdotcode::grid1::dotcode_grid1_get_property_grid: ERROR: failed to allocate memory for the property grid");
00310     return NULL;
00311   }
00312   GError *e = NULL;
00313   double *propcache = dotcode_grid1_get_property_cache(grid, mdb, property, &e);
00314   if((propcache == NULL) || (e != NULL)) {
00315     g_propagate_prefixed_error(err, e, "libdotcode::grid1::get_property_grid: Unable to set up the property cache!");
00316     free(props);
00317     return NULL;
00318   }
00319   int N_mats;
00320   for(N_mats=0; grid->materials[N_mats]!=NULL; N_mats++);
00321   int ierror;
00322   for(int i=0; i<N_mats; i++) {
00323     propcache[i] = get_property(mdb, property, grid->materials[i], &ierror);
00324     if(ierror != 0) {
00325       *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_GRID1_ERROR_NOSUCHPROPERTY, "libdotcode::grid1::dotcode_grid1_get_property_grid: ERROR: unable to find property %s in for material %s in the material database.", property, grid->materials[i]);
00326       free(propcache);
00327       free(props);
00328       return NULL;
00329     }
00330   }
00331   for(int k=0; k<(grid->N[2]); k++) {
00332     for(int j=0; j<(grid->N[1]); j++) {
00333       for(int i=0; i<(grid->N[0]); i++) {
00334   props[get_assignment_index(i, j, k, grid->N[0], grid->N[1])] = propcache[grid->assignments[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]];
00335       }
00336     }
00337   }
00338   free(propcache);
00339   return props;
00340 }
00341 
00342 double dotcode_grid1_get_property_at_site(const struct dotcode_grid1* grid, const struct matdb *mdb, const char* property, const int* index, GError **err) {
00343   int mat =  grid->assignments[get_assignment_index(index[0], index[1], index[2], grid->N[0], grid->N[1])];
00344   int ierror=0;
00345   double ppt = get_property(mdb, property, grid->materials[mat], &ierror);
00346   if(ierror != 0) {
00347     *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_GRID1_ERROR_NOSUCHPROPERTY, "libdotcode::grid1::dotcode_grid1_get_property_at_site: ERROR: got error %d (probably couldn't find property %s in for material %s in the material database).", ierror, property, grid->materials[mat]);
00348   }
00349   return ppt;
00350 }
00351 
00352 double dotcode_grid1_get_property_at_site_cached(const struct dotcode_grid1* grid, const double* propcache, const int* index) {
00353   return propcache[grid->assignments[get_assignment_index(index[0], index[1], index[2], grid->N[0], grid->N[1])]];
00354 }
00355 
00356 void dotcode_grid1_write_assignments_slice_text(const struct dotcode_grid1* grid, GFile* base, enum dotcode_coord coord, int index, GError **err) {
00357   GError *e;
00358   GString *s = g_string_new("matslice_");;
00359   switch(coord) {
00360   case DOTCODE_COORD_X:
00361     g_string_append_printf(s, "X=%d.pdata", index);
00362     break;
00363   case DOTCODE_COORD_Y:
00364     g_string_append_printf(s, "Y=%d.pdata", index);
00365     break;
00366   case DOTCODE_COORD_Z:
00367     g_string_append_printf(s, "Z=%d.pdata", index);
00368     break;
00369   }
00370   GFile* f;
00371   if(base == NULL) {
00372     f = g_file_new_for_path(s->str);
00373   }else{
00374     f = g_file_resolve_relative_path(base, s->str);
00375   }
00376   e = NULL;
00377   GFileIOStream *gfos = g_file_create_readwrite(f, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &e);
00378   if(e != NULL) {
00379     *err = e;
00380     return;
00381   }
00382   GOutputStream *os = g_io_stream_get_output_stream((GIOStream*)gfos);
00383   GDataOutputStream *dos = g_data_output_stream_new(os);
00384   g_string_printf(s, "#index\tmaterial\n");
00385   e=NULL;
00386   char *str;
00387   g_data_output_stream_put_string(dos, s->str, NULL, &e);
00388   if(e != NULL) {
00389     *err = e;
00390     g_string_free(s, TRUE);
00391     e=NULL;
00392     g_io_stream_close((GIOStream*)gfos, NULL, &e);
00393     if(e != NULL) {
00394       *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_ERRORED_THEN_CLOSED_ERROR, "libdotcode::grid1::dotcode_grid1_write_assignment_text: had an error (%s) while writing string (%s), but had another error (%s) while closing the file (%s)!\n", (*err)->message, s->str, e->message, str=g_file_get_uri(f));
00395       g_free(str);
00396     }
00397     return;
00398   }
00399   for(int i=0; (grid->materials)[i] != NULL; i++) {
00400     g_string_printf(s, "#%i\t%s\n", i, (grid->materials)[i]);
00401     e=NULL;
00402     char *str;
00403     g_data_output_stream_put_string(dos, s->str, NULL, &e);
00404     if(e != NULL) {
00405       *err = e;
00406       g_string_free(s, TRUE);
00407       e=NULL;
00408       g_io_stream_close((GIOStream*)gfos, NULL, &e);
00409       if(e != NULL) {
00410   *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_ERRORED_THEN_CLOSED_ERROR, "libdotcode::grid1::dotcode_grid1_write_assignment_text: had an error (%s) while writing string (%s), but had another error (%s) while closing the file (%s)!\n", (*err)->message, s->str, e->message, str=g_file_get_uri(f));
00411   g_free(str);
00412       }
00413       return;
00414     }
00415   }
00416   switch(coord) {
00417   case DOTCODE_COORD_X:
00418     g_string_printf(s, "#Y()\tZ(sites)\tmaterial index\n");
00419     break;
00420   case DOTCODE_COORD_Y:
00421     g_string_printf(s, "#X(sites)\tZ(sites)\tmaterial index\n");
00422     break;
00423   case DOTCODE_COORD_Z:
00424     g_string_printf(s, "#X(sites)\tY(sites)\tmaterial index\n");
00425     break;
00426   }
00427   e=NULL;
00428   g_data_output_stream_put_string(dos, s->str, NULL, &e);
00429   if(e != NULL) {
00430     *err = e;
00431     g_string_free(s, TRUE);
00432     e=NULL;
00433     g_io_stream_close((GIOStream*)gfos, NULL, &e);
00434     if(e != NULL) {
00435       *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_ERRORED_THEN_CLOSED_ERROR, "libdotcode::grid1::dotcode_grid1_write_assignment_text: had an error (%s) while writing string (%s), but had another error (%s) while closing the file (%s)!\n", (*err)->message, s->str, e->message, str=g_file_get_uri(f));
00436       g_free(str);
00437     }
00438     return;
00439   }
00440   for(int k=0; k<grid->N[2]; k++) {
00441     if((coord == DOTCODE_COORD_Z) && (k != index)) continue;
00442     for(int j=0; j<grid->N[1]; j++) {
00443       if((coord == DOTCODE_COORD_Y) && (j != index)) continue;
00444       for(int i=0; i<grid->N[0]; i++) {
00445   if((coord == DOTCODE_COORD_X) && (i != index)) continue;
00446   e=NULL;
00447   switch(coord) {
00448   case DOTCODE_COORD_X:
00449     g_string_printf(s, "%d\t%d\t%d\n", j, k, grid->assignments[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]);
00450     break;
00451   case DOTCODE_COORD_Y:
00452     g_string_printf(s, "%d\t%d\t%d\n", i, k, grid->assignments[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]);
00453     break;
00454   case DOTCODE_COORD_Z:
00455     g_string_printf(s, "%d\t%d\t%d\n", i, j, grid->assignments[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]);
00456     break;
00457   }
00458   g_data_output_stream_put_string(dos, s->str, NULL, &e);
00459   if(e != NULL) {
00460     *err = e;
00461     g_string_free(s, TRUE);
00462     e=NULL;
00463     g_io_stream_close((GIOStream*)gfos, NULL, &e);
00464     if(e != NULL) {
00465       *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_ERRORED_THEN_CLOSED_ERROR, "libdotcode::grid1::dotcode_grid1_write_assignment_text: had an error (%s) while writing string (%s), but had another error (%s) while closing the file (%s)!\n", (*err)->message, s->str, e->message, str=g_file_get_uri(f));
00466       g_free(str);
00467     }
00468     return;
00469   }
00470       }
00471     }
00472   }
00473   g_io_stream_close((GIOStream*)gfos, NULL, &e);
00474   if(e != NULL) {
00475     *err = e;
00476   }
00477   g_string_free(s, TRUE);
00478 }
00479 
00480 void dotcode_grid1_write_property_slice_text(const struct dotcode_grid1* grid, const double* property_array, const char* property_name, GFile* base, enum dotcode_coord coord, int index, GError **err) {
00481   GError *e;
00482   GString *s = g_string_new("propslice_");;
00483   switch(coord) {
00484   case DOTCODE_COORD_X:
00485     g_string_append_printf(s, "X=%d.pdata", index);
00486     break;
00487   case DOTCODE_COORD_Y:
00488     g_string_append_printf(s, "Y=%d.pdata", index);
00489     break;
00490   case DOTCODE_COORD_Z:
00491     g_string_append_printf(s, "Z=%d.pdata", index);
00492     break;
00493   }
00494   GFile* f;
00495   if(base == NULL) {
00496     f = g_file_new_for_path(s->str);
00497   }else{
00498     f = g_file_resolve_relative_path(base, s->str);
00499   }
00500   e = NULL;
00501   GFileIOStream *gfos = g_file_create_readwrite(f, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &e);
00502   if(e != NULL) {
00503     *err = e;
00504     return;
00505   }
00506   GOutputStream *os = g_io_stream_get_output_stream((GIOStream*)gfos);
00507   GDataOutputStream *dos = g_data_output_stream_new(os);
00508   switch(coord) {
00509   case DOTCODE_COORD_X:
00510     g_string_printf(s, "#Y()\tZ(sites)\t%s\n", property_name);
00511     break;
00512   case DOTCODE_COORD_Y:
00513     g_string_printf(s, "#X(sites)\tZ(sites)\t%s\n", property_name);
00514     break;
00515   case DOTCODE_COORD_Z:
00516     g_string_printf(s, "#X(sites)\tY(sites)\t%s\n", property_name);
00517     break;
00518   }
00519   e=NULL;
00520   g_data_output_stream_put_string(dos, s->str, NULL, &e);
00521   char* str;
00522   if(e != NULL) {
00523     *err = e;
00524     g_string_free(s, TRUE);
00525     e=NULL;
00526     g_io_stream_close((GIOStream*)gfos, NULL, &e);
00527     if(e != NULL) {
00528       *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_ERRORED_THEN_CLOSED_ERROR, "libdotcode::grid1::dotcode_grid1_write_property_text: had an error (%s) while writing string (%s), but had another error (%s) while closing the file (%s)!\n", (*err)->message, s->str, e->message, str=g_file_get_uri(f));
00529       g_free(str);
00530     }
00531     return;
00532   }
00533   for(int k=0; k<grid->N[2]; k++) {
00534     if((coord == DOTCODE_COORD_Z) && (k != index)) continue;
00535     for(int j=0; j<grid->N[1]; j++) {
00536       if((coord == DOTCODE_COORD_Y) && (j != index)) continue;
00537       for(int i=0; i<grid->N[0]; i++) {
00538   if((coord == DOTCODE_COORD_X) && (i != index)) continue;
00539   e=NULL;
00540   switch(coord) {
00541   case DOTCODE_COORD_X:
00542     g_string_printf(s, "%d\t%d\t%g\n", j, k, property_array[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]);
00543     break;
00544   case DOTCODE_COORD_Y:
00545     g_string_printf(s, "%d\t%d\t%g\n", i, k, property_array[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]);
00546     break;
00547   case DOTCODE_COORD_Z:
00548     g_string_printf(s, "%d\t%d\t%g\n", i, j, property_array[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]);
00549     break;
00550   }
00551   g_data_output_stream_put_string(dos, s->str, NULL, &e);
00552   if(e != NULL) {
00553     *err = e;
00554     g_string_free(s, TRUE);
00555     e=NULL;
00556     g_io_stream_close((GIOStream*)gfos, NULL, &e);
00557     if(e != NULL) {
00558       *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_ERRORED_THEN_CLOSED_ERROR, "libdotcode::grid1::dotcode_grid1_write_property_text: had an error (%s) while writing string (%s), but had another error (%s) while closing the file (%s)!\n", (*err)->message, s->str, e->message, str=g_file_get_uri(f));
00559       g_free(str);
00560     }
00561     return;
00562   }
00563       }
00564     }
00565   }
00566   g_io_stream_close((GIOStream*)gfos, NULL, &e);
00567   if(e != NULL) {
00568     *err = e;
00569   }
00570   g_string_free(s, TRUE);
00571 }
00572 
00573 double* dotcode_grid1_get_property_cache(const struct dotcode_grid1* grid, const struct matdb* mdb, const char* property_name, GError **err) {
00574   int N_mats;
00575   for(N_mats=0; grid->materials[N_mats]!=NULL; N_mats++);
00576   double* cache = (double*)malloc(N_mats*sizeof(double));
00577   if(cache == NULL) {
00578     *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_MALLOCFAIL, "libdotcode::grid1::dotcode_grid1_get_property_cache: ERROR: unable to allocate memory for the property cache (property=%s)", property_name);
00579     return NULL;
00580   }
00581   int ierror=0;
00582   for(int i=0; i<N_mats; i++) {
00583     cache[i] = get_property(mdb, property_name, grid->materials[i], &ierror);
00584     if(ierror != 0) {
00585       *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_GRID1_ERROR_NOSUCHPROPERTY, "libdotcode::grid1::dotcode_grid1_get_property_cache: ERROR: %d; probably unable to find property %s in for material %s in the material database.", ierror, property_name, grid->materials[i]);
00586       free(cache);
00587       return NULL;
00588     }
00589   }
00590   return cache;
00591 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines