|
funkalicious 0.1
|
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