00001
00007 #include "worldviews.h"
00008 #include "stringutils.h"
00009
00010
00011
00012
00013 int WorldViews::random_seed =123454321;
00014
00015 char WorldViews::default_type[WorldViews::MAX_INPUT_DEFAULT_LENGTH] = "Input_Gaussian";
00016 char WorldViews::default_angle[WorldViews::MAX_INPUT_DEFAULT_LENGTH] = "Random PI/2 PI/2";
00017 char WorldViews::default_position[WorldViews::MAX_INPUT_DEFAULT_LENGTH] = "Uncorrelate &uncorrelation 0 RN Random RN/2 RN/2";
00018 char WorldViews::default_scale[WorldViews::MAX_INPUT_DEFAULT_LENGTH] = "1.0";
00019 char WorldViews::default_offset[WorldViews::MAX_INPUT_DEFAULT_LENGTH] = "0.0";
00020 char WorldViews::default_xsigma[WorldViews::MAX_INPUT_DEFAULT_LENGTH] = "&xsigma";
00021 char WorldViews::default_ysigma[WorldViews::MAX_INPUT_DEFAULT_LENGTH] = "&ysigma";
00022 char WorldViews::default_phase[WorldViews::MAX_INPUT_DEFAULT_LENGTH] = "Random PI PI";
00023 char WorldViews::default_size_scale[WorldViews::MAX_INPUT_DEFAULT_LENGTH] = "1.0";
00024 char WorldViews::default_image_filename[WorldViews::MAX_INPUT_DEFAULT_LENGTH] = "image.pgm";
00025 char WorldViews::default_clone_name[CMD_MAX_LINE_LENGTH] = "";
00026
00027 char WorldViews::default_command[CMD_MAX_LINE_LENGTH] = "for i=0 i<inputs_pereye i=i+1 input_define Obj$i";
00028 char WorldViews::imagepath[CMD_MAX_LINE_LENGTH] = "../images/ ../../images/ ../../../images/";
00029
00030
00031 int WorldViews::distribution=Uninitialized;
00032 double WorldViews::input_offset=0.0;
00033 int WorldViews::inputs_pereye=1;
00034 double WorldViews::xsigma=7;
00035 double WorldViews::ysigma=1.5;
00036 int WorldViews::current_eye=0;
00037 double WorldViews::scale_input=1.0;
00038
00039 int WorldViews::input_log=True;
00040
00041 int WorldViews::input_accum_type=Retinal_Composite::Max;
00042
00043
00044 double WorldViews::input_separation_max=Uninitialized;
00045 int WorldViews::input_separation_max_enforce=False;
00046 double WorldViews::input_separation_min=Uninitialized;
00047 int WorldViews::input_separation_min_enforce=False;
00048
00049
00050
00051
00052 void WorldViews::register_params_and_commands( void )
00053 {
00054 00055 00056 00057
00058 static bool been_called=false;
00059 if (been_called) return;
00060 been_called=true;
00061
00062 params_define_param("input_current_eye",PARAM_INT,True,(char*)¤t_eye);
00063 params_define_doc("input_current_eye",
00064 "Read-only parameter which reports the eye in which an object is currently\n"
00065 "being drawn, cleared, etc., e.g. by input_draw. This can be useful for\n"
00066 "writing equations which place inputs at different but regularly-spaced\n"
00067 "positions, angles, etc. in each eye.\n\n"
00068
00069 "This value is available during the command input_define, but it is not\n"
00070 "currently useful there because all subsequent eyes link directly to the\n"
00071 "values in the first eye (with or without uncorrelation), and thus any\n"
00072 "value computed for a parameter in the higher eyes is ignored. There may\n"
00073 "be some way to circumvent this limitation.");
00074 SETFN_DEFINE(input_current_eye,read_only_param_setfn);
00075
00076 PARAM_II(PARAM_STRING,input_default_clone_name,&default_clone_name,0,MAX_INPUT_DEFAULT_LENGTH,
00077 "Name of default object to clone when none is specified. The default is to\n"
00078 "clone the entire contents of the retina, which can be useful for\n"
00079 "input_present_object to show all objects in their reset state. However,\n"
00080 "when using input_define without specifying the name of the object to clone,\n"
00081 "the name should ordinarily be specified via this parameter.");
00082
00083 PARAM_II(PARAM_STRING,input_default_image_filename,&default_image_filename,0,MAX_INPUT_DEFAULT_LENGTH,
00084 "Default filename used by Input_PGM when none is specified explicitly\n"
00085 "in a call to input_define.");
00086
00087 PARAM_II(PARAM_STRING,input_default_command,&default_command,0,CMD_MAX_LINE_LENGTH,
00088 "Default command used to construct retinal objects when none are created\n"
00089 "explicitly by a call to input_define. Usually just calls \"input_define\"\n"
00090 "\"inputs_pereye\" times, but can be changed to do something else, e.g. by\n"
00091 "setting the distribution parameter.");
00092
00093 PARAM_II(PARAM_STRING,input_default_type,&default_type,0,MAX_INPUT_DEFAULT_LENGTH,
00094 "Default type of retinal object to construct. Accepts any of the possibilities\n"
00095 "for the <objtype> parameter of input_define.");
00096
00097 PARAM_II(PARAM_STRING,input_default_angle,&default_angle,0,MAX_INPUT_DEFAULT_LENGTH,
00098 "Default theta used to construct most retinal objects when none is\n"
00099 "specified explicitly in a call to input_define. Usually a randomly\n"
00100 "chosen angle from the full range for a symmetric stimulus (0..PI)\n"
00101 "each presentation.");
00102
00103 PARAM_II(PARAM_STRING,input_default_position,&default_position,0,MAX_INPUT_DEFAULT_LENGTH,
00104 "Default x and y center used to construct most retinal objects when none is\n"
00105 "specified explicitly in a call to input_define. Usually a randomly chosen\n"
00106 "location on the full retina [0,RN) each presentation (for a persistent\n"
00107 "object defined with input_define), defaulting to the center of the retina\n"
00108 "(for temporary objects created with input_draw.)\n\n");
00109
00110 PARAM_II(PARAM_STRING,input_default_scale,&default_scale,0,MAX_INPUT_DEFAULT_LENGTH,
00111 "Default intensity scale used to construct most retinal objects when none is\n"
00112 "specified explicitly in a call to input_define.");
00113
00114 PARAM_II(PARAM_STRING,input_default_offset,&default_offset,0,MAX_INPUT_DEFAULT_LENGTH,
00115 "Default intensity offset used to construct most retinal objects when none is\n"
00116 "specified explicitly in a call to input_define.");
00117
00118 PARAM_II(PARAM_STRING,input_default_xsigma,&default_xsigma,0,MAX_INPUT_DEFAULT_LENGTH,
00119 "Default xsigma used to construct most retinal objects when none is\n"
00120 "specified explicitly in a call to input_define. Defaults to be a\n"
00121 "pointer to the global value of xsigma, so it will change any time\n"
00122 "that parameter does.");
00123
00124 PARAM_II(PARAM_STRING,input_default_ysigma,&default_ysigma,0,MAX_INPUT_DEFAULT_LENGTH,
00125 "Default ysigma used to construct most retinal objects when none is\n"
00126 "specified explicitly in a call to input_define. Defaults to be a\n"
00127 "pointer to the global value of ysigma, so it will change any time\n"
00128 "that parameter does.");
00129
00130 PARAM_II(PARAM_STRING,input_default_phase,&default_phase,0,MAX_INPUT_DEFAULT_LENGTH,
00131 "Default phase used to construct some retinal objects when none is\n"
00132 "specified explicitly in a call to input_define.");
00133
00134 PARAM_II(PARAM_STRING,input_default_size_scale,&default_size_scale,0,MAX_INPUT_DEFAULT_LENGTH,
00135 "Default size_scale for input objects taking that parameter.");
00136
00137 PARAM_II(PARAM_BOOL, input_log,&input_log,False,True,
00138 "If true, saves some information about the inputs presented at each iteration\n"
00139 "to the log file so that e.g. the input distribution can be analyzed.");
00140
00141 PARAM_N(PARAM_DOUBLE,scale_input,
00142 "Input scaling factor. The input level can be scaled to prevent saturating\n"
00143 "the network. See also input_offset.");
00144
00145 PARAM_LL(PARAM_INT, input_seed,&random_seed,0,
00146 "Value to which to reset the random number generator in input_reset.");
00147
00148 PARAM_LL(PARAM_DOUBLE,input_separation_max,&input_separation_max,0,
00149 "When input_separation_max_enforce is true, the maximum allowable\n"
00150 "distance between input centers.");
00151 params_define_default_expr("input_separation_max","3.0*rf_radius");
00152
00153 PARAM_II(PARAM_BOOL, input_separation_max_enforce,&input_separation_max_enforce,False,True,
00154 "Whether or not to ensure that input centers are separated by at most\n"
00155 "input_separation_max.");
00156
00157 PARAM_LL(PARAM_DOUBLE,input_separation_min,&input_separation_min,0,
00158 "When input_separation_min_enforce is true, the minimum allowable\n"
00159 "distance between input centers.");
00160 params_define_default_expr("input_separation_min","2.2*rf_radius");
00161
00162
00163 PARAM_II(PARAM_BOOL, input_separation_min_enforce,&input_separation_min_enforce,False,True,
00164 "Whether or not to ensure that input centers are separated by at least\n"
00165 "input_separation_min.");
00166
00167 PARAM_II(PARAM_INT, distribution,&distribution,Uninitialized,70,
00168 "Ordinarily, input distributions are defined using input_define or are\n"
00169 "generated automatically based on the defaults, but this parameter allows\n"
00170 "simple selection of a few that have historically been common. If there\n"
00171 "is any doubt about their meaning, just use input_define explicitly.\n\n"
00172
00173 "Unless otherwise noted, all distribute positions randomly and correlate\n"
00174 "them between the eyes using the uncorrelation parameter, all\n"
00175 "distribute angles randomly in the range [0..PI] radians, and keep all\n"
00176 "other parameters constant.\n\n"
00177
00178
00179 " 0 Uniformly random noise ranging from input_offset to (input_offset+\n"
00180 " scale_input) at every location on the retina.\n\n\n"
00181
00182
00183 "13 Circular gaussian input.\n"
00184 " (Typical distribution for ocular dominance maps.)\n\n\n"
00185
00186
00187 "14 Circular gaussian input with randomly chosen sigma.\n\n\n"
00188
00189
00190 "20 Ellipsoidal gaussian input.\n"
00191 " (Default distribution; typical for orientation maps.)\n\n\n"
00192
00193
00194 "21 Ellipsoidal gaussian input with random eccentricities. The\n"
00195 " mean xsigma and ysigma are kept the same as in distribution 20.\n\n\n"
00196
00197
00198 "22 Ellipsoidal gaussian input, all parallel to each other.\n\n\n"
00199
00200
00201 "23 Same as 20 with input_separation_min_enforce=True.\n\n\n"
00202
00203
00204 "24 Same as 22 with input_separation_min=True.\n\n\n"
00205
00206
00207 "25 Same as 23 with input_separation_max_enforce=True also.\n\n\n"
00208
00209
00210 "26 Same as 24 with input_separation_max_enforce=True also.\n\n\n"
00211
00212
00213 "60 Same as 20 except that all inputs are fixed at the center of the\n"
00214 " retina. (Typical distribution for tilt aftereffect tests.)");
00215 00216
00217
00218 PARAM_NN(PARAM_INT, input_accum_type,&input_accum_type,
00219 "Accumulation type for the retina. See Accum_Max, Accum_Min, Accum_Add, etc.");
00220
00221 PARAM_II(PARAM_STRING,imagepath,&imagepath,1,CMD_MAX_LINE_LENGTH,
00222 "Space-separated list of paths to search for images to read. The current\n"
00223 "directory is always searched first.");
00224
00225 PARAM_NN(PARAM_DOUBLE,input_offset,&input_offset,
00226 "Constant value to add to each retinal input pixel. See also scale_input.");
00227
00228 PARAM_LL(PARAM_INT, inputs_pereye,&inputs_pereye,0,
00229 "Default number of input items to create per eye, if none are explicitly\n"
00230 "defined by input_define. When changed after the network has been\n"
00231 "initialized, undefines all current inputs and regenerates a new set\n"
00232 "using input_default_command.");
00233 00234
00235
00236 PARAM_LL(PARAM_DOUBLE,xsigma,&xsigma,0,
00237 "Default X sigma (the semi-major axis, approximately half the\n"
00238 "horizontal width at half-height) of ellipsoidal input Gaussian\n"
00239 "or similar patterns. When changed after the network has been\n"
00240 "initialized, undefines all current inputs and regenerates a new\n"
00241 "set using input_default_command.");
00242
00243 PARAM_LL(PARAM_DOUBLE,ysigma,&ysigma,0,
00244 "Default Y sigma (the semi-minor axis, approximately half the\n"
00245 "vertical width at half-height) of ellipsoidal input Gaussian\n"
00246 "or similar patterns. When changed after the network has been\n"
00247 "initialized, undefines all current inputs and regenerates a new\n"
00248 "set using input_default_command.");
00249
00250 CONST_I(Accum_Max,Retinal_Composite::Max,False,
00251 "Input_Composite objects using this accumulation_type determine\n"
00252 "their activities at a given retinal location by taking the\n"
00253 "maximum of their childrens' activities at this location. This\n"
00254 "makes it easier to combine objects from overlapping pieces.");
00255
00256 CONST_I(Accum_Min,Retinal_Composite::Min,False,
00257 "Input_Composite objects using this accumulation_type determine\n"
00258 "their activities at a given retinal location by taking the\n"
00259 "minimum of their childrens' activities at this location. This\n"
00260 "makes it easier to combine objects which are on in the background\n"
00261 "and off in the foreground.");
00262
00263 CONST_I(Accum_Add,Retinal_Composite::Add,False,
00264 "Input_Composite objects using this accumulation_type determine\n"
00265 "their activities at a given retinal location by adding their\n"
00266 "childrens' activities at this location. This facilitates construction\n"
00267 "of objects using Boolean specifications, such as punching out holes from\n"
00268 "a larger object.");
00269
00270
00271 CONST_I(Accum_OneHot,Retinal_Composite::OneHot,False,
00272 "Input_Composite objects using this accumulation_type select\n"
00273 "only a single child each iteration, as chosen by the <hot-specifier>\n"
00274 "parameter to Input_Composite.\n\n"
00275
00276 "This accumulation type is useful for selecting one object (randomly, or in\n"
00277 "order) from a set of predefined stimuli.\n\n"
00278
00279 "The <hot-specifier> should be a ValueGenerator in the range [0,1.0];\n"
00280 "it is used to generate an index in the range [0,number_of_children-1].\n"
00281 "Values outside of that range are wrapped back inside using a modulo\n"
00282 "operator, so e.g. a continuously incrementing value will cycle through\n"
00283 "all elements in order. The default <hot-specifier> results in a random\n"
00284 "order.");
00285
00286
00287 CONST_S(Input_Composite,False,
00288 "Input object (see command input_define) with parameters:\n"
00289 " [<theta> [<cx> [<cy> [<size_scale> [<scale> [<offset> [<accum_type>] [<hot-specifier>]]]]]]]\n\n"
00290
00291 "Container for other objects, allowing a group of them to be moved\n"
00292 "and rotated as a unit. Only makes sense for input_define rather than\n"
00293 "input_draw, at present. The <name> parameter supplied in the call may\n"
00294 "henceforth serve as the name of the parent for a newly-defined object;\n"
00295 "the position, angle, and size of the newly-defined child object become\n"
00296 "relative to that of the composite.\n\n"
00297
00298 "Parameter <accum_type> may be one of the following (prefixed with Accum_):\n"
00299 "Max, Min, Add, OneHot. See Accum_OneHot for a description of the\n"
00300 "<hot-specifier>, and see Input_Gaussian for descriptions of the other\n"
00301 "parameters. Example:\n\n"
00302
00303 "input_define Face \"\" Input_Composite \"Normal PI/2 PI/18\"\n"
00304 "input_define Mask Face Input_Gaussian 0 0 0.0 7.00 5 1\n"
00305 "input_define LeftEye Face Input_Gaussian 0 -1 +2.5 1.25 2 -1\n"
00306 "input_define RightEye Face Input_Gaussian 0 -1 -2.5 1.25 2 -1\n"
00307 "input_define Mouth Face Input_Gaussian 0 +5 0.0 1.25 2 -1");
00308
00309 CONST_S(Input_UniformRandomNoise,False,
00310 "Input object (see command input_define) with parameters:\n"
00311 " [<scale> [<offset>]]\n\n"
00312
00313 "The activation of each receptor in the retina is chosen randomly from\n"
00314 "a uniform distribution in the range <offset> to <offset>+<scale>.");
00315
00316 CONST_S(Input_Gaussian,False,
00317 "Input object (see command input_define) with parameters:\n"
00318 " [<theta> [<cx> [<cy> [<xsigma> [<ysigma> [<scale> [<offset>]]]]]]]\n\n"
00319
00320 "Two-dimensional Gaussian-shaped input object, i.e. a blob, with the\n"
00321 "indicated parameters:\n\n"
00322
00323 "theta angle in radians, measured upwards from the left\n"
00324 " horizontal axis (contrary to standard\n"
00325 " mathematical usage, for historical reasons))\n"
00326 " (Defaults to input_default_angle.)\n\n"
00327
00328 "(cx,cy) location on retina (or parent object) of center\n"
00329 " relative to an origin at the upper left corner,\n"
00330 " extending downwards in the Y direction and to the\n"
00331 " right in the X direction. Values are floating-\n"
00332 " point, with receptor (i,j) encompassing an area\n"
00333 " starting at an upper left corner (i,j) and ending\n"
00334 " just before the lower right corner (i+1,j+1).\n"
00335 " Thus to center an item directly over receptor\n"
00336 " (i,j), place it at (i+0.5,j+0.5).\n"
00337 " (Defaults to input_default_position.)\n\n"
00338
00339 "xsigma sigma of the Gaussian in the X direction (the semi-\n"
00340 " major axis, i.e. one-half its width at half-intensity.\n"
00341 " (Defaults to input_default_xsigma.)\n\n"
00342
00343 "ysigma sigma of the Gaussian in the Y direction (the semi-\n"
00344 " minor axis, i.e. one-half its width at half-intensity.\n"
00345 " (Defaults to input_default_ysigma.)\n\n"
00346
00347 "scale intensity scale (Defaults to 1.0, full intensity.)\n\n"
00348
00349 "offset intensity offset (Defaults to 0.0, no offset.)\n\n\n"
00350
00351
00352 "Example:\n"
00353 " input_define Spot1 \"\" Input_Gaussian \"Random PI/2 PI/2\" RN/4 RN/4 xsigma/2 ysigma 1.0 0.0\n");
00354
00355 CONST_S(Input_Rectangle,False,
00356 "Input object (see command input_define) with parameters:\n"
00357 " [<cx> [<cy> [<xsigma> [<ysigma> [<scale>] [<offset>]]]]]\n\n"
00358
00359 "Axis-aligned rectangle centered at <cx>,<cy> with width 2*<xsigma>,\n"
00360 "height 2*<ysigma>, and brightness <scale>.\n\n"
00361
00362 "Depending on where the center falls on the grid, the actual length\n"
00363 "(height or width) may be larger or smaller than the nominal length by one\n"
00364 "pixel. To get e.g. an odd width (e.g. 3), you should specify a <cx> at the\n"
00365 "center of a pixel (e.g. 1.5); this will ensure that the center pixel\n"
00366 "plus equal numbers of pixels on either side are included. To get an even\n"
00367 "width, you should specify a pixel boundary instead (e.g. 2.0) so that an\n"
00368 "equal number of pixels are included on each side.\n\n"
00369
00370 "This object type can be useful for drawing a pattern pixel-by-pixel. To e.g.\n"
00371 "specify that the pixel at (3,1) should have activation 0.7, use:\n"
00372 " Input_Rectangle 3.5 1.5 0.5 0.5 scale=0.7");
00373
00374 CONST_S(Input_CircularGaussian,False,
00375 "Input object (see command input_define) with parameters:\n"
00376 " [<cx> [<cy> [<xsigma> [<scale> [<offset>]]]]]\n\n"
00377
00378 "Two-dimensional circular Gaussian with radial half-width <xsigma>,\n"
00379 "which defaults to be a pointer to the global xsigma.\n"
00380 "See Input_Gaussian for descriptions of the other parameters.");
00381
00382 CONST_S(Input_SineGrating,False,
00383 "Input object (see command input_define) with parameters:\n"
00384 " [<theta> [<freq> [<phase> [<scale> [<offset>]]]]]\n\n"
00385
00386 "Sine grating input object which covers the entire retina. The\n"
00387 "frequency and phase of the sine wave are set by <freq> and <phase>.\n"
00388 "The phase defaults to zero, and the frequency has an arbitrary default.\n"
00389 "Note that (for the default offset) the sine grating is half-rectified\n"
00390 "since negative activations are ignored; to get a full sine wave in the\n"
00391 "standard activity range 0-1, use an offset of 0.5 and a scale of 0.5.");
00392
00393 CONST_S(Input_Gabor,False,
00394 "Input object (see command input_define) with parameters:\n"
00395 " [<theta> [<cx> [<cy> [<xsigma> [<ysigma> [<freq> [<phase> [<scale> [<offset>]]]]]]]]]\n\n"
00396 "Gabor-shaped input object, i.e. a sine grating masked by a Gaussian.\n"
00397 "See Input_Gaussian and Input_SineGrating for descriptions of the\n"
00398 "parameters.");
00399
00400 CONST_S(Input_FuzzyLine,False,
00401 "Input object (see command input_define) with parameters:\n"
00402 " [<theta> [<cx> [<cy> [<ysigma> [<center_width> [<scale> [<offset>]]]]]]]\n\n"
00403
00404 "Infinite line of width <center_width> with one-dimensional Gaussian\n"
00405 "falloff (half-width <ysigma>) as distance increases from that point.\n"
00406 "(Full brightness is maintained for the entire <center_width>, after\n"
00407 "which the brightness decreases according to a Gaussian of half-width\n"
00408 "ysigma.) The <center_width> defaults to zero and the <ysigma> defaults\n"
00409 "to be a pointer to the global ysigma.");
00410
00411 CONST_S(Input_FuzzyRing,False,
00412 "Input object (see command input_define) with parameters:\n"
00413 " [<cx> [<cy> [<ysigma> [<center_width> [<radius> [<scale> [<offset>]]]]]]]\n\n"
00414
00415 "Circular ring (torus) of the given <radius> whose brightness is\n"
00416 "maximal for a distance of <center_width> around the radius, then\n"
00417 "falls off according to a one-dimensional Gaussian of half-width\n"
00418 "<ysigma> as radial distance increases from that point. The\n"
00419 "<center_width> defaults to zero and the <ysigma> defaults to\n"
00420 "be a pointer to the global ysigma.");
00421
00422 CONST_S(Input_PGM,False,
00423 "Input object (see command input_define) with parameters:\n"
00424 " [<filename> [<theta> [<cx> [<cy> [<size_scale> [<scale> [<offset>]]]]]]]\n\n"
00425
00426 "Reads input from the specified PGM-format file. The size_scale changes\n"
00427 "the effective size of the image on the retina. One common use is to work\n"
00428 "with images larger than the final desired size, oversampling them to avoid\n"
00429 "pixellation effects when doing rotations, etc. E.g. double-size\n"
00430 "images can be used with a size_scale of 0.5 and a world_size_scale of\n"
00431 "2.0, with the same results as single-sized images would have except\n"
00432 "that (with proper input convolution) aliasing should be reduced. See\n"
00433 "the documentation for Input_Gaussian for information about the other\n"
00434 "parameters.\n\n"
00435
00436 "The parameters default to the defaults of Input_Gaussian for images\n"
00437 "smaller than the retina in any dimension, i.e. any images that can\n"
00438 "be placed at an arbitrary location and angle. All larger images default\n"
00439 "to being upright with no angle variation, and to vary in position only\n"
00440 "as much as is possible without ever showing a border. This distinction\n"
00441 "reflects differences in the primary uses of image objects -- they can\n"
00442 "act as regular objects which happen to be defined in an image file, or as\n"
00443 "literal specification of the entire contents of the retina.\n\n"
00444
00445 "If you have a set of images that you want to present as the entire contents\n"
00446 "of the retina, e.g. to play a movie recorded from video, you can define\n"
00447 "hooks to clear the input and read in the appropriate frame each time. For\n"
00448 "example, assume that you have 1000 frames stored in PGM files named\n"
00449 "image_1.pgm, image_2.pgm, ..., image_1000.pgm. To present the appropriate\n"
00450 "file at each iteration, you could use these commands:\n\n"
00451
00452 " hook before_input 1-1000 input_undefine\n"
00453 " hook before_input 1-1000 input_define Image '' Input_PGM 'image_$iteration.pgm' PI/2 RN/2 RN/2 1.0\n\n"
00454
00455 "Here the Input_PGM parameters are used to force the images to appear upright\n"
00456 "in the center of the retina at the same size each time, which is appropriate\n"
00457 "for full-retina images.");
00458
00459 CONST_S(Input_Clone,False,
00460 "Input object (see command input_define) with parameters:\n"
00461 " [<name_of_original>]\n\n"
00462
00463 "Defines an object that is a clone of the object with the given name.\n"
00464 "Any ValueGenerators the object has are cloned too, such that the clone\n"
00465 "has the same value distribution but different actual values. The original\n"
00466 "object name (i.e. the object to clone) defaults to the value of\n"
00467 "input_default_clone_name; see that parameter's documentation for more\n"
00468 "details. Named ValueGenerator arguments appropriate for the cloned\n"
00469 "object may be passed in after the name of the original object; these\n"
00470 "will be applied after cloning to override the inherited settings.\n\n"
00471
00472 "The semantics of this operation are extremely tricky, and in fact it is\n"
00473 "only partially implemented. Specifically, in the case when num_eyes>1\n"
00474 "and uncorrelation!=0, a cloned object will differ from the original\n"
00475 "by not having any uncorrelation introduced. This difference is for\n"
00476 "very technical reasons having to do with how a cloned object is\n"
00477 "constructed for eyes other than the first, which is to clone the\n"
00478 "existing object in the current eye and replace its ValueGenerator\n"
00479 "parameter links to point to the newly cloned object in the first eye.\n"
00480 "This consideration is important only for input_define; input_draw\n"
00481 "always uses the starting state of the objects and thus is not\n"
00482 "affected by uncorrelation.");
00483 }
00484
00485
00486
00489 void WorldViews::init( void )
00490 {
00491
00492 define();
00493
00494
00495 if (!count_if(ISEQ(contents),not1(mem_fun(&Retinal_Composite::is_empty)))) {
00496
00497 const int oldverbosity = ipc_msg_level;
00498 const int newverbosity = IPC_SUMMARY;
00499 if (ipc_msg_level > newverbosity) ipc_msg_level=newverbosity;
00500 cmddefs_exec_str(default_command);
00501 if (ipc_msg_level==newverbosity) ipc_msg_level=oldverbosity;
00502 }
00503 }
00504
00505
00506
00507 bool WorldViews::next(void)
00508 {
00509
00510 if (input_log)
00511 ipc_log(IPC_ONE,"Iteration: %06d",iteration);
00512
00513 for (int eye=0; eye<num_eyes; eye++) {
00514 if (!contents[eye]->next())
00515 ipc_notify(IPC_ONE,IPC_CAUTION,
00516 "Failed to generate valid position for object in eye %d at iteration %06d",
00517 eye,iteration);
00518 else if (input_log) {
00519 string str=contents[eye]->stringrep();
00520 ipc_log(IPC_ONE," [%s]",str.c_str());
00521 }
00522 }
00523 ipc_log(IPC_ONE,"\n");
00524 return true;
00525 }
00526
00527
00529 void WorldViews::define( unsigned n_eyes )
00530 {
00531
00532 if (contents.size()>=n_eyes) return;
00533
00534 Retinal_Object::VarMap vars;
00535 vars.set("hot",new UR_VGen(0.5,0.5));
00536 vars.set("size_scale",new VGen(1.0));
00537 vars.set("scale",new VGen(&scale_input));
00538 vars.set("offset",new VGen(&input_offset));
00539
00540
00541 for (unsigned e=contents.size(); e<n_eyes; e++) {
00542 if (e!=0)
00543 vars.set("hot",new VGen(contents[0]->get_varptr("hot")));
00544
00545 const string e_str = String::stringrep(e);
00546 Retinal_AnchoredManagedComposite newobj("Eye"+e_str,
00547 &input_separation_min_enforce, &input_separation_min,
00548 &input_separation_max_enforce, &input_separation_max,
00549 Retinal_Composite::AccumulationType(input_accum_type),
00550 vars);
00551
00552 00553
00554 contents.push_back(dynamic_cast<value_type>(newobj.clone()));
00555 }
00556 }
00557
00558
00559
00561 bool WorldViews::create_object(StringArgs args, const string& name,
00562 WorldViews& reference_contents,
00563 bool link_eyes)
00564 {
00565 DistributedValueGeneratorFactory<Retinal_Object::Variable> vgf;
00566 RetinalObjectStringArgs::DefaultsMap defaults;
00567
00568
00569 defaults["theta"] = "${input_default_angle}";
00570 defaults["cx"] = "${input_default_position}";
00571 defaults["cy"] = "${input_default_position}";
00572 defaults["xsigma"] = "${input_default_xsigma}";
00573 defaults["ysigma"] = "${input_default_ysigma}";
00574 defaults["radius"] = "RN/4";
00575 defaults["scale"] = "${input_default_scale}";
00576 defaults["offset"] = "${input_default_offset}";
00577 defaults["hot"] = "Random 0.5 0.5";
00578 defaults["size_scale"] = "${input_default_size_scale}";
00579 defaults["phase"] = "${input_default_phase}";
00580 defaults["freq"] = "0.5";
00581 defaults["center_width"] = "0";
00582
00583 defaults["clone_name"] = "${input_default_clone_name}";
00584 defaults["image_filename"] = "${input_default_image_filename}";
00585 defaults["image_paths"] = "${imagepath}";
00586 defaults["type"] = "${input_default_type}";
00587 defaults["accum_type"] = "Accum_Add";
00588
00589 RetinalObjectFactory rof;
00590
00591
00592 Retinal_Object* masterobj=0;
00593 for (unsigned int e=0; e<contents.size(); e++) {
00594 WorldViews::set_current_eye(e);
00595 StringArgs arglist = args;
00596
00597 const string parent = arglist.next(string(""));
00598 Retinal_Composite* parentptr = dynamic_cast<Retinal_Composite*>(contents[e]->find(parent));
00599
00600 if (parentptr) {
00601 00602 00603 00604 00605 00606 00607 00608 00609 00610 00611 00612 00613
00614 RetinalObjectStringArgs sa(arglist, vgf, defaults, (link_eyes ? masterobj : 0));
00615 Retinal_Composite* basecomposite = reference_contents.contents[(link_eyes && masterobj) ? e : 0];
00616 Retinal_Object* newobj = rof.create(name, sa, basecomposite, RN, RN );
00617 if (newobj) {
00618 parentptr->add(newobj);
00619
00620 00621 00622 00623 00624
00625 if (!masterobj) masterobj = newobj;
00626 }
00627 }
00628 }
00629
00630 if (masterobj==0) {
00631 ipc_notify(IPC_ONE,IPC_ERROR,"Could not define input object");
00632 return 1;
00633 }
00634
00635 return 0;
00636 }
00637
00638
00640 void WorldViews::remove_object(const string& parent, const string& name)
00641 {
00642 for (unsigned int e=0; e<contents.size(); e++) {
00643 set_current_eye(e);
00644 Retinal_Composite* parentptr =
00645 dynamic_cast<Retinal_Composite*>(contents[e]->find(cmds(parent.c_str())));
00646
00647 if (parentptr) parentptr->remove(cmds(name.c_str()));
00648 }
00649 }
00650
00651
00653 void WorldViews::print_object(const string& parent, const string& name) const
00654 {
00655 for (unsigned int e=0; e<contents.size(); e++) {
00656 set_current_eye(e);
00657 Retinal_Object* parentptr = contents[e]->find(cmds(parent.c_str()));
00658
00659 if (parentptr) {
00660 Retinal_Object* childptr = parentptr->find(cmds(name.c_str()));
00661 if (childptr)
00662 ipc_notify(IPC_ONE,IPC_SUMMARY,childptr->stringrep().c_str());
00663 }
00664 }
00665 }
00666
00667
00669 cmdstat WorldViews::set_distribution(int dist, bool& changed)
00670 {
00671
00672 string cmdstr="for i=0 i<inputs_pereye i=i+1 input_define";
00673 switch (dist) {
00674 case 0:
00675 cmdstr+=" noise \"\" Input_UniformRandomNoise &scale_input &input_offset";
00676 break;
00677
00678 case 13:
00679 cmdstr+=" \"\" \"\" Input_CircularGaussian";
00680 break;
00681
00682 case 14:
00683 cmdstr+=" \"\" \"\" Input_CircularGaussian \""
00684 + string(WorldViews::default_position) + "\" \"" + WorldViews::default_position
00685 + "\" \"Random (ysigma-xsigma)/2 (ysigma-xsigma)/2\"";
00686 break;
00687
00688 case 20: case 23: case 25: case 61:
00689 cmdstr+="";
00690 break;
00691
00692 case 21:
00693 00694 00695 00696 00697 00698 00699 00700 00701 00702 00703
00704 cmdstr+=" \"\" \"\" Input_Gaussian \""
00705 + string(WorldViews::default_angle) + "\" \"" + WorldViews::default_position + "\" \"" + WorldViews::default_position
00706 + "\" \"Random xsigma 2*xsigma*xsigma\" \"Random ysigma 2*ysigma*ysigma\"";
00707 break;
00708
00709 case 22: case 24: case 26:
00710 cmddefs_exec_str("input_define_generator parallel_angle \"Random PI/2 PI/2\"");
00711 cmdstr+=" \"\" \"\" Input_Gaussian ¶llel_angle";
00712 break;
00713
00714 case 60:
00715 cmdstr+=" \"\" \"\" Input_Gaussian \""
00716 + string(WorldViews::default_angle) + "\" RN/2 RN/2";
00717 break;
00718
00719 case Uninitialized:
00720 return CMD_NO_ERROR;
00721
00722 default:
00723 ipc_notify(IPC_ONE,IPC_ERROR,"Don't know anything about distribution %d",dist);
00724 return CMD_PARAMETER_ERROR;
00725 }
00726 strncpy(WorldViews::default_command,cmdstr.c_str(),CMD_MAX_LINE_LENGTH);
00727 WorldViews::distribution=dist;
00728
00729
00730
00731 WorldViews::input_separation_min_enforce = (dist==23 || dist==24 || dist==25 || dist==26);
00732 WorldViews::input_separation_max_enforce = (dist==25 || dist==26);
00733
00734
00735 changed=true;
00736
00737 return CMD_NO_ERROR;
00738 }