2013-06-26 3 views
0

Помещение, я не программист, я физик, и я использую C++ в качестве инструмента для анализа данных (ROOT-пакет). Мое знание может быть ограничено!Разбиение вектора по таблице

Я не эта ситуацию, я читать данные из файла и сохранять их в векторе (никаких проблем с этим)

vector<double> data; 

с этими данными я хочу построить корреляционный сюжет, так что мне нужно разделить их в двух разных подмножествах, одна из которых будет X-элементами двумерной гистограммы, а другая - 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 | 

, как вы можете видеть, что есть записи, как A1-L и A1-R, что соответствует слева и справа от одной ячейки , с этой левой и правой стороны связаны int, которые соответствуют каналу , в этом случае 1 и 4. Я хочу, чтобы эти левая и правая стороны были на X и Ось Y моей двумерной гистограммы.

Проблема заключается в том, чтобы связать вектор данных так или иначе этой таблицы, чтобы я мог выбрать каналы, принадлежащие одной и той же ячейке, и поместить их один на ось X, а другой - на ось 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)); 

, а затем положить даже индекс data_ordered на оси X и нечетных значений по оси Y, но у меня есть проблема D0 ячейки и пустые!

Другая идея, что я должен был это создать struct как

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

, а затем попытаться работать с этим, но там речь идет мое отсутствие с ++ знаний! Может ли кто-нибудь дать мне подсказку о том, как решить эту проблему? Надеюсь, что мой вопрос достаточно ясен и что он соблюдает правила этого сайта!

EDIT ----------

Чтобы прояснить эту проблему, я пытаюсь объяснить это на примере

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

сделать data0 имеет индекс 0, и если я иду к столу Я вижу, что это соответствует cell D0, у которого нет другого партнера, и, допустим, на данный момент можно пренебречь.data1 имеет индекс 1 и соответствует левой части cell A1 (A1-L), поэтому мне нужно найти нужного партнера, который имеет индекс 4 в таблице, и в идеале приводит меня к выбору data4 из вектора, содержащего данные. Надеюсь, это прояснит ситуацию хотя бы немного!

+2

Что делает «PMT» эта проблема? В ваших исходных 'vector'' data', как этот порядок элементов относится к таблице, которую вы опубликовали? Является ли «Канал» индексом в исходный «вектор данных» для заданного поля? В вашем * final * output (nevermind intermediate stuff), что вы хотите сделать с данными для 'D0'? Не отображается? Вам нужно или нужно имя ячейки для вашего окончательного вывода? Помимо того факта, что ваша таблица упорядочена по «Каналу», имеет ли значение эта таблица значение для показа? Какую программу вы используете для компиляции и какую версию? – Yakk

+0

было бы неплохо увидеть исходные данные в векторе и то, как оно соответствует таблице. I.e - первая запись в векторе [0] = D001? и вы должны разделить их и т. д.? – SD1990

+0

Итак, что делать * с теми непарными и пустыми ячейками? –

ответ

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.

+0

Хорошо, я вижу некоторые вещи, которые я не понимаю, что такое DataType(): .... {}; синтаксис? (извините за мое невежество! Я пытаюсь учиться), можете ли вы указать мне где-нибудь, что я могу прочитать об этом? Большое спасибо за усилия! Я сейчас приму ответ и попытаюсь научиться его формировать! – drkg4b

+0

@ drkg4b, который является конструктором. C++ позволяет создавать типы, которые ведут себя как встроенные типы. В этом случае 'DataType' может быть сконструирован либо из строки, либо из строки и перечисления. Он поддерживает 'operator <', что позволяет нам сортировать его и хранить его как ключ к 'std :: map'. Я использовал std :: map для хранения результатов, что означает, что элементы слева/справа будут сгруппированы рядом друг с другом в нем - и с этим 'enum' вы получаете возможность наличия« одиночных »элементов также. – Yakk

+0

Удивительно! Спасибо, мне очень нужно научиться использовать эту структуру! – drkg4b