anfänger frage: ascii file einlesen und verarbeiten



  • hi

    also ich bin noch relativ neu im geschäft und versuche grad ein macro zu schreiben mit dem ich einen file einlesen kann in dem in 2 spalten x und y werte drinne stehn, in der regel 20-40 werte. diese will ich dann plotten fitten etc.

    bis jetzt muss ich das arraye mit den x und y werten noch mit hand vorher eintragen, ich würd es gern vom macro selber importieren lassen, hab aber keine idee wie ich es realisieren soll...

    ich paste mal meinen code und einen stück aus einer "import" file, vlt kann mir ja einer hier helfen

    ich benutze das root-macro vom CERN zum späteren fitten usw. das funktioniert auch problemlos...

    {
    gROOT->Reset();
    //Ini_t n = 20;
    
      Double_t x[26] = {-3.9, -3.6, -3.3, -2.7, -2.4, -2.1
                                    -2.8, -2.5, -1.2, -0.9, -0.6, -0.3
                                     0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8
                                      2.1, 2.4, 2.7, 3.0 3.3, 3.6, 3.9 };
    
      Double_t y[26] = {0.2832, 0.12966, 0.147, 0.153, 0.1586, 0.111
                        0.0886, 0.055, 0.0393, 0.0263, 0.0223, 0.0143
                        0.009, 0.0113, 0.0123, 0.012, 0.01 0.015 
                        0.025, 0.035, 0.042, 0.0586, 0.0546, 0.0376 0.0493, 0.0596};
    
    TGraph *gr = new TGraph(26,x,y);
    TCanvas *c1 = new TCanvas("c1","Graph Draw Options",200,10,600,400);
    gr->SetFillColor(40);
    gr->Draw("AB*");
    
    Double_t par[6];
    g1 = new TF1("g1","gaus",-4.5,-2.5);
    g2 = new TF1("g2","expo",3.0,7.0);
    total = new TF1("total","gaus(0)+expo(3)",0.6,9.0);
    total->SetLineColor(2);
    gr->Fit(g1,"R");
    gr->Fit(g2,"R+");
    g1->GetParameters(&par[0]);
    g2->GetParameters(&par[3]);
    total->SetParameters(par);
    gr->Fit(total,"R+");
    
    }
    

    hier mal einen kleinen auszug aus einer import-file

    -4 0.22
    -3.9 0.22
    -3.8 0.14
    -3.7 0.14
    -3.6 0.19
    -3.5 0.25
    -3.4 0.23
    -3.3 0.2
    -3.2 0.18
    -3.1 0.18
    -3 0.11
    -2.9 0.24
    -2.8 0.18
    -2.7 0.19
    -2.6 0.11
    -2.5 0.16
    -2.4 0.06
    -2.3 0.05
    -2.2 0.12
    -2.1 0.05
    -2 0.07
    -1.9 0.05



  • quant schrieb:

    ...macro...

    *schubber*

    Sorry - hat nix mit dem Thema zu tun.

    @Topic: Schau mal in den FAQ (oder einem C++-Buch/-Tutorial Deiner Wahl) unter "Streams". Da findest Du alles, was Du brauchst.

    irgendwie so:

    ifstream in("MeineDatei.txt");
       double d;
       in >> d;
    

    (Header, Fehlerbehandlung, ... habe ich erstmal weggelassen).

    Gruß,

    Simon2.



  • Das Einlesen ist verflucht einfach, wirst dich wundern 😉
    Erst einmal brauchst du natürlich die Strukturen, in die die Werte eingelesen werden sollen. Etwa so:

    struct Point
    {
        double x, y;
    };
    vector<Point> points; // Ein Array der Punkte, kann leicht vergrößert werden
    

    Zum einlesen der Datei deklarierst du dir eine Variable ifstream, mit ihr öffnest du die Datei (klick. Du deklarierst dir eine Variable vom Typ Point und liest in einer Schleife jeweils den x- und y-Wert ein und fügst den Punkt dem Array hinzu. Fertisch..



  • huhu also ich bin nun soweit aber irgendwas geht noch schief ^^ vlt wisst ihr ja rat, hab erst mal alles auskommentiert was nich wichtig ist atm

    //#include <fstream>
    
    {
    gROOT->Reset();
    //Ini_t n = 20;
    
    Double_t x[26], y[26];
    
    	ifstream myFile;
    	myFile.open ("14.dat");  //liegt im selben folder
    	myFile >> x >> y;
    	myFile.close();
    
    if (!myFile.eof())
    {
    cout << "x-wert: "<< x << "    "<< "y-wert: " << y << endl;
    
    //  Double_t x[26] = {-3.9, -3.6, -3.3, -2.7, -2.4, -2.1
    //		    -2.8, -2.5, -1.2, -0.9, -0.6, -0.3
    //		    0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8
    //                    2.1, 2.4, 2.7, 3.0 3.3, 3.6, 3.9 };
    
    //  Double_t y[26] = {0.2832, 0.12966, 0.147, 0.153, 0.1586, 0.111
    //                    0.0886, 0.055, 0.0393, 0.0263, 0.0223, 0.0143
    //                    0.009, 0.0113, 0.0123, 0.012, 0.01 0.015 
    //                    0.025, 0.035, 0.042, 0.0586, 0.0546, 0.0376 0.0493, 0.0596};
    
    TGraph *gr = new TGraph(26,x,y);
    TCanvas *c1 = new TCanvas("c1","Graph Draw Options",200,10,600,400);
    gr->SetFillColor(40);
    gr->Draw("AB*");
    
    //Double_t par[6];
    //g1 = new TF1("g1","gaus",-4.5,-2.5);
    //g2 = new TF1("g2","expo",3.0,7.0);
    //total = new TF1("total","gaus(0)+expo(3)",0.6,9.0);
    //total->SetLineColor(2);
    //gr->Fit(g1,"R");
    //gr->Fit(g2,"R+");
    //g1->GetParameters(&par[0]);
    //g2->GetParameters(&par[3]);
    //total->SetParameters(par);
    //gr->Fit(total,"R+");
    }
    }
    

    er ließt die werte irgendwie komisch ein und ich bekomme eine komische ausgabe in der shell:

    root [6] .x n.C
    x-wert: 0x17617e0 y-wert: 0x1601060
    Warning in TCanvas::ResizePad: c1 width changed from 64000 to 10

    Warning in TCanvas::ResizePad: c1 height changed from 64000 to 10

    Error in TGaxis::PaintAxis: length of axis is 0
    Error in TGaxis::PaintAxis: length of axis is 0
    root [7] Warning in TCanvas::ResizePad: c1 width changed from 64000 to 10

    Warning in TCanvas::ResizePad: c1 height changed from 64000 to 10



  • Es gibt keine Eingabe-Operatoren für Arrays, da mußt du schon die Elemente einzeln einlesen:

    Double_t x[26],y[26];
    for(int i=0;i<26;++i)
      myFile>>x[i]>>y[i];
    

    (btw, es ist erstaunlich, daß dein Programm durch den Compiler gekommen ist)



  • ich danke vielmals funktioniert nun alles, zur vollständigkeit hänge ich den code mal an

    //#include <fstream>
    
    {
    gROOT->Reset();
    
    Double_t x[88], y[88];
    
    	ifstream myFile;
    	myFile.open ("14.dat");  //liegt im selben folder
    
    		if (!myFile)
     		   {
          		   cout << "Fehler beim Oeffnen der Datei!\n";
           		   exit(1);
                       }
    
    	for(int i=0;i<88;++i)
            myFile>>x[i]>>y[i];
    
    	myFile.close();
    
    if (!myFile.eof())
    {
    for (int i=0;i<88;i++)
    cout << "x-wert: "<< x[i] << "    "<< "y-wert: " << y[i] << endl;
    
    TGraph *gr = new TGraph(88,x,y);
    TCanvas *c1 = new TCanvas("c1","Graph Draw Options",400,20,600,400);
    gr->SetFillColor(40);
    gr->Draw("AB*");
    
    }
    }
    


  • quant schrieb:

    ich danke vielmals funktioniert nun alles, zur vollständigkeit hänge ich den code mal an

    Hallo quant,

    Normalerweise sollte man so ein Format wie folgt einlesen.

    #include <fstream>
    #include <iostream>
    #include <iterator> // istream_iterator<>
    #include <vector>
    
    typedef double Double_t;
    struct XY
    {
        Double_t m_x, m_y;
    };
    std::istream& operator>>( std::istream& in, XY& xy )
    {
        return in >> xy.m_x >> xy.m_y;
    }
    
    int main()
    {
        using namespace std;
        // --   Einlesen
        ifstream myfile( "14.dat" );
        vector< XY > xy( (istream_iterator< XY >( myfile )), istream_iterator< XY >() );
        // jetzt ist alles in 'xy'
    

    aber da Du die Koordinaten in einzelnen Feldern benötigst, kannst Du sie dann auch gleich in der Form einlesen. Also:

    #include <fstream>
    #include <iostream>
    #include <vector>
    
    typedef double Double_t;
    
    int main()
    {
        using namespace std;
        // --   Einlesen
        ifstream myfile( "14.dat" );
        vector< Double_t > x;
        vector< Double_t > y;
        for( double xx, yy; myfile >> xx >> yy; )
        {
            x.push_back( xx );
            y.push_back( yy );
        }
    
        // --   und benutzen
        TGraph *gr = new TGraph( x.size(), &x[0], &y[0] ); 
        // usw.
    

    Bem.: Koordinaten in dieser Form - also einzeln - abzulegen ist übrigens schlechter Stil, weil ziemlich unhandlich. Wo kommt denn das TGraph&Co her?

    Gruß
    Werner



  • Tgraph und co sind fuctionen aus dem root tool vom CERN ist eine wissenschaftliche erweiterung für c oder wie man das genau nennt, kenne mich mit all dem noch nich so aus, code erst seit 4tagen ^^

    hab dir die page mal gelinkt

    http://root.cern.ch/

    lg

    edit:

    ich hab grad versucht es mal umzuschreiben, bekomme jetzt aber einen fehler:

    #include <fstream>
    #include <iostream>
    #include <vector>
    
    typedef double Double_t;
    gROOT->Reset();
    
    int main()
    {
        using namespace std;
        // --   Einlesen
        ifstream myfile( "14.dat" );
        vector< Double_t > x;
        vector< Double_t > y;
        for( double xx, yy; myfile >> xx >> yy; )
        {
            x.push_back( xx );
            y.push_back( yy );
        }
    
    TGraph *gr = new TGraph( x.size(), &x[0], &y[0] );
    TCanvas *c1 = new TCanvas("c1","Graph Draw Options",400,20,600,400);
    gr->SetFillColor(40);
    gr->Draw("AB*");
    
    //Double_t par[6];
    g1 = new TF1("g1","gausn",-4.0,-0.0);
    //g2 = new TF1("g2","expo",3.0,7.0);
    //total = new TF1("total","gaus(0)+expo(3)",0.6,9.0);
    //total->SetLineColor(2);
    gr->Fit(g1,"R");
    //gr->Fit(g2,"R+");
    //g1->GetParameters(&par[0]);
    //g2->GetParameters(&par[3]);
    //total->SetParameters(par);
    //gr->Fit(total,"R+");
    }
    

    root [18] .x fit.C
    Error: x already declared as different type. ~vector<double,allocator<double> >( ) called
    fit.C:11:
    *** Interpreter error recovered ***



  • quant schrieb:

    ich hab grad versucht es mal umzuschreiben, bekomme jetzt aber einen fehler:
    root [18] .x fit.C

    Error: x already declared as different type. ~vector<double,allocator<double> >( ) called
    fit.C:11:
    *** Interpreter error recovered ***

    Ist das wirklich in dieser Zeile:

    x.push_back( xx );
    

    ?

    Was für einen Compiler benutzt Du? Das 'Interpreter' verwirrt mich etwas ...

    Edit: lass mal das 'typedef double Double_t' weg; das war nur für mein Testprogramm!

    Gruß
    Werner



  • hi

    also ich use den standart linux compiler g++ und bin in der root-console vom root-tool ... habs nochma geändert und gestartet...

    #include <fstream>
    #include <iostream>
    #include <vector>
    
    gROOT->Reset();
    
    {
        using namespace std;
        // --   Einlesen
        ifstream myfile( "14.dat" );
        vector< Double_t > x;
        vector< Double_t > y;
        for( double xx, yy; myfile >> xx >> yy; )
        {
            x.push_back( xx );
            y.push_back( yy );
        }
    
    TGraph *gr = new TGraph( x.size(), &x[0], &y[0] );
    TCanvas *c1 = new TCanvas("c1","Graph Draw Options",400,20,600,400);
    gr->SetFillColor(40);
    gr->Draw("AB*");
    
    //Double_t par[6];
    g1 = new TF1("g1","gausn",-4.0,0.0);
    //g2 = new TF1("g2","expo",3.0,7.0);
    //total = new TF1("total","gaus(0)+expo(3)",0.6,9.0);
    //total->SetLineColor(2);
    gr->Fit(g1,"R");
    //gr->Fit(g2,"R+");
    //g1->GetParameters(&par[0]);
    //g2->GetParameters(&par[3]);
    //total->SetParameters(par);
    //gr->Fit(total,"R+");
    }
    

    bekomme nun eine andere meldung:

    root [6] .x fit.C
    Warning: Unknown type 'yy;' in function argument handled as int fit.C:13:

    *** Break *** segmentation violation
    Using host libthread_db library "/lib/libthread_db.so.1".
    Attaching to program: /proc/8274/exe, process 8274
    [Thread debugging using libthread_db enabled]
    [New Thread 47433660509808 (LWP 8274)]
    0x00002b24022d1af5 in waitpid () from /lib/libc.so.6
    error detected on stdin
    The program is running. Quit anyway (and detach it)? (y or n) [answered Y; input not from terminal]
    Detaching from program: /proc/8274/exe, process 8274
    Root >



  • EDIT: Inzwischen hast Du einen neuene Fehler gepostet. Dies hier bezieht sich auf "die Fehlermeldung mit x" (aber kann es sein, dass Du bei y/yy wieder einen Tippfehler hast ?):

    Ich wette ja, dass Du entweder irgendwo ein 'x' vergessen (z.B. statt "double xx" nur "double x" ) oder tatsächlich schon eine (vielleicht globale oder per #include importierte) Variable names "x" hast.

    Spaßeshelber kannst Du ja mal Deinen Vector umbenennen, also statt

    quant schrieb:

    ....

    vector< double > x;
    

    dann ein

    vector< double > xVec;
    

    Ach ja: Eine for-Schleife ist nicht unbedingt die Methode der Wahl für das, was Du vorhast. Da hätte ich ein while() genommen.

    Gruß,

    Simon2.



  • hmm ich muss gestehen ich bin mit der frage grad überfordert aber einen syntax-fehler finde ich auch nicht...

    naja jedenfalls läuft es ja mit dem anderen code... was ich jetzt noch gerne machen würde ist meine gaus-gefittete fkt. integrieren, nur weiss ich grad garnich wie ich das anstellen soll ^^

    hier mal meinen code wie weit er atm ist:

    //#include <fstream>
    
    {
    gROOT->Reset();
    gStyle->SetOptFit();
    
    Double_t x[88], y[88];
    
        ifstream myFile;
        myFile.open ("14.dat");  //liegt im selben folder
    
            if (!myFile)
     	    {
          	    cout << "Fehler beim Oeffnen der Datei!\n";
           	    exit(1);
                }
    
    	       for(int i=0;i<88;++i)
                   myFile>>x[i]>>y[i];
    
        myFile.close();
        if (!myFile.eof())
    
    {
    
    for (int i=0;i<88;i++)
    cout << "x-wert: "<< x[i] << "    "<< "y-wert: " << y[i] << endl;
    
    TGraph *gr = new TGraph(88,x,y);
    TCanvas *c1 = new TCanvas("c1","Graph Draw Options",400,20,600,400);
    gr->SetFillColor(40);
    gr->Draw("AB*");
    gr->GetXaxis()->SetTitle("Rapidity");
    gr->GetYaxis()->SetTitle("N(i) / DELTA Y");
    gr->GetXaxis()->CenterTitle();
    gr->GetYaxis()->CenterTitle();
    
    g1 = new TF1("g1","gausn",-4.0,-0.0);
    
    gr->Fit(g1,"R");
    
    gSystem->ProcessEvents();
    TImage *img = TImage::Create();
    img->FromPad(c1);
    img->WriteImage("canvas.png");
    
    }
    }
    

Anmelden zum Antworten