From: W. Trevor King Date: Sat, 23 Apr 2011 18:57:47 +0000 (-0400) Subject: Add open source force spectroscopy post. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=9a39e5abdcdbf94c37b8db57ea491e451764af2f;p=mw2txt.git Add open source force spectroscopy post. --- diff --git a/posts/Open_source_force_spectroscopy.mdwn b/posts/Open_source_force_spectroscopy.mdwn new file mode 100644 index 0000000..7987ea3 --- /dev/null +++ b/posts/Open_source_force_spectroscopy.mdwn @@ -0,0 +1,116 @@ +There are a number of open source packages dealing with aspects of +single-molecule force spectroscopy. Here's a list of everything I've +heard about to date. + +============= =========== ====================================================== +Package License Purpose +============= =========== ====================================================== +[[calibcant]] GPL v3+ Cantilever thermal calibration +[fs_kit][] GPL v2+ Force spectra analysis pattern recognition +[Hooke][] LGPL v3+ Force spectra analysis and unfolding force extraction +[[sawsim]] GPL v3+ Monte Carlo unfolding/refolding simulation and fitting +[refolding][] Apache v2.0 Double-pulse experiment control and analysis +============= =========== ====================================================== + +calibcant +========= + +[[Calibcant]] is my [[Python]] module for AFM cantilever calibration +via the thermal tune method. It's based on [[Comedi]], so it needs +work if you want to use it on a non-Linux system. If you're running a +Linux kernel, it should be pretty easy to get it running on your +system. Email me if there's any way I can help set it up for your +lab. + +fs_kit +====== + +[fs_kit][] is a package for force spectra analysis pattern +recognition. It was developed by Michael Kuhn and Maurice Hubain at +Daniel Müller's lab when they were at TU~Dresden +([paper][fs_kit_paper]). It has an [[Igor]] interface, but the bulk +of the project is in [[C++]] with a [wxWidgets][] interface. fs_kit +is versioned in CVS at `bioinformatics.org`, and you can check out +their code with: + + $ cvs -d:pserver:anonymous@bioinformatics.org:/cvsroot checkout fskit + +The last commit was on 2005/05/16, so it's a bit crusty. I patched +things up back in 2008 so it would compile again, + +[[!inline pages="./Open_source_force_spectroscopy/*.patch" archive=yes quick=yes]] + +but when I emailed Michael with the patches I got this: + + On Thu, Oct 23, 2008 at 11:21:42PM +0200, Michael Kuhn wrote: + > Hi Trevor, + > + > I'm glad you could fix fs-kit, the project is otherwise pretty dead, + > as was the link. I found an old file which should be the tutorial, + > hopefully in the latest version. The PDF is probably lost. + > + > bw, Michael + +So, it's a bit of a fixer-upper, but it was the first open source +package in this field that I know of. I've put up a [[PDF +version|fs_kit_tutorial]] of the tutorial Michael sent me in case +you're interested. + +Hooke +===== + +[Hooke][] is a [[force spectroscopy]] data analysis package written in +[[Python]]. It was initially developed by Massimo Sandal, Fabrizio +Benedetti, Marco Brucale, Alberto Gomez-Casado while at Bruno Samorì's +lab at U~Bologna ([paper][hooke_paper]. Suprisingly, there are +commits by all of the authors except Samorì himself). Hooke provides +the interface between your raw data and theory. It has a drivers for +reading most force spectroscopy file formats, and a large number of +commands for manipulating and analyzing the data. + +I liked Hooke so much I threw out my already-written package that had +been performing a similar role and proceeded to work over Hooke to +merge together the diverging command-line and GUI forks. +Unfortunately, my fork has not yet been merged back in as the main +branch, but I'm optimistic that it will eventually. The homepage for +my branch is [[here|Hooke]]. + +sawsim +====== + +While programs like Hooke can extract unfolding forces from +velocity-clamp experiments, the unfolding force histograms are +generally compared to simulated data to estimate the underlying +kinetic parameters. [[Sawsim]] is my package for performing such +simulations and fitting them to the experimental histograms +([paper][sawsim_paper). The single-pull simulator is written in +[[C]], and there is a nice [[Python]] wrapper that manages the +thousands of simulated pulls needed to explore the possible model +parameter space. The whole package ends up being pretty fast, +flexible, and convenient. + +refolding +========= + +[Refolding][refolding] is a suite for performing and analyzing +double-pulse refolding experiments. It was initially developed by +Daniel Aioanei, also at the Samorí lab in Bologna (these guys are +great!). The experiment-driver is mostly written in [[Java]] with the +analysis code in [[Python]]. The driver is curious; it uses the +NanoScope scripting interface to drive the experiment *through* the +NanoScope software by impersonating a mouse-wielding user (like +[Selenium][] does for web browsers). See the `RobotNanoDriver.java` +code for details. + +[fs_kit]: http://fskit.blogspot.com/ +[fs_kit_paper]: http://dx.doi.org/10.1111/j.1365-2818.2005.01478.x +[wxWidgets]: http://www.wxwidgets.org/ +[Hooke]: http://code.google.com/p/hooke/ +[Hooke_paper]: http://dx.doi.org/10.1093/bioinformatics/btp180 +[sawsim_paper]: http://dx.doi.org/10.1016/j.ijbiomac.2009.12.001 +[refolding]: http://code.google.com/p/refolding/ +[refolding_paper]: http://dx.doi.org/10.1093/bioinformatics/btq663 +[Selenium]: http://seleniumhq.org/ + +[[!tag tags/programming]] +[[!tag tags/theory]] diff --git a/posts/Open_source_force_spectroscopy/0001-Added-math.h-include-to-fs_align_histogram2d.h.patch b/posts/Open_source_force_spectroscopy/0001-Added-math.h-include-to-fs_align_histogram2d.h.patch new file mode 100644 index 0000000..eeccd49 --- /dev/null +++ b/posts/Open_source_force_spectroscopy/0001-Added-math.h-include-to-fs_align_histogram2d.h.patch @@ -0,0 +1,31 @@ +From 67bdccaf0d328eae57142235dd66b1bdf2a1be66 Mon Sep 17 00:00:00 2001 +From: W. Trevor King +Date: Tue, 21 Oct 2008 09:36:29 -0400 +Subject: [PATCH] Added math.h include to fs_align_histogram2d.h. + +Do Mac/Windows compilers include math.h by default? +I was getting: + /usr/bin/gcc -W -Wall -Wno-long-double -I/sw/include -Dfs_gui_wxwidgets -I/usr/lib/wx/include/gtk2-unicode-release-2.8 -I/usr/include/wx-2.8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ + src/fs_align_aspectrum.cpp -c -o fs_align_aspectrum.o + In file included from src/fs_align_aspectrum.h:5, + from src/fs_align_aspectrum.cpp:1: + src/fs_align_histogram2d.h: In constructor `fs_align::fineHistogram2D::fineHistogram2D(size_t, size_t, double, double, double, double, double, double)': + src/fs_align_histogram2d.h:130: error: `ceil' was not declared in this scope +with gcc 4.2.3 (Ubuntu 4.2.3-2ubuntu7) +--- + src/fs_align_histogram2d.h | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/src/fs_align_histogram2d.h b/src/fs_align_histogram2d.h +index f29e37e..5cd8f39 100644 +--- a/src/fs_align_histogram2d.h ++++ b/src/fs_align_histogram2d.h +@@ -1,4 +1,5 @@ + ++#include + #include + #include + #include +-- +1.5.4.3 + diff --git a/posts/Open_source_force_spectroscopy/0002-changed-abs-double-to-fabs-double-in-fs_fit_spectr.patch b/posts/Open_source_force_spectroscopy/0002-changed-abs-double-to-fabs-double-in-fs_fit_spectr.patch new file mode 100644 index 0000000..75275ed --- /dev/null +++ b/posts/Open_source_force_spectroscopy/0002-changed-abs-double-to-fabs-double-in-fs_fit_spectr.patch @@ -0,0 +1,45 @@ +From 81f8a53d2c0ec948f9396fc58be0328b502392c4 Mon Sep 17 00:00:00 2001 +From: W. Trevor King +Date: Tue, 21 Oct 2008 10:28:29 -0400 +Subject: [PATCH] changed abs(double) to fabs(double) in fs_fit_spectrum.cpp + +Also added math.h include to fs_select_tree.cpp +--- + src/fs_fit_spectrum.cpp | 4 ++-- + src/fs_select_tree.cpp | 1 + + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/fs_fit_spectrum.cpp b/src/fs_fit_spectrum.cpp +index 6c04d7b..1e295b8 100644 +--- a/src/fs_fit_spectrum.cpp ++++ b/src/fs_fit_spectrum.cpp +@@ -572,7 +572,7 @@ void fs_fit::Spectrum::adjustZeroTSS() throw (fs_fitFitException) + if (tss > high_tss) + throw fs_fitFitException("contact point not found","cp_not_found"); + +- if (abs(force) < range) ++ if (fabs(force) < range) + { + if (!first) { first = true; first_idx = i; } + n++; +@@ -597,7 +597,7 @@ void fs_fit::Spectrum::adjustZeroTSS() throw (fs_fitFitException) + const double tss = gsl_vector_get(data->rawtss, i); + const double force = gsl_vector_get(data->rawforce, i) - data->bl_a - data->bl_b * tss; + +- if (abs(force) < range) ++ if (fabs(force) < range) + sd += sqr(tss - shift); + + i++; +diff --git a/src/fs_select_tree.cpp b/src/fs_select_tree.cpp +index fff072d..407cf5e 100644 +--- a/src/fs_select_tree.cpp ++++ b/src/fs_select_tree.cpp +@@ -1,3 +1,4 @@ ++#include + #include "fs_select_tree.h" + + void fs_select::Tree::loadTree(string filename) +-- +1.5.4.3 + diff --git a/posts/Open_source_force_spectroscopy/0003-Updated-wxWindows-code-to-compile-on-wx-2.8.patch b/posts/Open_source_force_spectroscopy/0003-Updated-wxWindows-code-to-compile-on-wx-2.8.patch new file mode 100644 index 0000000..0d5c7a7 --- /dev/null +++ b/posts/Open_source_force_spectroscopy/0003-Updated-wxWindows-code-to-compile-on-wx-2.8.patch @@ -0,0 +1,1269 @@ +From 9c4d46b8007f85fa4d7c6c285c1c64a766d4001e Mon Sep 17 00:00:00 2001 +From: W. Trevor King +Date: Tue, 21 Oct 2008 19:53:51 -0400 +Subject: [PATCH] Updated wxWindows code to compile on wx-2.8. + +Most of the difficulties were caused by wxString no longer being +interchangable with c strings and stdlib strings. I also cleaned +up the logging code a bit. +--- + src/fs_align_aspectrum.cpp | 19 ++-- + src/fs_align_aspectrumvector.cpp | 15 +-- + src/fs_align_clusterdriver.cpp | 24 +++--- + src/fs_fit_fitfrontend.cpp | 18 ++-- + src/fs_fit_model.cpp | 26 +++--- + src/fs_fit_spectrum.cpp | 73 ++++++++------ + src/fs_gui.wxg | 16 ++-- + src/fs_gui_app.cpp | 3 +- + src/fs_gui_layout.cpp | 204 ++++++++++++++++++++------------------ + src/fs_gui_layout.h | 14 ++- + src/fs_kit_driver.cpp | 73 +++++++++----- + src/fs_kit_options.cpp | 6 +- + src/fs_kit_options.h | 10 +-- + 13 files changed, 272 insertions(+), 229 deletions(-) + +diff --git a/src/fs_align_aspectrum.cpp b/src/fs_align_aspectrum.cpp +index 1528449..22f04e0 100644 +--- a/src/fs_align_aspectrum.cpp ++++ b/src/fs_align_aspectrum.cpp +@@ -64,7 +64,8 @@ bool fs_align::ASpectrumFile::loadDataFromStream(string path, istream& list_inpu + + if (list_filename.empty() || peaks.empty()) return false; + +- if (options.logLevel >= 4) { ostringstream log; log << "loading file " << path << filename << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 4) ++ *options.stdOut << "loading file " << path << filename << endl; + + // load data into matrix + FILE* f = fopen( (path + filename).c_str(), "r"); +@@ -131,7 +132,8 @@ bool fs_align::ASpectrumFile::loadDataFromStream(string path, istream& list_inpu + string s, t; + double max_tss; + info_input >> s >> t >> min_tss >> max_tss; +- if (options.logLevel >= 4) { ostringstream log; log << "reading peak info " << s << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 4) ++ *options.stdOut << "reading peak info " << s << endl; + info_input >> s; + while (s != "end") { info_input >> t >> max_tss >> s; } + +@@ -215,7 +217,8 @@ bool fs_align::ASpectrumFile::loadPeaksFromStream(istream& fit_input) + fit_input >> filename >> xname >> status; + } + +- if (options.logLevel >= 2) { ostringstream log; log << "reading peaks " << filename << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 2) ++ *options.stdOut << "reading peaks " << filename << endl; + + // store baseline data + fit_input >> bl_sd >> bl_mintss >> bl_mintss_sd >> bl_a >> bl_a_sd >> bl_b >> bl_b_sd; +@@ -340,12 +343,10 @@ fs_align::SpectrumDistance* fs_align::ASpectrum::overlaySpectrum(ASpectrum& s) + } + + if (options.logLevel >= 5) +- { +- ostringstream log; log << "overlap: " << getName() << " and " << s.getName() << +- ": score " << maxscore / sqrt(1.0*nx*s.nx) << ", shift " << +- options.alignPointDistance * maxshift + min_tss - s.min_tss << endl; +- *options.stdOut << log.str().c_str(); +- } ++ *options.stdOut << "overlap: " << getName() << " and " << s.getName() ++ << ": score " << maxscore / sqrt(1.0*nx*s.nx) ++ << ", shift " << options.alignPointDistance * maxshift + min_tss - s.min_tss ++ << endl; + + SpectrumDistance* dist = new SpectrumDistance(this, &s, maxscore / sqrt(1.0*(nx*s.nx)), options.alignPointDistance * maxshift + min_tss - s.min_tss); + +diff --git a/src/fs_align_aspectrumvector.cpp b/src/fs_align_aspectrumvector.cpp +index 887f350..7f2ff3a 100644 +--- a/src/fs_align_aspectrumvector.cpp ++++ b/src/fs_align_aspectrumvector.cpp +@@ -13,21 +13,18 @@ fs_align::ASpectrumVector::ASpectrumVector(Options& options) + ifstream fit_input(fit_filename.c_str()); + ifstream info_input(info_filename.c_str()); + +- if (!list_input) +- { +- ostringstream log; log << "ERROR: Could not find file " << list_filename << endl; *options.stdOut << log.str().c_str(); ++ if (!list_input) { ++ *options.stdOut << "ERROR: Could not find file " << list_filename << endl; + return; + } + +- if (!fit_input) +- { +- ostringstream log; log << "ERROR: Could not find file " << info_filename << endl; *options.stdOut << log.str().c_str(); ++ if (!fit_input) { ++ *options.stdOut << "ERROR: Could not find file " << info_filename << endl; + return; + } + +- if (!info_input) +- { +- ostringstream log; log << "ERROR: Could not find file " << fit_filename << endl; *options.stdOut << log.str().c_str(); ++ if (!info_input) { ++ *options.stdOut << "ERROR: Could not find file " << fit_filename << endl; + return; + } + +diff --git a/src/fs_align_clusterdriver.cpp b/src/fs_align_clusterdriver.cpp +index 170edfa..48c323a 100644 +--- a/src/fs_align_clusterdriver.cpp ++++ b/src/fs_align_clusterdriver.cpp +@@ -14,9 +14,7 @@ void fs_align::ClusterDriver::doClustering() + const int n_dist = ssv.size() * (ssv.size() - 1) / 2; + + if (options.logLevel >= 1) +- { +- { ostringstream log; log << "computing " << n_dist << " pairwise distances" << endl; *options.stdOut << log.str().c_str(); } +- } ++ *options.stdOut << "computing " << n_dist << " pairwise distances" << endl; + + time_t start_time = time(0); + bool first = true; +@@ -38,15 +36,13 @@ void fs_align::ClusterDriver::doClustering() + double dt = difftime(time(0), start_time); + const int f = (ssv.size() - 1); + +- { ostringstream log; log << "calculated " << f << " distances in " << dt << " seconds" << endl; *options.stdOut << log.str().c_str(); } +- { ostringstream log; log << "est. remaining time for distance calculation: " << dt * n_dist / f << " seconds" << endl; *options.stdOut << log.str().c_str(); } ++ *options.stdOut << "calculated " << f << " distances in " << dt << " seconds" << endl; ++ *options.stdOut << "est. remaining time for distance calculation: " << dt * n_dist / f << " seconds" << endl; + } + } + + if (options.logLevel >= 1) +- { +- { ostringstream log; log << "distances have been calculated; clustering..." << endl; *options.stdOut << log.str().c_str(); } +- } ++ *options.stdOut << "distances have been calculated; clustering..." << endl; + + + dlist.sort(cmpSpectrumDistancePtr()); +@@ -62,7 +58,8 @@ void fs_align::ClusterDriver::doClustering() + ASpectrumCluster *nc = new ASpectrumCluster(lowest, options); + ssv.push_back(nc); + +- if (options.logLevel >= 4) { ostringstream log; log << "best overlap: " << lowest->oa->getName() << "\t" << lowest->ob->getName() << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 4) ++ *options.stdOut << "best overlap: " << lowest->oa->getName() << "\t" << lowest->ob->getName() << endl; + + *tree << nc->getNumber() << " " << -lowest->score << endl; + +@@ -132,7 +129,8 @@ void fs_align::ClusterDriver::alignSpectra() + + shift /= n; + +- if (options.logLevel >= 4) { ostringstream log; log << "shifting spectra by " << shift << " to center alignment" << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 4) ++ *options.stdOut << "shifting spectra by " << shift << " to center alignment" << endl; + + // add average alignment shift to all spectra + // in result, average alignment shift is zero +@@ -142,11 +140,13 @@ void fs_align::ClusterDriver::alignSpectra() + // as soon as we encounter a cluster, break loop + if (s->isCluster()) break; + +- if (options.logLevel >= 4) { ostringstream log; log << s->getShift(); *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 4) ++ *options.stdOut << s->getShift(); + + s->setShift(s->getShift() - shift); + +- if (options.logLevel >= 4) { ostringstream log; log << "\t" << s->getShift() << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 4) ++ *options.stdOut << "\t" << s->getShift() << endl; + } + } + +diff --git a/src/fs_fit_fitfrontend.cpp b/src/fs_fit_fitfrontend.cpp +index b7a0db6..8931ebc 100644 +--- a/src/fs_fit_fitfrontend.cpp ++++ b/src/fs_fit_fitfrontend.cpp +@@ -76,9 +76,11 @@ void fs_fit::FitFrontend::printHeader(ostream *o) { + + Model *m = 0; + // model selection +- if (options.model == "wlc") m = new wlcModel(max_peaks, options); else +- if (options.model == "wlc_p") m = new wlcModel_p(max_peaks, options); else +- ; // model not found but oh well ++ if (options.model == "wlc") ++ m = new wlcModel(max_peaks, options); ++ else if (options.model == "wlc_p") ++ m = new wlcModel_p(max_peaks, options); ++ // else // model not found but oh well + + m->streamHeader(o); + +@@ -156,7 +158,7 @@ void fs_fit::FitFrontend::processSpectrum(string path, string filename, string x + + *temp_output << "end" << endl; + +- { ostringstream log; log << "ERROR: " << filename << " -- " << e.getError() << endl; *options.stdOut << log.str().c_str(); } ++ *options.stdOut << "ERROR: " << filename << " -- " << e.getError() << endl; + } + + string result = temp_output->str(); +@@ -190,7 +192,9 @@ void fs_fit::FitFrontend::processFit() try { + count++; + } + +- if (options.logLevel >= 1) { ostringstream log; log << "processed " << count << " spectra" << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 1) { ++ *options.stdOut << "processed " << count << " spectra" << endl; ++ } + + printHeader(output_fitting); + for (list::iterator it = output_buffer.begin(); it != output_buffer.end(); it++) +@@ -202,9 +206,9 @@ void fs_fit::FitFrontend::processFit() try { + + } + catch (fs_fitInitException& e) { +- { ostringstream log; log << "ERROR: An error occured during initialization. No spectra are processed:" << endl << e.getError() << endl; *options.stdOut << log.str().c_str(); } ++ *options.stdOut << "ERROR: An error occured during initialization. No spectra are processed:" << endl << e.getError() << endl; + } + catch (fs_fitException& e) { +- { ostringstream log; log << "ERROR: " << e.getError() << endl; *options.stdOut << log.str().c_str(); } ++ *options.stdOut << "ERROR: " << e.getError() << endl; + } + +diff --git a/src/fs_fit_model.cpp b/src/fs_fit_model.cpp +index 1461c08..2d56f3d 100644 +--- a/src/fs_fit_model.cpp ++++ b/src/fs_fit_model.cpp +@@ -156,16 +156,12 @@ void fs_fit::Model::printSolverState(int iter, gsl_multifit_fdfsolver *solver) + { + if (options.logLevel < 3) return; + +- { ostringstream log; log << "it: " << setw(3) << iter << " fit: "; *options.stdOut << log.str().c_str(); } ++ *options.stdOut << "it: " << setw(3) << iter << " fit: "; + + for (size_t i = 0; i < getFitParams(); i++) +- { +- { ostringstream log; log << setw(8) << gsl_vector_get(solver->x, i); *options.stdOut << log.str().c_str(); } +- } +- +- { ostringstream log; log << " |f(x)| = " << setw(8) << gsl_blas_dnrm2 (solver->f); *options.stdOut << log.str().c_str(); } ++ *options.stdOut << setw(8) << gsl_vector_get(solver->x, i); + +- { ostringstream log; log << endl; *options.stdOut << log.str().c_str(); } ++ *options.stdOut << " |f(x)| = " << setw(8) << gsl_blas_dnrm2 (solver->f) << endl; + + } + +@@ -183,8 +179,8 @@ void fs_fit::Model::printFunction(gsl_multifit_fdfsolver *solver) + { + for (int pos = it->getStart(); pos < it->getEnd(); pos++) + { +- { ostringstream log; log << setw(10) << gsl_vector_get(data->tss, pos) << "\t" << setw(10) << gsl_vector_get(data->force, pos) << setw(10) << "\t" << gsl_vector_get(solver->f, xpos) + gsl_vector_get(data->force, pos) << endl; *options.stdOut << log.str().c_str(); } +- xpos++; ++ *options.stdOut << setw(10) << gsl_vector_get(data->tss, pos) << "\t" << setw(10) << gsl_vector_get(data->force, pos) << setw(10) << "\t" << gsl_vector_get(solver->f, xpos) + gsl_vector_get(data->force, pos) << endl; ++ xpos++; + } + mpos++; + } +@@ -266,7 +262,8 @@ string fs_fit::Model::fitData(const double merge_threshold) throw(fs_fitExceptio + throw fs_fitFitException(s.str(),"sc_no_peaks"); + } + +- if (delete_last > 0 && options.logLevel >= 3) { ostringstream log; log << "deleting last " << delete_last << "peak(s) with high countour length..." << endl; *options.stdOut << log.str().c_str(); } ++ if (delete_last > 0 && options.logLevel >= 3) ++ *options.stdOut << "deleting last " << delete_last << "peak(s) with high countour length..." << endl; + + // check if peaks are too close to each other, if so, they will be merged + // (peaks will be merged pairwise) +@@ -275,7 +272,8 @@ string fs_fit::Model::fitData(const double merge_threshold) throw(fs_fitExceptio + for (size_t i = getCommonParams(); i < getFitParams() - (delete_last + 1) * getPeakParams(); i += getPeakParams()) + if (gsl_vector_get(solver->x,i+getPeakParams()) - gsl_vector_get(solver->x,i) < merge_threshold) { merge_peaks++; i += getPeakParams(); } + +- if (options.logLevel >= 3) { ostringstream log; log << "merging " << merge_peaks << " peaks..." << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 3) ++ *options.stdOut << "merging " << merge_peaks << " peaks..." << endl; + + if (merge_peaks > 0 || delete_last > 0) + { +@@ -342,7 +340,8 @@ string fs_fit::Model::fitData(const double merge_threshold) throw(fs_fitExceptio + { + // no peaks to merge, therefore: finish fitting + +- if (options.logLevel >= 3) { ostringstream log; log << gsl_strerror(status) << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 3) ++ *options.stdOut << gsl_strerror(status) << endl; + + // determine covariance matrix, assign parameters and parameter standard deviation + gsl_matrix *covar = gsl_matrix_alloc(getFitParams(), getFitParams()); +@@ -356,7 +355,8 @@ string fs_fit::Model::fitData(const double merge_threshold) throw(fs_fitExceptio + for (size_t i=0; i= 3) { ostringstream log; log << setw(10) << gsl_vector_get(solver->x, i) << setw(10) << gsl_vector_get(params_sd, i) << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 3) ++ *options.stdOut << setw(10) << gsl_vector_get(solver->x, i) << setw(10) << gsl_vector_get(params_sd, i) << endl; + } + + printFunction(solver); +diff --git a/src/fs_fit_spectrum.cpp b/src/fs_fit_spectrum.cpp +index 1e295b8..8cffd5e 100644 +--- a/src/fs_fit_spectrum.cpp ++++ b/src/fs_fit_spectrum.cpp +@@ -75,7 +75,8 @@ void fs_fit::Spectrum::loadFromASCIIFile(string path, string filename, int datap + { + if (datapoints != -1) this->datapoints = datapoints; + +- if (options.logLevel >= 2) { ostringstream log; log << "loading file " << path << filename << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 2) ++ *options.stdOut << "loading file " << path << filename << endl; + + rawpoints = getNumberOfFields(filename); + +@@ -142,7 +143,8 @@ void fs_fit::Spectrum::loadFromASCIIFile(string path, string filename, int datap + + // cout << filename << "\t" << datapoints << "\t" << data->force << endl; + +- if (options.logLevel >= 3) { ostringstream log; log << rawpoints << " points have been read, tss moved by " << -data->bl_mintss << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 3) ++ *options.stdOut << rawpoints << " points have been read, tss moved by " << -data->bl_mintss << endl; + } + + void fs_fit::Spectrum::reducePoints(double min_tss, double max_tss) +@@ -206,7 +208,8 @@ void fs_fit::Spectrum::reducePoints(double min_tss, double max_tss) + // cout << t_avg << "\t" << f_avg << "\t" << sqrt(sd / (n_smooth - 1)) << endl; + } + +- if (options.logLevel >= 3) { ostringstream log; log << rawpoints << " points have been reduced to " << points << " points"<< endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 3) ++ *options.stdOut << rawpoints << " points have been reduced to " << points << " points"<< endl; + } + + double fs_fit::Spectrum::fractionBaseline(double fraction) +@@ -229,11 +232,11 @@ double fs_fit::Spectrum::fractionBaseline(double fraction) + data->bl_asd = sqrt(cov00); + data->bl_bsd = sqrt(cov11); + +- if (options.logLevel >= 3) { ostringstream log; log << "baseline fit: " << setw(5) << fraction +- << " [" << gsl_vector_get(data->tss,start) << ", " << gsl_vector_get(data->tss,points-1) << "] " +- << " -- y = " << data->bl_a << " + x * " << data->bl_b << +- " -- sd = " << data->bl_sd << endl; +- *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 3) ++ *options.stdOut << "baseline fit: " << setw(5) << fraction ++ << " [" << gsl_vector_get(data->tss,start) << ", " << gsl_vector_get(data->tss,points-1) << "] " ++ << " -- y = " << data->bl_a << " + x * " << data->bl_b ++ << " -- sd = " << data->bl_sd << endl; + + return data->bl_sd; + } +@@ -256,12 +259,14 @@ double fs_fit::Spectrum::fullSpectrumSD() + + double bl_sd = sqrt(chisq/(n-1)); + +- if (options.logLevel >= 3) { ostringstream log; log << "baseline fit to all points: " +- << setw(5) << data->bl_fraction +- << " [" << gsl_vector_get(data->rawtss,start) << ", " << gsl_vector_get(data->rawtss,rawpoints-1) << "] " +- << " -- y = " << bl_a << " + x * " << bl_b << +- " -- sd = " << bl_sd << endl; +- *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 3) ++ *options.stdOut << "baseline fit to all points: " ++ << setw(5) << data->bl_fraction ++ << " [" << gsl_vector_get(data->rawtss,start) ++ << ", " << gsl_vector_get(data->rawtss,rawpoints-1) ++ << "] " ++ << " -- y = " << bl_a << " + x * " << bl_b ++ << " -- sd = " << bl_sd << endl; + + data->full_sd = bl_sd; + +@@ -303,7 +308,8 @@ double fs_fit::Spectrum::iterativeBaseline(const double guess, const double incr + // check if baseline is too long + if (errorNotAttached()) { throw fs_fitFitException("no attachment","no_attachment"); } + if (warnNotAttached()) { +- if (options.logLevel >= 2) { ostringstream log; log << "WARNING: over 50% of the spectrum are baseline" << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 2) ++ *options.stdOut << "WARNING: over 50% of the spectrum are baseline" << endl; + } + + return sd; +@@ -380,12 +386,12 @@ void fs_fit::Spectrum::refineBaseline(const double mintss) + /*data->bl_asd = sqrt(cov00); + data->bl_bsd = sqrt(cov11); + */ +- if (options.logLevel >= 3) { ostringstream log; log << "refining baseline: " << setw(5) << fitpoints << " -- y = " << p_a << " + x * " << p_b << ++ if (options.logLevel >= 3) { ++ *options.stdOut << "refining baseline: " << setw(5) << fitpoints << " -- y = " << p_a << " + x * " << p_b << + " -- sd = " << p_sd << endl; +- *options.stdOut << log.str().c_str(); } +- if (options.logLevel >= 3) { ostringstream log; log << " best: " << setw(5) << min_pts << " -- y = " << min_a << " + x * " << min_b << ++ *options.stdOut << " best: " << setw(5) << min_pts << " -- y = " << min_a << " + x * " << min_b << + " -- sd = " << min_sd << endl; +- *options.stdOut << log.str().c_str(); } ++ } + + gsl_vector_free(extbl_x); + gsl_vector_free(extbl_y); +@@ -404,7 +410,8 @@ void fs_fit::Spectrum::subtractBaseline() + data->rawforce->data[i] -= data->bl_a + data->bl_b * data->rawtss->data[j]; + } + +- if (options.logLevel >= 3) { ostringstream log; log << "baseline subtracted: y = " << data->bl_a << " + x * " << data->bl_b << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 3) ++ *options.stdOut << "baseline subtracted: y = " << data->bl_a << " + x * " << data->bl_b << endl; + } + + int fs_fit::Spectrum::initChunks(double sd_factor, double minforce, double mintss) +@@ -416,9 +423,9 @@ int fs_fit::Spectrum::initChunks(double sd_factor, double minforce, double mints + // init number of condensed points -- is incremented by createChunk + data->fit_points = 0; + +- if (options.logLevel >= 3) { ostringstream log; log << "dividing spectrum in chunks, peak threshold: " << threshold << +- " pN, minimal peak force " << minforce << " pN, minimal tip-sample separation: " << mintss << " nm. " << endl; +- *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 3) ++ *options.stdOut << "dividing spectrum in chunks, peak threshold: " << threshold << ++ " pN, minimal peak force " << minforce << " pN, minimal tip-sample separation: " << mintss << " nm. " << endl; + + // skip non-specific interactions -- start scanning mintss nm after smallest tss + size_t start = 1; +@@ -545,12 +552,14 @@ void fs_fit::Spectrum::createChunk(int start, int end, double minforce, double m + data->chunks.push_back(c); + data->fit_points += c.getPoints(); + +- if (options.logLevel >= 3) { ostringstream log; log << "new chunk " << c.getFirst() << " -- " << c.getLast() << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 3) ++ *options.stdOut << "new chunk " << c.getFirst() << " -- " << c.getLast() << endl; + } + + void fs_fit::Spectrum::adjustZeroTSS() throw (fs_fitFitException) + { +- if (options.logLevel >= 3) { ostringstream log; log << "Detecting contact point." << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 3) ++ *options.stdOut << "Detecting contact point." << endl; + + const double max_force = 2 * data->full_sd; + const double range = 1 * data->full_sd; +@@ -609,17 +618,17 @@ void fs_fit::Spectrum::adjustZeroTSS() throw (fs_fitFitException) + data->bl_mintss += shift; + data->bl_mintss_sd = sd; + +- if (options.logLevel >= 3) { ostringstream log; log << "shifted by " << shift << " nm" << endl; *options.stdOut << log.str().c_str(); } ++ if (options.logLevel >= 3) ++ *options.stdOut << "shifted by " << shift << " nm" << endl; + + gsl_vector_add_constant(data->rawtss, -shift); + } + + void fs_fit::Spectrum::streamDataPoints(ostream* o) + { +- for (size_t i = 0; i < points; i++) +- { ostringstream log; log << gsl_vector_get(data->tss, i) +- << "\t" << gsl_vector_get(data->force, i) +- << "\t" << gsl_vector_get(data->force_sd, i) +- << "\t" << gsl_vector_get(data->weight, i) << endl; +- *options.stdOut << log.str().c_str(); } ++ for (size_t i = 0; i < points; i++) ++ *options.stdOut << gsl_vector_get(data->tss, i) ++ << "\t" << gsl_vector_get(data->force, i) ++ << "\t" << gsl_vector_get(data->force_sd, i) ++ << "\t" << gsl_vector_get(data->weight, i) << endl; + } +diff --git a/src/fs_gui.wxg b/src/fs_gui.wxg +index a8e6b17..4252552 100644 +--- a/src/fs_gui.wxg ++++ b/src/fs_gui.wxg +@@ -1,7 +1,7 @@ + +- ++ + +- ++ + + + fs_kit +@@ -99,10 +99,10 @@ + 0 + + +- Load settings file + +- 1 ++ Load settings file + ID_SET_OPEN ++ 1 + + + +@@ -184,8 +184,8 @@ + 0 + + +- Load list of spectra filenames + ++ Load list of spectra filenames + ID_SPEC_OPEN + + +@@ -281,8 +281,8 @@ + 0 + + +- Pick output directory + ++ Pick output directory + ID_SELECT_DIR + + +@@ -441,10 +441,10 @@ + 0 + + +- ++ ++ ID_LOGLEVEL + -1, 5 + 0 +- ID_LOGLEVEL + 40, -1 + + +diff --git a/src/fs_gui_app.cpp b/src/fs_gui_app.cpp +index b085cce..b83ebc6 100644 +--- a/src/fs_gui_app.cpp ++++ b/src/fs_gui_app.cpp +@@ -27,8 +27,7 @@ + bool BasicApplication::OnInit() + { + guiFrame *frame +- = new guiFrame +- (0, -1, "fs_gui"); ++ = new guiFrame(0, -1, wxString("fs_gui", wxConvUTF8)); + + frame->Show(TRUE); + SetTopWindow(frame); +diff --git a/src/fs_gui_layout.cpp b/src/fs_gui_layout.cpp +index 3d928b7..a9dca2a 100644 +--- a/src/fs_gui_layout.cpp ++++ b/src/fs_gui_layout.cpp +@@ -1,4 +1,4 @@ +-// -*- C++ -*- generated by wxGlade 0.3.1 on Sat Feb 14 18:44:55 2004 ++// -*- C++ -*- generated by wxGlade 0.6.3 on Tue Oct 21 13:38:33 2008 + // DO NOT EDIT BETWEEN "begin wxGlade" AND "end wxGlade" + + /* fs_kit +@@ -19,9 +19,10 @@ + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +- ++ + #ifdef fs_gui_wxwidgets + ++#include "fs_kit_options.h" + #include "fs_gui_layout.h" + + enum { +@@ -54,61 +55,66 @@ BEGIN_EVENT_TABLE(guiFrame, wxFrame) + EVT_SPINCTRL (ID_LOGLEVEL, guiFrame::OnLogLevel) + END_EVENT_TABLE() + ++// begin wxGlade: ::extracode ++// end wxGlade ++ ++ ++ + guiFrame::guiFrame(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style): + wxFrame(parent, id, title, pos, size, wxDEFAULT_FRAME_STYLE) + { + // begin wxGlade: guiFrame::guiFrame +- notebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize, 0); +- notebook_pane_2 = new wxPanel(notebook, -1); +- notebook_log = new wxPanel(notebook, -1); +- borderpanel = new wxPanel(this, -1); +- middlepanel = new wxPanel(this, -1); +- toppanel = new wxPanel(this, -1); ++ notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0); ++ notebook_pane_2 = new wxPanel(notebook, wxID_ANY); ++ notebook_log = new wxPanel(notebook, wxID_ANY); ++ borderpanel = new wxPanel(this, wxID_ANY); ++ middlepanel = new wxPanel(this, wxID_ANY); ++ toppanel = new wxPanel(this, wxID_ANY); + frame_menubar = new wxMenuBar(); +- SetMenuBar(frame_menubar); + wxMenu* menu_file = new wxMenu(); +- menu_file->Append(wxNewId(), wxT("&Open settings"), wxT(""), wxITEM_NORMAL); ++ menu_file->Append(wxNewId(), wxT("&Open settings"), wxEmptyString, wxITEM_NORMAL); + menu_file->Append(ID_EXIT, wxT("E&xit"), wxT("Exit fs_gui"), wxITEM_NORMAL); + frame_menubar->Append(menu_file, wxT("File")); +- frame_statusbar = CreateStatusBar(1); +- lblSettings = new wxStaticText(toppanel, -1, wxT("Settings:")); ++ SetMenuBar(frame_menubar); ++ frame_statusbar = CreateStatusBar(1, 0); ++ lblSettings = new wxStaticText(toppanel, wxID_ANY, wxT("Settings:")); + const wxString SettingsCombo_choices[] = { +- wxT("") ++ wxT("choice 1") + }; +- SettingsCombo = new wxComboBox(toppanel, -1, "", wxDefaultPosition, wxDefaultSize, 1, SettingsCombo_choices, wxCB_DROPDOWN); ++ SettingsCombo = new wxComboBox(toppanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 1, SettingsCombo_choices, wxCB_DROPDOWN); + SettingsLoad = new wxButton(toppanel, ID_SET_OPEN, wxT("Load...")); + SettingsSave = new wxButton(toppanel, ID_SET_SAVE , wxT("Save...")); + SettingsSaveAs = new wxButton(toppanel, ID_SET_SAVEAS, wxT("Save As...")); +- lblSpectra = new wxStaticText(toppanel, -1, wxT("Spectra:")); ++ lblSpectra = new wxStaticText(toppanel, wxID_ANY, wxT("Spectra:")); + const wxString SpectraCombo_choices[] = { +- wxT("") ++ wxT("choice 1") + }; +- SpectraCombo = new wxComboBox(toppanel, -1, "", wxDefaultPosition, wxDefaultSize, 1, SpectraCombo_choices, wxCB_DROPDOWN); ++ SpectraCombo = new wxComboBox(toppanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 1, SpectraCombo_choices, wxCB_DROPDOWN); + SpectraLoad = new wxButton(toppanel, ID_SPEC_OPEN, wxT("Load...")); +- SpectraSave = new wxButton(toppanel, -1, wxT("Save...")); +- SpectraSaveAs = new wxButton(toppanel, -1, wxT("Save As...")); +- lblDirectory = new wxStaticText(toppanel, -1, wxT("Output directory:")); ++ SpectraSave = new wxButton(toppanel, wxID_ANY, wxT("Save...")); ++ SpectraSaveAs = new wxButton(toppanel, wxID_ANY, wxT("Save As...")); ++ lblDirectory = new wxStaticText(toppanel, wxID_ANY, wxT("Output directory:")); + const wxString OutputDirectoryCombo_choices[] = { +- wxT("") ++ wxT("choice 1") + }; +- OutputDirectoryCombo = new wxComboBox(toppanel, -1, "", wxDefaultPosition, wxDefaultSize, 1, OutputDirectoryCombo_choices, wxCB_DROPDOWN); ++ OutputDirectoryCombo = new wxComboBox(toppanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 1, OutputDirectoryCombo_choices, wxCB_DROPDOWN); + SelectDir = new wxButton(toppanel, ID_SELECT_DIR, wxT("Select...")); +- lblExpName = new wxStaticText(toppanel, -1, wxT("Experiment name:")); ++ lblExpName = new wxStaticText(toppanel, wxID_ANY, wxT("Experiment name:")); + const wxString ExperimentNameCombo_choices[] = { +- wxT("") ++ wxT("choice 1") + }; +- ExperimentNameCombo = new wxComboBox(toppanel, -1, "", wxDefaultPosition, wxDefaultSize, 1, ExperimentNameCombo_choices, wxCB_DROPDOWN); +- radioProcessSpectra = new wxRadioButton(toppanel, -1, wxT("Process Spectra:")); +- chkFit = new wxCheckBox(toppanel, -1, wxT("Fit spectra")); +- chkAlign = new wxCheckBox(toppanel, -1, wxT("Align spectra")); +- chkSelect = new wxCheckBox(toppanel, -1, wxT("Select spectra")); +- chkClassify = new wxCheckBox(toppanel, -1, wxT("Classify peaks")); +- lblLogLevel = new wxStaticText(toppanel, -1, wxT("Log activty (-1 to 2 recommended):")); +- LogLevelCtrl = new wxSpinCtrl(toppanel, ID_LOGLEVEL, "0", wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -1, 5); +- LogLevelLbl = new wxStaticText(toppanel, -1, wxT("LogLevelLbl")); ++ ExperimentNameCombo = new wxComboBox(toppanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 1, ExperimentNameCombo_choices, wxCB_DROPDOWN); ++ radioProcessSpectra = new wxRadioButton(toppanel, wxID_ANY, wxT("Process Spectra:")); ++ chkFit = new wxCheckBox(toppanel, wxID_ANY, wxT("Fit spectra")); ++ chkAlign = new wxCheckBox(toppanel, wxID_ANY, wxT("Align spectra")); ++ chkSelect = new wxCheckBox(toppanel, wxID_ANY, wxT("Select spectra")); ++ chkClassify = new wxCheckBox(toppanel, wxID_ANY, wxT("Classify peaks")); ++ lblLogLevel = new wxStaticText(toppanel, wxID_ANY, wxT("Log activty (-1 to 2 recommended):")); ++ LogLevelCtrl = new wxSpinCtrl(toppanel, ID_LOGLEVEL, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxTE_AUTO_URL, -1, 5); ++ LogLevelLbl = new wxStaticText(toppanel, wxID_ANY, wxT("LogLevelLbl")); + Start = new wxButton(middlepanel, ID_START, wxT("Start")); +- LogTextCtrl = new wxTextCtrl(notebook_log, ID_LOG_TEXTCTRL, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY); +- label_1 = new wxStaticText(notebook_pane_2, -1, wxT("Currently, the following features are not implemented:\n\n- providing a history of previously selected settings, file names, etc\n- validating manual (keyboard) input \n")); ++ LogTextCtrl = new wxTextCtrl(notebook_log, ID_LOG_TEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY); ++ label_1 = new wxStaticText(notebook_pane_2, wxID_ANY, wxT("Currently, the following features are not implemented:\n\n- providing a history of previously selected settings, file names, etc\n- validating manual (keyboard) input \n")); + + set_properties(); + do_layout(); +@@ -120,8 +126,8 @@ guiFrame::guiFrame(wxWindow* parent, int id, const wxString& title, const wxPoin + SpectraCombo->Clear(); + SettingsCombo->Clear(); + OutputDirectoryCombo->Clear(); +- +- wrapper = 0; ++ ++ wrapper = 0; + } + + +@@ -138,26 +144,26 @@ void guiFrame::set_properties() + for(int i = 0; i < frame_statusbar->GetFieldsCount(); ++i) { + frame_statusbar->SetStatusText(frame_statusbar_fields[i], i); + } +- SettingsCombo->SetSize(wxSize(200, -1)); ++ SettingsCombo->SetMinSize(wxSize(200, -1)); + SettingsCombo->SetToolTip(wxT("Select settings file")); + SettingsCombo->SetSelection(0); + SettingsLoad->SetToolTip(wxT("Load settings file")); + SettingsLoad->SetFocus(); +- SpectraCombo->SetSize(wxSize(200, -1)); ++ SpectraCombo->SetMinSize(wxSize(200, -1)); + SpectraCombo->SetToolTip(wxT("Select list of spectra filenames")); + SpectraCombo->SetSelection(0); + SpectraLoad->SetToolTip(wxT("Load list of spectra filenames")); + SpectraSave->Enable(false); + SpectraSaveAs->Enable(false); +- OutputDirectoryCombo->SetSize(wxSize(200, -1)); ++ OutputDirectoryCombo->SetMinSize(wxSize(200, -1)); + OutputDirectoryCombo->SetToolTip(wxT("Select output directory (empty: directory of settings file)")); + OutputDirectoryCombo->SetSelection(0); + SelectDir->SetToolTip(wxT("Pick output directory")); +- ExperimentNameCombo->SetSize(wxSize(200, -1)); ++ ExperimentNameCombo->SetMinSize(wxSize(200, -1)); + ExperimentNameCombo->SetToolTip(wxT("Enter or select experiment name")); + ExperimentNameCombo->SetSelection(0); + radioProcessSpectra->SetValue(1); +- LogLevelCtrl->SetSize(wxSize(40, -1)); ++ LogLevelCtrl->SetMinSize(wxSize(40, -1)); + Start->SetDefault(); + // end wxGlade + +@@ -240,45 +246,30 @@ void guiFrame::do_layout() + topsizer->Add(20, 10, 0, 0, 0); + spacesizer->Add(topsizer, 0, wxEXPAND, 0); + spacesizer->Add(5, 20, 0, 0, 0); +- toppanel->SetAutoLayout(true); + toppanel->SetSizer(spacesizer); +- spacesizer->Fit(toppanel); +- spacesizer->SetSizeHints(toppanel); + mainsizer->Add(toppanel, 0, wxEXPAND, 0); + middlesizer->Add(5, 20, 0, 0, 0); + middlesizer->Add(Start, 0, 0, 0); +- middlepanel->SetAutoLayout(true); + middlepanel->SetSizer(middlesizer); +- middlesizer->Fit(middlepanel); +- middlesizer->SetSizeHints(middlepanel); + mainsizer->Add(middlepanel, 0, wxEXPAND, 0); + bordersizer->Add(20, 10, 0, 0, 0); +- borderpanel->SetAutoLayout(true); + borderpanel->SetSizer(bordersizer); +- bordersizer->Fit(borderpanel); +- bordersizer->SetSizeHints(borderpanel); + mainsizer->Add(borderpanel, 0, wxEXPAND, 0); + sizer_1->Add(LogTextCtrl, 1, wxALL|wxEXPAND, 0); +- notebook_log->SetAutoLayout(true); + notebook_log->SetSizer(sizer_1); +- sizer_1->Fit(notebook_log); +- sizer_1->SetSizeHints(notebook_log); + sizer_8->Add(label_1, 0, 0, 0); +- notebook_pane_2->SetAutoLayout(true); + notebook_pane_2->SetSizer(sizer_8); +- sizer_8->Fit(notebook_pane_2); +- sizer_8->SetSizeHints(notebook_pane_2); + notebook->AddPage(notebook_log, wxT("Log")); + notebook->AddPage(notebook_pane_2, wxT("Read Me")); +- mainsizer->Add(new wxNotebookSizer(notebook), 1, wxALL|wxEXPAND, 0); +- SetAutoLayout(true); ++ mainsizer->Add(notebook, 1, wxALL|wxEXPAND, 0); + SetSizer(mainsizer); + mainsizer->Fit(this); +- mainsizer->SetSizeHints(this); + Layout(); + // end wxGlade + } + ++ ++ + void guiFrame::OnLogFull(wxCommandEvent& event) + { + LogTextCtrl->Clear(); +@@ -286,7 +277,7 @@ void guiFrame::OnLogFull(wxCommandEvent& event) + + wxString guiFrame::DescribeLogLevel(int level) + { +- wxString s; ++ string s; + + switch (level) + { +@@ -329,7 +320,7 @@ wxString guiFrame::DescribeLogLevel(int level) + + if (level > 3) s += " NOTE: Only use this when you process very few files. It's slow!"; + +- return s; ++ return wxString(s.c_str(), wxConvUTF8); + } + + void guiFrame::OnLogLevel(wxSpinEvent& event) +@@ -351,14 +342,18 @@ void guiFrame::OnMenu(wxCommandEvent& event) + // load settings file + case ID_SET_OPEN: + { +- wxFileDialog *fd = new wxFileDialog(this, "Choose a settings file", +- "", "", "INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxOPEN); ++ wxFileDialog *fd = new wxFileDialog(this, ++ wxString("Choose a settings file", wxConvUTF8), ++ wxString("", wxConvUTF8), ++ wxString("", wxConvUTF8), ++ wxString("INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxConvUTF8), ++ wxOPEN); + + if (fd->ShowModal() == wxID_OK) + { + SettingsCombo->SetValue(fd->GetPath()); + readOptions(); +- LogTextCtrl->AppendText("Loaded settings file: " + fd->GetPath() + "\n"); ++ LogTextCtrl->AppendText(wxString("Loaded settings file: ", wxConvUTF8) + fd->GetPath() + wxString("\n", wxConvUTF8)); + } + + delete fd; +@@ -367,9 +362,13 @@ void guiFrame::OnMenu(wxCommandEvent& event) + // display save as dialog and fall through to actual saving + case ID_SET_SAVEAS: + { +- wxFileDialog *fd = new wxFileDialog(this, "Save settings file as", +- "", "", "INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxSAVE | wxOVERWRITE_PROMPT); +- ++ wxFileDialog *fd = new wxFileDialog(this, ++ wxString("Save settings file as", wxConvUTF8), ++ wxString("", wxConvUTF8), ++ wxString("", wxConvUTF8), ++ wxString("INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxConvUTF8), ++ wxSAVE | wxOVERWRITE_PROMPT); ++ + bool fall_through = false; + if (fd->ShowModal() == wxID_OK) + { +@@ -384,10 +383,14 @@ void guiFrame::OnMenu(wxCommandEvent& event) + // save settings (fall through from above!) + case ID_SET_SAVE: + { +- if (SettingsCombo->GetValue() == "") { +- +- wxFileDialog *fd = new wxFileDialog(this, "Save settings file as", +- "", "", "INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxSAVE | wxOVERWRITE_PROMPT); ++ if (SettingsCombo->GetValue() == wxString("", wxConvUTF8)) { ++ ++ wxFileDialog *fd = new wxFileDialog(this, ++ wxString("Save settings file as", wxConvUTF8), ++ wxString("", wxConvUTF8), ++ wxString("", wxConvUTF8), ++ wxString("INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxConvUTF8), ++ wxSAVE | wxOVERWRITE_PROMPT); + + if (fd->ShowModal() == wxID_OK) + SettingsCombo->SetValue(fd->GetPath()); +@@ -395,27 +398,31 @@ void guiFrame::OnMenu(wxCommandEvent& event) + delete fd; + } + +- if (SettingsCombo->GetValue() == "") break; ++ if (SettingsCombo->GetValue() == wxString("", wxConvUTF8)) break; + +- ofstream out(SettingsCombo->GetValue()); +- +- if (out) { +- Options *options = new Options(encodeOptions(), LogTextCtrl); +- options->printOptions(&out); +- } ++ ofstream out(SettingsCombo->GetValue().mb_str()); + ++ if (out) { ++ Options *options = new Options(encodeOptions(), LogTextCtrl); ++ options->printOptions(&out); ++ } ++ + break; + } + // load spectrum file + case ID_SPEC_OPEN: + { +- wxFileDialog *fd = new wxFileDialog(this, "Choose a settings file", +- "", "", "Filenames list (filenames.txt)|filenames.txt|Text files (*.txt)|*.txt|All files (*.*)|*.*", wxOPEN); ++ wxFileDialog *fd = new wxFileDialog(this, ++ wxString("Choose a settings file", wxConvUTF8), ++ wxString("", wxConvUTF8), ++ wxString("", wxConvUTF8), ++ wxString("INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxConvUTF8), ++ wxOPEN); + + if (fd->ShowModal() == wxID_OK) + { + SpectraCombo->SetValue(fd->GetPath()); +- LogTextCtrl->AppendText("Loaded filenames list: " + fd->GetPath() + "\n"); ++ LogTextCtrl->AppendText(wxString("Loaded filenames list: ", wxConvUTF8) + fd->GetPath() + wxString("\n", wxConvUTF8)); + } + + delete fd; +@@ -424,12 +431,15 @@ void guiFrame::OnMenu(wxCommandEvent& event) + // select output directory + case ID_SELECT_DIR: + { +- wxDirDialog *dd = new wxDirDialog(this, "Choose an output directory", "", wxDD_NEW_DIR_BUTTON); ++ wxDirDialog *dd = new wxDirDialog(this, ++ wxString("Choose an output directory", wxConvUTF8), ++ wxString("", wxConvUTF8), ++ wxDD_NEW_DIR_BUTTON); + + if (dd->ShowModal() == wxID_OK) + { + OutputDirectoryCombo->SetValue(dd->GetPath()); +- LogTextCtrl->AppendText("Selected output directory: " + dd->GetPath() + "\n"); ++ LogTextCtrl->AppendText(wxString("Selected output directory: ", wxConvUTF8) + dd->GetPath() + wxString("\n", wxConvUTF8)); + } + + delete dd; +@@ -440,15 +450,15 @@ void guiFrame::OnMenu(wxCommandEvent& event) + { + if (!wrapper) + { +- Start->SetLabel("Stop"); ++ Start->SetLabel(wxString("Stop", wxConvUTF8)); + toppanel->Disable(); +- LogTextCtrl->AppendText("Started fs_kit computation\n"); ++ LogTextCtrl->AppendText(wxString("Started fs_kit computation\n", wxConvUTF8)); + wrapper = new GUIWrapper(encodeOptions(), LogTextCtrl); + wrapper->Run(); + delete wrapper; + wrapper = 0; +- LogTextCtrl->AppendText("Finished fs_kit computation\n"); +- Start->SetLabel("Start"); ++ LogTextCtrl->AppendText(wxString("Finished fs_kit computation\n", wxConvUTF8)); ++ Start->SetLabel(wxString("Start", wxConvUTF8)); + toppanel->Enable(); + } + else +@@ -466,7 +476,7 @@ void guiFrame::readOptions() + { + // create options object + string o = ""; +- o += "-o \"" + SettingsCombo->GetValue() + "\"\n"; ++ o += "-o \"" + std::string(SettingsCombo->GetValue().mb_str()) + "\"\n"; + Options *options = new Options(o, LogTextCtrl); + + chkAlign->SetValue(options->processAlign); +@@ -474,13 +484,13 @@ void guiFrame::readOptions() + chkClassify->SetValue(options->processPC); + chkSelect->SetValue(options->processSelect); + +- SpectraCombo->SetValue(options->inputFileList.c_str()); ++ SpectraCombo->SetValue(wxString(options->inputFileList.c_str(), wxConvUTF8)); + + LogLevelCtrl->SetValue(options->logLevel); + LogLevelLbl->SetLabel(DescribeLogLevel(LogLevelCtrl->GetValue())); + + // split up experiment name into path and file name +- wxFileName en = wxFileName(options->experimentName.c_str()); ++ wxFileName en = wxFileName(wxString(options->experimentName.c_str(), wxConvUTF8)); + OutputDirectoryCombo->SetValue(en.GetPath(wxPATH_GET_VOLUME)); + ExperimentNameCombo->SetValue(en.GetName()); + +@@ -492,7 +502,7 @@ string guiFrame::encodeOptions() + string o = ""; + + // settings file should be read at first, hence put it in front +- o += "-o \"" + SettingsCombo->GetValue() + "\"\n"; ++ o += "-o \"" + std::string(SettingsCombo->GetValue().mb_str()) + "\"\n"; + + // the following options will override those in the settings file + o += "-align " + string(chkAlign->IsChecked() ? "1" : "0") + "\n"; +@@ -502,19 +512,19 @@ string guiFrame::encodeOptions() + + o += "-log_level " + Options::int2string(LogLevelCtrl->GetValue()) + "\n"; + +- if (!SpectraCombo->GetValue().empty()) o += "-files_list \"" + SpectraCombo->GetValue() + "\"\n"; ++ if (!SpectraCombo->GetValue().empty()) o += "-files_list \"" + std::string(SpectraCombo->GetValue().mb_str()) + "\"\n"; + if (!ExperimentNameCombo->GetValue().empty()) + { + o += "-experiment_name \""; + + if (!OutputDirectoryCombo->GetValue().empty()) + { +- o += OutputDirectoryCombo->GetValue(); ++ o += std::string(OutputDirectoryCombo->GetValue().mb_str()); + if (OutputDirectoryCombo->GetValue().Last() != wxFileName::GetPathSeparator()) + o += wxFileName::GetPathSeparator(); +- } ++ } + +- o += ExperimentNameCombo->GetValue() + "\"\n"; ++ o += std::string(ExperimentNameCombo->GetValue().mb_str()) + "\"\n"; + } + + // "-log_level" +@@ -525,5 +535,3 @@ string guiFrame::encodeOptions() + #endif // fs_gui_wxwidgets + + +- +- +diff --git a/src/fs_gui_layout.h b/src/fs_gui_layout.h +index b569bbc..c569ec0 100644 +--- a/src/fs_gui_layout.h ++++ b/src/fs_gui_layout.h +@@ -1,4 +1,4 @@ +-// -*- C++ -*- generated by wxGlade 0.3.1 on Sat Feb 14 18:44:55 2004 ++// -*- C++ -*- generated by wxGlade 0.6.3 on Tue Oct 21 13:38:33 2008 + // DO NOT EDIT BETWEEN "begin wxGlade" AND "end wxGlade" + + /* fs_kit +@@ -31,11 +31,15 @@ + #include + // end wxGlade + ++ + #ifndef FS_GUI_LAYOUT_H + #define FS_GUI_LAYOUT_H + + #include "fs_gui_wrapper.h" + ++// begin wxGlade: ::extracode ++// end wxGlade ++ + + class guiFrame: public wxFrame { + public: +@@ -55,7 +59,7 @@ private: + void set_properties(); + void do_layout(); + // end wxGlade +- ++ + protected: + // begin wxGlade: guiFrame::attributes + wxMenuBar* frame_menubar; +@@ -93,14 +97,14 @@ protected: + wxPanel* notebook_pane_2; + wxNotebook* notebook; + // end wxGlade +- ++ + GUIWrapper* wrapper; +- ++ + string encodeOptions(); + void readOptions(); + + DECLARE_EVENT_TABLE() +-}; ++}; // wxGlade: end class + + + #endif // FS_GUI_LAYOUT_H +diff --git a/src/fs_kit_driver.cpp b/src/fs_kit_driver.cpp +index 1251e3e..d9df296 100644 +--- a/src/fs_kit_driver.cpp ++++ b/src/fs_kit_driver.cpp +@@ -17,6 +17,7 @@ + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + ++#include "fs_kit_options.h" // logger + #include "fs_kit_driver.h" + + int fs_driver::fsDriver::doRun () { +@@ -30,60 +31,73 @@ int fs_driver::fsDriver::doRun () { + if (!options->processSP) { + if (options->processFit) { + +- if (options->logLevel >= 0) { ostringstream log; log << "process FIT ..."; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 0) ++ *options->stdOut << "process FIT ..."; + + clock_t start = clock(), end; + + fs_fit::FitFrontend fitfrontend(*options); + fitfrontend.processFit(); +- ++ + end = clock(); + const double elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; +- if (options->logLevel >= 0) { ostringstream log; log << " done in " << setw(5) << elapsed << " seconds" << endl; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 0) ++ *options->stdOut << " done in " << setw(5) << elapsed << " seconds" << endl; + } + + if (options->processAlign) { + +- if (options->logLevel >= 0) { ostringstream log; log << "process ALIGN ..."; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 0) ++ *options->stdOut << "process ALIGN ..."; ++ + + clock_t start = clock(), end; + +- if (options->logLevel >= 2) { ostringstream log; log << " initializing ..."; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 2) ++ *options->stdOut << " initializing ..."; + fs_align::ClusterDriver acd(*options); +- if (options->logLevel >= 2) { ostringstream log; log << " clustering spectra ..."; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 2) ++ *options->stdOut << " clustering spectra ..."; + acd.doClustering(); +- if (options->logLevel >= 2) { ostringstream log; log << " aligning spectra ..."; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 2) ++ *options->stdOut << " aligning spectra ..."; + acd.alignSpectra(); +- if (options->logLevel >= 2) { ostringstream log; log << " printing spectra ..."; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 2) ++ *options->stdOut << " printing spectra ..."; + acd.printSpectra(); + + end = clock(); + const double elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; +- if (options->logLevel >= 0) { ostringstream log; log << " done in " << setw(5) << elapsed << " seconds" << endl; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 0) ++ *options->stdOut << " done in " << setw(5) << elapsed << " seconds" << endl; + } + + // todo: the selection logic should be moved out to e.g. fs_select_driver + if (options->processSelect) { + +- if (options->logLevel >= 0) { ostringstream log; log << "process SELECT"; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 0) ++ *options->stdOut << "process SELECT"; + + clock_t start = clock(), end; + + fs_select::Tree t(*options); + + double d = options->selectAvg * t.getAvg() + options->selectSD * t.getSD() + options->selectAbs; +- if (options->logLevel >= 0) { ostringstream log; log << " (merge_distance: " << d << ") ..."; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 0) ++ *options->stdOut << " (merge_distance: " << d << ") ..."; + + select_filenames = t.streamLeavesMaxD(t.getTop(), d); + select_filenames.push_front(options->getFileName(options->alignName, false)); + + end = clock(); + const double elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; +- if (options->logLevel >= 0) { ostringstream log; log << " done in " << setw(5) << elapsed << " seconds" << endl; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 0) ++ *options->stdOut << " done in " << setw(5) << elapsed << " seconds" << endl; + + if (options->processPC) { + +- if (options->logLevel >= 0) { ostringstream log; log << "process PC ..."; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 0) ++ *options->stdOut << "process PC ..."; + + clock_t start = clock(), end; + +@@ -91,7 +105,7 @@ int fs_driver::fsDriver::doRun () { + + string current = *it; + +- { ostringstream log; log << endl << "\t" << current << " ..."; *options->stdOut << log.str().c_str(); } ++ *options->stdOut << endl << "\t" << current << " ..."; + + fs_pc::ClusterDriver pc(current, *options); + +@@ -108,7 +122,8 @@ int fs_driver::fsDriver::doRun () { + + end = clock(); + const double elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; +- if (options->logLevel >= 0) { ostringstream log; log << " done in " << setw(5) << elapsed << " seconds" << endl; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 0) ++ *options->stdOut << " done in " << setw(5) << elapsed << " seconds" << endl; + } + + } else { +@@ -118,14 +133,15 @@ int fs_driver::fsDriver::doRun () { + clock_t start = clock(), end; + + if (options->pcFile == "") { +- if (options->logLevel >= 0) { ostringstream log; log << "ERROR: no file for classification specified" << endl; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 0) ++ *options->stdOut << "ERROR: no file for classification specified" << endl; + return 1; + } + +- if (options->logLevel >= 0) { ostringstream log; log << "process PC ..."; *options->stdOut << log.str().c_str(); } +- +- if (options->logLevel >= 0) { ostringstream log; log << endl << "\t" << options->pcFile << " ..."; *options->stdOut << log.str().c_str(); } +- ++ if (options->logLevel >= 0) { ++ *options->stdOut << "process PC ..."; ++ *options->stdOut << endl << "\t" << options->pcFile << " ..."; ++ } + fs_pc::ClusterDriver pc(options->pcFile, *options); + + pc.doClustering(); +@@ -138,7 +154,8 @@ int fs_driver::fsDriver::doRun () { + + end = clock(); + const double elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; +- if (options->logLevel >= 0) { ostringstream log; log << " done in " << setw(5) << elapsed << " seconds" << endl; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 0) ++ *options->stdOut << " done in " << setw(5) << elapsed << " seconds" << endl; + } + + } +@@ -147,18 +164,22 @@ int fs_driver::fsDriver::doRun () { + { + // options->processSP is set + +- if (options->logLevel >= 0) { ostringstream log; log << "process SELECT"; *options->stdOut << log.str().c_str(); } +- if (options->logLevel >= 0) { ostringstream log; log << " (" << options->peakFile << " " << options->peakStr << ") ..."; *options->stdOut << log.str().c_str(); } +- ++ if (options->logLevel >= 0) ++ *options->stdOut << "process SELECT"; ++ if (options->logLevel >= 0) ++ *options->stdOut << " (" << options->peakFile << " " << options->peakStr << ") ..."; ++ + SelectPeak sp; + sp.init(*options); + sp.processFile(options->peakFile); + +- if (options->logLevel >= 0) { ostringstream log; log << " done" << endl; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 0) ++ *options->stdOut << " done" << endl; + + } + +- if (options->logLevel >= 0) { ostringstream log; log << endl << "fs_kit done" << endl << endl << flush; *options->stdOut << log.str().c_str(); } ++ if (options->logLevel >= 0) ++ *options->stdOut << endl << "fs_kit done" << endl << endl << flush; + + return 0; + +diff --git a/src/fs_kit_options.cpp b/src/fs_kit_options.cpp +index 12849df..2f61b26 100644 +--- a/src/fs_kit_options.cpp ++++ b/src/fs_kit_options.cpp +@@ -1,8 +1,11 @@ + #include "fs_kit_options.h" + + #ifdef fs_gui_wxwidgets ++#if wxHAS_TEXT_WINDOW_STREAM == 0 ++#error "Your compiler does not support wxTextCtrl streams" ++#endif + Options::Options(string opt, wxTextCtrl* log) { +- stdOut = log; ++ stdOut = new ostream(log); + InitOptions(opt); + } + #endif +@@ -156,6 +159,7 @@ void Options::defaultOptions() { + logLevel = 1; + + commonFields = 10; ++ + } + + string Options::int2string(int num, int cntr) { +diff --git a/src/fs_kit_options.h b/src/fs_kit_options.h +index f75c555..4fd957f 100644 +--- a/src/fs_kit_options.h ++++ b/src/fs_kit_options.h +@@ -3,8 +3,8 @@ + + #include + #include +-#include + #include ++#include + #include + + #ifdef fs_gui_wxwidgets +@@ -33,12 +33,7 @@ class Options { + + public: + +-// use TextCtrl if running in wxWindows to direct log output +-#ifdef fs_gui_wxwidgets +- wxTextCtrl *stdOut; +-#else +- ostream *stdOut; +-#endif ++ ostream *stdOut; + + static string int2string(int num, int cntr = 0); + +@@ -112,6 +107,7 @@ public: + void printOptions(ostream* out = 0, bool print_all = true, bool print_description = false); + + void setStop(bool stop = true) { stopRequested = stop; } ++ + }; + + #endif +-- +1.5.4.3 + diff --git a/posts/Open_source_force_spectroscopy/0004-Added-wxglade-entry-to-Makefile-for-regenerating-aut.patch b/posts/Open_source_force_spectroscopy/0004-Added-wxglade-entry-to-Makefile-for-regenerating-aut.patch new file mode 100644 index 0000000..0b1bfad --- /dev/null +++ b/posts/Open_source_force_spectroscopy/0004-Added-wxglade-entry-to-Makefile-for-regenerating-aut.patch @@ -0,0 +1,45 @@ +From 6375e1f233b9366ca0ba40fac785764df0a6edb2 Mon Sep 17 00:00:00 2001 +From: W. Trevor King +Date: Tue, 21 Oct 2008 19:57:03 -0400 +Subject: [PATCH] Added wxglade entry to Makefile for regenerating automatic code. + +Also updated Makefile defaults for my Linux installation. +--- + Makefile | 10 +++++++--- + 1 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/Makefile b/Makefile +index ccb2e69..5edf183 100644 +--- a/Makefile ++++ b/Makefile +@@ -13,16 +13,17 @@ + # The following two lines can be determined by running: + + # wx-config --cppflags +-WX_CCFLAGS = -I/sw/lib/wx/include/mac-ansi-release-2.5 -I/sw/include/wx-2.5 -D__WXMAC__ -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -DWX_PRECOMP -DNO_GCC_PRAGMA ++WX_CCFLAGS = -I/usr/lib/wx/include/gtk2-unicode-release-2.8 -I/usr/include/wx-2.8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ + + # wx-config --libs +-WX_LIBS = -L/sw/lib -L/sw/lib -framework QuickTime -framework IOKit -framework Carbon -framework Cocoa -framework System -lwx_mac_xrc-2.5 -lwx_mac_html-2.5 -lwx_mac_adv-2.5 -lwx_mac_core-2.5 -lwx_base_carbon_xml-2.5 -lwx_base_carbon_net-2.5 -lwx_base_carbon-2.5 ++WX_LIBS = -pthread -Wl,-Bsymbolic-functions -lwx_gtk2u_richtext-2.8 -lwx_gtk2u_aui-2.8 -lwx_gtk2u_xrc-2.8 -lwx_gtk2u_qa-2.8 -lwx_gtk2u_html-2.8 -lwx_gtk2u_adv-2.8 -lwx_gtk2u_core-2.8 -lwx_baseu_xml-2.8 -lwx_baseu_net-2.8 -lwx_baseu-2.8 + + # If fs_gui_wxwidgets is set, fs_kit gets compiled with the GUI + WX_FSKITFLAG = -Dfs_gui_wxwidgets + + CC = /usr/bin/gcc +-CC_OPTIONS = -W -Wall -Wno-long-double -I/sw/include $(WX_FSKITFLAG) $(WX_CCFLAGS) ++#CC_OPTIONS = -W -Wall -Wno-long-double -I/sw/include $(WX_FSKITFLAG) $(WX_CCFLAGS) ++CC_OPTIONS = -W -Wall $(WX_FSKITFLAG) $(WX_CCFLAGS) + LNK_OPTIONS = -L/sw/lib -lgsl -lgslcblas -lstdc++ $(WX_LIBS) + + # +@@ -185,3 +186,6 @@ fs_select_tree.o : src/fs_select_tree.cpp + + + ##### END RUN #### ++ ++src/fs_gui_layout.cpp : src/fs_gui.wxg ++ wxglade -g C++ -o src/fs_gui_layout src/fs_gui.wxg +-- +1.5.4.3 + diff --git a/posts/Open_source_force_spectroscopy/fs_kit_tutorial.pdf b/posts/Open_source_force_spectroscopy/fs_kit_tutorial.pdf new file mode 100644 index 0000000..1a8b5b3 Binary files /dev/null and b/posts/Open_source_force_spectroscopy/fs_kit_tutorial.pdf differ