/* NIGHTFALL Light Curve Synthesis Program */ /* Copyright (C) 1998 Rainer Wichmann */ /* */ /* This program is free software; you can redistribute it */ /* and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include "Light.h" #ifdef _WITH_PGPLOT #ifndef _WITH_GNUPLOT #include "cpgplot.h" #endif #endif #ifdef _WITH_GTK #ifdef _WITH_PGPLOT /* global variables */ static int profilePosition = 0; /* store phase */ static int profileVelocity = 0; /* velocity instead of lambda */ static double profileMax, profileMin; /* min, max (y) for plot window */ static int profileState = 0; /* block GUI input */ /**************************************************************************** @package nightfall @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de) @version 1.0 @short Plot line profile @param (int) GtkEnd The flag for what to do @return (void) @heading Plotting ****************************************************************************/ void PlotGtkProfile(int GtkEnd) { float GtkPhase; /* the orbital phase */ long i = 0; /* loop variable */ char profileTitle[32]; /* title string */ float Profile[PROFILE_ARRAY]; /* the profile */ float Lambda[PROFILE_ARRAY]; /* the wavelengths */ double Offset; /* offset arry start to resr wavelength*/ double SpeedOfLight = 2.9979e8; /* in meter/second */ double DeltaLambda; /* resolution */ char file_out[256+4]; /* ps output file */ float xtick, ytick; /* tickmarks */ sprintf(file_out, "%s%s", Out_Plot_File, "/CPS"); /* >>>>>>>>>>>>>>>>>>>>>> initialize <<<<<<<<<<<<<<<<<<<<<<<<<< */ /* ------------------ the resolution -------------- */ DeltaLambda = Orbit.LambdaZero / PROFILE_RES; /* ------------------ the starting wavelength -------------- */ Offset = Orbit.LambdaZero - (PROFILE_ARRAY/2) * DeltaLambda; /* -------------------- the array for the profile ------------ */ for (i = 0; i < PROFILE_ARRAY; ++i) { if (profileVelocity == 0) Lambda[i] = Offset + i * DeltaLambda; else Lambda[i] = (((Offset + i * DeltaLambda) - Orbit.LambdaZero) /Orbit.LambdaZero) * SpeedOfLight / 1000.; Profile[i] = ProData[profilePosition][i]; } GtkPhase = ProData[profilePosition][PROFILE_ARRAY]; /* >>>>>>>>>>>>>>>>>>>>> open plot device <<<<<<<<<<<<<<<<<<<<<<<<<<<< */ #ifdef _WITH_GNUPLOT /* only open if not open already because of the sleep(1) in cpgopen() */ if (GtkEnd == 3) { if (cpgopen("/XSERVE") != 1) { make_dialog (_(errmsg[2])); return; } } if (GtkEnd == 2) { if (cpgopen(file_out) != 1) { make_dialog (_(errmsg[1])); return; } } gnu_start(); #else if (GtkEnd != 2) { if(cpgopen("/XSERVE") != 1) { make_dialog (_(errmsg[2])); return; } } else { if(cpgopen(file_out) != 1) { make_dialog (_(errmsg[1])); return; } } #endif /* >>>>>>>>>>>>>>>>>>>>> plot <<<<<<<<<<<<<<<<<<<<<<<<<<<< */ cpgscf(2); cpgslw(1); cpgsch(1.2); cpgsvp(0.1,0.9,0.2,0.9); if (profileVelocity == 0) { cpgswin(Offset, (Offset + (PROFILE_ARRAY-1) * DeltaLambda), profileMin, profileMax); xtick = 0.1 * (int)(10 * fabs( ((PROFILE_ARRAY-1) * DeltaLambda) / 7)); sprintf(profileTitle, _("Line profile at phase %5.2f"), GtkPhase); cpglab(_("Wavelength (nm)"), _("Flux"), profileTitle); } else { cpgswin( ( ( Offset-Orbit.LambdaZero ) / Orbit.LambdaZero ) *SpeedOfLight/1000., ( ( (Offset+(PROFILE_ARRAY-1)*DeltaLambda ) - Orbit.LambdaZero ) /Orbit.LambdaZero ) * SpeedOfLight / 1000., profileMin, profileMax); xtick = 0.1 * (int)(10 * fabs(( (( ( Offset-Orbit.LambdaZero ) / Orbit.LambdaZero ) *SpeedOfLight/1000.) - (( ( (Offset+(PROFILE_ARRAY-1)*DeltaLambda ) - Orbit.LambdaZero ) /Orbit.LambdaZero ) * SpeedOfLight / 1000.) ) / 7)); sprintf(profileTitle, _("Line profile at phase %5.2f"), GtkPhase); cpglab(_("Velocity (km/s)"), _("Flux"), profileTitle); } ytick = 0.1 * (int)( 10.0 * fabs( (profileMin - profileMax) / 5)); #ifdef _WITH_GNUPLOT cpgbox("BCNST", xtick, 0, "BCNST", ytick, 0); #else cpgbox("BCNST", 0,0, "BCNST", 0,0); #endif cpgline(PROFILE_ARRAY, Lambda, Profile); /* >>>>>>>>>>>>>>>>>>>>> close plot <<<<<<<<<<<<<<<<<<<<<<<<<<<< */ if (GtkEnd == 2) my_cpgend(); else cpgend(); return; } /**************************************************************************** @package nightfall @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de) @version 1.0 @short Make hardcopy of profile (ps file) @param (GtkWidget) *widget Discarded @param (gpointer) *data Discarded @return (void) @heading Plotting ****************************************************************************/ void hard_profile (GtkWidget *widget, gpointer *data) { PlotGtkProfile (2); return; } /**************************************************************************** @package nightfall @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de) @version 1.0 @short Destroy the Profiler @param (GtkWidget) *widget Discarded @param (gpointer) *data Widget to destroy @return (void) @heading Plotting ****************************************************************************/ void delete_profile (GtkWidget *widget, gpointer *data) { gtk_widget_destroy (GTK_WIDGET (data) ); return; } /**************************************************************************** @package nightfall @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de) @version 1.0 @short Change the orbital phase for line profile @param (GtkAdjustment) *adj The phase @param (gpointer) *data Discarded @return (void) @heading Plotting ****************************************************************************/ void profile_change (GtkAdjustment *adj, GtkWidget *data) { /* the new position */ profilePosition = (int) adj->value; if (profilePosition < 0) profilePosition = 0; if (profilePosition > (PhaseSteps-1)) profilePosition = (PhaseSteps-1); PlotGtkProfile (ON); return; } /**************************************************************************** @package nightfall @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de) @version 1.0 @short Change scale between velocity and wavelength @param (GtkWidget) *widget Discarded @param (gpointer) *data Discarded @return (void) @heading Plotting ****************************************************************************/ void profile_scale (GtkWidget *widget, gpointer *data) { /* 0 = wavelength, 1 = velocity */ sscanf ((char *) data, "%d", &profileVelocity); if (profileVelocity != profileState) { PlotGtkProfile (ON); profileState = profileVelocity; } return; } /**************************************************************************** @package nightfall @author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de) @version 1.0 @short Interactive line profile display @param (void) @return (void) @heading Plotting ****************************************************************************/ void Profiler() { GtkWidget *label; GtkWidget *button; GtkWidget *vbox; GtkWidget *hbox; GtkWidget *frame; GtkWidget *separator; GtkWidget *scale1; GtkObject *adj1; GtkWidget *profile_window; GSList *group; GtkTooltips *tooltips; unsigned long i, j; /* loop variables */ tooltips = gtk_tooltips_new (); gtk_tooltips_set_delay (tooltips, 1800); profileMax = -100000.; profileMin = 100000.; for (j = 0; j < PhaseSteps; ++j) { for (i = 0; i < PROFILE_ARRAY; ++i) { profileMax = MAX(ProData[j][i], profileMax); profileMin = MIN(ProData[j][i], profileMin); } } if (profileMax == profileMin) { profileMax = 1.0; profileMin = 0.0; } /* >>>>>>>>>>>>>>>>>>>>> MAKE WIDGET <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ profile_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); /* gtk_widget_set_usize (profile_window, 200, 150); */ gtk_window_set_position(GTK_WINDOW(profile_window), GTK_WIN_POS_MOUSE); #ifdef USING_GTK2 gtk_window_set_resizable(GTK_WINDOW(profile_window), TRUE); #else gtk_window_set_policy (GTK_WINDOW(profile_window), FALSE, FALSE, TRUE); #endif /* gtk_window_set_policy (GTK_WINDOW(profile_window), TRUE, TRUE, FALSE); */ gtk_signal_connect (GTK_OBJECT (profile_window), "destroy", (GtkSignalFunc) delete_profile, GTK_WIDGET (profile_window)); gtk_window_set_title (GTK_WINDOW (profile_window), _("Profiler") ); gtk_container_set_border_width (GTK_CONTAINER (profile_window), 0); frame = gtk_frame_new (_("Viewing Options") ); gtk_container_add (GTK_CONTAINER (profile_window), frame); gtk_container_set_border_width(GTK_CONTAINER(frame), 2); gtk_widget_show (frame); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (frame), vbox); gtk_widget_show (vbox); adj1 = gtk_adjustment_new (0.0, 0.0, PhaseSteps, 1.0, 1.0, 1.0); gtk_signal_connect (GTK_OBJECT (adj1), "value_changed", GTK_SIGNAL_FUNC (profile_change), NULL); hbox = gtk_hbox_new (TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (hbox), 4); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); scale1 = gtk_hscale_new(GTK_ADJUSTMENT (adj1)); gtk_range_set_update_policy (GTK_RANGE (scale1), GTK_UPDATE_CONTINUOUS); gtk_box_pack_start (GTK_BOX (hbox), scale1, TRUE, TRUE, 0); gtk_widget_show (scale1); hbox = gtk_hbox_new (TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (hbox), 4); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); label = gtk_label_new (_("Profile Position") ); gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); gtk_widget_show (label); hbox = gtk_hbox_new (TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (hbox), 4); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); button = gtk_radio_button_new_with_label (NULL, _("Wavelength") ); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) profile_scale, (gpointer) "0"); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); gtk_widget_show (button); group = gtk_radio_button_group (GTK_RADIO_BUTTON (button)); button = gtk_radio_button_new_with_label(group, _("Velocity") ); gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) profile_scale, (gpointer) "1"); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); gtk_widget_show (button); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0); gtk_widget_show (separator); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0); gtk_widget_show (hbox); #ifdef USING_GTK2 button = gtk_button_new_with_label (_("Postscript") ); gtk_button_set_image (GTK_BUTTON(button), gtk_image_new_from_stock (GTK_STOCK_PRINT, GTK_ICON_SIZE_SMALL_TOOLBAR) ); #else button = gtk_button_new_with_label (_("Postscript") ); #endif gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) hard_profile, NULL); gtk_tooltips_set_tip (tooltips, button, _("Make postscript hardcopy from current plot"), NULL); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); (GTK_WIDGET_FLAGS (button) |= (GTK_CAN_DEFAULT)); gtk_widget_grab_default (button); gtk_widget_show (button); #ifdef USING_GTK2 button = gtk_button_new_from_stock(GTK_STOCK_OK); #else button = gtk_button_new_with_label (_("Close") ); #endif gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) delete_profile, GTK_WIDGET (profile_window)); gtk_tooltips_set_tip (tooltips, button, _("Close Profiler"), NULL); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); (GTK_WIDGET_FLAGS (button) |= (GTK_CAN_DEFAULT)); gtk_widget_grab_default (button); gtk_widget_show (button); gtk_widget_show (profile_window); /* >>>>>>>>>>>>>>>>>>>>>>> initial plot <<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ profileState = 0; profileVelocity = 0; PlotGtkProfile (3); return; } /* with pgplot */ #endif /* with gtk */ #endif