Beispiel #1
0
int main(int argc, char **argv)
{
  SCANNED_ARG *s_arg;
  SDDS_DATASET inputPage, outputPage;
  
  char *inputfile, *outputfile;
  char **inputColumnName, **inputStringColumnName, **inputDoubleColumnName;
  char **outputStringColumnName, **outputDoubleColumnName, **matchColumn=NULL;
  long inputRows, inputDoubleColumns, inputStringColumns, indexColumn=0, matchColumns=0, noOldColumnNamesColumn=0;
  long outputRows, outputDoubleColumns, outputStringColumns;
  char **inputParameterName;
  int32_t inputParameters, inputColumns;
  char *inputDescription, *inputContents;
  char *outputDescription;
  long i, i_arg, col;
  char *buffer;
  char **columnOfStrings;
  long buffer_size;
#define BUFFER_SIZE_INCREMENT 16384
  MATRIX *R, *RInv;
  long OldStringColumnsDefined;
  char *inputStringRows, *outputStringRows;
  char **stringArray, *stringParameter;
  long token_length;
  long verbose;
  char format[32];
  long digits;
  char *Symbol, *Root;
  void *parameterPointer;
  long ascii;
  unsigned long pipeFlags, majorOrderFlag;
  long tmpfile_used, noWarnings;
  long ipage=0, columnType;
  char *oldColumnNames, *newColumnNamesColumn;
  short columnMajorOrder=-1;
  
  inputColumnName = outputStringColumnName = outputDoubleColumnName = inputParameterName = NULL;
  outputRows = outputDoubleColumns = outputStringColumns = OldStringColumnsDefined = 0;

  SDDS_RegisterProgramName(argv[0]);

  argc = scanargs(&s_arg, argc, argv);
  if (argc==1) 
    bomb(NULL,  USAGE);

  inputfile = outputfile = NULL;
  verbose = 0;
  Symbol = Root = NULL;
  ascii = 0;
  digits=3;
  pipeFlags = 0;
  tmpfile_used = 0;
  noWarnings = 0;
  oldColumnNames = NULL;
  newColumnNamesColumn = NULL;
  
  for (i_arg=1; i_arg<argc; i_arg++) {
    if (s_arg[i_arg].arg_type==OPTION) {
      switch(match_string(s_arg[i_arg].list[0], commandline_option, COMMANDLINE_OPTIONS, 
                          UNIQUE_MATCH)) {
      case CLO_MAJOR_ORDER:
        majorOrderFlag=0;
        s_arg[i_arg].n_items--;
        if (s_arg[i_arg].n_items>0 &&
            (!scanItemList(&majorOrderFlag, s_arg[i_arg].list+1, &s_arg[i_arg].n_items, 0,
                           "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
                           "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER,
                           NULL)))
          SDDS_Bomb("invalid -majorOrder syntax/values");
        if (majorOrderFlag&SDDS_COLUMN_MAJOR_ORDER)
          columnMajorOrder=1;
        else if (majorOrderFlag&SDDS_ROW_MAJOR_ORDER)
          columnMajorOrder=0;
        break;
      case CLO_MATCH_COLUMN:
        matchColumns = s_arg[i_arg].n_items-1;
        matchColumn = s_arg[i_arg].list+1;
        break;
      case CLO_INDEX_COLUMN:
        indexColumn = 1;
        break;
      case CLO_NO_OLDCOLUMNNAMES:
        noOldColumnNamesColumn = 1;
        break;
      case CLO_VERBOSE:
        verbose=1;
        break;
      case CLO_ASCII:
        ascii=1;
        break;
      case CLO_DIGITS:
        if (!(get_long(&digits, s_arg[i_arg].list[1])))
          bomb("no string given for option -digits", USAGE);
        break;
      case CLO_COLUMNROOT:
        if (!(Root=s_arg[i_arg].list[1]))
          SDDS_Bomb("No root string given");
        break;
      case CLO_SYMBOL:
        if (!(Symbol=s_arg[i_arg].list[1]))
          SDDS_Bomb("No symbol string given");
        break;
      case CLO_PIPE:
        if (!processPipeOption(s_arg[i_arg].list+1, s_arg[i_arg].n_items-1, &pipeFlags))
          SDDS_Bomb("invalid -pipe syntax");
        break;
      case CLO_OLDCOLUMNNAMES:
        if (!(oldColumnNames=s_arg[i_arg].list[1]))
          SDDS_Bomb("No oldColumnNames string given");
        break;
      case CLO_NEWCOLUMNNAMES:
        if (s_arg[i_arg].n_items!=2 ||
            SDDS_StringIsBlank(newColumnNamesColumn = s_arg[i_arg].list[1]))
          SDDS_Bomb("Invalid -newColumnNames syntax/value");
        break;
      default:
        bomb("unrecognized option given", USAGE);
      }
    }
    else {
      if (!inputfile)
        inputfile = s_arg[i_arg].list[0];
      else if (!outputfile)
        outputfile = s_arg[i_arg].list[0];
      else
        bomb("too many filenames given", USAGE);
    }
  }

  processFilenames("sddstranpose", &inputfile, &outputfile, pipeFlags, noWarnings, &tmpfile_used);
  if (newColumnNamesColumn && Root) 
    SDDS_Bomb("-root and -newColumnNames are incompatible");
  
  if (!SDDS_InitializeInput(&inputPage, inputfile) ||
      !(inputParameterName=(char**)SDDS_GetParameterNames(&inputPage, &inputParameters)) ||
      !SDDS_GetDescription(&inputPage, &inputDescription, &inputContents))
    SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors|SDDS_VERBOSE_PrintErrors);
  if (matchColumns) 
    inputColumnName = getMatchingSDDSNames(&inputPage, matchColumn, matchColumns, &inputColumns, SDDS_MATCH_COLUMN); 
  else {
    if (!(inputColumnName=(char**)SDDS_GetColumnNames(&inputPage, &inputColumns)))
      SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors|SDDS_VERBOSE_PrintErrors);
  }
  
  inputDoubleColumns=0;
  inputStringColumns=0;
  inputDoubleColumnName=(char**)malloc(inputColumns*sizeof(char*));
  inputStringColumnName=(char**)malloc(inputColumns*sizeof(char*));
  inputRows = 0;
  /***********                                  \
   * read data *
   \***********/
  while (0<SDDS_ReadTable(&inputPage)) {
    ipage ++;
#if defined(DEBUG)
    fprintf(stderr, "working on page %ld\n", ipage);
#endif
    if (ipage==1) {
      SDDS_DeferSavingLayout(1);
      if( !SDDS_SetColumnFlags(&inputPage, 0))
        SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors|SDDS_VERBOSE_PrintErrors);
      /* count the string and numerical columns in the input file */
      for (i=0;i<inputColumns;i++) {
        if ( SDDS_NUMERIC_TYPE( columnType = SDDS_GetColumnType( &inputPage, i))) {
          inputDoubleColumnName[inputDoubleColumns]=inputColumnName[i];
          inputDoubleColumns++;
        }
      }
      for (i=0; i<inputPage.layout.n_columns; i++) {
        if (inputPage.layout.column_definition[i].type == SDDS_STRING ) {
          inputStringColumnName[inputStringColumns] = inputPage.layout.column_definition[i].name;
          inputStringColumns++;
        }
      }
      if( !(inputRows=SDDS_CountRowsOfInterest(&inputPage)))
        SDDS_Bomb("No rows in dataset.");
    }
    else {
      /* these statements are executed on the subsequent pages */
      if (inputRows != SDDS_CountRowsOfInterest(&inputPage)) {
        SDDS_Bomb("Datasets don't have the same number of rows.\nProcessing stopped before reaching the end of the input file.");
      }
    }
#if defined(DEBUG)
    fprintf(stderr, "row flags set\n");
#endif
    if (inputDoubleColumns == 0)
      SDDS_Bomb("No numerical columns in file.");
    if ((ipage==1) && verbose) {
      fprintf(stderr, "No. of double/float/integer columns: %ld.\n", inputDoubleColumns);
      fprintf(stderr, "No. of string columns: %ld.\n", inputStringColumns);
      fprintf(stderr, "No. of rows: %ld.\n", inputRows);
    }
    /****************\
     * transpose data *
     \****************/
    if (inputDoubleColumns) {
      if (ipage == 1) {
        m_alloc(&RInv, inputRows, inputDoubleColumns);
        m_alloc(&R, inputDoubleColumns, inputRows);
      }
      for (col=0;col<inputDoubleColumns;col++){
        if (!(R->a[col]=(double*)SDDS_GetColumnInDoubles(&inputPage, inputDoubleColumnName[col]))) {
          SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
      }
      if (verbose) {
        m_show(R, "%9.6le ", "Transpose of input matrix:\n", stdout);
      }
      m_trans(RInv, R);
    }
    /***************************\
     * determine existence of    *
     * transposed string columns *
     \***************************/
    if (ipage == 1) {
      OldStringColumnsDefined=0;
      switch(SDDS_CheckParameter(&inputPage, OLD_STRING_COLUMN_NAMES, NULL, SDDS_STRING, NULL)){
      case SDDS_CHECK_OKAY:
        OldStringColumnsDefined=1;
        break;
      case SDDS_CHECK_NONEXISTENT:
        break;
      case SDDS_CHECK_WRONGTYPE:
      case SDDS_CHECK_WRONGUNITS:
        fprintf(stderr, "Something wrong with parameter OldStringColumns.\n"); 
        exit(1);
        break;
      }
      if (OldStringColumnsDefined){
        /* decompose OldStringColumns into names of string columns for the output file */
        if (!SDDS_GetParameter(&inputPage, OLD_STRING_COLUMN_NAMES, &inputStringRows))
          SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        if (verbose) {
          fprintf(stderr, "Parameter OldStringColumns: %s.\n", inputStringRows);
        }
        outputStringColumnName=(char**)malloc(sizeof(char*));
        outputStringColumns=0;
        buffer_size=BUFFER_SIZE_INCREMENT;
        buffer=(char*)malloc(sizeof(char)*buffer_size);
        while ( 0 <= (token_length = SDDS_GetToken(inputStringRows, buffer, BUFFER_SIZE_INCREMENT))){
          if (!token_length)
            SDDS_Bomb("A null string was detected in parameter OldStringColumns.\n");
          if (!SDDS_CopyString(&outputStringColumnName[outputStringColumns], buffer))
            SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
          if (verbose) {
            fprintf(stderr, "Output string column: %s\n", outputStringColumnName[outputStringColumns]);
          }
          outputStringColumns++;
        }
      }
    }
    
    /*********************\
     * define output page *
     \*********************/
    if ( ipage == 1 ) {
      outputRows = inputDoubleColumns;
      outputDoubleColumns = inputRows;
      if (inputDescription){
        outputDescription = (char*) malloc( sizeof(char) * (strlen("Transpose of ") + strlen(inputDescription) + 1));
        strcat(strcpy(outputDescription, "Transpose of "), inputDescription);
        if (!SDDS_InitializeOutput(&outputPage, ascii?SDDS_ASCII:SDDS_BINARY, 1, outputDescription, inputContents, outputfile))
          SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }
      else {
        if (!SDDS_InitializeOutput(&outputPage, ascii?SDDS_ASCII:SDDS_BINARY, 1, NULL, NULL, outputfile))
          SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }    
      if (columnMajorOrder!=-1)
        outputPage.layout.data_mode.column_major = columnMajorOrder;
      else
        outputPage.layout.data_mode.column_major = inputPage.layout.data_mode.column_major;
      /***********************************\
       * define names for double columns *
       \***********************************/
      if (!Root && inputStringColumns ) {
        /* use specified string column, or first string column encountered */
        if (!newColumnNamesColumn)
          /* first string column encountered */
          outputDoubleColumnName = (char**) SDDS_GetColumn(&inputPage, inputStringColumnName[0]);
        else {
          /* use specified string column */
          if (SDDS_CheckColumn(&inputPage, newColumnNamesColumn, NULL, SDDS_STRING, stderr)!=SDDS_CHECK_OKAY)
            SDDS_Bomb("column named with -newColumnNames does not exist in input");
          outputDoubleColumnName = (char**)SDDS_GetColumn(&inputPage, newColumnNamesColumn);
        }
        for (i=1; i<inputRows; i++) {
          
          if (match_string(outputDoubleColumnName[i-1], outputDoubleColumnName+i, inputRows-i, EXACT_MATCH)>=0) {
            fprintf(stderr, "Error, duplicate %s found in input file string column %s, can not be used as output column names\n",  outputDoubleColumnName[i-1], newColumnNamesColumn ? newColumnNamesColumn : inputStringColumnName[0]);
            exit(1);
          }
        }
      }
      else {
        /* use command line options to produce column names in the output file */
        outputDoubleColumnName = (char**) malloc( outputDoubleColumns * sizeof(char*) );
        digits = MAX(digits, log10(inputRows) + 1);
        if (!Root){
          Root = (char*) malloc( sizeof(char) * (strlen("Column")+1) );
          strcpy(Root, "Column");
        }
        if (outputDoubleColumns!=1) {
          for ( i=0; i < outputDoubleColumns; i++){
            outputDoubleColumnName[i] = (char*) malloc( sizeof(char) * (strlen(Root)+digits+1));
            sprintf(format, "%s%%0%ldld", Root, digits);
            sprintf(outputDoubleColumnName[i], format, i);
          }
        }
        else {/* only one row to transpose */
          outputDoubleColumnName[0] = (char*) malloc( sizeof(char) * (strlen(Root)+1));
          strcpy( outputDoubleColumnName[0], Root);
        }
      }
      
      
      /*************************\
       * define string columns *
       \*************************/
      if (OldStringColumnsDefined) {
        if (!SDDS_DefineSimpleColumns(&outputPage, outputStringColumns, 
                                      outputStringColumnName, NULL, SDDS_STRING))
          SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }
      else {
        /* by default there should be at least one string column, that of the old column names. */
        if (!noOldColumnNamesColumn) {
          outputStringColumns = 1;
          outputStringColumnName = (char**) malloc( sizeof(char*));
          if (oldColumnNames) {
            /* commanline option specification */
            outputStringColumnName[0] = oldColumnNames;
          }
          else {
            outputStringColumnName[0] = (char*) malloc( sizeof(char) * (strlen("OldColumnNames") + 1));
            strcpy(outputStringColumnName[0], "OldColumnNames");
          }
          if ( 0 > SDDS_DefineColumn(&outputPage, outputStringColumnName[0], NULL, NULL, NULL, NULL, SDDS_STRING, 0))
            SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
      }
      if (indexColumn && !SDDS_DefineSimpleColumn(&outputPage, "Index", NULL, SDDS_LONG))
        SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      /*************************\
       * define double columns *
       \*************************/
      for ( i=0; i < outputDoubleColumns; i++)
        if (Symbol){
          if (0>SDDS_DefineColumn(&outputPage, outputDoubleColumnName[i], Symbol, NULL, NULL, 
                                  NULL, SDDS_DOUBLE, 0))
            SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
        else {
          if (0>SDDS_DefineColumn(&outputPage, outputDoubleColumnName[i], NULL, NULL, NULL, 
                                  NULL, SDDS_DOUBLE, 0))
            SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
      /********************************\
       * define string parameters       *
       * i.e. transposed string columns *
       \********************************/
      if ( inputStringColumns>1 ) {
        if (0>SDDS_DefineParameter(&outputPage, OLD_STRING_COLUMN_NAMES, 
                                   NULL, NULL, "Transposed string columns", NULL, SDDS_STRING, 
                                   NULL))
          SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        for ( i=0; i < inputStringColumns; i++){
          if (0>SDDS_DefineParameter(&outputPage, inputStringColumnName[i], NULL, NULL, "Transposed string column data", NULL, 
                                     SDDS_STRING, NULL))
            SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
      }
      
      /*************************\
       * transfer parameters not *
       * associated with old     *
       * string columns          *
       \*************************/
      if (inputParameters) {
        for ( i=0; i < inputParameters; i++) {
          if ( (0 > match_string(inputParameterName[i], outputStringColumnName, outputStringColumns, 0) &&
                strcasecmp(inputParameterName[i], OLD_STRING_COLUMN_NAMES)))
            if ( 0 > SDDS_TransferParameterDefinition(&outputPage, &inputPage, inputParameterName[i], NULL))
              SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
      }
      
      /***************\
       * write layout *
       \***************/
      SDDS_DeferSavingLayout(0);
      /* if InputFile is not already transfered ot the output file, then create it. */
      switch( SDDS_CheckParameter(&outputPage, "InputFile", NULL, SDDS_STRING, NULL) ) {
      case SDDS_CHECK_NONEXISTENT:
        if (0>SDDS_DefineParameter(&outputPage, "InputFile", NULL, NULL, "Original matrix file", NULL, SDDS_STRING, NULL))
          SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        break;
      default:
        break;
      }
      if (!SDDS_WriteLayout(&outputPage) )
        SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
#if defined(DEBUG)
    fprintf(stderr, "table layout defined\n");
#endif

    if (!SDDS_StartTable(&outputPage, outputRows) )
      SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    if (ipage == 1) {
      if (!SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, 
                              "InputFile", inputfile?inputfile:"pipe", NULL))
        SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
    /***************************************\
     * assign string columns    from input *
     * to     string parameters in output  *
     \**************************************/
    if ( inputStringColumns > 1) {
      for ( i=0; i < inputStringColumns; i++){
        columnOfStrings = (char**) SDDS_GetColumn(&inputPage, inputStringColumnName[i]);
        stringParameter = JoinStrings(columnOfStrings, inputRows, BUFFER_SIZE_INCREMENT);
        if ( !SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, 
                                 inputStringColumnName[i], stringParameter, NULL))
          SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        free(columnOfStrings);
        free(stringParameter);
      }
      outputStringRows = JoinStrings(inputStringColumnName, inputStringColumns, BUFFER_SIZE_INCREMENT);
      if (!SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, 
                              OLD_STRING_COLUMN_NAMES, outputStringRows, NULL))
        SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
    
#if defined(DEBUG)
    fprintf(stderr, "string parameters assigned\n");
#endif
    
    if (inputParameters){
      for ( i=0; i < inputParameters; i++){
        if ( (0 > match_string(inputParameterName[i], outputStringColumnName, outputStringColumns, 0) &&
              strcasecmp(inputParameterName[i], OLD_STRING_COLUMN_NAMES))) {
          parameterPointer = (void*) SDDS_GetParameter(&inputPage, inputParameterName[i], NULL);
          if (!SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_REFERENCE, 
                                  inputParameterName[i], parameterPointer, NULL))
            SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
          free(parameterPointer);
        }
      }
    }
#if defined(DEBUG)
    fprintf(stderr, "input parameters assigned\n");
#endif
    
    /**********************************\
     * assign data to                   *
     * output table part of data set    *
     \**********************************/
    if (outputRows) {
      /***************************\
       * assign string column data *
       \***************************/
      if (OldStringColumnsDefined){
        for ( i=0 ; i < outputStringColumns; i++){
          if (!SDDS_GetParameter(&inputPage, outputStringColumnName[i], &stringParameter))
            SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
          stringArray=TokenizeString(stringParameter, outputRows);
          if (!SDDS_SetColumn(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_REFERENCE, 
                              stringArray, outputRows, outputStringColumnName[i]))
            SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
      }
      else {
        if (!noOldColumnNamesColumn && !SDDS_SetColumn(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_REFERENCE, 
                            inputDoubleColumnName, outputRows, outputStringColumnName[0]))
          SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }
#if defined(DEBUG)
      fprintf(stderr, "string data columns assigned\n");
#endif
      /***************************\
       * assign double column data *
       \***************************/
      for ( i=0 ; i < outputDoubleColumns; i++) /* i is the row index */
        if (!SDDS_SetColumn(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_REFERENCE, 
                            RInv->a[i], outputRows, outputDoubleColumnName[i]))
          SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      if (indexColumn) {
        for (i=0; i<outputRows; i++)
          if (!SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, i, "Index", i, NULL))
            SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }
#if defined(DEBUG)
      fprintf(stderr, "double data columns assigned\n");
#endif
    }
    
#if defined(DEBUG)
    fprintf(stderr, "data assigned\n");
#endif
    if (!SDDS_WriteTable(&outputPage))
      SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
#if defined(DEBUG)
    fprintf(stderr, "data written out\n");
#endif
  }    
  if (inputDoubleColumns) {
    m_free(&RInv);
    m_free(&R);
  }
  if (inputColumnName) {
    SDDS_FreeStringArray(inputColumnName, inputColumns);
    free(inputColumnName);
  }
  if (inputStringColumns)
    free(inputStringColumnName);
  if (inputDescription)
    free(inputDescription);
  if (inputParameterName) {
    SDDS_FreeStringArray(inputParameterName, inputParameters);
    free(inputParameterName);
  }
  if (outputDoubleColumns) {
    SDDS_FreeStringArray(outputDoubleColumnName, outputDoubleColumns);
    free(outputDoubleColumnName);
  }
  
  if (!SDDS_Terminate(&inputPage) || !SDDS_Terminate(&outputPage))
    SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  
  if (tmpfile_used && !replaceFileAndBackUp(inputfile, outputfile)) 
    exit(1);
  return(0);
}
Beispiel #2
0
int main( int argc, char **argv)
{
  SCANNED_ARG *scanned;
  char *inputfile, *outputfile;
  SDDS_DATASET twissPage, resultsPage;
  double particles, charge, length;
  long verbosity, noWarning, i, elements, superperiods, growthRatesOnly, force;
  double pCentral0, I1, I2, I3, I4, I5, taux, tauy, taudelta;
  double EMeV;
  double emitx0, emitx, emitxInput, emityInput, emity, coupling, sigmaz0, sigmaz;
  double sigmaDelta0, sigmaDelta, sigmaDeltaInput, xGrowthRate, yGrowthRate, zGrowthRate;
  double xGrowthRateInitial, yGrowthRateInitial, zGrowthRateInitial;
  double emitxOld, sigmaDeltaOld;
  long method, converged;
/* used in simplex minimization */
  double yReturn, *xGuess, *dxGuess, *xLowerLimit, *xUpperLimit;
  short *disable;
  long dimensions = 15, maxEvaluations = 500, maxPasses = 2;
  double target = 1e-6;
  int32_t integrationTurns, integrationStepSize;
  long integrationPoints = 0;
  double *exInteg=NULL, *eyInteg=NULL, *elInteg=NULL, *xRateInteg=NULL, *yRateInteg=NULL, *zRateInteg=NULL;
  double *SdeltaInteg=NULL, *SzInteg=NULL;
  int32_t *passInteg=NULL;
  unsigned long dummyFlags;
  double rfVoltage, rfHarmonic;
  double alphac, U0, circumference, energy;
  double *xRateVsS, *yRateVsS, *zRateVsS;
  
  SDDS_RegisterProgramName(argv[0]);
  argc  =  scanargs(&scanned, argc, argv);
  if (argc == 1)
    bomb(NULL, USAGE);

  xRateVsS = yRateVsS = zRateVsS = NULL;
  inputfile  =  NULL;
  outputfile  =  NULL;
  energy = 0;
  verbosity = 0;
  isRing = 1;
  particles = 0;
  charge = 0;
  coupling = emityInput = 0;
  force = 1;
  length = 0;
  superperiods=1;
  method = 0;
  emitxInput = 0;
  sigmaDeltaInput = 0;
  growthRatesOnly = 0;
  integrationTurns = 0;
  rfVoltage = rfHarmonic = 0;
  noWarning = 0;
  for (i = 1; i<argc; i++) {
    if (scanned[i].arg_type == OPTION) {
      delete_chars(scanned[i].list[0], "_");
      switch(match_string(scanned[i].list[0], option, N_OPTIONS, UNIQUE_MATCH)) {
      case VERBOSE:
        if(scanned[i].n_items > 1 ) {
          get_long(&verbosity, scanned[i].list[1]);
        } else {
          verbosity=1;
        }
        break;
      case ISRING:
        if(scanned[i].n_items > 1 ) {
          get_long(&isRing, scanned[i].list[1]);
        } else {
          isRing=1;
        }
        break;
      case CHARGE:
        get_double(&charge, scanned[i].list[1]);
        break;
      case EMITXINPUT:
        /* This is really the emitx+emity, not emitx */
        get_double(&emitxInput, scanned[i].list[1]);
        break;
      case EMITINPUT:
        get_double(&emitxInput, scanned[i].list[1]);
        break;
      case DELTAINPUT:
        get_double(&sigmaDeltaInput, scanned[i].list[1]);
        break;
      case LENGTH:
        get_double(&length, scanned[i].list[1]);
        length /= 1000; /* convert input length from mm to m */
        break;
      case COUPLING:
        get_double(&coupling, scanned[i].list[1]);
        break;
      case EMITYINPUT:
        get_double(&emityInput, scanned[i].list[1]);
        break;
      case FORCECOUPLING:
        get_long(&force, scanned[i].list[1]);
        break;
      case PARTICLES:
        get_double(&particles, scanned[i].list[1]);
        break;
      case SUPERPERIOD:
        get_long(&superperiods, scanned[i].list[1]);
        break;
      case METHOD:
        get_long(&method, scanned[i].list[1]);
        break;
      case GROWTHRATESONLY:
        growthRatesOnly = 1;
        break;
      case SET_TARGET:
        if (scanned[i].n_items!=2 ||
            !get_double(&target, scanned[i].list[1]) ||
            target<0)
          bomb("invalid -target syntax", NULL);
        break;
      case RF:
        if (scanned[i].n_items<2)
          bomb("invalid -rf syntax", NULL);
        scanned[i].n_items--;
        rfVoltage = rfHarmonic = 0;
        if (!scanItemList(&dummyFlags, scanned[i].list+1, &scanned[i].n_items, 0,
                          "voltage", SDDS_DOUBLE, &rfVoltage, 1, 0,
                          "harmonic", SDDS_DOUBLE, &rfHarmonic, 1, 0,
                          NULL) ||
            rfVoltage<=0 || rfHarmonic<=0)
          bomb("invalid -rf syntax/values", "-rf=voltage=MV,harmonic=<value>");
        break;
      case SET_ENERGY:
        if (scanned[i].n_items!=2)
          bomb("invalid -energy syntax", NULL);
        if (!sscanf(scanned[i].list[1], "%lf", &energy) || energy<=0)
          bomb("invalid -energy syntax/values", "-energy=<MeV>");
        break;
      case SET_INTEGRATE:
        if (scanned[i].n_items<2)
          bomb("invalid -integrate syntax", NULL);
        integrationTurns = 0;
        integrationStepSize = 1;
        scanned[i].n_items--;
        if (!scanItemList(&dummyFlags, scanned[i].list+1, &scanned[i].n_items, 0,
                          "turns", SDDS_LONG, &integrationTurns, 1, 0,
                          "stepsize", SDDS_LONG, &integrationStepSize, 1, 0,
                          NULL) ||
            integrationTurns<=0 || integrationStepSize<1) 
          bomb("invalid -integrate syntax", NULL);
        break;
      case NO_WARNING:
        noWarning = 1;
        break;
      default:
        fprintf(stderr, "Unknown option %s given", scanned[i].list[0]);
        exit(1);
        break;
      }
    }
    else {
      if (!inputfile)
        inputfile  =  scanned[i].list[0];
      else if (!outputfile) 
        outputfile =  scanned[i].list[0];
      else
        bomb("too many filenames given", NULL);
    }
  }
  if (charge && particles) {
    bomb("Options charge and particles cannot be both specified.",NULL);
  }
  if (!charge) 
    charge = particles * e_mks;
  if (!particles) {
    /* command line input value is in units of nC */
    charge /= 1e9; 
    particles = charge/ e_mks;
  }
  if ((!coupling && !emityInput) || (coupling && emityInput))
    bomb("Give -coupling or -emityInput (but not both)", NULL);
  if (!length && !rfVoltage) 
    bomb("Specify either the bunch length or the rf voltage.", NULL);

  if (growthRatesOnly && integrationTurns) {
    growthRatesOnly = 0;
    if (!noWarning)
      fprintf( stdout, "*Warning* -growthRatesOnly option is incompatiable with -integrate option. The -growthRatesOnly will be disabled.\n");
  }
  
  if (!growthRatesOnly && !integrationTurns && !noWarning)  
    fprintf( stdout, "*Warning* The growth rate contribution columns in the results file will be those calculated from the equilibrium (or final) condition.\n");
  if (integrationTurns && !isRing) {
    integrationTurns = 0;
    fprintf( stdout, "*Warning* -isRing=0 is incompatiable with -integrate option. The -integrate will be disabled.\n");
  }
  if (energy && !isRing) {
    energy = 0;
    fprintf( stdout, "*Warning* you can not scale energy for linac beam. Scaling will be disabled.\n");
  }

  /***************************************************\
   * get parameter information from first input file  *
   \***************************************************/
  if (verbosity)
    fprintf( stdout, "Opening \"%s\" for checking presence of parameters.\n", inputfile);
  if (!SDDS_InitializeInput(&twissPage, inputfile))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  /* read first page of input file to get parameters 
     I1 I2 I3 I4 I5.
     Check presence of first radiation integral.
     */
  SDDS_ReadPage(&twissPage);
  /* parameter Type */
  switch(SDDS_CheckParameter(&twissPage, "I1", NULL, SDDS_DOUBLE, verbosity?stdout:NULL)) {
  case SDDS_CHECK_NONEXISTENT:
    if (verbosity)
      fprintf( stdout, "\tParameter I1 not found in input file.\n");
    break;
  case SDDS_CHECK_WRONGTYPE:
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    exitElegant(1);
    break;
  case SDDS_CHECK_OKAY:
    break;
  default:
    fprintf( stdout, "Unexpected result from SDDS_CheckParameter routine while checking parameter Type.\n");
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    exitElegant(1);
    break;
  }
  if (verbosity)
    fprintf( stdout, "Opening \"%s\" for writing...\n", outputfile);
  if (!SDDS_InitializeOutput(&resultsPage, SDDS_BINARY, 1, "Intra-beam scattering rates",
                             "Intra-beam scattering rates", outputfile))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  if (!SDDS_TransferParameterDefinition(&resultsPage, &twissPage, "I1", NULL) ||
      !SDDS_TransferParameterDefinition(&resultsPage, &twissPage, "I2", NULL) ||
      !SDDS_TransferParameterDefinition(&resultsPage, &twissPage, "I3", NULL) ||
      !SDDS_TransferParameterDefinition(&resultsPage, &twissPage, "I4", NULL) ||             
      !SDDS_TransferParameterDefinition(&resultsPage, &twissPage, "I5", NULL) ||             
      !SDDS_TransferParameterDefinition(&resultsPage, &twissPage, "pCentral", NULL) ||
      !SDDS_TransferParameterDefinition(&resultsPage, &twissPage, "taux", NULL) ||
      !SDDS_TransferParameterDefinition(&resultsPage, &twissPage, "tauy", NULL) ||
      !SDDS_TransferParameterDefinition(&resultsPage, &twissPage, "taudelta", NULL) )
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);

  if (0>SDDS_DefineParameter(&resultsPage, "Superperiods", NULL, NULL, "Superperiods", NULL, SDDS_LONG, NULL) ||
      0>SDDS_DefineParameter(&resultsPage, "Energy", "E", "MeV", "Total Energy", NULL, SDDS_DOUBLE, NULL) ||
      0>SDDS_DefineParameter(&resultsPage, "Particles", NULL, NULL, "Particles", NULL, SDDS_DOUBLE, NULL) ||
      0>SDDS_DefineParameter(&resultsPage, "Charge", NULL, "nC", "Charge", NULL, SDDS_DOUBLE, NULL) ||
      0>SDDS_DefineParameter(&resultsPage, "PeakCurrent", "I$bp$n", "A", "Peak Current", NULL, SDDS_DOUBLE, NULL) ||
      0>SDDS_DefineParameter(&resultsPage, "RfVoltage", NULL, "MV", "Rf Voltage", NULL, SDDS_DOUBLE, NULL) ||
      0>SDDS_DefineParameter(&resultsPage, "xGrowthRateInitial", "g$bIBS,x$n", "1/s", "Initial IBS emittance growth rate in the horizontal plane", NULL, SDDS_DOUBLE, NULL) ||
      0>SDDS_DefineParameter(&resultsPage, "yGrowthRateInitial", "g$bIBS,y$n", "1/s", "Initial IBS emittance growth rate in the vertical plane", NULL, SDDS_DOUBLE, NULL) ||
      0>SDDS_DefineParameter(&resultsPage, "zGrowthRateInitial", "g$bIBS,z$n", "1/s", "Initial IBS emittance growth rate in the longitudinal plane", NULL, SDDS_DOUBLE, NULL))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);

  if (0>SDDS_DefineParameter(&resultsPage, "Convergence", NULL, NULL, "Convergence state of emittance calculations", NULL, SDDS_STRING, NULL) ||
      0>SDDS_DefineParameter(&resultsPage, "emitx0", "$ge$r$bx,0$n", "$gp$rm", "Equilibrium horizontal emittance with no coupling and no IBS", NULL, SDDS_DOUBLE, NULL) ||
      0>SDDS_DefineParameter(&resultsPage, "emitxInput", "$ge$r$bx,Input$n", "$gp$rm", "Initial horizontal emittance with coupling", NULL, SDDS_DOUBLE, NULL) ||
      0>SDDS_DefineParameter(&resultsPage, "emityInput", "$ge$r$by,Input$n", "$gp$rm", "Initial vertical emittance with coupling", NULL, SDDS_DOUBLE, NULL))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  
  /* requested equilibrium emittances or integrate emittances turn-by-turn*/
  if (!growthRatesOnly) {
    if (0>SDDS_DefineParameter(&resultsPage, "xGrowthRate", "g$bIBS,x$n", "1/s", "IBS emittance growth rate in the horizontal plane", NULL, SDDS_DOUBLE, NULL) ||
        0>SDDS_DefineParameter(&resultsPage, "yGrowthRate", "g$bIBS,y$n", "1/s", "IBS emittance growth rate in the vertical plane", NULL, SDDS_DOUBLE, NULL) ||
        0>SDDS_DefineParameter(&resultsPage, "zGrowthRate", "g$bIBS,z$n", "1/s", "IBS emittance growth rate in the longitudinal plane", NULL, SDDS_DOUBLE, NULL) ||
0>SDDS_DefineParameter(&resultsPage, "emitx", "$ge$r$bx$n", "$gp$rm", "Horizontal emittance with coupling and with IBS", NULL, SDDS_DOUBLE, NULL) ||
        0>SDDS_DefineParameter(&resultsPage, "emity", "$ge$r$by$n", "$gp$rm", "Vertical emittance with coupling and with IBS", NULL, SDDS_DOUBLE, NULL) ||
        0>SDDS_DefineParameter(&resultsPage, "sigmaDelta", "$gs$r$bd$n", NULL, "Relative momentum spread with IBS", NULL, SDDS_DOUBLE, NULL) || 
        0>SDDS_DefineParameter(&resultsPage, "sigmaz", "$gs$r$bz$n", "m", "Bunch length with IBS", NULL, SDDS_DOUBLE, NULL))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  
  
  if (0>SDDS_DefineParameter(&resultsPage, "sigmaDelta0", "$gs$r$bd,0$n", NULL, "Equilibrium relative momentum spread without IBS", NULL, SDDS_DOUBLE, NULL) ||
      0>SDDS_DefineParameter(&resultsPage, "sigmaDeltaInput", "$gs$r$bd,0$n", NULL, "Initial relative momentum spread", NULL, SDDS_DOUBLE, NULL) ||
      0>SDDS_DefineParameter(&resultsPage, "sigmaz0", "$gs$r$bz,0$n", "m", "Bunch length without IBS", NULL, SDDS_DOUBLE, NULL))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);

  if (verbosity)
    fprintf( stdout, "Opening for reading \"%s\"\n", inputfile);
  if (!SDDS_InitializeInput(&twissPage, inputfile))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  
  if (integrationTurns) {
    if (SDDS_DefineColumn(&resultsPage, "ex", "$ge$r$bx$n", "$gp$rm", "Horizontal Emittance", NULL, SDDS_DOUBLE, 0)<0 ||
        SDDS_DefineColumn(&resultsPage, "ey", "$ge$r$by$n", "$gp$rm", "Vertical Emittance", NULL, SDDS_DOUBLE, 0)<0 ||
        SDDS_DefineColumn(&resultsPage, "el", "$ge$r$bl$n", "s", "Longitudinal Emittance", NULL, SDDS_DOUBLE, 0)<0 ||
        SDDS_DefineColumn(&resultsPage, "Sdelta", "$gs$bd$n$r", "", "Fractional RMS Energy Spread", NULL, SDDS_DOUBLE, 0)<0 ||
        SDDS_DefineColumn(&resultsPage, "Sz", "$gs$r$bz$n", "m", "RMS Bunch Length", NULL, SDDS_DOUBLE, 0)<0 ||
        SDDS_DefineColumn(&resultsPage, "IBSRatex", NULL, "1/s", "Horizontal IBS Emittance Growth Rate", NULL, SDDS_DOUBLE, 0)<0 ||
        SDDS_DefineColumn(&resultsPage, "IBSRatey", NULL, "1/s", "Vertical IBS Emittance Growth Rate", NULL, SDDS_DOUBLE, 0)<0 ||
        SDDS_DefineColumn(&resultsPage, "IBSRatel", NULL, "1/s", "Longitudinal IBS Emittance Growth Rate", NULL, SDDS_DOUBLE, 0)<0 ||
        SDDS_DefineColumn(&resultsPage, "Pass", NULL, NULL, NULL, NULL, SDDS_LONG, 0)<0)
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    integrationPoints = integrationTurns/integrationStepSize+1;
    if (!(exInteg = SDDS_Malloc(sizeof(*exInteg)*integrationPoints)) ||
        !(eyInteg = SDDS_Malloc(sizeof(*eyInteg)*integrationPoints)) ||
        !(elInteg = SDDS_Malloc(sizeof(*elInteg)*integrationPoints)) ||
        !(SdeltaInteg = SDDS_Malloc(sizeof(*SdeltaInteg)*integrationPoints)) ||
        !(SzInteg = SDDS_Malloc(sizeof(*SzInteg)*integrationPoints)) ||
        !(xRateInteg = SDDS_Malloc(sizeof(*xRateInteg)*integrationPoints)) ||
        !(yRateInteg = SDDS_Malloc(sizeof(*yRateInteg)*integrationPoints)) ||
        !(zRateInteg = SDDS_Malloc(sizeof(*zRateInteg)*integrationPoints)) ||
        !(passInteg = SDDS_Malloc(sizeof(*passInteg)*integrationPoints)))
      bomb("memory allocation failure (integration arrays)", NULL);
  } else {
    if (SDDS_DefineColumn(&resultsPage, "s", NULL, "m", "Position", NULL, SDDS_DOUBLE, 0)<0 ||
        SDDS_DefineColumn(&resultsPage, "dIBSRatex", NULL, "1/s", "Local Horizontal IBS Emittance Growth Rate",  NULL, SDDS_DOUBLE, 0)<0 ||
        SDDS_DefineColumn(&resultsPage, "dIBSRatey", NULL, "1/s", "Local Vertical IBS Emittance Growth Rate",  NULL, SDDS_DOUBLE, 0)<0 ||
        SDDS_DefineColumn(&resultsPage, "dIBSRatel", NULL, "1/s", "Local Longitudinal IBS Emittance Growth Rate",  NULL, SDDS_DOUBLE, 0)<0)
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }

  if (!SDDS_WriteLayout(&resultsPage) )
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);

  while(SDDS_ReadPage(&twissPage)>0) {
    if (!SDDS_GetParameters(&twissPage,
                            "pCentral", &pCentral0,
                            "I1", &I1,
                            "I2", &I2,
                            "I3", &I3,
                            "I4", &I4,
                            "I5", &I5,
                            "taux", &taux,
			    "tauy", &tauy,
                            "taudelta", &taudelta,
                            "alphac", &alphac,
                            "U0", &U0,
                            NULL) )
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    EMeV = sqrt(sqr(pCentral0) + 1) * me_mev;
    elements = SDDS_CountRowsOfInterest(&twissPage);
    s = SDDS_GetColumnInDoubles(&twissPage, "s");
    pCentral = SDDS_GetColumnInDoubles(&twissPage, "pCentral0");
    circumference = s[elements-1]*superperiods;
    U0 *= superperiods;
    if (energy!=0) {
      /* scale to new energy */
      pCentral0 = sqrt(sqr(energy/me_mev)-1);
      taux /= ipow(energy/EMeV, 3);
      tauy /= ipow(energy/EMeV, 3);
      taudelta /= ipow(energy/EMeV, 3);
      U0 *= ipow(energy/EMeV, 4);
      for (i=0; i<elements; i++) pCentral[i] = pCentral0;
      EMeV = energy;
    }
    
    if (!length && U0>rfVoltage)
      bomb("energy loss per turn is greater than rf voltage", NULL);
    betax = SDDS_GetColumnInDoubles(&twissPage, "betax");
    betay = SDDS_GetColumnInDoubles(&twissPage, "betay");
    alphax = SDDS_GetColumnInDoubles(&twissPage, "alphax");
    alphay = SDDS_GetColumnInDoubles(&twissPage, "alphay");
    etax = SDDS_GetColumnInDoubles(&twissPage, "etax");
    etaxp = SDDS_GetColumnInDoubles(&twissPage, "etaxp");
    etay = SDDS_GetColumnInDoubles(&twissPage, "etay");
    etayp = SDDS_GetColumnInDoubles(&twissPage, "etayp");

    /* emitx0 and sigmaDelta0 are unperturbed quantities 
       (i.e. no coupling and no IBS) that
       zibs requires to internally calculate the quantum excitation.
       (zibs doesn't use the radiation integrals but should!) 
       */
    emitx0 = 55.0/ (32.*sqrt(3.)) * hbar_mks * sqr(pCentral0)/ (me_mks * c_mks)
      * I5 / (I2 - I4);
    sigmaDelta0 = sqrt(55.0/ (32.*sqrt(3.)) * hbar_mks * sqr(pCentral0)/ (me_mks * c_mks)
      * I3 / (2 * I2 + I4));
    /* use unperturbed quantities in no input supplied. */
    if (!sigmaDeltaInput)
      sigmaDeltaInput = sigmaDelta0;
    if (!emitxInput)
      emitxInput = emitx0/ ( 1 + coupling);
    else 
      /* The emitxInput value is really emit=emitx+emity */
      emitxInput = emitxInput/ ( 1 + coupling);
    if (!emityInput)
      emityInput = emitxInput * coupling;
    else
      coupling = emityInput/emityInput;
    sigmaDelta = sigmaDeltaInput;
    if (length)
      sigmaz0 = length;
    else {
      /* compute length in m from rf voltage, energy spread, etc */
      sigmaz0 = 
        circumference*sigmaDelta*
          sqrt(alphac*EMeV/(PIx2*rfHarmonic*sqrt(sqr(rfVoltage)-sqr(U0))));
    }
    sigmaz = sigmaz0;
    emity = emityInput;
    emitx = emitxInput;

    if (integrationPoints) {
      IBSIntegrate(exInteg, eyInteg, elInteg, passInteg,
                   SdeltaInteg, SzInteg,
                   xRateInteg, yRateInteg, zRateInteg,
                   integrationTurns, integrationStepSize, 
                   pCentral0, emitx, emity, sigmaDelta, sigmaz, particles,
                   emitx0, sigmaDelta0, 2./taux, 2./tauy, 2./taudelta, coupling,
                   s, pCentral, betax, alphax, betay, alphay, etax, etaxp, etay, etayp, elements,
                   superperiods, verbosity, isRing, force);
    } else {
      if (!(xRateVsS = SDDS_Realloc(xRateVsS, sizeof(*xRateVsS)*elements)) ||
          !(yRateVsS = SDDS_Realloc(yRateVsS, sizeof(*yRateVsS)*elements)) ||
          !(zRateVsS = SDDS_Realloc(zRateVsS, sizeof(*zRateVsS)*elements)) )
        bomb("memory allocation failure", NULL);
    }

    /* This call is to get the initial growth rates for writing to results file.
       This applies for any running option selected in the commandline */
    IBSRate(particles, elements, superperiods, verbosity, isRing,
             emitx, emity, sigmaDelta, sigmaz, 
             s, pCentral, betax, alphax, betay, alphay, etax, etaxp, etay, etayp,
             NULL, NULL, NULL, 
            &xGrowthRateInitial, &yGrowthRateInitial, &zGrowthRateInitial, 0);

    /* iterating for equilibrium emittances and final growth rates */
    if (!integrationTurns && !growthRatesOnly && isRing) {
      if (verbosity > 1) {
        fprintf (stdout, "Starting values:\nemitx: %10.5g sigmaDelta %10.5g.\n", emitx, sigmaDelta);
      }
      emitxOld = emitx;
      sigmaDeltaOld = sigmaDelta;
      xGuess = (double*) malloc(sizeof(double)*dimensions);
      dxGuess = (double*) malloc(sizeof(double)*dimensions);
      xLowerLimit = (double*) malloc(sizeof(double)*dimensions);
      xUpperLimit = (double*) malloc(sizeof(double)*dimensions);
      disable = (short*) malloc(sizeof(short)*dimensions);
      xGuess[0] = MAX(emitx, emitx0/ (1 + coupling));
      xGuess[1] = MAX(sigmaDelta, sigmaDelta0);
      dxGuess[0] = emitx * 0.1;
      dxGuess[1] = sigmaDelta * 0.1;
      xLowerLimit[0] = emitx0/ (1 + coupling);
      xLowerLimit[1] = sigmaDelta0;
      xUpperLimit[0] = emitx0/ (1 + coupling) * 200;
      xUpperLimit[1] = MIN(sigmaDelta0 * 100, 1.0);
      /* assign other variables to array which are not supoosed
         to be varied by simplex minimization
         */
      xGuess[2] = pCentral0;
      xGuess[3] = emity;
      xGuess[4] = sigmaz0;
      xGuess[5] = particles;
      xGuess[6] = emitx0;
      xGuess[7] = sigmaDelta0;
      xGuess[8] = taux;
      xGuess[9] = tauy;
      xGuess[10] = taudelta;
      xGuess[11] = coupling;
      xGuess[12] = elements;
      xGuess[13] = superperiods;
      xGuess[14] = verbosity;
      xLowerLimit[2] = pCentral0;
      xLowerLimit[3] = emity;
      xLowerLimit[4] = sigmaz0;
      xLowerLimit[5] = particles;
      xLowerLimit[6] = emitx0;
      xLowerLimit[7] = sigmaDelta0;
      xLowerLimit[8] = taux;
      xLowerLimit[9] = tauy;
      xLowerLimit[10] = taudelta;
      xLowerLimit[11] = coupling;
      xLowerLimit[12] = elements;
      xLowerLimit[13] = superperiods;
      xLowerLimit[14] = verbosity;
      xUpperLimit[2] = pCentral0;
      xUpperLimit[3] = emity;
      xUpperLimit[4] = sigmaz0;
      xUpperLimit[5] = particles;
      xUpperLimit[6] = emitx0;
      xUpperLimit[7] = sigmaDelta0;
      xUpperLimit[8] = taux;
      xUpperLimit[9] = tauy;
      xUpperLimit[10] = taudelta;
      xUpperLimit[11] = coupling;
      xUpperLimit[12] = elements;
      xUpperLimit[13] = superperiods;
      xUpperLimit[14] = verbosity;
      disable[0] = 0;
      disable[1] = 0;
      for (i=2 ; i<dimensions ; i++) {
        dxGuess[i] = 0.0;
        disable[i] = 1;
      }
      if (verbosity) {
        fprintf( stdout, "Doing simplex minimization...\n");
      }
      simplexMin( &yReturn, xGuess, dxGuess, xLowerLimit, xUpperLimit, disable, dimensions,
                 target, target/100.0, IBSequations, verbosity?IBSsimplexReport:NULL, 
                 maxEvaluations, maxPasses, 12, 3.0, 1.0, 0);
      /* final answers */
      emitx = xGuess[0];
      sigmaDelta = xGuess[1];
      emity = emitx * coupling;
      sigmaz = sigmaz0 * (sigmaDelta/ sigmaDelta0);
    }

    /* calculate growth rates contributions at equilibrium or
     just one time (-growthRateOnly option) */
     if (!integrationPoints) {
       IBSRate(particles, elements, superperiods, verbosity, isRing, 
                emitx, emity, sigmaDelta, sigmaz, 
                s, pCentral, betax, alphax, betay, alphay, etax, etaxp, etay, etayp,
                xRateVsS, yRateVsS, zRateVsS, 
               &xGrowthRate, &yGrowthRate, &zGrowthRate, 0);
     } else {
       /* final growth rates and emittances after integration */
       xGrowthRate = xRateInteg[integrationPoints - 1] ;
       yGrowthRate = yRateInteg[integrationPoints - 1] ;
       zGrowthRate = zRateInteg[integrationPoints - 1] ;
       emitx = exInteg[integrationPoints - 1] ;
       emity = eyInteg[integrationPoints - 1] ;
       sigmaDelta = SdeltaInteg[integrationPoints - 1] ;
       sigmaz = SzInteg[integrationPoints - 1] ;
     }
    
    
    
    converged = 1;

    if (0>SDDS_StartPage(&resultsPage, integrationPoints?integrationPoints:elements) ||
        !SDDS_SetParameters(&resultsPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,
                            "Convergence", converged?"Emittance converged":"Emittance did not converge",
                            "pCentral", pCentral0, "RfVoltage", rfVoltage,
                            "I1", I1,
                            "I2", I2,
                            "I3", I3,
                            "I4", I4,
                            "I5", I5,
                            "taux", taux,
                            "tauy", tauy,
                            "taudelta", taudelta,
                            "Energy", EMeV,
                            "Particles", particles,
                            "Charge", (1e9 * charge),
                            "PeakCurrent", (charge*c_mks/(sqrt(2*PI)*sigmaz)),
                            "Superperiods", superperiods,
                            "emitx0", emitx0,
                            "emitxInput", emitxInput,
                            "emityInput", emityInput,
                            "xGrowthRateInitial", xGrowthRateInitial,
                            "yGrowthRateInitial", yGrowthRateInitial,
                            "zGrowthRateInitial", zGrowthRateInitial,
                            "sigmaDeltaInput", sigmaDeltaInput,
                            "sigmaDelta0", sigmaDelta0,
                            "sigmaz0", sigmaz0, NULL) ||
        (!growthRatesOnly && 
         !SDDS_SetParameters(&resultsPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,
                             "xGrowthRate", xGrowthRate,
                             "yGrowthRate", yGrowthRate,
                             "zGrowthRate", zGrowthRate,
                             "emitx", emitx,
                             "emity", emity,
                             "sigmaDelta", sigmaDelta,
                             "sigmaz", sigmaz, NULL)) ||
         (integrationPoints && 
          (!SDDS_SetColumn(&resultsPage, SDDS_SET_BY_NAME, exInteg, integrationPoints, "ex") ||
           !SDDS_SetColumn(&resultsPage, SDDS_SET_BY_NAME, eyInteg, integrationPoints, "ey") ||
          !SDDS_SetColumn(&resultsPage, SDDS_SET_BY_NAME, elInteg, integrationPoints, "el") ||
          !SDDS_SetColumn(&resultsPage, SDDS_SET_BY_NAME, SdeltaInteg, integrationPoints, "Sdelta") ||
          !SDDS_SetColumn(&resultsPage, SDDS_SET_BY_NAME, SzInteg, integrationPoints, "Sz") ||
          !SDDS_SetColumn(&resultsPage, SDDS_SET_BY_NAME, xRateInteg, integrationPoints, "IBSRatex") ||
          !SDDS_SetColumn(&resultsPage, SDDS_SET_BY_NAME, yRateInteg, integrationPoints, "IBSRatey") ||
          !SDDS_SetColumn(&resultsPage, SDDS_SET_BY_NAME, zRateInteg, integrationPoints, "IBSRatel") ||
          !SDDS_SetColumn(&resultsPage, SDDS_SET_BY_NAME, passInteg, integrationPoints, "Pass"))) ||
        (!integrationPoints && 
         (!SDDS_SetColumn(&resultsPage, SDDS_SET_BY_NAME, s, elements, "s") ||
          !SDDS_SetColumn(&resultsPage, SDDS_SET_BY_NAME, xRateVsS, elements, "dIBSRatex") ||
          !SDDS_SetColumn(&resultsPage, SDDS_SET_BY_NAME, yRateVsS, elements, "dIBSRatey") ||
          !SDDS_SetColumn(&resultsPage, SDDS_SET_BY_NAME, zRateVsS, elements, "dIBSRatel"))) ||
        !SDDS_WritePage(&resultsPage))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  
  if (!SDDS_Terminate(&twissPage) || !SDDS_Terminate(&resultsPage))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  
  return(0);
}
Beispiel #3
0
void SetupOutputFile(char *outputfile, SDDS_DATASET *SDDSout, int mode, SDDS_DATASET *SDDSin, long copyCols, char **copyCol, long copyPars, char **copyPar) {
  long i, cols=0, pars=0;
  char **column=NULL, **par=NULL;
  if (!SDDS_InitializeOutput(SDDSout, SDDS_BINARY, 1, NULL, NULL, outputfile))
    SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  if (copyCols) {
    column = getMatchingSDDSNames(SDDSin, copyCol, copyCols, &cols, SDDS_MATCH_COLUMN);
    SDDS_SetColumnFlags(SDDSin, 0);
    for (i=0; i<cols; i++) {
      if (!SDDS_TransferColumnDefinition(SDDSout, SDDSin, column[i], NULL))
	SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      if (!SDDS_SetColumnsOfInterest(SDDSin, SDDS_MATCH_STRING, column[i], SDDS_OR))
	SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
    SDDS_FreeStringArray(column, cols);
  }
  if (copyPars) {
    par = getMatchingSDDSNames(SDDSin, copyPar, copyPars, &pars, SDDS_MATCH_PARAMETER);
    for (i=0; i<pars; i++) {
      if (!SDDS_TransferParameterDefinition(SDDSout, SDDSin, par[i], NULL))
	SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
    SDDS_FreeStringArray(par, pars);
  }
  if (verbose > 1 ) { fprintf(stdout, "cols %ld pars %ld\n", cols, pars); }
  if (!SDDS_DefineSimpleParameter(SDDSout, "sddsxra_mode", NULL, SDDS_LONG) ||
      !SDDS_DefineSimpleParameter(SDDSout, "TargetMaterial", NULL, SDDS_STRING) ||
      !SDDS_DefineSimpleParameter(SDDSout, "TargetFormula", NULL, SDDS_STRING) ||
      !SDDS_DefineSimpleParameter(SDDSout, "MassThickness", "g/cm^2", SDDS_DOUBLE) ||
      !SDDS_DefineSimpleParameter(SDDSout, "TargetThickness", "mm", SDDS_DOUBLE) ||
      !SDDS_DefineSimpleParameter(SDDSout, "TargetDensity", "g/cm^3", SDDS_DOUBLE) ||
      !SDDS_DefineSimpleParameter(SDDSout, "ThetaIn", "degrees", SDDS_DOUBLE) ||
      !SDDS_DefineSimpleColumn(SDDSout, "PhotonEnergy", "eV", SDDS_DOUBLE))
    SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  if (mode!=1 && mode!=6 && mode!=11) {
    if (SDDS_DefineColumn(SDDSout, "TotalCS", NULL, "cm^2/g", "Total x-ray cross section",NULL, SDDS_DOUBLE, 0)<0 ||
	SDDS_DefineColumn(SDDSout, "PhotoCS", NULL, "cm^2/g", "Photoelectric cross section",NULL, SDDS_DOUBLE, 0)<0 ||
	SDDS_DefineColumn(SDDSout, "CoherentCS", NULL, "cm^2/g", "Coherent scattering cross section ",NULL, SDDS_DOUBLE, 0)<0 ||
	SDDS_DefineColumn(SDDSout, "IncoherentCS", NULL, "cm^2/g", "Incoherent scattering cross section ",NULL, SDDS_DOUBLE, 0)<0)
      SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  if (mode==1 || mode==6) {
    if (SDDS_DefineColumn(SDDSout, "RefracIndex_Re", NULL, NULL, "Real part of refractive index", NULL, SDDS_DOUBLE, 0)<0 ||
	SDDS_DefineColumn(SDDSout, "RefracIndex_Im", NULL, NULL, "Imaginary part of refractive index", NULL, SDDS_DOUBLE, 0)<0 ||
	SDDS_DefineColumn(SDDSout, "delta", NULL, NULL, "Real part of 1 - n", NULL, SDDS_DOUBLE, 0)<0 ||
	SDDS_DefineColumn(SDDSout, "beta", NULL, NULL, "Imaginary part 1 - n", NULL, SDDS_DOUBLE, 0)<0)
      SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  } else if (mode==11) {
    if (SDDS_DefineColumn(SDDSout, "F1", NULL, NULL, "Atomic scattering factor f1", NULL, SDDS_DOUBLE, 0)<0 ||
	SDDS_DefineColumn(SDDSout, "F2", NULL, NULL, "Atomic scattering factor f2", NULL, SDDS_DOUBLE, 0)<0)
      SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  if (mode==6) {
    if (SDDS_DefineColumn(SDDSout, "Reflectivity", NULL, "g/cm^3", NULL, NULL, SDDS_DOUBLE, 0)<0 ||
	!SDDS_DefineSimpleParameter(SDDSout, "Polarization", NULL, SDDS_DOUBLE))
      SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  if (mode==2 || mode==4 || mode==12 || mode==14) {
    if (SDDS_DefineColumn(SDDSout, "Transmission", NULL, NULL, "Ratio of x-ray beam transmitted through the film target", NULL, SDDS_DOUBLE, 0)<0 ||
	SDDS_DefineColumn(SDDSout, "Absorption", NULL, NULL, "Ratio of x-ray beam absorbed by the film target", NULL, SDDS_DOUBLE, 0)<0 )
      SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  if (mode==4 ||  mode==14 ) {
    if (SDDS_DefineColumn(SDDSout, "TotalElectronYieldFront", NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0)<0 ||
	SDDS_DefineColumn(SDDSout, "TotalElectronYieldBack", NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0)<0 ||
	SDDS_DefineColumn(SDDSout, "TotalElectronYield", NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0)<0 ||
	!SDDS_DefineSimpleParameter(SDDSout, "TargetEfficiency", "g/cm^2", SDDS_DOUBLE))
      SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  if (mode==20) {
    if (!SDDS_DefineSimpleParameter(SDDSout, "ShellID", NULL, SDDS_LONG) ||
	!SDDS_DefineSimpleParameter(SDDSout, "ShellName", NULL, SDDS_STRING) ||
	!SDDS_DefineSimpleParameter(SDDSout, "EdgeEnergy", "eV", SDDS_DOUBLE) ||
	!SDDS_DefineSimpleParameter(SDDSout, "FluorYield", NULL, SDDS_DOUBLE) ||
	!SDDS_DefineSimpleParameter(SDDSout, "JumpFactor", NULL, SDDS_DOUBLE) ||
	!SDDS_DefineSimpleParameter(SDDSout, "LevelWidth", "eV", SDDS_DOUBLE) ||
	!SDDS_DefineSimpleParameter(SDDSout, "ElectronConfig", "e", SDDS_DOUBLE))
      SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  if (!SDDS_WriteLayout(SDDSout))
    SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
}