diff --git a/src/client/widgets/spectrum/spectrum.c b/src/client/widgets/spectrum/spectrum.c
index f031f4c9dc2cefb3aff01a2ce0ddf0f0556aba97..118a17e781ca26c5fcf0d902d69cebc812e0abb9 100644
--- a/src/client/widgets/spectrum/spectrum.c
+++ b/src/client/widgets/spectrum/spectrum.c
@@ -30,6 +30,9 @@
 #include <fitfunc.h>
 #include <math.h>
 
+#include <glib/gstdio.h>
+#include <locale.h>
+
 G_DEFINE_TYPE_WITH_PRIVATE(Spectrum, spectrum, GTK_TYPE_BOX)
 
 #define SPECTRUM_DEFAULT_AVG_LEN 10
@@ -282,15 +285,170 @@ static gboolean spectrum_handle_getpos_azel_cb(gpointer instance,
 	hor.el = (double) pos->el_arcsec / 3600.0;
 
 
+	p->cfg->pos_hor = hor;
 	p->cfg->pos_equ = horizontal_to_equatorial(hor,
 						   p->cfg->lat, p->cfg->lon,
 						   0.0);
+	p->cfg->pos_gal = horizontal_to_galactic(hor, p->cfg->lat, p->cfg->lon);
+
 
 	return TRUE;
 }
 
 
+static void spectrum_record_add(Spectrum *p, struct spectrum *sp)
+{
+	size_t i;
+
+	time_t now;
+	struct tm *t;
+
+
+	if (!p->cfg->rec)
+		return;
+
+	if (!sp)
+		return;
+
 
+	setlocale(LC_ALL, "C");
+
+
+	time(&now);
+	t = localtime(&now);
+
+	fprintf(p->cfg->rec, "%.4f %.4f %d %d %d %.4f %.4f %.4f %.4f "
+			     "%.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %d ",
+			     p->cfg->lat, p->cfg->lon,
+			     t->tm_year + 1900, t->tm_mon  + 1,
+			     t->tm_mday, local_sidereal_time(p->cfg->lon),
+			     p->cfg->pos_hor.az, p->cfg->pos_hor.el,
+			     p->cfg->pos_equ.ra, p->cfg->pos_equ.dec,
+			     p->cfg->pos_gal.lat, p->cfg->pos_gal.lon,
+			     sp->x[0], sp->x[sp->n - 1],
+			     spectrum_convert_x2(sp->x[0], p),
+			     spectrum_convert_x2(sp->x[sp->n - 1], p),
+			     p->cfg->freq_ref_mhz, sp->n);
+
+
+	for (i = 0; i <  sp->n; i++)
+		fprintf(p->cfg->rec, "%.4f ", sp->y[i]);
+
+	fprintf(p->cfg->rec, "\n");
+
+	setlocale(LC_ALL, "");
+}
+
+
+static void spectrum_record_start(Spectrum *p)
+{
+	GtkWidget *dia;
+	GtkFileChooser *chooser;
+	gint res;
+
+	GtkWidget *win;
+
+	gchar *fname;
+
+
+	win = gtk_widget_get_toplevel(GTK_WIDGET(p));
+
+	if (!GTK_IS_WINDOW(win)) {
+		g_warning("%s: toplevel widget is not a window", __func__);
+		return;
+	}
+
+	fname = g_strdup_printf("record.dat");
+
+	dia = gtk_file_chooser_dialog_new("Select Record File",
+					  GTK_WINDOW(win),
+					  GTK_FILE_CHOOSER_ACTION_SAVE,
+					  "_Cancel",
+					  GTK_RESPONSE_CANCEL,
+					  "_Save",
+					  GTK_RESPONSE_ACCEPT,
+					  NULL);
+
+	chooser = GTK_FILE_CHOOSER(dia);
+
+	gtk_file_chooser_set_do_overwrite_confirmation(chooser, TRUE);
+
+	gtk_file_chooser_set_current_name(chooser, fname);
+
+	gtk_file_chooser_set_current_folder(chooser,g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS));
+
+	res = gtk_dialog_run(GTK_DIALOG(dia));
+
+	g_free(fname);
+
+	if (res == GTK_RESPONSE_ACCEPT) {
+
+		fname = gtk_file_chooser_get_filename(chooser);
+
+
+		p->cfg->rec = g_fopen(fname, "w");
+
+		if (!p->cfg->rec) {
+			GtkWidget *dia;
+			GtkWindow * win;
+
+			win = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(p)));
+			dia = gtk_message_dialog_new(win,
+						     GTK_DIALOG_MODAL,
+						     GTK_MESSAGE_ERROR,
+						     GTK_BUTTONS_CLOSE,
+						     "Could not open file %s",
+						     fname);
+
+			gtk_dialog_run(GTK_DIALOG(dia));
+			gtk_widget_destroy(dia);
+		}
+
+		fprintf(p->cfg->rec,
+			"# Format: LAT LON YEAR MONTH DAY LST AZ EL RA DE "
+			"GLAT GLON FIRST_FREQ[MHz] LAST_FREQ[MHz] REF_FREQ[MHz]"
+			"VRAD0[km/s] VRAD1[km/s] BINS "
+			"Amplitude[K](1...N)\n");
+
+
+
+		g_free(fname);
+	}
+
+	gtk_widget_destroy(dia);
+}
+
+
+static void spectrum_rec_button_toggle(GtkToggleButton *btn,
+				       gpointer         data)
+{
+	Spectrum *p;
+
+	GtkStyleContext *ctx;
+
+
+	p = SPECTRUM(data);
+
+	ctx = gtk_widget_get_style_context(GTK_WIDGET (btn));
+
+	if (gtk_toggle_button_get_active(btn)) {
+		spectrum_record_start(p);
+		gtk_style_context_add_class(ctx, "destructive-action");
+	} else {
+		if (p->cfg->rec) {
+			fclose(p->cfg->rec);
+			p->cfg->rec = NULL;
+		}
+	}
+
+	/* if failed or disabled, set inactive */
+	if (!p->cfg->rec) {
+		gtk_style_context_remove_class(ctx, "destructive-action");
+		gtk_toggle_button_set_active(btn, FALSE);
+	}
+
+
+}
 
 
 /**
@@ -806,7 +964,7 @@ static void spectrum_handle_pr_spec_data(gpointer instance,
 	gdouble *frq;
 	gdouble *amp;
 
-	struct spectrum *sp;
+	struct spectrum *sp = NULL;
 
 	Spectrum *p;
 
@@ -816,6 +974,16 @@ static void spectrum_handle_pr_spec_data(gpointer instance,
 	if (!s->n)
 		return;
 
+
+
+	/* update positions */
+	p->cfg->pos_equ = horizontal_to_equatorial(p->cfg->pos_hor,
+						   p->cfg->lat, p->cfg->lon,
+						   0.0);
+	p->cfg->pos_gal = horizontal_to_galactic(p->cfg->pos_hor,
+						 p->cfg->lat, p->cfg->lon);
+
+
 	frq = g_malloc(s->n * sizeof(gdouble));
 	amp = g_malloc(s->n * sizeof(gdouble));
 
@@ -837,6 +1005,11 @@ static void spectrum_handle_pr_spec_data(gpointer instance,
 	sp->y = amp;
 	sp->n = s->n;
 
+
+	/* write to file if enabled, this one does not need a copy */
+	spectrum_record_add(p, sp);
+
+	/* this one does */
 	spectrum_append_data(p, sp);
 }
 
@@ -1138,7 +1311,6 @@ GtkWidget *spectrum_vrest_ctrl_new(Spectrum *p)
 }
 
 
-
 /**
  * @brief create vertical spectrum control bar
  */
@@ -1170,6 +1342,7 @@ static GtkWidget *spectrum_sidebar_new(Spectrum *p)
 	gtk_grid_attach(grid, w, 1, 0, 1, 1);
 
 
+
 	w = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
 	gtk_grid_attach(grid, w, 0, 1, 2, 1);
 
@@ -1179,7 +1352,7 @@ static GtkWidget *spectrum_sidebar_new(Spectrum *p)
 	gtk_label_set_xalign(GTK_LABEL(w), 0.0);
 	gtk_grid_attach(grid, w, 0, 2, 1, 1);
 
-	w = gtk_spin_button_new_with_range(0, 100, 1);
+	w = gtk_spin_button_new_with_range(0, 1000, 1);
 	gtk_entry_set_alignment(GTK_ENTRY(w), 1.0);
 	gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(w), TRUE);
 	gtk_spin_button_set_digits(GTK_SPIN_BUTTON(w), 0);
@@ -1228,7 +1401,7 @@ static GtkWidget *spectrum_sidebar_new(Spectrum *p)
 	gtk_label_set_xalign(GTK_LABEL(w), 0.0);
 	gtk_grid_attach(grid, w, 0, 7, 1, 1);
 
-	w = gtk_spin_button_new_with_range(0, 100, 1);
+	w = gtk_spin_button_new_with_range(0, 1000, 1);
 	gtk_entry_set_alignment(GTK_ENTRY(w), 1.0);
 	gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(w), TRUE);
 	gtk_spin_button_set_digits(GTK_SPIN_BUTTON(w), 0);
@@ -1280,8 +1453,21 @@ static GtkWidget *spectrum_sidebar_new(Spectrum *p)
 	w = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
 	gtk_grid_attach(grid, w, 0, 14, 2, 1);
 
-	w = gtk_label_new("");
+
+	w = gtk_toggle_button_new_with_label("Record");
+	gtk_button_set_always_show_image(GTK_BUTTON(w), TRUE);
+	gtk_button_set_image(GTK_BUTTON(w),
+			     gtk_image_new_from_icon_name("media-record-symbolic",
+							  GTK_ICON_SIZE_BUTTON));
+	g_signal_connect(G_OBJECT(w), "toggled",
+			 G_CALLBACK(spectrum_rec_button_toggle), p);
+
+
 	gtk_grid_attach(grid, w, 0, 15, 2, 1);
+
+
+	w = gtk_label_new("");
+	gtk_grid_attach(grid, w, 0, 16, 2, 1);
 	p->cfg->fit.fitpar = GTK_LABEL(w);
 
 
@@ -1375,6 +1561,7 @@ static void spectrum_init(Spectrum *p)
 	p->cfg = spectrum_get_instance_private(p);
 
 	p->cfg->timer = g_timer_new();
+	p->cfg->rec   = NULL;
 	p->cfg->avg   = NULL;
 	p->cfg->n_avg = SPECTRUM_DEFAULT_AVG_LEN;
 	p->cfg->r_avg = NULL;
diff --git a/src/client/widgets/spectrum/spectrum_cfg.h b/src/client/widgets/spectrum/spectrum_cfg.h
index fa0710ca25c6af9153df34b30495c53289bc7562..5284ae4adb7b75046babecf9c10e9cc13b39c165 100644
--- a/src/client/widgets/spectrum/spectrum_cfg.h
+++ b/src/client/widgets/spectrum/spectrum_cfg.h
@@ -49,6 +49,8 @@ struct _SpectrumConfig {
 
 	GTimer *timer;
 
+	FILE *rec;
+
 	GList                    *per;
 	void                   *r_per;
 	gsize                   n_per;
@@ -68,7 +70,9 @@ struct _SpectrumConfig {
 
 	gdouble lat;
 	gdouble lon;
+	struct coord_horizontal	pos_hor;
 	struct coord_equatorial	pos_equ;
+	struct coord_galactic	pos_gal;
 
 	gdouble freq_ref_mhz;