Logo Search packages:      
Sourcecode: paul version File versions  Download package

physical.c

/*****************************************************************************
 *                                                                           *
 * Programm:  paul                                                           *
 *            (P)rogramm zur (A)uswertung und (U)mformung von                *
 *            (L)aserbildern                                                 *
 * Modul:     physical.c                                                     *
 *            Functions to handle physical data                              *
 * Author:    Andreas Tille                                                  *
 * Date:      05.03.1999                                                     *
 * Copyright: Andreas Tille, 1999; GNU Public License                        *
 *                                                                           *
 *****************************************************************************/

#include "paul.h"

#ifdef PHYSICAL_PAUL

#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#ifdef HAVE_DATABOX
#include <gtkdatabox.h>
#endif

#include "names.h"

PHYS_GLOBAL *PhysicalInit(char *filename)
/* create a pointer to the global physical info chunks
 * 
 */
{
  CHUNK *ap, *sp, SP[] = { 
    {PH_date,  {NULL}, CT_STRING, EDITABLE} , /* date of recording the image              */
    {PH_probe, {NULL}, CT_STRING, EDITABLE} , /* name of the crystal sample               */
    {PH_U,     {0},    CT_DOUBLE, EDITABLE} , /* forcing amplitude [V]                    */
    {PH_f,     {0},    CT_DOUBLE, EDITABLE} , /* forcing frequency [Hz]                   */
    {PH_f_s,   {0},    CT_DOUBLE, EDITABLE} , /* frequency of stroboscope                 */
    {PH_delay, {0},    CT_DOUBLE, EDITABLE} , /* trigger delay                            */
    {PH_temp,  {0},    CT_DOUBLE, EDITABLE} , /* measuring temperature                    */
    {PH_ndata, {0},    CT_INT,    EDITABLE} , /* number of data points in the phase curve */
    {PH_t_m,   {0},    CT_DOUBLE, EDITABLE} , /* duration of measure                      */
    {PH_cannm, {NULL}, CT_STRING, EDITABLE} , /* canonical name of the images (may be     *
                                           * used to load all images of a data set)   */
    {PH_nimg,  {0},    CT_INT,    EDITABLE} , /* number of images                         */
    {NULL,     {NULL}, 0,         INVALID} ,
  };
  PHYS_GLOBAL *pg;
  int          nchunks;

  pg       = g_new0(PHYS_GLOBAL, 1);
  nchunks  = sizeof(SP) / sizeof(SP[0]);
  pg->spec = g_new0(CHUNK, nchunks);
  pg->file = filename;
  for ( ap = pg->spec, sp = SP; sp->key != NULL; ap++, sp++ )
    CopyChunk(ap, sp);
  ap->key        = NULL;

  return pg;
}

static char *GetItem(char **buf)
/* obtain item name
 * --- Parameter: ---
 * char **buf       : pointer to string containing item name delimited by ':'
 * --- Return: ---
 * char  *GetItem() : allocated memory with item, NULL if failed
 * char **buf       : now points after delimited by ':' and its following spaces
 */
{
  register char *ap;
  char          *item;
   
  if ( !*buf ) return NULL;
  ap = *buf - 1;
  while ( *++ap && *ap != ':' ) ;
  if ( !*ap ) return NULL;
  item = g_new0(char, ap - *buf + 1);
  strncpy(item, *buf, ap - *buf);
  while ( (*++ap) == ' ' || *ap == '\t' ) ;
  if ( *ap ) *buf = ap;
  return item;
}

static char *ReadString(char *buf)
/* Read string until '\n'
 * --- Parameter: ---
 * char *buf          : buffer
 * --- Return: ---
 * char *ReadString() : allocated string
 */
{
  register char *s, *ap;

  if ( !buf ) return NULL;
  
  if ( !(ap = strchr(buf, '\n')) ) return g_strdup(buf);
  while ( --ap > buf ) 
    if ( *ap != ' ' && *ap != '\t' ) break;
  if ( ap <= buf ) return NULL;
  s = g_new0(char, ap - buf + 1);
  strncpy(s, buf, ap - buf + 1);
  return s;
}

static void LoadPhysicalOk(GtkWidget *widget, GtkFileSelection *fs)
/*
 * --- Parameter: ---
 * GtkWidget        *widget : OK-button inside GtkFileSelection widget (can be ignored)
 * GtkFileSelection *fs     : GtkFileSelection widget
 *                            connected data: PAUL *p
 */
{
  PAUL       *p;
  char       *filename;

  g_return_if_fail ( GTK_IS_FILE_SELECTION(fs) );
  g_return_if_fail ( (p = gtk_object_get_user_data(GTK_OBJECT(fs)) ) );
  g_return_if_fail ( IS_PAUL(p) );

  filename = g_strdup(ChdirToLoadDir(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)))) ;
  g_return_if_fail ( CheckFile(filename) );
  
  gtk_widget_destroy(GTK_WIDGET(fs));
  LoadPhysicalParameters(filename);
}

static int NumData(PHYS_GLOBAL *pg)
/* Obtain number of data points in phase curve
 * --- Parameter: ---
 * PHYS_GLOBAL *pg       : global physical data structure
 * --- Return: ---
 * int          NumData(): number of data points, -1 if invalid structure
 */
{
  double d_num_data;
  int    ndata;
   
  g_return_val_if_fail ( pg, -1 ) ;
   
  if ( Chunk2Double(pg->spec, PH_ndata, &d_num_data) == RET_ERR ) {
    g_warning(_("Unknown number of data points for %s."), phasecurve);
    return -1;
  }
  if ( (ndata = (int)d_num_data) <= 0 ) 
    g_warning(_("No data points for %s."), phasecurve);
  return ndata;
}


void FreePhysical(PHYS_GLOBAL **pg)
/* Free all members of global physical data structure and the structure pointer itself
 */
{
  if ( *pg ) {
    FreeSpecs((*pg)->spec);
    FREE((*pg)->file);
    FREE((*pg)->D);
    FREE((*pg)->Dt);
    FREE(*pg);
  }
}
  
static int DoLoadPhysical(GtkWidget *button, char *filename)
/* Load file with physical parameters normally created from OMA
 * --- Parameter: ---
 * GtkWidget *button                  : "Yes" button from "AreYouSure()" or NULL
 * char      *filename                : filename of physicale date file
 * --- Return: ---
 * int        LoadPhysicalParameters(): RET_ERR or RET_OK
 */
{
  int          fh, len;
  struct stat  stat_buf;
  char        *buf, *data, *item, *ap, *data_buf;
  double      *dp, *dtp, *fip;
  PHYS_GLOBAL *pg;

  if ( button ) g_return_val_if_fail ( GTK_IS_BUTTON(button), RET_ERR ) ;
  g_return_val_if_fail ( filename, RET_ERR );
  if ( (fh  = open(filename, O_RDONLY)) < 0 ) {
    g_warning("Unable to find physical information file %s.", filename);
    return RET_ERR;
  }

  if ( PG ) FreePhysical(&PG);
  PG = PhysicalInit(filename);
  pg = PG;

  stat(filename, &stat_buf);
  data_buf = g_new0(char, stat_buf.st_size + 1);
  if ( stat_buf.st_size != ( len = read(fh, data_buf, stat_buf.st_size)) ) {
    close(fh);
    FREE(data_buf);
    g_return_val_if_fail ( stat_buf.st_size == len, RET_ERR );
  }
  data = data_buf - 1;
  while ( *++data ) {
    if ( *data != '\n' ) continue;
    if ( !*++data || !isalpha(*data) ) break;
  }
  if ( !data ) {
     g_warning(_("%s contains no valid physical data"), filename);
     FREE(data_buf);
     close(fh);
     return RET_ERR;
  }
  *(data-1) = 0; /* mark the end of the header */
  ap = data_buf;
  while ( (item = GetItem(&ap)) ) {
    buf = ReadString(ap);
    if ( SetSpec(pg->spec, item, buf) ) 
      g_warning(_("Unknown physical specification \"%s\" in physical data file %s"), 
                item, filename);
    FREE(item);
    if ( !(ap = strchr(ap, '\n') ) ) break;
    ++ap;
  }

  if ( (len = NumData(pg)) <= 0 ) {
    FREE(data_buf);
    return RET_ERR;
  }

  pg->D  = g_new(double, len);
  pg->Dt = g_new(double, len);
  ap = data;
  for ( fip = (dp = pg->D) + len, dtp = pg->Dt; dp < fip; dp++, dtp++ ) {
    if ( sscanf(ap, "%lg,%lg", dp, dtp) != 2 ) {
      g_warning(_("Error while reading phase kurve at value number %i."), dp - pg->D);
      SetDoubleSpec(pg->spec, PH_ndata, 0);
      FREE(pg->D);
      FREE(pg->Dt);
      FREE(data_buf);
      return RET_ERR;
    }
    if ( !(ap = strchr(ap, '\n') ) ) break;
    ++ap;
  }
  if ( dp < fip ) {
    g_warning(_("Only %i data points from %i of phase curve could be read."), dp - pg->D, len);
    SetDoubleSpec(pg->spec, PH_ndata, (double)(dp - pg->D));
  }
  FREE(data_buf);
  return RET_OK;
}

int LoadPhysicalParameters(char *filename)
/* Load file with physical parameters normally created from OMA
 * --- Parameter: ---
 * char *filename                : filename of physicale date file
 * --- Return: ---
 * int   LoadPhysicalParameters(): RET_ERR or RET_OK
 */
{
  char       *buf;

  g_return_val_if_fail ( filename, RET_ERR );

  if ( PG ) {
    if ( !strcmp(PG->file, filename) ) return RET_OK;
                                 /* Same file loaded before.  Ignore loading */
    buf = g_strdup_printf(_("Do you want to replace physical data from\nfile %s by data of file %s?"),
                          PG->file, filename);
    AreYouSure(filename, GTK_SIGNAL_FUNC(DoLoadPhysical), buf);
    FREE(buf);
    return RET_OK;
  }
  return DoLoadPhysical(NULL, filename);
}


void LoadPhysical(PAUL *p)
/*
 * --- Parameter: ---
 * PAUL      *p     : PAUL structure
 */
{
  g_return_if_fail ( IS_PAUL(p) ) ;
  
  FileSelectionLoadSave(p, GTK_SIGNAL_FUNC(LoadPhysicalOk), NULL, "Load physical information", "*.wfm");
}

#ifdef HAVE_DATABOX
int ShowPhasePoint(PAUL *p, PICTURE *bild)
{
#define MARKLEN 3
  static   GtkWidget *curve = NULL;
                    /* hold internal copy of p-curve because PAUL *p isn't known to ApplyPicture() */
  static   gfloat    *X, *Y;
  static   double     f_mod = -1, t_meas = -1;
  static   int        ndata;
  
  double              t_img;
  register gfloat    *x, *y, *fip;
  register double    *xc, *yc;
  int                 ncur;

  g_return_val_if_fail ( PG, RET_ERR ) ;
  if ( IS_PAUL(p) ) {
    g_return_val_if_fail ( p->curve, RET_ERR ) ;
    g_return_val_if_fail ( GTK_IS_DATABOX(p->curve), RET_ERR ) ;
    curve = p->curve;
    X = g_new(gfloat, MARKLEN);
    Y = g_new(gfloat, MARKLEN);
    g_return_val_if_fail ( Chunk2Double(PG->spec, PH_ndata, &f_mod) == RET_OK, RET_ERR);
    ndata = (int)f_mod;
    g_return_val_if_fail ( Chunk2Double(PG->spec, PH_f_s, &f_mod) == RET_OK, RET_ERR);
    g_return_val_if_fail ( Chunk2Double(PG->spec, PH_t_m, &t_meas) == RET_OK, RET_ERR);
  } else {
    g_return_val_if_fail ( curve, RET_ERR ) ;
    g_return_val_if_fail ( GTK_IS_DATABOX(curve), RET_ERR ) ;
    g_return_val_if_fail ( X, RET_ERR ) ;
    g_return_val_if_fail ( Y, RET_ERR ) ;
  }
  if ( Chunk2Double(bild->spec, ChunkRelTime, &t_img) != RET_OK )
    return RET_ERR; /* May fail if in "move images" mode */

  if ( t_img == 0.0 ) ncur = 0;
  else 
    ncur = (int)(t_img / t_meas) % ndata;
     /*
    ncur = (int)(((double)ndata * t_meas) / t_img);
     */
  
/* printf("%s(%i) rel_time = %g, ncur = %i\n", __FILE__, __LINE__, t_img, ncur); */
  for ( fip = (x = X) + MARKLEN, y = Y, xc = PG->D + ncur, yc = PG->Dt + ncur; x < fip; ) {
    *(x++) = (gfloat)*(xc++);
    *(y++) = (gfloat)*(yc++);
  }

  if ( IS_PAUL(p) ) {
    GdkColor color;

    color.red=65535;
    color.green=0;
    color.blue=0;
    gtk_databox_data_add_x_y(GTK_DATABOX(curve), MARKLEN, X, Y, color, GTK_DATABOX_POINTS, 8);
    gtk_databox_rescale(GTK_DATABOX(curve));
  } else
    gtk_databox_redraw(GTK_DATABOX(curve));

  return RET_OK;
}
               
int ShowPhaseCurve(PAUL *p, PHYS_GLOBAL *pg)
/* Create GtkDatabox widget to show phase curve
 * --- Parameter: ---
 * PAUL        *p               : PAUL structure
 * PHYS_GLOBAL *pg              : structure of global physical data
 * --- Return: ---
 * int          ShowPhaseCurve(): RET_ERR or RET_OK
 */
{
  static GtkWidget *window = NULL;
  char             *buf;
  int               ndata;
  gfloat           *X, *Y, *x, *y;
  double           *d, *dt, *fip;
  GdkColor          color = { 0, 0, 0 };
  
  g_return_val_if_fail ( IS_PAUL(p), RET_ERR ) ;
  g_return_val_if_fail ( pg, RET_ERR ) ;
  g_return_val_if_fail ( pg->D && pg->Dt, RET_ERR ) ;
  g_return_val_if_fail ( (ndata = NumData(pg)) > 0, RET_ERR ) ;

  if ( window ) {
    if (!GTK_WIDGET_VISIBLE(window) ) gtk_widget_show_all(window);
    return RET_OK;
  }

  g_return_val_if_fail ( p->curve == NULL, RET_ERR ) ;
  
  p->curve = GTK_WIDGET(gtk_databox_new());
  gtk_signal_connect(GTK_OBJECT(p->curve), "destroy", GTK_SIGNAL_FUNC(gtk_databox_data_destroy_all),
                     NULL);
  if ( pg->file ) buf = g_strdup_printf(_("%s of %s"), PhaseCurve, pg->file);
  else            buf = g_strdup(PhaseCurve);
  window = CreateDataboxFrame(p->curve, buf);
  FREE(buf);

  X = g_new0(gfloat, ndata);
  Y = g_new0(gfloat, ndata);
  for ( fip = (d = pg->D) + ndata, dt = pg->Dt, x = X, y = Y; d < fip; d++, dt++, x++, y++ ) {
    *x = *d;
    *y = *dt;
  }

  gtk_databox_data_add_x_y(GTK_DATABOX(p->curve), ndata, X, Y, color, GTK_DATABOX_POINTS, 0);
  gtk_databox_rescale(GTK_DATABOX(p->curve));
  gtk_widget_show(p->curve);
  ShowPhasePoint(p, BILD(p->activ));

  return RET_OK;
}
#endif /* DATABOX */
               
#endif


Generated by  Doxygen 1.6.0   Back to index