Пример #1
0
void store_fitpoint_ctwiss_parameters(MARK *fpt, char *name, long occurence,
                                      double betax1, double betax2,
                                      double betay1, double betay2,
                                      double etax, double etay,
                                      double tilt)
{
    long i;
    double data[7];
    static char *suffix[7] = {
        "betax1", "betax2", "betay1", "betay2", "cetax", "cetay", "tilt"
    };
    static char s[200];

    data[0] = betax1;
    data[1] = betax2;
    data[2] = betay1;
    data[3] = betay2;
    data[4] = etax;
    data[5] = etay;
    data[6] = tilt;

    if (!(fpt->init_flags&16)) {
        fpt->ctwiss_mem = tmalloc(sizeof(*(fpt->ctwiss_mem))*12);
        fpt->init_flags |= 16;
        for (i=0; i<7; i++) {
            sprintf(s, "%s#%ld.%s", name, occurence, suffix[i]);
            fpt->ctwiss_mem[i] = rpn_create_mem(s, 0);
        }
    }
    for (i=0; i<7; i++)
        rpn_store(data[i], NULL, fpt->ctwiss_mem[i]);
}
Пример #2
0
void store_in_str_mem(void)
{
  static long i_mem;
  static char *name;
  static char buffer[LBUFFER];
  
  if ((name = get_token_rpn(code_ptr->text,
                            buffer, LBUFFER, &(code_ptr->position)))==NULL) {
    fputs("store_in_mem syntax: sto name\n", stderr);
    stop();
    rpn_set_error();
    return;
  }
  
  if (sstackptr<1) {
    fputs("ssto requires value on stack\n", stderr);
    stop();
    rpn_set_error();
    return;
  }
  
  if ((i_mem = rpn_create_mem(name,1))>=0)
    str_memoryData[i_mem] = sstack[sstackptr-1];
}
Пример #3
0
long do_chromaticity_correction(CHROM_CORRECTION *chrom, RUN *run, LINE_LIST *beamline,
            double *clorb, long step, long last_iteration)
{
    VMATRIX *M;
    double chromx0, chromy0, dchromx=0, dchromy=0;
    double K2=0.0, *K2ptr;
    ELEMENT_LIST *context;
    long i, K2_param=0, type=0, iter, count;
    double beta_x, alpha_x, eta_x, etap_x;
    double beta_y, alpha_y, eta_y, etap_y;
    double K2_min, K2_max;
    unsigned long unstable;
    double lastError, presentError;
    char buffer[256];
    
    log_entry("do_chromaticity_correction");

    if (!beamline->matrix || !beamline->twiss0) {
        if (!beamline->twiss0)
            beamline->twiss0 = tmalloc(sizeof(*beamline->twiss0));
        if (!beamline->elem_twiss) {
            ELEMENT_LIST *eptr;
            eptr = beamline->elem_twiss = &(beamline->elem);
            while (eptr) {
                if (eptr->type==T_RECIRC)
                    beamline->elem_twiss = beamline->elem_recirc = eptr;
                eptr = eptr->succ;
                }
            }
        if (beamline->matrix) {
          free_matrices(beamline->matrix);
          free(beamline->matrix);
          beamline->matrix = NULL;
        }
        beamline->matrix = compute_periodic_twiss(&beta_x, &alpha_x, &eta_x, &etap_x, beamline->tune,
						  &beta_y, &alpha_y, &eta_y, &etap_y, beamline->tune+1, 
						  beamline->elem_twiss, clorb, run, &unstable, NULL, NULL);

        beamline->twiss0->betax  = beta_x;
        beamline->twiss0->alphax = alpha_x;
        beamline->twiss0->phix   = 0;
        beamline->twiss0->etax   = eta_x;
        beamline->twiss0->etapx  = etap_x;
        beamline->twiss0->betay  = beta_y;
        beamline->twiss0->alphay = alpha_y;
        beamline->twiss0->phiy   = 0;
        beamline->twiss0->etay   = eta_y;
        beamline->twiss0->etapy  = etap_y;
        
        propagate_twiss_parameters(beamline->twiss0, beamline->tune, beamline->waists,
                                   NULL, beamline->elem_twiss, run, clorb, 
				   beamline->couplingFactor);
        }
    else if (beamline->matrix->order<2) {
      if (beamline->matrix) {
          free_matrices(beamline->matrix);
          free(beamline->matrix);
          beamline->matrix = NULL;
        }
      beamline->matrix = full_matrix(beamline->elem_twiss, run, 2);
    }

    if (!(M = beamline->matrix) || !M->C || !M->R || !M->T)
        bombElegant("something wrong with transfer map for beamline (do_chromaticity_correction.1)", NULL);

    computeChromaticities(&chromx0, &chromy0, 
			  NULL, NULL, NULL, NULL, beamline->twiss0,
			  beamline->elast->twiss, M);

    if (verbosityLevel>0) {
      fprintf(stdout, "\nAdjusting chromaticities:\n");
      fflush(stdout);
      fprintf(stdout, "initial chromaticities:  %e  %e\n", chromx0, chromy0);
      fflush(stdout);
    }
    
    presentError = DBL_MAX;
    for (iter=0; iter<chrom->n_iterations; iter++) {
        K2_max = -(K2_min = DBL_MAX);
        dchromx = chrom->chromx - chromx0;
        dchromy = chrom->chromy - chromy0;
        if (chrom->tolerance>0 &&
            chrom->tolerance>fabs(dchromx) &&
            chrom->tolerance>fabs(dchromy) )
          break;

        lastError = presentError;
        presentError = sqr(dchromx)+sqr(dchromy);
        if (iter && presentError>lastError) {
          fprintf(stdout, "Error increasing---reducing gain\n");
          fflush(stdout);
          chrom->correction_fraction /= 10;
        }

        if (chrom->use_perturbed_matrix)
          computeChromCorrectionMatrix(run, beamline, chrom);
        chrom->dchrom->a[0][0] = dchromx;
        chrom->dchrom->a[1][0] = dchromy;

        m_mult(chrom->dK2, chrom->T, chrom->dchrom);
        for (i=0; i<chrom->n_families; i++) {
          if (isnan(chrom->correction_fraction*chrom->dK2->a[i][0]) ||
              isinf(chrom->correction_fraction*chrom->dK2->a[i][0]))
            break;
        }
        if (i!=chrom->n_families) {
          fprintf(stdout, "Unable to correct chromaticity---diverged\n");
          fflush(stdout);
          return 0;
        }
        for (i=0; i<chrom->n_families; i++) {
            context = NULL;
            count = 0;
            while ((context=find_element(chrom->name[i], &context, beamline->elem_twiss))) {
                if (count==0 && (K2_param = confirm_parameter("K2", context->type))<0) {
                    fprintf(stdout, "error: element %s doesn't have K2 parameter\n",
                            context->name);
                    fflush(stdout);
                    exitElegant(1);
                    }
                if (!(K2ptr = (double*)(context->p_elem + entity_description[context->type].parameter[K2_param].offset)))
                    bombElegant("K2ptr NULL in setup_chromaticity_correction", NULL);
                K2 = (*K2ptr += chrom->correction_fraction*chrom->dK2->a[i][0]);
                if (chrom->strengthLimit>0 && chrom->strengthLimit<fabs(K2)) {
                  K2 = *K2ptr = SIGN(K2)*chrom->strengthLimit;
                }
                sprintf(buffer, "%s#%ld.K2", context->name, context->occurence);
                rpn_store(K2, NULL, rpn_create_mem(buffer, 0));
                if (K2>K2_max)
                  K2_max = K2;
                if (K2<K2_min)
                  K2_min = K2;
                if (context->matrix) {
                  free_matrices(context->matrix);
                  free(context->matrix);
                  context->matrix = NULL;
                  }
                compute_matrix(context, run, NULL);
                type = context->type;
                count++;
                /* fprintf(stdout, "new value of %s#%ld[K2] is  %.15lg 1/m^3\n", 
                       chrom->name[i], context->occurence, K2);
                   fflush(stdout);
                       */
              }
            if (verbosityLevel>1) {
              fprintf(stdout, "Change for family %ld (%ld sextupoles): %e\n",
                      i, count, chrom->correction_fraction*chrom->dK2->a[i][0]);
              fflush(stdout);
            }
            if (alter_defined_values)
              change_defined_parameter(chrom->name[i], K2_param, type, K2, NULL, LOAD_FLAG_ABSOLUTE);
            }    

        if (beamline->links) {
          /* rebaseline_element_links(beamline->links, run, beamline); */
          assert_element_links(beamline->links, run, beamline, 
                               STATIC_LINK+DYNAMIC_LINK+(alter_defined_values?LINK_ELEMENT_DEFINITION:0));
        }
        
        if (beamline->matrix) {
          free_matrices(beamline->matrix);
          free(beamline->matrix);
          beamline->matrix = NULL;
        }
        M = beamline->matrix = compute_periodic_twiss(&beta_x, &alpha_x, &eta_x, &etap_x, beamline->tune,
                                                      &beta_y, &alpha_y, &eta_y, &etap_y, beamline->tune+1, 
                                                      beamline->elem_twiss, clorb, run, &unstable, NULL, NULL);
        beamline->twiss0->betax  = beta_x;
        beamline->twiss0->alphax = alpha_x;
        beamline->twiss0->phix   = 0;
        beamline->twiss0->etax   = eta_x;
        beamline->twiss0->etapx  = etap_x;
        beamline->twiss0->betay  = beta_y;
        beamline->twiss0->alphay = alpha_y;
        beamline->twiss0->phiy   = 0;
        beamline->twiss0->etay   = eta_y;
        beamline->twiss0->etapy  = etap_y;
        
        if (!M || !M->C || !M->R || !M->T)
            bombElegant("something wrong with transfer map for beamline (do_chromaticity_correction.2)", NULL);
        computeChromaticities(&chromx0, &chromy0, 
			      NULL, NULL, NULL, NULL, beamline->twiss0, 
			      beamline->elast->twiss, M);
        beamline->chromaticity[0] = chromx0;
        beamline->chromaticity[1] = chromy0;
        if (verbosityLevel>0) {
          fprintf(stdout, "resulting chromaticities:  %e  %e\n", chromx0, chromy0);
          fprintf(stdout, "min, max sextupole strength:  %e  %e  1/m^2\n", K2_min, K2_max);
          fflush(stdout);
        }
      }
    
    if (fp_sl && last_iteration) {
        for (i=0; i<chrom->n_families; i++) {
            context = NULL;
            while ((context=find_element(chrom->name[i], &context, beamline->elem_twiss))) {
              if (( K2_param = confirm_parameter("K2", context->type))<0)
                bombElegant("confirm_parameter doesn't return offset for K2 parameter.\n", NULL);
              fprintf(fp_sl, "%ld %e %s\n", 
                      step,
                      *((double*)(context->p_elem + entity_description[context->type].parameter[K2_param].offset)),
                      chrom->name[i]);
            }
          }
        fflush(fp_sl);
      }
    

    propagate_twiss_parameters(beamline->twiss0, beamline->tune, 
                               beamline->waists, NULL, beamline->elem_twiss, run, clorb,
			       beamline->couplingFactor);
    log_exit("do_chromaticity_correction");

    if (chrom->tolerance>0 &&
        (chrom->tolerance<fabs(dchromx) || chrom->tolerance<fabs(dchromy))
        && chrom->exit_on_failure) {
      fprintf(stdout, "Chromaticity correction failure---exiting!\n");
      exitElegant(1);
    }

    return 1;
  }
Пример #4
0
long assert_element_links(ELEMENT_LINKS *links, RUN *run, LINE_LIST *beamline, long flags)
{
    long i_link, i_elem, i_item, matrices_changed;
    long elem_type, data_type, param;
    double value;
    ELEMENT_LIST **targ, **sour;
    char *p_elem;
    short lengthChanged = 0;
    
    log_entry("assert_element_links");
    if (!links || links->n_links==0) {
        log_exit("assert_element_links");
        return(0);
        }

    if (!links->target_name || !links->item || !links->source_name || !links->equation ||
            !links->n_targets || !links->target_elem || !links->source_elem) {
        fputs("error: link structure has null pointers (assert_element_links)", stdout);
        abort();
        }

    matrices_changed = 0;
    for (i_link=0; i_link<links->n_links; i_link++) {
        if (!(flags&links->flags[i_link]))
            continue;
        targ = links->target_elem[i_link];
        sour = links->source_elem[i_link];
        elem_type = targ[0]->type;
        param     = links->target_param[i_link];
        data_type = entity_description[elem_type].parameter[param].type;
#if DEBUG
        fprintf(stdout, "asserting %ld links of %s.%s to %s\n", links->n_targets[i_link],
            links->target_name[i_link], links->item[i_link], links->source_name[i_link]);
        fflush(stdout);
        fprintf(stdout, "source type is %ld, with %ld parameters\n", sour[0]->type, 
                    entity_description[sour[0]->type].n_params);
        fflush(stdout);
#endif
        for (i_elem=0; i_elem<links->n_targets[i_link]; i_elem++) {
#if DEBUG
            fprintf(stdout, "  working on element %ld\n", i_elem);
            fflush(stdout);
#endif
            p_elem = sour[i_elem]->p_elem;
            for (i_item=0; i_item<entity_description[sour[0]->type].n_params; i_item++) {
  	        char s[1024];
		double value0;
                switch (entity_description[sour[0]->type].parameter[i_item].type) {
                    case IS_DOUBLE:
                        value = *((double*)(p_elem+entity_description[sour[0]->type].parameter[i_item].offset));
                        rpn_store(value, NULL, rpn_create_mem(entity_description[sour[0]->type].parameter[i_item].name, 0));
                        value0 = *((double*)(sour[i_elem]->p_elem0+entity_description[sour[0]->type].parameter[i_item].offset));
			sprintf(s, "%s0", entity_description[sour[0]->type].parameter[i_item].name);
                        rpn_store(value0, NULL, rpn_create_mem(s, 0));
                        break;
                    case IS_LONG:
                        value = *((long*)(p_elem+entity_description[sour[0]->type].parameter[i_item].offset));
                        rpn_store(value, NULL, rpn_create_mem(entity_description[sour[0]->type].parameter[i_item].name, 0));
                        value0 = *((long*)(sour[i_elem]->p_elem0+entity_description[sour[0]->type].parameter[i_item].offset));
			sprintf(s, "%s0", entity_description[sour[0]->type].parameter[i_item].name);
                        rpn_store(value0, NULL, rpn_create_mem(s, 0));
                        break;
                    default:
                        break;
                    }
#if DEBUG 
                fprintf(stdout, "    asserting value %e for %s\n", value, entity_description[sour[0]->type].parameter[i_item].name);
                fprintf(stdout, "    asserting value %e for %s0\n", value0, entity_description[sour[0]->type].parameter[i_item].name);
                fflush(stdout);
#endif
                }
            p_elem = targ[i_elem]->p_elem;

            rpn_clear();
            /* push original value onto stack */
            if (verbosity>1)
                fprintf(stdout, "prior value is %.15g for %s#%ld.%s at z=%.15gm\n",
                        links->baseline_value[i_link][i_elem], 
                        links->target_name[i_link], targ[i_elem]->occurence, links->item[i_link], 
                        targ[i_elem]->end_pos);
            push_num(links->baseline_value[i_link][i_elem]);
            value = rpn(links->equation[i_link]);
            if (rpn_check_error()) exitElegant(1);
            rpn_clear();
            if (value>links->maximum[i_link])
              value = links->maximum[i_link];
            if (value<links->minimum[i_link])
              value = links->minimum[i_link];
            if (verbosity>0)
                fprintf(stdout, "asserting value %.15g for %s#%ld.%s at z=%.15gm\n",
                    value, links->target_name[i_link], targ[i_elem]->occurence, links->item[i_link], targ[i_elem]->end_pos);
                fflush(stdout);
            if (entity_description[elem_type].flags&HAS_LENGTH && 
                entity_description[elem_type].parameter[param].offset==0)
              lengthChanged = 1;
            switch (data_type) {
                case IS_DOUBLE:
                    *((double*)(p_elem+entity_description[elem_type].parameter[param].offset)) = value;
                    break;
                case IS_LONG:
                    *((long*)(p_elem+entity_description[elem_type].parameter[param].offset)) = 
                      nearestInteger(value);
                    break;
                case IS_STRING:
                default:
                    bombElegant("unknown/invalid variable quantity (assert_element_links)", NULL);
                    exitElegant(1);
                }
            if (flags&LINK_ELEMENT_DEFINITION) 
                change_defined_parameter_values(&targ[i_elem]->name, &param, &targ[i_elem]->type, &value, 1);
            if ((entity_description[targ[0]->type].parameter[param].flags&PARAM_CHANGES_MATRIX) && targ[i_elem]->matrix) {
                free_matrices(targ[i_elem]->matrix);
                tfree(targ[i_elem]->matrix);
                targ[i_elem]->matrix = NULL;
                compute_matrix(targ[i_elem], run, NULL);
                matrices_changed++;
                }
            }
        }
#if DEBUG
    print_line(stdout, beamline);
#endif
    if (lengthChanged)
      compute_end_positions(beamline);
    log_exit("assert_element_links");
    return(matrices_changed);
    }
Пример #5
0
void run_rpn_load(NAMELIST_TEXT *nltext, RUN *run)
{
  SDDS_DATASET SDDSin;
  long code, foundPage, iColumn, matchRow, rows, iParameter;
  int32_t columns, parameters;
  char *parameterValue = NULL;
  double *data, data1;
  char **columnName, **matchColumnData, *memName = NULL;
  char **parameterName;
  
  /* process the namelist text */
  set_namelist_processing_flags(STICKY_NAMELIST_DEFAULTS);
  set_print_namelist_flags(0);
  if (processNamelist(&rpn_load, nltext)==NAMELIST_ERROR)
    bombElegant(NULL, NULL);
  if (echoNamelists) print_namelist(stdout, &rpn_load);
  
  if (match_column && strlen(match_column)) {
    if (use_row!=-1) {
      fprintf(stdout, "Error: you asked to match a column and also gave use_row.\n");
      exitElegant(1);
    } 
    if (!match_column_value || !strlen(match_column_value)) {
      fprintf(stdout, "Error: you must give match_column_value with match_column\n");
      exitElegant(1);
    }
  }
  if (match_parameter && strlen(match_parameter)) {
    if (use_page!=-1) {
      fprintf(stdout, "Error: you asked to match a parameter and also gave use_page.\n");
      exitElegant(1);
    }
    if (!match_parameter_value || !strlen(match_parameter_value)) {
      fprintf(stdout, "Error: you must give match_parameter_value with match_parameter\n");
      exitElegant(1);
    }
  }
    
  if (!filename || !strlen(filename)) {
    fprintf(stdout, "Error: no filename given for rpn_load.\n");
    exitElegant(1);
  }

  filename = compose_filename(filename, run->rootname);
  
  if (!SDDS_InitializeInputFromSearchPath(&SDDSin, filename)) {
    fprintf(stdout, "Error: couldn't initialize SDDS input for %s\n",
            filename);
    exitElegant(1);
  }

  foundPage = 0;
  while ((code=SDDS_ReadPage(&SDDSin))>0) {
    if (use_page>0) {
      if (code==use_page) {
        foundPage = 1;
        break;
      }
      continue;
    }
    if (match_parameter && strlen(match_parameter)) {
      if (!(parameterValue=SDDS_GetParameterAsString(&SDDSin, match_parameter, NULL)))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      if (!wild_match(parameterValue, match_parameter_value))
        continue;
      foundPage = 1;
      break;
    }
    if (use_page==-1 && SDDS_CheckEndOfFile(&SDDSin)==1) {
      foundPage = 1;
      break;
    }
  }

  if (!foundPage) {
    fprintf(stdout, "Error: no appropriate page found\n");
    exitElegant(1);
  }

  if (!load_parameters) {
    if ((columnName = SDDS_GetColumnNames(&SDDSin, &columns))==NULL) {
      fprintf(stdout, "Warning: No columns in file!\n");
      return;
    }

    rows = SDDS_RowCount(&SDDSin);
    matchRow = rows-1;
    if (use_row!=-1) {
      if (use_row>=rows) {
        fprintf(stdout, "Error: number of rows in file (%ld) less than needed for use_row=%ld\n",
                rows, use_row);
        exitElegant(1);
      }
      matchRow = use_row;
    } 

    if (match_column) {
      if (SDDS_GetNamedColumnType(&SDDSin, match_column)!=SDDS_STRING) {
        fprintf(stdout, "Error: column %s nonexistent or not string type.\n",
                match_column);
        exitElegant(1);
      }
      if (!(matchColumnData=SDDS_GetColumn(&SDDSin, match_column))) {
        fprintf(stdout, "Error: unable to get data for column %s\n", match_column);
        exitElegant(1);
      }
      if (matching_row_number<0) {
        /* use last match */
        for (matchRow=rows-1; matchRow>=0; matchRow--)
          if (wild_match(matchColumnData[matchRow], match_column_value))
            break;
      } else {
        /* use nth match */
        for (matchRow=0; matchRow<rows; matchRow++)
          if (wild_match(matchColumnData[matchRow], match_column_value) &&
              matching_row_number-- == 0)
            break;
      }
      
      if (matchRow<0 || matchRow>=rows) {
        fprintf(stdout, "Error: unable to find match for %s in column %s\n",
                match_column_value, match_column);
        exitElegant(1);
      }
      SDDS_FreeStringArray(matchColumnData, rows);
    }
    
    for (iColumn=0; iColumn<columns; iColumn++) {
      switch (SDDS_GetNamedColumnType(&SDDSin, columnName[iColumn])) {
      case SDDS_CHARACTER:
      case SDDS_STRING:
        break;
      default:
        if (!(data=SDDS_GetColumnInDoubles(&SDDSin, columnName[iColumn]))) {
          fprintf(stdout, "Error: unable to get data for column %s as numerical data.\n",
                  columnName[iColumn]);
          exitElegant(1);
        }
        if (!(memName=SDDS_Realloc(memName, sizeof(*memName)*((tag?strlen(tag):0)+strlen(columnName[iColumn])+2)))) {
          fprintf(stdout, "Memory allocation failure trying to create memory name for loaded data\n");
          exitElegant(1);
        }
        if (tag && strlen(tag))
          sprintf(memName, "%s.%s", tag, columnName[iColumn]);
        else
          sprintf(memName, "%s", columnName[iColumn]);
        rpn_store(data[matchRow], NULL, rpn_create_mem(memName, 0));
        fprintf(stdout, "%le --> %s\n", data[matchRow], memName);
        free(columnName[iColumn]);
        free(data);
      }
    }
    if (memName)
      free(memName);
    if (columnName)
      free(columnName);
  } else {
    /* load data from parameters */
    if ((parameterName = SDDS_GetParameterNames(&SDDSin, &parameters))==NULL) {
      fprintf(stdout, "Warning: No parameters in file!\n");
      return;
    }

    for (iParameter=0; iParameter<parameters; iParameter++) {
      switch (SDDS_GetNamedParameterType(&SDDSin, parameterName[iParameter])) {
      case SDDS_CHARACTER:
      case SDDS_STRING:
        break;
      default:
        if (!SDDS_GetParameterAsDouble(&SDDSin, parameterName[iParameter], &data1)) {
          fprintf(stdout, "Error: unable to get data for parameter %s as numerical data.\n",
                  parameterName[iParameter]);
          exitElegant(1);
        }
        if (!(memName=SDDS_Realloc(memName, sizeof(*memName)*((tag?strlen(tag):0)+strlen(parameterName[iParameter])+2)))) {
          fprintf(stdout, "Memory allocation failure trying to create memory name for loaded data\n");
          exitElegant(1);
        }
        if (tag && strlen(tag))
          sprintf(memName, "%s.%s", tag, parameterName[iParameter]);
        else
          sprintf(memName, "%s", parameterName[iParameter]);
        rpn_store(data1, NULL, rpn_create_mem(memName, 0));
        fprintf(stdout, "%le --> %s\n", data1,  memName);
        free(parameterName[iParameter]);
      }
    }
    if (memName)
      free(memName);
    if (parameterName)
      free(parameterName);
  }
}
Пример #6
0
int main(int argc, char **argv)
{
    double x_lo, x_hi, y_lo, y_hi, dx, dy, x, y;
    double **z_data, z_min, z_max, z_val;
    long ix, iy, nx, ny;
    long x_rpn_var, y_rpn_var;
    char *z_equation = NULL;
    char *rpn_defns_file;
    char *rpn_init_command;
    char *z_udf = "Z.UDF";
    char *input, *output, *label[4];
    long i_arg;
    SCANNED_ARG *s_arg;
    FILE *fp;
    unsigned long pipeFlags;
    char pfix[IFPF_BUF_SIZE], *ptr;
    char * rpn_defns;
#if defined(LINUX)
    struct stat sts;
#endif

    if (argc<2 || argc>(2+N_OPTIONS)) 
        bomb(NULL, USAGE);

    output = NULL;
    nx = ny = 0;
    rpn_defns_file = NULL;
    rpn_init_command = NULL;
    pipeFlags = 0;

    for (ix=0; ix<4; ix++)
        label[ix] = " ";
    scanargs(&s_arg, argc, argv);
    for (i_arg=1; i_arg<argc; i_arg++) {
        if (s_arg[i_arg].arg_type==OPTION) {
            delete_chars(s_arg[i_arg].list[0], "_");
            switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
                case SET_RPN_DEFNS_FILE:
                    if (s_arg[i_arg].n_items!=2 ||
                            !(rpn_defns_file=s_arg[i_arg].list[1]))
                        bomb("incorrect -rpndefnsfile syntax", NULL);
                    break;
                case SET_RPN_INIT_COMMAND:
		  /*
                    if (s_arg[i_arg].n_items!=2 ||
                            !(rpn_init_command = s_arg[i_arg].list[1]))
                        bomb("incorrect -rpncommand syntax", NULL);
		  */
		  if ((s_arg[i_arg].n_items<2) || (s_arg[i_arg].n_items>3))
		    SDDS_Bomb("incorrect -rpncommand syntax");
		  if (s_arg[i_arg].n_items==2) {
		    if (!strlen(rpn_init_command=s_arg[i_arg].list[1])) {
		      SDDS_Bomb("incorrect -rpncommand syntax");
		    }
		  } else if (s_arg[i_arg].n_items==3) {
		    if (strncmp(s_arg[i_arg].list[2], "algebraic", strlen(s_arg[i_arg].list[2]))==0) {
		      ptr = addOuterParentheses(s_arg[i_arg].list[1]);
		      if2pf(pfix, ptr, sizeof pfix);
		      free(ptr);
		      if (!SDDS_CopyString(&rpn_init_command, pfix)) {
			fprintf(stderr, "error: problem copying argument string\n");
			return(1);
		      }
		    } else {
		      SDDS_Bomb("incorrect -rpncommand syntax");
		    }
		  }
		  break;
                case SET_Z_EQUATION:
		  /*
                    if (s_arg[i_arg].n_items!=2 ||
			!(z_equation=s_arg[i_arg].list[1]))
                        bomb("incorrect -zequation syntax", NULL);
		  */
		  if ((s_arg[i_arg].n_items<2) || (s_arg[i_arg].n_items>3))
		    SDDS_Bomb("incorrect -zequation syntax");
		  if (s_arg[i_arg].n_items==2) {
		    if (!strlen(z_equation=s_arg[i_arg].list[1])) {
		      SDDS_Bomb("incorrect -zequation syntax");
		    }
		  } else if (s_arg[i_arg].n_items==3) {
		    if (strncmp(s_arg[i_arg].list[2], "algebraic", strlen(s_arg[i_arg].list[2]))==0) {
		      if2pf(pfix, s_arg[i_arg].list[1], sizeof pfix);
		      if (!SDDS_CopyString(&z_equation, pfix)) {
			fprintf(stderr, "error: problem copying argument string\n");
			return(1);
		      }
		    } else {
		      SDDS_Bomb("incorrect -zequation syntax");
		    }
		  }
		  break;
                case SET_X_RANGE:
                    if (s_arg[i_arg].n_items!=4 ||
                            1!=sscanf(s_arg[i_arg].list[1], "%le", &x_lo) ||
                            1!=sscanf(s_arg[i_arg].list[2], "%le", &x_hi) ||
                            x_lo>=x_hi || 
                            1!=sscanf(s_arg[i_arg].list[3], "%ld", &nx) ||
                            nx<=1) 
                        bomb("incorrect -xrange syntax", NULL);
                    break;
                case SET_Y_RANGE:
                    if (s_arg[i_arg].n_items!=4 ||
                            1!=sscanf(s_arg[i_arg].list[1], "%le", &y_lo) ||
                            1!=sscanf(s_arg[i_arg].list[2], "%le", &y_hi) ||
                            y_lo>=y_hi || 
                            1!=sscanf(s_arg[i_arg].list[3], "%ld", &ny) ||
                            ny<=1) 
                        bomb("incorrect -yrange syntax", NULL);
                    break;
                  case SET_PIPE:
                    if (!processPipeOption(s_arg[i_arg].list+1, s_arg[i_arg].n_items-1, &pipeFlags))
                        bomb("invalid -pipe syntax", NULL);
                    break;
                  default:
                    fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
                    bomb(NULL, NULL);
                    break;
                }
            }
        else {
            if (output==NULL) 
                output = s_arg[i_arg].list[0];
            else
                bomb("too many filenames (sddscongen)", NULL);
            }
        }

    pipeFlags |= DEFAULT_STDIN;
    input = NULL;
    processFilenames("sddscongen", &input, &output, pipeFlags, 0, NULL);

    if (nx==0)
        bomb("-xrange must be supplied", NULL);    
    if (ny==0)
        bomb("-yrange must be supplied", NULL);    
    
    if (z_equation==NULL)
        bomb("-zequation must be supplied", NULL);

    if(!rpn_defns_file) {
	rpn_defns_file=getenv("RPN_DEFNS");
	/*if failed, check where default setting exists for a linux system, G. Shen, Dec 31, 2009 */
	if(!rpn_defns_file) {
#if defined(LINUX)
	    if (!(stat(rpn_default, &sts) == -1 && errno == ENOENT)) { /* check whether default file exists */
		rpn_defns = rpn_default;
	    }
#endif
	}
    }
    rpn(rpn_defns_file);
    /* rpn(rpn_defns_file?rpn_defns_file:getenv("RPN_DEFNS")); */
    if (rpn_init_command)
        rpn(rpn_init_command);
    x_rpn_var = rpn_create_mem("x", 0);
    y_rpn_var = rpn_create_mem("y", 0);
    create_udf(z_udf, z_equation);

    z_data = (double**)array_2d(sizeof(double), 0, nx-1, 0, ny-1);
    dx = (x_hi-x_lo)/(nx-1);
    dy = (y_hi-y_lo)/(ny-1);
    z_min =  FLT_MAX;
    z_max = -FLT_MAX;
    
    for (ix=0,x=x_lo; ix<nx; ix++,x+=dx) {
        for (iy=0,y=y_lo; iy<ny; iy++,y+=dy) {
            rpn_store(x, NULL, x_rpn_var);
            rpn_store(y, NULL, y_rpn_var);
            if ((z_val = z_data[ix][iy] = rpn(z_udf))>z_max)
                z_max = z_val;
            if (z_val<z_min)
                z_min = z_val;
            rpn_clear();
            }
        }

    if (output)
        fp = fopen_e(output, "w", 0);
    else
        fp = stdout;
    fprintf(fp, "SDDS1\n&parameter name=Variable1Name, type=string, fixed_value=x &end\n");
    fprintf(fp, "&parameter name=Variable2Name, type=string, fixed_value=y &end\n");
    fprintf(fp, "&parameter name=xInterval, type=double, fixed_value=%e &end\n", dx);
    fprintf(fp, "&parameter name=xMinimum, type=double, fixed_value=%e &end\n", x_lo);
    fprintf(fp, "&parameter name=xDimension, type=long, fixed_value=%ld &end\n", nx);
    fprintf(fp, "&parameter name=yInterval, type=double, fixed_value=%e &end\n", dy);
    fprintf(fp, "&parameter name=yMinimum, type=double, fixed_value=%e &end\n", y_lo);
    fprintf(fp, "&parameter name=yDimension, type=long, fixed_value=%ld &end\n", ny);
    fprintf(fp, "&column name=z, type=double, description=\"%s\" &end\n", z_equation);
    fprintf(fp, "&data mode=ascii, no_row_counts=1 &end\n");
    for (ix=0; ix<nx; ix++)
         for (iy=0; iy<ny; iy++)
             fprintf(fp, "%e\n", z_data[ix][iy]);
    return(0);
}