2016-11-27 2 views
0

Я использую gcc как компилятор и gnuplot-iostream.h как поток для комбинирования кода на C++ и функций gnuplot.Как продолжить выполнение кода на C++ после вызова gnuplot?

Что я делаю:

Я пытаюсь сделать подгонку данных через Gnuplot и извлечь конечные параметры подходят из сгенерированного fit.log файла для дальнейшей обработки.

чем проблема:

При выполнении кода, как этот

std::cout << "Starting to fit" << std::endl; 
if (bStartFit == true) 
{ 
    // gp << doing stuf here; 
    std::cout << "Test end" << std::endl; 
} 
std::cout << "Fit is done" << std::endl; 

выход будет:

Starting to fit 
Fit is done 
Test end 
//gnuplot stuff 

Мой вопрос: как заставить код выполнять GNUPLOT вещи точно при необходимости, и после выполнения кода C++. Например:

  • напишите вступительное сообщение;
  • запишите функцию sin (x) (как пример);
  • Подождите, пока gnuplot не будет закрыт;
  • напишите сообщение или сделайте что-нибудь ПОСЛЕ завершения gnuplot.

спасибо, P

EDIT:

std::string filename = "fit.log"; 
    if (bStartFit == true) 
    { 
    // Using Gnuplot for the data fit (command are parsed as the strings): 
    // 1. define the fit function. 
    gp << "f(x) = imfpZP * x**(-b) + c * x**(d) + g * x**(h) \n"; 
    // 2. fit parameters first assumption. 
    gp << "b = 1.1; c = 0.5; d = 1.0; g = 2.0; h = 0.1 \n"; 
    // 3. fit range. 
    gp << "fit [50:10000] f(x) 'agn.iimfp' via b,c,d,g,h \n"; 
    // 4. set the logarithmic scale. 
    gp << "set logscale \n"; 
    // 5. plot the fitted data. 
    gp << "plot 'agn.iimfp' w l lw 2 tit 'orig', f(x) w l lw 2 tit 'fit' \n"; 

    std::cout << "Fit was successful" << std::endl; 
    } 

    // Opening the generated fit.log file to store the fit parameters: 
    std::ifstream inFIT(filename.c_str()); 
    if (inFIT.is_open()) 
    { 
    std::cout << "FIT log is opened" << std::endl; 

    std::string line; 
    int lineCounter = 0; 
    while (std::getline(inFIT, line)) 
    { 
     lineCounter++; 
    } 
    std::cout << "Total lines: " << lineCounter << std::endl; 

    // Getting the five lines with fit parameters from the fit.log: 
    std::fstream& GoToLine(std::fstream& file, unsigned int lineNumber); 
    std::fstream file(filename.c_str()); 


    GoToLine(file, lineCounter - 15); 
    std::string b_Line; 
    std::getline(file, b_Line); 
    std::cout << b_Line << std::endl; 
    std::istringstream sb(b_Line); 
    std::string tempStr; 
    char tempChar; 
    sb >> tempStr >> tempChar >> b 
    // similar code to get another 4 lines 

;

+0

Что значит _ "gnuplot stuff" _ ?? Как вы называете gnuplot? –

+0

Я совсем не уверен, что использование * gnuplot iostream * соответствует вашим потребностям. –

+0

от «gnuplot stuff» Я имею в виду заголовок gnuplot, если я использую команду «fit», я также получу подходящие итерации, и сам сюжет будет последним. –

ответ

0

Это конкретная операционная система. Я предполагаю, что вы на Linux (или, по крайней мере, на какой-то POSIX ОС). Тогда вы действительно должны прочитать Advanced Linux Programming. И использование strace(1) может быть полезно для понимания того, что происходит.

Вы можете использовать popen(3), но вы, вероятно, следует явно использовать system calls (они перечислены в syscalls(2)) как pipe(2), fork(2), dup2(2), execve(2), waitpid(2) и т.д. И очень вероятно, имеют некоторые event loop (например, вокруг poll(2)).

Кстати, вы должны знать, что выход вход buffered, и вы, вероятно, хотите быть уверены, что ваш Gnuplot поток регулярно продували (поэтому используйте std::endl или std::flush соответствующим образом на него). Написание \n не достаточно!Вы, вероятно, следует кодировать по крайней мере

gp << "plot 'agn.iimfp' w l lw 2 tit 'orig', f(x) w l lw 2 tit 'fit' " 
    << std::endl; 

(я заменил некоторые \n внутри строки с явным использованием std::endl)

Я не знаю много о gnuplot stream (я предполагаю, что это немного похоже на некоторые специализированные popen, но с использованием потоков C++), но я предполагаю, что вы должны выполнить команду gnuplot print или printerr, чтобы передать вашей вызывающей программе тот факт, что данная кривая была построена. (Но тогда вам нужен подлинный цикл событий, и вы определяете двунаправленный протокол между gnuplot и вашей программой.).

Возможно, Qt или POCO могут быть релевантными, поскольку они предоставляют некоторое представление о цикле событий и процессах. Возможно, у вас может быть несколько потоков (один управляет gnuplot, а другой для остальных), но у вас есть проблемы с синхронизацией.

(я достаточно не понимаю, что ваша программа должна делать, и как вы закодировали его, так что слепой думает, я чувствую ваш вопрос очень неясен)

Подробнее о Inter-Process Communications.

+0

Эй, я работаю на Linux-машине, это правда, но я бы не хотел использовать системные вызовы, если это возможно. Я новичок в этом gnuplot-iostream и столкнулся с такой проблемой, которую я могу решить, написав две отдельные программы, но сначала я хотел бы выяснить, может быть, есть способ решить ее в рамках одного кода. –

+0

Но ваш вопрос не показывает достаточно кода и до сих пор не ясен. Я считаю, что вы недопонимаете что-то важное. Возможно, проблемы не там, где вы им верите. –

+0

С помощью Qt мне нужно будет написать подходящую функцию самостоятельно. В моей работе мне нужно использовать gnuplot, чтобы получить параметры подстановки и использовать их позже в коде C++ и gnuplot. Итак, это не очень хорошая альтернатива для меня –