0

前提として、私はプログラマーではなく、物理学者であり、データを分析するためのツールとして c++ を使用しています (ROOT パッケージ)。私の知識は限られているかもしれません!

私はこのような状況にあり、ファイルからデータを読み取り、それらをベクトルに保存します(問題ありません)

vector<double> data;

このデータを使用して相関プロットをプロットしたいので、それらを 2 つの異なるサブセットに分割する必要があります。そのうちの 1 つは 2D ヒストグラムの X エントリになり、もう 1 つは Y エントリになります。

分割は次のようにする必要があります。私はこのテーブルを持っています(問題を説明するために、その一部のみをコピーします)

************* LBA - LBC **************
--------------------------------------
Cell Name  |  Channel   |    PMT     |
D0         |          0 |          1 |
A1-L       |          1 |          2 |
BC1-R      |          2 |          3 |
BC1-L      |          3 |          4 |
A1-R       |          4 |          5 |
A2-L       |          5 |          6 |
BC2-R      |          6 |          7 |
BC2-L      |          7 |          8 |
A2-R       |          8 |          9 |
A3-L       |          9 |         10 |
A3-R       |         10 |         11 |
BC3-L      |         11 |         12 |
BC3-R      |         12 |         13 |
D1-L       |         13 |         14 |
D1-R       |         14 |         15 |
A4-L       |         15 |         16 |
BC4-R      |         16 |         17 |
BC4-L      |         17 |         18 |
A4-R       |         18 |         19 |
A5-L       |         19 |         20 |
...
None       |         31 |         32 |

ご覧のとおり、1 つのセルの左側と右側に対応する と のA1-Lようなエントリがあり、この左側と右側にはチャネル(この場合は 1 と 4) に対応するan が関連付けられています。 2D ヒストグラムの X 軸と Y 軸に配置します。A1-Rint

問題は、同じセルに属するチャネルを選択して、1 つを X 軸に、もう 1 つを Y 軸に配置できるように、このテーブルをデータのベクトルに関連付けることです。事態を複雑にするために、この例のようにパートナーを持たD0ないセルや、チャネル 31 のように関連付けられたセルを持たないチャネルもあります。


私の試みた解決策は、インデックス ベクトルを作成することです。

vector<int> indexing = (0, 1, 4, ....);

および順序付けられたデータ ベクトル

vector<double> data_ordered;

順序付けられたベクトルを次のようなもので埋めます

for( vector<int> iterator it = indexing.begin(); it != indexing.end(); ++it)
    data_ordered.push_back(data.at(*it));

次に、X 軸に偶数インデックスdata_ordered、Y 軸に奇数値を配置しますが、D0セルと空のセルに問題があります。

私が持っていた別のアイデアは、struct好きなものを作成することです

struct cell{
    string cell_name;
    int left_channel;
    int right_channel;
    double data;
    ....
    other informations
};

それを使って作業しようとしましたが、C++ の知識が不足しています。誰かがこの問題を解決する方法についてヒントをくれますか? 私の質問が十分に明確で、このサイトのルールを尊重していることを願っています!

編集 - - - - -

問題を明確にするために、例を挙げて説明しようとしました

vector<double> data = (data0, data1, data2, data3, data4, ...);

dodata0にはインデックス 0 があり、テーブルに移動すると、cell D0他にパートナーがいない に対応していることがわかります。今のところ無視できるとしましょう。data1はインデックス 1 を持ち、cell A1( A1-L) の左側の部分に対応するため、テーブル内のインデックス 4 を持つ適切なパートナーを見つける必要があり、理想的にdata4はデータを含むベクトルから選択するように導きます。これで状況が少しでも明確になることを願っています!

4

1 に答える 1

1

大まかに、あなたが望むことを行うエンジンは次のとおりです。

#include <vector>
#include <map>
#include <string>
#include <iostream>

enum sub_entry { left, right, only };

struct DataType {
  std::string cell;
  sub_entry sub;
  DataType( DataType const& o ): cell(o.cell), sub(o.sub) {};
  DataType( const char* c, sub_entry s=only ):
    cell( c ),
    sub( s )
  {}
  DataType(): cell("UNUSED"), sub(only) {};
  // lexographic weak ordering:
  bool operator<( DataType const& o ) const {
    if (cell != o.cell)
      return cell < o.cell;
    return sub < o.sub;
  }
};

typedef std::vector< double > RawData;
typedef std::vector< DataType > LookupTable;
typedef std::map< DataType, double > OrganizedData;

OrganizedData organize( RawData const& raw, LookupTable const& table )
{
  OrganizedData retval;
  for( unsigned i = 0; i < raw.size() && i < table.size(); ++i ) {
    DataType d = table[i];
    retval[d] = raw[i];
  }
  return retval;
}

void PrintOrganizedData( OrganizedData const& data ) {
  for (OrganizedData::const_iterator it = data.begin(); it != data.end(); ++it ) {
    std::cout << (*it).first.cell;
    switch( (*it).first.sub ) {
      case left: {
        std::cout << "-L";
      } break;
      case right: {
        std::cout << "-R";
      } break;
      case only: {
      } break;
    }
    std::cout << " is " << (*it).second << "\n";
  }
}

int main() {
  RawData test;
  test.push_back(3.14);
  test.push_back(2.8);
  test.push_back(-1);
  LookupTable table;
  table.resize(3);
  table[0] = DataType("A1", left);
  table[1] = "D0";
  table[2] = DataType("A1", right);
  OrganizedData org = organize( test, table );
  PrintOrganizedData( org );
}

ルックアップ テーブルには、どのチャネルがどのセル名とサイドにマップされるかが格納されます。

ルックアップ テーブルの未使用のエントリは に設定する必要があります。DataType()これにより、その値が場所に格納されるようにフラグが立てられ"UNUSED"ます。(保管はされますが、後で破棄できます)。

この結果は、からデータ(CellName, Side)へのマップdoubleです。データをダンプするだけの単純なプリンターを含めました。グラフ作成ソフトを持っていれば、そこからグラフを作成する方法を見つけることができます。スキップは、その印刷ループの"UNUSED"チェックインを伴う演習です。(*it).first.cell == "UNUSED"

すべてが C++03 に準拠していると思います。C++11 コンパイラを使用している場合、上記の一連の処理がより適切になります。

于 2013-06-26T14:27:10.143 に答える