funkalicious 0.1

dc_sweep_n_slice_args.c

Go to the documentation of this file.
00001 /**Args for dc_sweep_n_slice
00002 
00003 
00004     Copyright (C) 2011 Joseph Pingenot
00005 
00006     This program is free software: you can redistribute it and/or modify
00007     it under the terms of the GNU Affero General Public License as published by
00008     the Free Software Foundation, either version 3 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU Affero General Public License for more details.
00015 
00016     You should have received a copy of the GNU Affero General Public License
00017     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 
00019 */
00020 
00021 #include <errno.h>
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <gio/gio.h>
00026 #include <math.h>
00027 #include <glib-2.0/glib.h>
00028 #include "config.h"
00029 #include "dc_sweep_n_slice_args.h"
00030 
00031 #define GET_DC_SWEEP_N_SLICE_ARGS_DOMAIN 1024
00032 
00033 extern void program_print_version(FILE* f);
00034 extern void libdotcode_print_version(FILE* f);
00035 extern void libpostproc_print_version(FILE* f);
00036 extern const char* version_info;
00037 
00038 void print_version_info() {
00039   program_print_version(stdout);
00040   libdotcode_print_version(stdout);
00041   libpostproc_print_version(stdout);
00042   printf("autotools info:\n\tProject: %s\n\tVersion: %s\n", PACKAGE_NAME, VERSION);
00043   printf("Platform information:\n\tSize of int=%d double=%d\n\tEndianness: %s\n", SIZEOF_INT, SIZEOF_DOUBLE,
00044 #ifdef WORDS_BIGENDIAN
00045    "big"
00046 #else
00047    "little"
00048 #endif
00049    );
00050 }
00051 
00052 double double_from_string(const char* s, GError **err) {
00053   double d;
00054   char *end;
00055   errno = 0;
00056   d = strtod(s, &end);
00057   if(((end == s) && (d == 0)) || (errno != 0)) {
00058     *err = g_error_new(GET_DC_SWEEP_N_SLICE_ARGS_DOMAIN, 2, "dc_sweep_n_slice_args.c::double_from_string: Error occurred converting string (%s) to double: %s", s, strerror(errno));
00059     return nan("NaN");
00060   }
00061   return d;
00062 }
00063 int int_from_string(const char* s, GError **err) {
00064   int d;
00065   char *end;
00066   errno = 0;
00067   d = strtod(s, &end);
00068   if(((end == s) && (d == 0)) || (errno != 0)) {
00069     *err = g_error_new(GET_DC_SWEEP_N_SLICE_ARGS_DOMAIN, 2, "dc_sweep_n_slice_args.c::int_from_string: Error occurred converting string (%s) to int: %s", s, strerror(errno));
00070     return nan("NaN");
00071   }
00072   return d;
00073 }
00074 
00075 
00076 void get_args(int argc, char** argv, struct args* args, GError **err) {
00077   /**set defaults*/
00078   args->use_110_coordinates=FALSE;
00079   args->use_max_probability_point=TRUE;
00080   args->use_gridsite=FALSE;
00081   for(int i=0; i<3; i++) {
00082     args->axes[i]=FALSE;
00083     args->planes[i]=FALSE;
00084     args->point[i]=0;
00085     args->gridsite[i]=0;
00086     args->sweeps[i]=FALSE;
00087   }
00088   args->wavefunctions=NULL;
00089   args->bands=NULL;
00090   gboolean print_version;
00091   gchar* position = NULL;
00092   gchar* gridsite = NULL;
00093   gboolean each_band = FALSE;
00094   GOptionEntry options[] = {
00095     { "version", 'v', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &print_version, "Print version information about this program", NULL },
00096     //{ "110", '1', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &(args->use_110_coordinates), "Use the (110) coordinate system instead of (100) (i.e. use coordinate system x->(110), y->(-110), z->(001))", NULL},
00097     { "xaxis", 'x', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &(args->axes[0]), "Save the wavefunction along the x axis", NULL},
00098     { "yaxis", 'y', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &(args->axes[1]), "Save the wavefunction along the y axis", NULL},
00099     { "zaxis", 'z', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &(args->axes[2]), "Save the wavefunction along the z axis", NULL},
00100     { "sweepx", 'X', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &(args->sweeps[0]), "Sweep (plot into a pbm each cooordinate of) the wavefunction along the x axis", NULL},
00101     { "sweepy", 'Y', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &(args->sweeps[1]), "Sweep (plot into a pbm each cooordinate of) the wavefunction along the y axis", NULL},
00102     { "sweepz", 'Z', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &(args->sweeps[2]), "Sweep (plot into a pbm each cooordinate of) the wavefunction along the z axis", NULL},
00103     { "xy", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &(args->planes[0]), "Save the wavefunction in the xy plane", NULL},
00104     { "xz", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &(args->planes[1]), "Save the wavefunction in the xz plane", NULL},
00105     { "yz", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &(args->planes[2]), "Save the wavefunction in the yz plane", NULL},
00106     { "all-bands", 'a', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &each_band, "Print all of the bands separately instead of the total probability density.", NULL},
00107     { "at", '@', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING, &position, "Position at which to print the wavefunction along the specified directions.  Point consists of comma-separted set of floats (will be snapped to gridsite).  If no site is given (either with -@ or -g), default is to get the maximum wavefunction prboability density.", NULL},
00108     { "gridsite", 'g', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING, &gridsite, "Gridsite at which to print the wavefunction along the specified directions.  Point consists of comma-separted set of integers.  If no site is given (either with -@ or -g), default is to get the maximum wavefunction prboability density.", NULL},
00109       {NULL}
00110   };
00111   GOptionContext *ctx;
00112   ctx = g_option_context_new("- create a dotcode potential for the specified grid of nearest neighbors");
00113   g_option_context_add_main_entries(ctx, options, "Options");
00114   g_option_context_parse(ctx, &argc, &argv, NULL);
00115   g_option_context_free(ctx);
00116 
00117   if(print_version) {
00118     print_version_info();
00119     *err = g_error_new(GET_DC_SWEEP_N_SLICE_ARGS_DOMAIN, 1, "No error; user just wanted version information. This shouldn't be printed.\nIf it was printed, then you have encountered a bug that needs fixed.");
00120     return;
00121   }
00122 
00123   
00124   if((gridsite != NULL) && (position != NULL)) {
00125     *err = g_error_new(GET_DC_SWEEP_N_SLICE_ARGS_DOMAIN, 2, "You must specify *either* --at OR --gridsite; NOT BOTH.");
00126     return;
00127   }
00128   if(gridsite != NULL) {
00129     args->use_max_probability_point=FALSE;
00130     args->use_gridsite=TRUE;
00131     char** gridsite_coords = g_strsplit(gridsite, ",", 3);
00132     for(int i=0; i<3; ++i) {
00133       if(gridsite_coords[i] == NULL) {
00134   *err = g_error_new(GET_DC_SWEEP_N_SLICE_ARGS_DOMAIN, 3, "There were only %d gridsite arguments (received string %s); there should be *three*, comma-separated integer arguments.", i, gridsite);
00135   g_strfreev(gridsite_coords);
00136   return;
00137       }
00138       GError *e = NULL;
00139       args->gridsite[i] = int_from_string(gridsite_coords[i], &e);
00140       if(e != NULL) {
00141   g_propagate_prefixed_error(err, e, "Error converting gridsite coordinate string (%s) (coordinate %d in original string %s) into integer: ", gridsite_coords[i], i, gridsite);
00142   return;
00143       }
00144     }
00145     g_strfreev(gridsite_coords);
00146   }else if(position != NULL) {
00147     args->use_max_probability_point=FALSE;
00148     args->use_gridsite=FALSE;
00149     char** position_coords = g_strsplit(position, ",", 3);
00150     for(int i=0; i<3; ++i) {
00151       if(position_coords[i] == NULL) {
00152   *err = g_error_new(GET_DC_SWEEP_N_SLICE_ARGS_DOMAIN, 3, "There were only %d position arguments (received string %s); there should be *three*, comma-separated integer arguments.", i, position);
00153   g_strfreev(position_coords);
00154   return;
00155       }
00156       GError *e = NULL;
00157       args->point[i] = double_from_string(position_coords[i], &e);
00158       if(e != NULL) {
00159   g_propagate_prefixed_error(err, e, "Error converting position coordinate string (%s) (coordinate %d in original string %s) into double: ", position_coords[i], i, position);
00160   return;
00161       }
00162     }
00163     g_strfreev(position_coords);
00164   }
00165   
00166   if(each_band) {
00167     for(int i=0; i<DC_BAND_VOP+1; ++i) {
00168       enum dotcode_band* band = (enum dotcode_band*)malloc(sizeof(enum dotcode_band));
00169       if(band == NULL) {
00170   *err = g_error_new(GET_DC_SWEEP_N_SLICE_ARGS_DOMAIN, 4, "Failed to allocate storage for a dotcode band.");
00171   return;
00172       }
00173       *band = i;
00174       args->bands = g_list_append(args->bands, band);
00175     }
00176   }
00177 
00178   for(int i=1; i<argc; ++i) {
00179     struct wavefunction* wf = (struct wavefunction*)malloc(sizeof(struct wavefunction));
00180     if(wf == NULL) {
00181       *err = g_error_new(GET_DC_SWEEP_N_SLICE_ARGS_DOMAIN, 4, "Failed to allocate storage for a dotcode wavefunction struct (file was %s).", argv[i]);
00182     }
00183     wf->file = g_file_new_for_commandline_arg(argv[i]);
00184     args->wavefunctions = g_list_append(args->wavefunctions, wf);
00185   }
00186 }
00187   
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines