1 #include "domaintype.h"
4 domainType::~domainType() {}
6 // конструктор класса для инициализации
7 domainType::domainType() {}
9 // конструктор класса для полноценной инициализации данных
10 domainType::domainType(const std::vector< size_t > &index, const std::vector< RVec > &reference,
11 const int windowSize, const int domainMinimumSize,
12 const int domainSearchAlgorythm, const int timeStepBetweenWindowStarts,
13 const unsigned int sliceNum, const double epsilon, const double delta,
14 const std::string outPutFileName) {
15 setDefaults(index, reference, windowSize, domainMinimumSize, domainSearchAlgorythm, timeStepBetweenWindowStarts, sliceNum, epsilon, delta, outPutFileName);
18 // set numeric values to "-1" / string value to "" - if you want default settings
19 // функция заполнения необходимыми данными для вычисления структурных доменов
20 void domainType::setDefaults(const std::vector< size_t > &index, const std::vector< RVec > &reference,
21 const int windowSize, const int domainMinimumSize,
22 const int domainSearchAlgorythm, const int timeStepBetweenWindows,
23 const unsigned int sliceNum, const double epsilon, const double delta,
24 const std::string outPutFileName) {
27 refTable.resize(reference.size());
28 for (size_t i {0}; i < reference.size(); i++) {
29 refTable[i].resize(0);
30 for (size_t j {0}; j < reference.size(); j++) {
31 refTable[i].push_back(reference[i] - reference[j]);
34 // слава шиве, слава индусам... зачем столько ифов?
35 if (epsilon != -1) { eps = epsilon; }
36 if (delta != -1) { dlt = delta; }
37 if (windowSize != -1) { window = windowSize; }
38 if (domainMinimumSize != -1) { dms = domainMinimumSize; }
39 if (domainSearchAlgorythm != -1) { dsa = domainSearchAlgorythm; }
40 if (timeStepBetweenWindows != -1) { ts = timeStepBetweenWindows; }
41 if (outPutFileName != "") { outPut = outPutFileName; }
43 domsizes.resize(sliceNum);
47 // фукнция обновления данных для выделения структурных доменов
48 void domainType::update(const std::vector< std::vector< RVec > > &frame, const int frameNumber) {
49 // громакс считает с нуля, проверял; инициализируем новое "окно"
50 if (frameNumber % ts == 0) {
51 graph.resize(graph.size() + 1);
52 graph.back().resize(structIndex.size() - static_cast< size_t >(dms) + 1);
53 for (auto &i : graph.back()) {
57 // заполняем структуру данных для структурных доменов
58 for (auto &i : graph) {
59 #pragma omp parallel for
60 for (size_t j = 0; j < i.size(); j++) {
61 for (size_t k1 {0}; k1 < i[j].size(); k1++) {
62 for (size_t k2 {k1}; k2 < i[j].size(); k2++) {
63 if ((frame[j][k1] - frame[j][k2] - refTable[k1][k2]).norm() <= static_cast< float >(eps)) {
76 // считаем число эффективных обновлений
77 if (graph.size() > 0) {
80 // в случае, если число обновлений равно размеру окна, выделяем на нём домены
81 if (updateCount == window) {
87 // инициализация матриц соотношений в структуре
88 void domainType::setGraph(std::vector< std::vector< node > > &smallGraph) {
90 smallGraph.resize(refTable.size());
91 for (size_t i {0}; i < refTable.size(); i++) {
92 smallGraph[i].resize(0);
93 smallGraph[i].resize(refTable.size());
94 for (size_t j {0}; j < refTable.size(); j++) {
95 smallGraph[i][j].num = 0;
96 smallGraph[i][j].check = false;
101 // "зануление" элементов матриц вошедших в домен
102 void domainType::deleteDomainFromGraph(const std::vector< size_t > &domain) {
103 for (auto &i : graph.front()) {
104 for (const auto &j : domain) {
105 for (size_t k {0}; k < i.size(); k++) {
106 i[j][k].check = false;
107 i[k][j].check = false;
113 // подсчёт размеров всех потенциально возможных доменов и проверка на наличие домена для выделения
114 bool domainType::searchDomainSizes() {
116 for (size_t i {0}; i < graph.front().size(); i++) {
117 domsizes[i].resize(0); // необходимо переопределять память
118 domsizes[i].resize(graph.front()[i].size(), 0);
119 for (size_t j {0}; j < graph.front()[i].size(); j++) {
120 for (const auto &k : graph.front()[i][j]) {
125 if ((!flag) && (domsizes[i][j] >= dms)) {
133 // функция выделения доменов
134 void domainType::getDomains() {
135 // проверка элементов матриц на создание на их основе доменов
136 for (auto &i : graph.front()) {
137 for (auto &j : i) { // -> матрица соотношений в структуре всё на всё
138 for (auto &k : j) { // -> матрица соотношений в структуре всё на всё
139 if (k.num >= window * dlt) {
146 // итеративное выделение доменов одним из двух(пока что) способов
147 // в случае если цикл запустился, то гарантированно имеется домен для выделения
148 while (searchDomainSizes()) {
149 size_t t1 {0}, t2 {0};
150 for (size_t i {0}; i < domsizes.size(); i++) {
151 for (size_t j {0}; j < domsizes[i].size(); j++) {
152 if ((dsa == 0) && (domsizes[i][j] > domsizes[t1][t2])) {
153 // из-за физических ограничений по памяти в общем случае нельзя хранить всю подноготную данных на
154 // основе которых было полученно "вхождение" атомов в домен, потому мы только знаем, что размер
155 // совпадает, а сказать который из двух стабильнее нельзя, либо нужно придумать что-то новое
159 if ((dsa == 2) && ((domsizes[i][j] < domsizes[t1][t2]) || ((domsizes[i][j] >= dms) && (domsizes[t1][t2] < dms)))) {
165 // выделяем найдённый домен
166 domains.resize(domains.size() + 1);
167 for (size_t i {0}; i < graph.front()[t1][t2].size(); i++) {
168 if (graph.front()[t1][t2][i].check) {
169 domains.back().push_back(i);
172 //выход из поиска доменов при данном режиме обработки
176 // удаляем его из матриц
177 deleteDomainFromGraph(domains.back());
179 // удаляем рассматриваемое окно из вектора
180 graph.erase(graph.begin());
181 // смещаем счётчик обновлений для следующего окна, std::max для случая если окна не пересекаются
182 updateCount = std::max(0, window - ts);
185 // функция печати ndx и selectionList файлов
186 void domainType::print(int currentFrame) {
187 if (domains.size() == 0) {
190 FILE *ndxFile {std::fopen(outPut.c_str(), "a+")}, *slFile {std::fopen(("selectionList-" + outPut.substr(0, outPut.size() - 4)).c_str(), "a+")};
191 short int writeCount {0};
192 for (size_t i {0}; i < domains.size(); i++) {
193 // domain - стартовая позиция в фреймах - номер домена - минимальный размер домена -
194 // константа тепловых колебаний (отклонения) - константа входимости (отклонения)
195 std::fprintf(ndxFile, "[domain-stPos-%06d-num-%03lu-dms-%03d-epsi-%04.3f-delta-%04.3f]\n", currentFrame - window + 1, i + 1, dms, eps, dlt);
196 std::fprintf(slFile, "group %cdomain-stPos-%06d-num-%03lu-dms-%03d-epsi-%04.3f-delta-%04.3f%c;\n", '"', currentFrame - window + 1, i + 1, dms, eps, dlt, '"');
199 for (size_t j {0}; j < domains[i].size(); j++) {
201 if (writeCount > 20) {
203 std::fprintf(ndxFile, "\n");
205 std::fprintf(ndxFile, "%5lu ", structIndex[domains[i][j]] + 1);
206 std::printf("%5lu ", structIndex[domains[i][j]] + 1);
208 std::fprintf(ndxFile,"\n\n");
211 std::fprintf(ndxFile,"\n");
212 std::fclose(ndxFile);