Changeset 12943


Ignore:
Timestamp:
Feb 26, 2012, 12:46:47 PM (8 years ago)
Author:
tbretz
Message:
Implemented a root-mode which allows to use mathematical expressions instead of just column names.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/fitsdump.cc

    r12912 r12943  
    7575
    7676    vector<MyColumn> InitColumns(vector<string> list);
     77    vector<MyColumn> InitColumnsRoot(vector<string> &list);
    7778
    7879    double GetDouble(const MyColumn &, size_t) const;
     
    8081    ///Display the selected columns values VS time
    8182    void Dump(ofstream &, const vector<MyColumn> &, const string &, size_t, size_t, const string &);
     83    void DumpRoot(ofstream &, const vector<string> &, const string &, size_t, size_t, const string &);
    8284    void DumpMinMax(ofstream &, const vector<MyColumn> &, size_t, size_t, bool);
    8385    void DumpStats(ofstream &, const vector<MyColumn> &, size_t, size_t);
     
    215217        const string val1  = what[5];
    216218
    217         const uint32_t first = val0.empty() ? 0 : atoi(val0.c_str());
     219        const uint32_t first = atol(val0.c_str());
    218220        const uint32_t last  = (val0.empty() && delim.empty()) ? col.num-1 : (val1.empty() ? first : atoi(val1.c_str()));
    219221
     
    242244        mycol.first = first;
    243245        mycol.last  = last;
     246        mycol.ptr   = SetPtrAddress(name);
    244247
    245248        vec.push_back(mycol);
    246249    }
    247 
    248     for (auto it=vec.begin(); it!=vec.end(); it++)
    249         it->ptr = SetPtrAddress(it->name);
    250250
    251251    return vec;
     
    292292    const fits::Table::Keys &fKeyMap = GetKeys();
    293293
     294#ifdef HAVE_ROOT
    294295    TFormula select;
    295296    if (!filter.empty() && select.Compile(filter.c_str()))
    296297        throw runtime_error("Syntax Error: TFormula::Compile failed for '"+filter+"'");
     298#endif
    297299
    298300    fout << "## --------------------------------------------------------------------------\n";
     
    303305    fout << "## NumRows:   \t" << GetInt("NAXIS2") << '\n';
    304306    fout << "## Comment:   \t" << ((fKeyMap.find("COMMENT") != fKeyMap.end()) ? fKeyMap.find("COMMENT")->second.value : "") << '\n';
     307#ifdef HAVE_ROOT
    305308    if (!filter.empty())
    306309        fout << "## Selection: \t" << select.GetExpFormula() << '\n';
     310#endif
    307311    fout << "## --------------------------------------------------------------------------\n";
    308312    ListKeywords(fout);
     
    323327            fout << "[" << it->first << ":" << it->last << "]";
    324328
    325         fout << ": " << it->col.unit << '\n';
     329        if (!it->col.unit.empty())
     330            fout << ": " << it->col.unit;
     331        fout << '\n';
    326332
    327333        num += it->last-it->first+1;
     
    331337    // -----------------------------------------------------------------
    332338
     339#ifdef HAVE_ROOT
    333340    vector<Double_t> data(num);
     341#endif
    334342
    335343    const size_t last = limit ? first + limit : size_t(-1);
     
    342350
    343351        size_t p = 0;
     352
     353#ifdef HAVE_ROOT
     354        data[p++] = first-1;
     355#endif
    344356
    345357        ostringstream out;
     
    380392                }
    381393
     394#ifdef HAVE_ROOT
    382395                if (!filter.empty())
    383396                    data[p] = GetDouble(*it, i);
     397#endif
    384398            }
    385399
     
    387401                out << "'" << msg << "' ";
    388402        }
    389 
     403#ifdef HAVE_ROOT
    390404        if (!filter.empty() && select.EvalPar(0, data.data())<0.5)
    391405            continue;
    392 
     406#endif
    393407        fout << out.str() << endl;
    394408    }
     409}
     410
     411vector<MyColumn> FitsDumper::InitColumnsRoot(vector<string> &names)
     412{
     413    static const boost::regex expr("[^\\[]([[:word:].]+)(\\[([[:digit:]]+)\\])?");
     414
     415    const fits::Table::Columns &cols = GetColumns();
     416
     417    vector<MyColumn> vec;
     418
     419    for (auto it=names.begin(); it!=names.end(); it++)
     420    {
     421        if (it->empty())
     422            continue;
     423
     424        *it = ' '+*it;
     425
     426        string::const_iterator beg = it->begin();
     427        string::const_iterator end = it->end();
     428
     429        boost::smatch what;
     430        while (boost::regex_search(beg, end, what, expr, boost::match_extra))
     431        {
     432            const string all  = what[0];
     433            const string name = what[1];
     434            const size_t idx  = atol(string(what[3]).c_str());
     435
     436            // Check if found colum is valid
     437            const auto ic = cols.find(name);
     438            if (ic==cols.end())
     439            {
     440                beg++;
     441                //cout << "Column '" << name << "' does not exist." << endl;
     442                //return vector<MyColumn>();
     443                continue;
     444            }
     445            if (idx>=ic->second.num)
     446            {
     447                cout << "Column '" << name << "' has no index " << idx << "." << endl;
     448                return vector<MyColumn>();
     449            }
     450
     451            // find index if column already exists
     452            size_t p = 0;
     453            for (; p<vec.size(); p++)
     454                if (vec[p].name==name)
     455                    break;
     456
     457            ostringstream id;
     458            id << '[' << p << ']';
     459
     460            it->replace(beg-it->begin()+what.position(1), what.length()-1, id.str());
     461
     462            beg = what[0].first+3;
     463            end = it->end();
     464
     465            if (p<vec.size())
     466                continue;
     467
     468            // Column not found, add new column
     469            MyColumn mycol;
     470
     471            mycol.name  = name;
     472            mycol.col   = ic->second;
     473            mycol.first = idx;
     474            mycol.last  = idx;
     475            mycol.ptr   = SetPtrAddress(name);
     476
     477            vec.push_back(mycol);
     478        }
     479    }
     480
     481    ostringstream id;
     482    id << '[' << vec.size() << ']';
     483
     484    for (auto it=names.begin(); it!=names.end(); it++)
     485    {
     486        while (1)
     487        {
     488            auto p = it->find_first_of('#');
     489            if (p==string::npos)
     490                break;
     491
     492            it->replace(p, 1, id.str());
     493        }
     494    }
     495
     496    //cout << endl;
     497    //for (size_t i=0; i<vec.size(); i++)
     498    //    cout << "val[" << i << "] = " << vec[i].name << '[' << vec[i].first << ']' << endl;
     499    //cout << endl;
     500
     501    return vec;
     502}
     503
     504void FitsDumper::DumpRoot(ofstream &fout, const vector<string> &cols, const string &filter, size_t first, size_t limit, const string &filename)
     505{
     506#ifdef HAVE_ROOT
     507    vector<string> names(cols);
     508    names.insert(names.begin(), filter);
     509
     510    const vector<MyColumn> vec = InitColumnsRoot(names);
     511    if (vec.size()==0)
     512        return;
     513
     514    vector<TFormula> form(names.size());
     515
     516    auto ifo = form.begin();
     517    for (auto it=names.begin(); it!=names.end(); it++, ifo++)
     518    {
     519        if (!it->empty() && ifo->Compile(it->c_str()))
     520            throw runtime_error("Syntax Error: TFormula::Compile failed for '"+*it+"'");
     521    }
     522
     523    const fits::Table::Keys &fKeyMap = GetKeys();
     524
     525    fout << "## --------------------------------------------------------------------------\n";
     526    fout << "## Fits file:  \t" << fFilename << '\n';
     527    if (filename!="-")
     528        fout << "## File:      \t" << filename << '\n';
     529    fout << "## Table:     \t" << fKeyMap.find("EXTNAME")->second.value << '\n';
     530    fout << "## NumRows:   \t" << GetInt("NAXIS2") << '\n';
     531    fout << "## Comment:   \t" << ((fKeyMap.find("COMMENT") != fKeyMap.end()) ? fKeyMap.find("COMMENT")->second.value : "") << '\n';
     532    fout << "## --------------------------------------------------------------------------\n";
     533    ListKeywords(fout);
     534    fout << "## --------------------------------------------------------------------------\n";
     535    fout << "##\n";
     536    if (!filter.empty())
     537        fout << "## Selection: " << form[0].GetExpFormula() << "\n##\n";
     538
     539    size_t num = 0;
     540    for (auto it=vec.begin(); it!=vec.end(); it++, num++)
     541    {
     542        fout << "## [" << num << "] = " << it->name;
     543
     544        if (it->first==it->last)
     545        {
     546            if (it->first!=0)
     547                fout << "[" << it->first << "]";
     548        }
     549        else
     550            fout << "[" << it->first << ":" << it->last << "]";
     551
     552        if (!it->col.unit.empty())
     553            fout << ": " << it->col.unit;
     554        fout << '\n';
     555    }
     556    fout << "##\n";
     557    fout << "## --------------------------------------------------------------------------\n";
     558    fout << "#\n";
     559
     560    fout << "# ";
     561    for (auto it=form.begin()+1; it!=form.end(); it++)
     562        fout << " \"" << it->GetExpFormula() << "\"";
     563    fout << "\n#" << endl;
     564
     565    // -----------------------------------------------------------------
     566
     567    vector<Double_t> data(vec.size()+1);
     568
     569    const size_t last = limit ? first + limit : size_t(-1);
     570
     571    while (GetRow(first++))
     572    {
     573        const size_t row = GetRow();
     574        if (row==GetNumRows() || row==last)
     575            break;
     576
     577        //data[p++] = first-1;
     578
     579        ostringstream out;
     580        out.precision(fout.precision());
     581
     582        size_t p = 0;
     583        for (auto it=vec.begin(); it!=vec.end(); it++, p++)
     584            data[p] = GetDouble(*it, it->first);
     585
     586        data[p] = first;
     587
     588        if (!filter.empty() && form[0].EvalPar(0, data.data())<0.5)
     589            continue;
     590
     591        for (auto iform=form.begin()+1; iform!=form.end(); iform++)
     592            out << iform->EvalPar(0, data.data()) << " ";
     593
     594        fout << out.str() << endl;
     595    }
     596#endif
    395597}
    396598
     
    616818    fout.precision(conf.Get<int>("precision"));
    617819
     820    const string filter = conf.Has("filter") ? conf.Get<string>("filter") : "";
     821
     822    const size_t first  = conf.Get<size_t>("first");
     823    const size_t limit  = conf.Get<size_t>("limit");
     824
     825    if (conf.Get<bool>("root"))
     826    {
     827        DumpRoot(fout, conf.Vec<string>("col"), filter, first, limit, filename);
     828        return 0;
     829    }
     830
    618831    const vector<MyColumn> cols = InitColumns(conf.Vec<string>("col"));
    619832    if (cols.size()==0)
    620833        return false;
    621834
    622     const string filter = conf.Has("filter") ? conf.Get<string>("filter") : "";
    623 
    624     const size_t first  = conf.Get<size_t>("first");
    625     const size_t limit  = conf.Get<size_t>("limit");
    626835
    627836    if (conf.Get<bool>("minmax"))
     
    649858        "Usage: fitsdump [OPTIONS] fitsfile col col ... \n"
    650859        "  or:  fitsdump [OPTIONS]\n";
     860
    651861    cout << endl;
    652862}
     
    654864void PrintHelp()
    655865{
    656     //
     866    cout <<
     867        "\n"
     868        "To address a column several syntax is possible:\n"
     869        "  ColumnName:        Will address all fields of a column\n"
     870        "  ColumnName[n]:     Will address the n-th field of a column (starts with 0)\n"
     871        "  ColumnName[n1:n2]: Will address all fields between n1 and including n2\n"
     872#ifdef HAVE_ROOT
     873        "\n"
     874        "To select some columns can use --filter\n"
     875        "Such a selction is evaluated using TFormula, hence, every "
     876        "mathematical operation allowed in TFormula is allowed there, too. "
     877        "The reference is the column index as printed in the output stream, "
     878        "starting with 1. The index 0 is reserved for the row number.\n"
     879        "\n"
     880        "Example:\n"
     881        "  fitsdump Zd --filter=\"[0]>20 && cos([1])*TMath::RadToDeg()<45\"\n"
     882        "\n"
     883        "In --root mode, fitsdump support TFormula's syntax for all columns and the filter "
     884        "You can then refer to a column or a (single) index of the column just by its name "
     885        "If the index is omitted, 0 is assumed\n"
     886        "\n"
     887
     888        "Example:\n"
     889        "  fitsdump \"(Zd+Err)*TMath::DegToRad()\" --filter=\"Num>100 && Num<200\"\n"
     890        "is identical to\n"
     891        "  fitsdump \"(Zd[0]+Err[0])*TMath::DegToRad()\" --filter=\"Num[0]>100 && Num[0]<200\"\n"
     892        "A special placeholder exists for the row number:\n"
     893        "  fitsdump \"#\" --filter=\"#>10 && #<100\"\n"
     894#endif
     895        "\n";
     896    cout << endl;
    657897}
    658898
     
    678918        ("limit",       var<size_t>(size_t(0)),     "Limit for the maximum number of rows to read (0=unlimited)")
    679919#ifdef HAVE_ROOT
     920        ("root,r",      po_switch(),                "Enable root mode")
    680921        ("filter,r",    var<string>(""),            "Filter to restrict the selection of events (e.g. '[0]>10 && [0]<20';  does not work with stat and minmax yet)")
    681922#endif
Note: See TracChangeset for help on using the changeset viewer.