1 #ifndef bstm_ingest_boxm2_scene_function_hxx_
2 #define bstm_ingest_boxm2_scene_function_hxx_
3
4 #include "bstm_ingest_boxm2_scene_function.h"
5
6 //#define ALPHA_SCALING
7 #define DEBUG
8
9 template <bstm_data_type APM_TYPE, boxm2_data_type BOXM2_APM_TYPE>
10 bstm_ingest_boxm2_scene_function<APM_TYPE, BOXM2_APM_TYPE>::
bstm_ingest_boxm2_scene_function(bstm_block * blk,bstm_time_block * blk_t,std::map<std::string,bstm_data_base * > & datas,boxm2_block * boxm2_blk,std::map<std::string,boxm2_data_base * > & boxm2_datas,double local_time,double p_threshold,double app_threshold)11 bstm_ingest_boxm2_scene_function(
12 bstm_block *blk,
13 bstm_time_block *blk_t,
14 std::map<std::string, bstm_data_base *> &datas,
15 boxm2_block *boxm2_blk,
16 std::map<std::string, boxm2_data_base *> &boxm2_datas,
17 double local_time,
18 double p_threshold,
19 double app_threshold) {
20 p_threshold_ = p_threshold;
21 app_threshold_ = app_threshold;
22
23 init_data(blk, blk_t, datas, boxm2_blk, boxm2_datas, local_time);
24 conform();
25 ingest();
26 }
27
28 template <bstm_data_type APM_TYPE, boxm2_data_type BOXM2_APM_TYPE>
init_data(bstm_block * blk,bstm_time_block * blk_t,std::map<std::string,bstm_data_base * > & datas,boxm2_block * boxm2_blk,std::map<std::string,boxm2_data_base * > & boxm2_datas,double local_time)29 bool bstm_ingest_boxm2_scene_function<APM_TYPE, BOXM2_APM_TYPE>::init_data(
30 bstm_block *blk,
31 bstm_time_block *blk_t,
32 std::map<std::string, bstm_data_base *> &datas,
33 boxm2_block *boxm2_blk,
34 std::map<std::string, boxm2_data_base *> &boxm2_datas,
35 double local_time) {
36 local_time_ = local_time;
37
38 // store block and pointer to uchar16 3d block
39 blk_ = blk;
40 blk_t_ = blk_t;
41 boxm2_blk_ = boxm2_blk;
42
43 // store data buffers
44 for (std::map<std::string, bstm_data_base *>::const_iterator iter =
45 datas.begin();
46 iter != datas.end();
47 iter++) {
48 if (iter->first == bstm_data_traits<BSTM_ALPHA>::prefix("")) { // if alpha,
49 alpha_ =
50 (bstm_data_traits<BSTM_ALPHA>::datatype *)iter->second->data_buffer();
51 } else { // if app model
52 apm_model_ = (typename bstm_data_traits<APM_TYPE>::datatype *)
53 iter->second->data_buffer();
54 }
55 }
56
57 // get boxm2 data buffers
58 for (std::map<std::string, boxm2_data_base *>::const_iterator iter =
59 boxm2_datas.begin();
60 iter != boxm2_datas.end();
61 iter++) {
62 if (iter->first == boxm2_data_traits<BOXM2_ALPHA>::prefix("")) // if alpha,
63 boxm2_alpha_ = (boxm2_data_traits<BOXM2_ALPHA>::datatype *)
64 iter->second->data_buffer();
65 else // if app model
66 boxm2_apm_model_ =
67 (typename boxm2_data_traits<BOXM2_APM_TYPE>::datatype *)
68 iter->second->data_buffer();
69 }
70
71 // block max level
72 max_level_ = blk_->max_level();
73 max_level_t_ = blk_t_->max_level();
74
75 // length of one side of a sub block
76 block_len_ = blk->sub_block_dim().x();
77
78 // number of time trees
79 sub_block_num_t_ = blk_t_->sub_block_num();
80
81 // USE rootlevel to determine MAX_INNER and MAX_CELLS
82 if (max_level_t_ == 1) {
83 std::cout << "Trying to refine scene with max level 1" << std::endl;
84 return true;
85 } else if (max_level_t_ == 2) {
86 MAX_INNER_CELLS_T_ = 1, MAX_CELLS_T_ = 3;
87 } else if (max_level_t_ == 3) {
88 MAX_INNER_CELLS_T_ = 3, MAX_CELLS_T_ = 7;
89 } else if (max_level_t_ == 4) {
90 MAX_INNER_CELLS_T_ = 7, MAX_CELLS_T_ = 15;
91 } else if (max_level_t_ == 5) {
92 MAX_INNER_CELLS_T_ = 15, MAX_CELLS_T_ = 31;
93 } else if (max_level_t_ == 6) {
94 MAX_INNER_CELLS_T_ = 31, MAX_CELLS_T_ = 63;
95 } else
96 std::cerr << "ERROR! No max_level_t_\n";
97
98 // USE rootlevel to determine MAX_INNER and MAX_CELLS
99 if (max_level_ == 1) {
100 std::cout << "Trying to refine scene with max level 1" << std::endl;
101 return true;
102 } else if (max_level_ == 2) {
103 MAX_INNER_CELLS_ = 1, MAX_CELLS_ = 9;
104 } else if (max_level_ == 3) {
105 MAX_INNER_CELLS_ = 9, MAX_CELLS_ = 73;
106 } else if (max_level_ == 4) {
107 MAX_INNER_CELLS_ = 73, MAX_CELLS_ = 585;
108 } else
109 std::cerr << "ERROR! No max_level_\n";
110
111 // for debugging
112 num_split_ = 0;
113
114 return true;
115 }
116
117 template <bstm_data_type APM_TYPE, boxm2_data_type BOXM2_APM_TYPE>
conform()118 bool bstm_ingest_boxm2_scene_function<APM_TYPE, BOXM2_APM_TYPE>::conform() {
119 boxm2_array_3d<uchar16> &trees = blk_->trees();
120 boxm2_array_3d<uchar16> boxm2_trees = boxm2_blk_->trees_copy();
121 uchar16 *trees_copy = new uchar16[trees.size()]; // copy of those trees
122 int *dataIndex = new int[trees.size()]; // data index for each new tree
123 int currIndex = 0; // curr tree being looked at
124 int dataSize = 0; // running sum of data size
125
126 // 1. loop over each tree, refine it in place
127 boxm2_array_3d<uchar16>::iterator blk_iter;
128 boxm2_array_3d<uchar16>::const_iterator boxm2_blk_iter;
129 for (blk_iter = trees.begin(), boxm2_blk_iter = boxm2_trees.begin();
130 blk_iter != trees.end();
131 ++blk_iter, ++boxm2_blk_iter, ++currIndex) {
132 // 0. store data index for eahc tree.
133 dataIndex[currIndex] = dataSize;
134
135 // 1. get current tree information
136 uchar16 tree = (*blk_iter);
137 boct_bit_tree curr_tree((unsigned char *)tree.data_block(), max_level_);
138
139 uchar16 boxm2_tree = (*boxm2_blk_iter);
140 boct_bit_tree boxm2_curr_tree((unsigned char *)boxm2_tree.data_block(),
141 max_level_);
142
143 // 2. make sure the bstm tree is as refined as boxm2 tree
144 boct_bit_tree refined_tree = this->conform_tree(curr_tree, boxm2_curr_tree);
145 int newSize = refined_tree.num_cells();
146
147 // cache refined tree
148 std::memcpy(
149 trees_copy[currIndex].data_block(), refined_tree.get_bits(), 16);
150 dataSize += newSize;
151 }
152
153 // 2. allocate new time blk of the appropriate size
154 bstm_block_id id = blk_->block_id();
155 bstm_block_metadata m_data;
156 m_data.init_level_t_ = blk_t_->init_level();
157 m_data.max_level_t_ = blk_t_->max_level();
158 m_data.sub_block_num_t_ = blk_t_->sub_block_num();
159 bstm_time_block *newTimeBlk =
160 new bstm_time_block(id, m_data, dataSize); // create empty time block
161
162 boxm2_array_1d<uchar8> &new_time_trees =
163 newTimeBlk->time_trees(); // refined trees
164 // std::cout<<"Number of new time trees: "<< new_time_trees.size() -
165 // blk_t_->time_trees().size() <<std::endl;
166
167 // allocate buffer to hold depth differences, one difference per time tree
168 // will be used to scale alpha later on
169 char *depth_diff = new char[new_time_trees.size()];
170 std::memset(
171 depth_diff, 0, sizeof(char) * new_time_trees.size()); // zero out buffer
172
173 // 3. loop through trees again, putting the time trees in the right place
174 int newInitCount = 0;
175 currIndex = 0;
176 for (blk_iter = trees.begin(); blk_iter != trees.end();
177 ++blk_iter, ++currIndex) {
178 // 1. get current tree information
179 uchar16 tree = (*blk_iter);
180 boct_bit_tree old_tree((unsigned char *)tree.data_block(), max_level_);
181
182 // 2. refine tree locally (only updates refined_tree and returns new tree
183 // size)
184 boct_bit_tree refined_tree(
185 (unsigned char *)trees_copy[currIndex].data_block(), max_level_);
186
187 // 2.5 pack data bits into refined tree
188 // store data index in bits [10, 11, 12, 13] ;
189 int root_index = dataIndex[currIndex];
190 refined_tree.set_data_ptr(root_index, false); // is not random
191
192 // 3. swap data from old location to new location
193 newInitCount +=
194 this->move_time_trees(old_tree, refined_tree, newTimeBlk, depth_diff);
195
196 // 4. store old tree in new tree, swap data out
197 std::memcpy(blk_iter, refined_tree.get_bits(), 16);
198 }
199
200 delete[] dataIndex;
201 delete[] trees_copy;
202
203 // 4. loop over time trees to calculate the size of new data blocks
204 // keep index of data sizes, but don't save into them just yet
205 dataIndex = new int[new_time_trees.size()]; // data index for each new tree
206 currIndex = 0; // curr tree being looked at
207 dataSize = 0; // running sum of data size
208 boxm2_array_1d<uchar8>::iterator time_trees_iter;
209 for (time_trees_iter = new_time_trees.begin();
210 time_trees_iter != new_time_trees.end();
211 ++time_trees_iter, ++currIndex) {
212 // 0. store data index for each tree.
213 dataIndex[currIndex] = dataSize;
214
215 // 1. get refined tree
216 bstm_time_tree new_time_tree(
217 (unsigned char *)(*time_trees_iter).data_block(), max_level_t_);
218
219 // 2. save its new size
220 int newSize = new_time_tree.num_leaves(); // number of leaves, not all
221 // cells.
222 dataSize += newSize;
223 }
224
225 // 5. alloc new data buffers with appropriate size
226 bstm_data_base *newA = new bstm_data_base(
227 new char[dataSize * bstm_data_traits<BSTM_ALPHA>::datasize()],
228 dataSize *bstm_data_traits<BSTM_ALPHA>::datasize(),
229 id);
230
231 bstm_data_base *newM = new bstm_data_base(
232 new char[dataSize * bstm_data_traits<APM_TYPE>::datasize()],
233 dataSize *bstm_data_traits<APM_TYPE>::datasize(),
234 id);
235
236 bstm_data_traits<BSTM_ALPHA>::datatype *alpha_cpy =
237 (bstm_data_traits<BSTM_ALPHA>::datatype *)newA->data_buffer();
238 typename bstm_data_traits<APM_TYPE>::datatype *mog_cpy =
239 (typename bstm_data_traits<APM_TYPE>::datatype *)newM->data_buffer();
240
241 // 6. copy data from old data to new buffers
242 currIndex = 0;
243 for (time_trees_iter = new_time_trees.begin();
244 time_trees_iter != new_time_trees.end();
245 ++time_trees_iter, ++currIndex) {
246 // 1. get refined tree
247 bstm_time_tree new_time_tree(
248 (unsigned char *)(*time_trees_iter).data_block(), max_level_t_);
249
250 // 2. get data pointer
251 int old_data_ptr = new_time_tree.get_data_ptr();
252 int new_data_ptr = dataIndex[currIndex];
253
254 // 3. copy data using old ptr to new data buffers
255 std::memcpy(
256 &(alpha_cpy[new_data_ptr]),
257 &(alpha_[old_data_ptr]),
258 bstm_data_traits<BSTM_ALPHA>::datasize() *
259 new_time_tree.num_leaves()); // number of leaves, not all cells.
260 std::memcpy(
261 &(mog_cpy[new_data_ptr]),
262 &(apm_model_[old_data_ptr]),
263 bstm_data_traits<APM_TYPE>::datasize() *
264 new_time_tree.num_leaves()); // number of leaves, not all cells.
265
266 // scale alpha data using the depth they were copied from
267 // to be consistent.
268 #ifdef ALPHA_SCALING
269 if (depth_diff[currIndex] > 0)
270 for (int i = 0; i < new_time_tree.num_cells(); i++)
271 alpha_cpy[new_data_ptr + i] *= float(1 << (int)depth_diff[currIndex]);
272 #endif
273
274 // 4. correct data ptr
275 new_time_tree.set_data_ptr(dataIndex[currIndex]);
276
277 // 5. save it back
278 std::memcpy(time_trees_iter, new_time_tree.get_bits(), TT_NUM_BYTES);
279 }
280
281 delete[] dataIndex;
282 delete[] depth_diff;
283
284 // 7. update cache, replace time trees
285 bstm_cache_sptr cache = bstm_cache::instance();
286 cache->replace_time_block(id, newTimeBlk);
287 cache->replace_data_base(id, bstm_data_traits<BSTM_ALPHA>::prefix(), newA);
288 cache->replace_data_base(id, bstm_data_traits<APM_TYPE>::prefix(), newM);
289
290 blk_t_ = newTimeBlk;
291 alpha_ = alpha_cpy;
292 apm_model_ = mog_cpy;
293
294 return true;
295 }
296
297 template <bstm_data_type APM_TYPE, boxm2_data_type BOXM2_APM_TYPE>
move_time_trees(boct_bit_tree & unrefined_tree,boct_bit_tree & refined_tree,bstm_time_block * newTimeBlk,char * depth_diff)298 int bstm_ingest_boxm2_scene_function<APM_TYPE, BOXM2_APM_TYPE>::move_time_trees(
299 boct_bit_tree &unrefined_tree,
300 boct_bit_tree &refined_tree,
301 bstm_time_block *newTimeBlk,
302 char *depth_diff) {
303 int newSize = refined_tree.num_cells();
304
305 // zip through each leaf cell and
306 int oldDataPtr = unrefined_tree.get_data_ptr(false);
307 int newDataPtr = refined_tree.get_data_ptr(false);
308 int newInitCount = 0;
309 int cellsMoved = 0;
310
311 for (int j = 0; j < MAX_CELLS_ && cellsMoved < newSize; ++j) {
312 // if parent bit is 1, then you're a valid cell
313 int pj = unrefined_tree.parent_index(j); // Bit_index of parent bit
314 bool validCellOld = (j == 0) || unrefined_tree.bit_at(pj);
315 bool validCellNew = (j == 0) || refined_tree.bit_at(pj);
316 if (validCellOld && validCellNew) {
317 // move data to new location
318
319 boxm2_array_1d<vnl_vector_fixed<unsigned char, 8> > old_time_trees =
320 blk_t_->get_cell_all_tt(oldDataPtr); // get all tt from prev. loc
321 // newTimeBlk->set_cell_all_tt(newDataPtr,old_time_trees); //set all tt to
322 // new loc
323
324 if (!refined_tree.is_leaf(j)) // if the time trees being copied belong to
325 // an inner cell, erase their time trees
326 {
327 vnl_vector_fixed<unsigned char, 8> *erased_old_time_trees =
328 new vnl_vector_fixed<unsigned char, 8>[sub_block_num_t_];
329 for (unsigned int t_idx = 0; t_idx < sub_block_num_t_; ++t_idx) {
330 bstm_time_tree tmp_tree(
331 old_time_trees[t_idx]
332 .data_block()); // create tree by copying the tree data
333 tmp_tree.erase_cells(); // erase all cells except for root.
334 erased_old_time_trees[t_idx].set(
335 tmp_tree.get_bits()); // copy to erased_old_time_trees
336 }
337 newTimeBlk->set_cell_all_tt(
338 newDataPtr,
339 boxm2_array_1d<vnl_vector_fixed<unsigned char, 8> >(
340 sub_block_num_t_,
341 erased_old_time_trees)); // set all tt to new loc
342 delete[] erased_old_time_trees;
343 } else // if the time trees being copied belong to a leaf, copy them as
344 // they are.
345 newTimeBlk->set_cell_all_tt(newDataPtr,
346 old_time_trees); // set all tt to new loc
347
348 // increment
349 ++oldDataPtr;
350 ++newDataPtr;
351 ++cellsMoved;
352 }
353 // case where it's a new leaf...
354 else if (validCellNew) {
355 // find parent in old tree
356 int valid_parent_bit = pj;
357 while (
358 valid_parent_bit != 0 &&
359 !unrefined_tree.bit_at(unrefined_tree.parent_index(valid_parent_bit)))
360 valid_parent_bit = unrefined_tree.parent_index(valid_parent_bit);
361
362 int parent_dataPtr =
363 unrefined_tree.get_data_index(valid_parent_bit, false);
364
365 // move root data to new location
366 boxm2_array_1d<vnl_vector_fixed<unsigned char, 8> > old_time_trees =
367 blk_t_->get_cell_all_tt(parent_dataPtr); // get all tt from root loc
368 newTimeBlk->set_cell_all_tt(
369 newDataPtr, old_time_trees); // set all tt to new loc(child)
370
371 // save depth differences
372 for (unsigned int i = 0; i < sub_block_num_t_; ++i)
373 depth_diff[newDataPtr + i] =
374 char(refined_tree.depth_at(j) -
375 unrefined_tree.depth_at(valid_parent_bit));
376
377 // update new data pointer
378 ++newDataPtr;
379 ++newInitCount;
380 ++cellsMoved;
381 }
382 }
383
384 return newInitCount;
385 }
386
387 template <bstm_data_type APM_TYPE, boxm2_data_type BOXM2_APM_TYPE>
388 boct_bit_tree
conform_tree(boct_bit_tree curr_tree,boct_bit_tree boxm2_curr_tree)389 bstm_ingest_boxm2_scene_function<APM_TYPE, BOXM2_APM_TYPE>::conform_tree(
390 boct_bit_tree curr_tree, boct_bit_tree boxm2_curr_tree) {
391 boct_bit_tree refined_tree(curr_tree.get_bits(),
392 max_level_); // initialize tree to return
393
394 for (int i = 0; i < MAX_INNER_CELLS_;
395 ++i) //(iterate through the max number of inner cells)
396 if (boxm2_curr_tree.bit_at(i) == 1 &&
397 refined_tree.bit_at(i) ==
398 0) // if boxm2 cell is divided, also divide bstm cell
399 refined_tree.set_bit_at(i, true);
400
401 return refined_tree;
402 }
403
404 template <bstm_data_type APM_TYPE, boxm2_data_type BOXM2_APM_TYPE>
ingest()405 bool bstm_ingest_boxm2_scene_function<APM_TYPE, BOXM2_APM_TYPE>::ingest() {
406 // loop over each tree in blk and boxm2_blk.
407 //--loop over each cell in the bstm tree
408 //----loop over cell's time trees.
409 //------if time tree does contain local_time,
410 //--------refine time tree(boxm2 dataptr, time tree)
411 //----keep record of the datasize for alpha, mog, numobs etc.
412
413 const boxm2_array_3d<uchar16> &trees = blk_->trees();
414 const boxm2_array_3d<uchar16> &boxm2_trees = boxm2_blk_->trees();
415 boxm2_array_1d<uchar8> &time_trees =
416 blk_t_->time_trees(); // time trees to refine
417
418 // make a copy of the time trees in blk_t_
419 uchar8 *time_tree_copy_buffer = new uchar8[time_trees.size()];
420 boxm2_array_1d<uchar8> time_trees_blk_copy(time_trees.size(),
421 time_tree_copy_buffer);
422 for (unsigned int i = 0; i < time_trees.size(); ++i)
423 std::memcpy(time_trees_blk_copy[i].data_block(),
424 time_trees[i].data_block(),
425 TT_NUM_BYTES);
426
427 int *dataIndex = new int[time_trees.size()]; // data index for each new tree
428 int dataSize = 0; // running sum of data size
429 int currIndex = 0;
430
431 // alloc new data buffers with appropriate size
432 bstm_block_id id = blk_->block_id();
433 bstm_cache_sptr cache = bstm_cache::instance();
434 bstm_data_base *change_buffer = cache->get_data_base_new(
435 id,
436 bstm_data_traits<BSTM_CHANGE>::prefix(),
437 blk_t_->tree_buff_length() * bstm_data_traits<BSTM_CHANGE>::datasize());
438
439 change_array_ =
440 (bstm_data_traits<BSTM_CHANGE>::datatype *)change_buffer->data_buffer();
441
442 int tree_index = 0;
443 boxm2_array_3d<uchar16>::const_iterator blk_iter, boxm2_blk_iter;
444 for (blk_iter = trees.begin(), boxm2_blk_iter = boxm2_trees.begin();
445 blk_iter != trees.end();
446 ++blk_iter, ++boxm2_blk_iter) {
447 // load boct trees from both blk and boxm2_blk
448 uchar16 tree = (*blk_iter);
449 boct_bit_tree curr_tree((unsigned char *)tree.data_block(), max_level_);
450
451 uchar16 boxm2_tree = (*boxm2_blk_iter);
452 boct_bit_tree boxm2_curr_tree((unsigned char *)boxm2_tree.data_block(),
453 max_level_);
454
455 int num_cells = curr_tree.num_cells();
456 int num_processed_cells = 0;
457 for (int i = 0; i < MAX_CELLS_ && num_processed_cells < num_cells; ++i) {
458 int pi = (i - 1) >> 3; // Bit_index of parent bit
459 if ((i == 0) || curr_tree.bit_at(pi)) {
460 bool is_leaf = !curr_tree.bit_at(i);
461
462 // it might be that the bstm cell is further divided than the boxm2
463 // cell.
464 int i_boxm2 = i;
465 while (i_boxm2 != 0 &&
466 !boxm2_curr_tree.bit_at(boxm2_curr_tree.parent_index(i_boxm2)))
467 i_boxm2 = boxm2_curr_tree.parent_index(i_boxm2);
468
469 // get data ptr for both trees
470 int bstm_data_offset = curr_tree.get_data_index(i, false);
471 int boxm2_data_offset = boxm2_curr_tree.get_data_index(i_boxm2, false);
472
473 // refine all the time trees associated with curr cell.
474 this->refine_all_time_trees(bstm_data_offset,
475 boxm2_data_offset,
476 dataIndex,
477 currIndex,
478 dataSize,
479 curr_tree.depth_at(i),
480 boxm2_curr_tree.depth_at(i_boxm2),
481 is_leaf);
482 num_processed_cells++;
483 }
484 }
485 tree_index++;
486 }
487
488 // std::cout << "New data size is " << dataSize << std::endl;
489
490 bstm_data_base *newA = new bstm_data_base(
491 new char[dataSize * bstm_data_traits<BSTM_ALPHA>::datasize()],
492 dataSize *bstm_data_traits<BSTM_ALPHA>::datasize(),
493 id);
494 bstm_data_base *newM = new bstm_data_base(
495 new char[dataSize * bstm_data_traits<APM_TYPE>::datasize()],
496 dataSize *bstm_data_traits<APM_TYPE>::datasize(),
497 id);
498 bstm_data_traits<BSTM_ALPHA>::datatype *alpha_cpy =
499 (bstm_data_traits<BSTM_ALPHA>::datatype *)newA->data_buffer();
500 typename bstm_data_traits<APM_TYPE>::datatype *apm_cpy =
501 (typename bstm_data_traits<APM_TYPE>::datatype *)newM->data_buffer();
502
503 // loop over each tree in blk and boxm2_blk.
504 //--loop over each time tree
505 //----copy everything from old tree's data
506 //----except for the current cell, copy that from boxm2 data.
507 currIndex = 0;
508 int newInitCount = 0;
509
510 for (blk_iter = trees.begin(), boxm2_blk_iter = boxm2_trees.begin();
511 blk_iter != trees.end();
512 ++blk_iter, ++boxm2_blk_iter) {
513 // load boct trees from both blk and boxm2_blk
514 uchar16 tree = (*blk_iter);
515 boct_bit_tree curr_tree((unsigned char *)tree.data_block(), max_level_);
516
517 uchar16 boxm2_tree = (*boxm2_blk_iter);
518 boct_bit_tree boxm2_curr_tree((unsigned char *)boxm2_tree.data_block(),
519 max_level_);
520
521 int num_cells = curr_tree.num_cells();
522 int num_processed_cells = 0;
523 for (int i = 0; i < MAX_CELLS_ && num_processed_cells < num_cells; ++i) {
524 int pi = (i - 1) >> 3; // Bit_index of parent bit
525 if ((i == 0) || curr_tree.bit_at(pi)) {
526 // it might be that the bstm cell is further divided than the boxm2
527 // cell.
528 int i_boxm2 = i;
529 while (i_boxm2 != 0 &&
530 !boxm2_curr_tree.bit_at(boxm2_curr_tree.parent_index(i_boxm2)))
531 i_boxm2 = boxm2_curr_tree.parent_index(i_boxm2);
532
533 // get data ptr for both trees
534 int bstm_data_offset = curr_tree.get_data_index(i, false);
535 int boxm2_data_offset = boxm2_curr_tree.get_data_index(i_boxm2, false);
536
537 int depth_diff =
538 curr_tree.depth_at(i) - boxm2_curr_tree.depth_at(i_boxm2);
539 newInitCount += move_all_time_trees_data(time_trees_blk_copy,
540 bstm_data_offset,
541 boxm2_data_offset,
542 dataIndex,
543 currIndex,
544 alpha_cpy,
545 apm_cpy,
546 depth_diff);
547 num_processed_cells++;
548 }
549 }
550 }
551
552 // std::cout<<"Number of new cells: "<<newInitCount<<std::endl;
553
554 // replace databases
555 cache->replace_data_base(id, bstm_data_traits<BSTM_ALPHA>::prefix(), newA);
556 cache->replace_data_base(id, bstm_data_traits<APM_TYPE>::prefix(), newM);
557
558 delete[] time_tree_copy_buffer;
559 delete[] dataIndex;
560
561 return true;
562 }
563
564 template <bstm_data_type APM_TYPE, boxm2_data_type BOXM2_APM_TYPE>
565 int bstm_ingest_boxm2_scene_function<APM_TYPE, BOXM2_APM_TYPE>::
move_all_time_trees_data(boxm2_array_1d<uchar8> & time_trees_blk_copy,int bstm_data_offset,int boxm2_data_offset,int * dataIndex,int & currIndex,bstm_data_traits<BSTM_ALPHA>::datatype * alpha_cpy,typename bstm_data_traits<APM_TYPE>::datatype * apm_cpy,int depth_diff)566 move_all_time_trees_data(
567 boxm2_array_1d<uchar8> &time_trees_blk_copy,
568 int bstm_data_offset,
569 int boxm2_data_offset,
570 int *dataIndex,
571 int &currIndex,
572 bstm_data_traits<BSTM_ALPHA>::datatype *alpha_cpy,
573 typename bstm_data_traits<APM_TYPE>::datatype *apm_cpy,
574 int depth_diff) {
575 // load original time trees
576 boxm2_array_1d<uchar8> time_trees_copy(
577 sub_block_num_t_,
578 &(time_trees_blk_copy[bstm_data_offset * sub_block_num_t_]));
579
580 boxm2_array_1d<uchar8> time_trees_refined =
581 blk_t_->get_cell_all_tt(bstm_data_offset);
582
583 // zip thru time trees
584 int newInitCount = 0;
585 for (unsigned int t = 0; t < time_trees_refined.size(); ++t) {
586 bstm_time_tree refined_tree(time_trees_refined[t].data_block(),
587 max_level_t_);
588 bstm_time_tree original_tree(time_trees_copy[t].data_block(), max_level_t_);
589
590 // set the root data pointer of the refined tree
591 int root_index = dataIndex[currIndex];
592 refined_tree.set_data_ptr(root_index);
593
594 newInitCount +=
595 this->move_data(original_tree, refined_tree, alpha_cpy, apm_cpy);
596
597 if (t ==
598 blk_t_->tree_index(
599 local_time_)) // if this time tree contains the queried time
600 {
601 float cell_min, cell_max;
602 refined_tree.cell_range(
603 refined_tree.traverse(local_time_ - blk_t_->tree_index(local_time_)),
604 cell_min,
605 cell_max);
606 if (cell_min ==
607 local_time_ -
608 blk_t_->tree_index(local_time_)) { // if the current time is the
609 // start of a cell in which new
610 // data will be placed
611 this->place_curr_data(
612 refined_tree, boxm2_data_offset, alpha_cpy, apm_cpy, depth_diff);
613 }
614 }
615
616 // make sure to write the refined bits to blk_t_
617 uchar8 refined_bits(refined_tree.get_bits());
618 blk_t_->set_cell_tt(bstm_data_offset, refined_bits, t);
619
620 currIndex++;
621 }
622 return newInitCount;
623 }
624
625 template <bstm_data_type APM_TYPE, boxm2_data_type BOXM2_APM_TYPE>
626 bool bstm_ingest_boxm2_scene_function<APM_TYPE, BOXM2_APM_TYPE>::
refine_all_time_trees(int bstm_data_offset,int boxm2_data_offset,int * dataIndex,int & currIndex,int & dataSize,int currDepth,int currDepth_boxm2,bool is_leaf)627 refine_all_time_trees(int bstm_data_offset,
628 int boxm2_data_offset,
629 int *dataIndex,
630 int &currIndex,
631 int &dataSize,
632 int currDepth,
633 int currDepth_boxm2,
634 bool is_leaf) {
635 bool refined_any_time_tree = false;
636 // zip thru time trees
637 int newSize = 0;
638 boxm2_array_1d<uchar8> all_time_trees =
639 blk_t_->get_cell_all_tt(bstm_data_offset);
640 for (unsigned int t = 0; t < all_time_trees.size(); ++t) {
641 dataIndex[currIndex] = dataSize;
642
643 bstm_time_tree tmp_tree(all_time_trees[t].data_block(), max_level_t_);
644 // if this time tree contains the queried time and it is a leaf.
645 // if not a leaf, don't bother refining its time tree to save space.
646 if (t == blk_t_->tree_index(local_time_) && is_leaf) {
647 bstm_time_tree refined_t_tree = this->refine_time_tree(tmp_tree,
648 bstm_data_offset,
649 boxm2_data_offset,
650 currDepth,
651 currDepth_boxm2);
652 uchar8 refined_bits(refined_t_tree.get_bits());
653 blk_t_->set_cell_tt(
654 bstm_data_offset, refined_bits, t); // save it in time block
655 newSize =
656 refined_t_tree.num_leaves(); // count up the number of cells needed
657 } else
658 newSize = tmp_tree.num_leaves(); // count up the number of cells needed
659
660 if (tmp_tree.num_cells() != newSize)
661 refined_any_time_tree = true;
662
663 dataSize += newSize;
664 currIndex++;
665 }
666 return refined_any_time_tree;
667 }
668
669 template <bstm_data_type APM_TYPE, boxm2_data_type BOXM2_APM_TYPE>
670 void bstm_ingest_boxm2_scene_function<APM_TYPE, BOXM2_APM_TYPE>::
place_curr_data(bstm_time_tree & refined_tree,int boxm2_data_offset,bstm_data_traits<BSTM_ALPHA>::datatype * alpha_cpy,typename bstm_data_traits<APM_TYPE>::datatype * apm_cpy,int depth_diff)671 place_curr_data(bstm_time_tree &refined_tree,
672 int boxm2_data_offset,
673 bstm_data_traits<BSTM_ALPHA>::datatype *alpha_cpy,
674 typename bstm_data_traits<APM_TYPE>::datatype *apm_cpy,
675 int
676 #ifdef ALPHA_SCALING
677 depth_diff
678 #endif
679 ) {
680 float trees_local_time = local_time_ - blk_t_->tree_index(local_time_);
681 int new_ptr =
682 refined_tree.get_data_index(refined_tree.traverse(trees_local_time));
683
684 #ifdef DEBUG
685 if (new_ptr == -1)
686 std::cerr << "ERROR, data index is -1\n";
687 #endif
688
689 alpha_cpy[new_ptr] = boxm2_alpha_[boxm2_data_offset];
690 apm_cpy[new_ptr] = boxm2_apm_model_[boxm2_data_offset];
691
692 #ifdef ALPHA_SCALING
693 alpha_cpy[new_ptr] *= float(
694 1 << (int)depth_diff); // scale alpha to be consistent with its depth.
695 #endif
696 }
697
698 template <bstm_data_type APM_TYPE, boxm2_data_type BOXM2_APM_TYPE>
699 bstm_time_tree
refine_time_tree(const bstm_time_tree & input_tree,int bstm_data_offset,int boxm2_data_offset,int currDepth,int currDepth_boxm2)700 bstm_ingest_boxm2_scene_function<APM_TYPE, BOXM2_APM_TYPE>::refine_time_tree(
701 const bstm_time_tree &input_tree,
702 int bstm_data_offset,
703 int boxm2_data_offset,
704 int currDepth,
705 int currDepth_boxm2) {
706 // initialize tree to return
707 bstm_time_tree refined_tree(input_tree.get_bits(), max_level_t_);
708
709 float trees_local_time = local_time_ - blk_t_->tree_index(local_time_);
710
711 if (currDepth < currDepth_boxm2)
712 std::cout << "ERROR: boxm2 and bstm depths don't match!" << std::endl;
713
714 // first, query for boxm2 data
715 double side_len_boxm2 = block_len_ / double(1 << currDepth_boxm2);
716 boxm2_data_traits<BOXM2_ALPHA>::datatype boxm2_curr_alpha =
717 boxm2_alpha_[boxm2_data_offset];
718 float boxm2_p = 1 - std::exp(-boxm2_curr_alpha * side_len_boxm2);
719 typename boxm2_data_traits<BOXM2_APM_TYPE>::datatype boxm2_mog =
720 boxm2_apm_model_[boxm2_data_offset];
721
722 // and then bstm data
723 double side_len = block_len_ / double(1 << currDepth);
724 int data_offset =
725 refined_tree.get_data_index(refined_tree.traverse(trees_local_time));
726
727 #ifdef DEBUG
728 if (data_offset == -1)
729 std::cerr << "ERROR, data index is -1!\n";
730 #endif
731
732 bstm_data_traits<BSTM_ALPHA>::datatype alpha = alpha_[data_offset];
733 float p = 1 - std::exp(-alpha * side_len);
734 typename bstm_data_traits<APM_TYPE>::datatype mog = apm_model_[data_offset];
735
736 // save change of probabilities
737 change_array_[bstm_data_offset] = std::fabs(boxm2_p - p);
738
739 if (is_similar(p, mog, boxm2_p, boxm2_mog))
740 return refined_tree;
741 else // need to refine time tree
742 {
743 bool split_complete = false;
744 while (!split_complete) {
745 int curr_cell = refined_tree.traverse(trees_local_time);
746 int currDepth = refined_tree.depth_at(curr_cell);
747
748 float cell_min, cell_max;
749 refined_tree.cell_range(curr_cell, cell_min, cell_max);
750 if (cell_min == trees_local_time) // found cell starting at queried time.
751 split_complete = true; // we're done here.
752 else if (currDepth < TT_NUM_LVLS - 1) {
753 refined_tree.set_bit_at(curr_cell, true); // split curr_cell
754 ++num_split_t_;
755 } else // reached end of tree...
756 split_complete = true;
757 }
758
759 return refined_tree;
760 }
761 }
762
763 template <bstm_data_type APM_TYPE, boxm2_data_type BOXM2_APM_TYPE>
is_similar(float p,typename bstm_data_traits<APM_TYPE>::datatype mog,float boxm2_p,typename boxm2_data_traits<BOXM2_APM_TYPE>::datatype boxm2_mog)764 bool bstm_ingest_boxm2_scene_function<APM_TYPE, BOXM2_APM_TYPE>::is_similar(
765 float p,
766 typename bstm_data_traits<APM_TYPE>::datatype mog,
767 float boxm2_p,
768 typename boxm2_data_traits<BOXM2_APM_TYPE>::datatype boxm2_mog) {
769 return bstm_similarity_traits<APM_TYPE, BOXM2_APM_TYPE>::is_similar(
770 mog, boxm2_mog, p, boxm2_p, p_threshold_, app_threshold_);
771 }
772
773 template <bstm_data_type APM_TYPE, boxm2_data_type BOXM2_APM_TYPE>
move_data(bstm_time_tree & unrefined_tree,bstm_time_tree & refined_tree,bstm_data_traits<BSTM_ALPHA>::datatype * alpha_cpy,typename bstm_data_traits<APM_TYPE>::datatype * apm_cpy)774 int bstm_ingest_boxm2_scene_function<APM_TYPE, BOXM2_APM_TYPE>::move_data(
775 bstm_time_tree &unrefined_tree,
776 bstm_time_tree &refined_tree,
777 bstm_data_traits<BSTM_ALPHA>::datatype *alpha_cpy,
778 typename bstm_data_traits<APM_TYPE>::datatype *apm_cpy) {
779 int newInitCount = 0;
780
781 std::vector<int> new_leaves = refined_tree.get_leaf_bits();
782 std::vector<int> old_leaves = unrefined_tree.get_leaf_bits();
783
784 for (int & new_leave : new_leaves) {
785 // get new data ptr
786 int newDataPtr = refined_tree.get_data_index(new_leave);
787
788 // find out if this leaf exists in the unrefined tree as well
789 int pj = unrefined_tree.parent_index(new_leave); // Bit_index of parent bit
790 bool validCellOld = (new_leave == 0) || unrefined_tree.bit_at(pj);
791
792 int oldDataPtr;
793 if (validCellOld) // if they both exist
794 oldDataPtr = unrefined_tree.get_data_index(new_leave);
795 else {
796 // find parent in old tree
797 int valid_parent_bit = pj;
798 while (
799 valid_parent_bit != 0 &&
800 !unrefined_tree.bit_at(unrefined_tree.parent_index(valid_parent_bit)))
801 valid_parent_bit = unrefined_tree.parent_index(valid_parent_bit);
802
803 oldDataPtr = unrefined_tree.get_data_index(valid_parent_bit);
804
805 // increment new cell count
806 newInitCount++;
807 }
808 // copy data
809 alpha_cpy[newDataPtr] = alpha_[oldDataPtr];
810 apm_cpy[newDataPtr] = apm_model_[oldDataPtr];
811 }
812 return newInitCount;
813 }
814
815 // OLD DEPRECATED CODE
816 #if 0
817
818 template <bstm_data_type APM_TYPE, boxm2_data_type BOXM2_APM_TYPE>
819 int bstm_ingest_boxm2_scene_function<APM_TYPE, BOXM2_APM_TYPE>::move_data(bstm_time_tree& unrefined_tree, bstm_time_tree& refined_tree,
820 bstm_data_traits<BSTM_ALPHA>::datatype* alpha_cpy,
821 typename bstm_data_traits<APM_TYPE>::datatype * apm_cpy )
822 {
823 int newSize = refined_tree.num_cells();
824
825 //zip through each leaf cell and
826 int oldDataPtr = unrefined_tree.get_data_ptr();
827 int newDataPtr = refined_tree.get_data_ptr();
828 int newInitCount = 0;
829 int cellsMoved = 0;
830 for (int j=0; j<MAX_CELLS_T_ && cellsMoved<newSize; ++j)
831 {
832 //--------------------------------------------------------------------
833 //4 Cases:
834 // - Old cell and new cell exist - transfer data over
835 // - new cell exists, old cell doesn't - create new occupancy based on depth
836 // - old cell exists, new cell doesn't - uh oh this is bad news
837 // - neither cell exists - do nothing and carry on
838 //--------------------------------------------------------------------
839 //if parent bit is 1, then you're a valid cell
840 int pj = unrefined_tree.parent_index(j); //Bit_index of parent bit
841 bool validCellOld = (j==0) || unrefined_tree.bit_at(pj);
842 bool validCellNew = (j==0) || refined_tree.bit_at(pj);
843 if (validCellOld && validCellNew) {
844 //move root data to new location
845 alpha_cpy[newDataPtr] = alpha_[oldDataPtr];
846 apm_cpy[newDataPtr] = apm_model_[oldDataPtr];
847
848 //increment
849 ++oldDataPtr;
850 ++newDataPtr;
851 ++cellsMoved;
852 }
853 //case where it's a new leaf...
854 else if (validCellNew) {
855 //find parent in old tree
856 int valid_parent_bit = pj;
857 while ( valid_parent_bit !=0 && !unrefined_tree.bit_at( unrefined_tree.parent_index(valid_parent_bit) ) )
858 valid_parent_bit = unrefined_tree.parent_index(valid_parent_bit);
859
860 int parent_data_ptr = unrefined_tree.get_data_index(valid_parent_bit);
861
862 #ifdef DEBUG
863 if (parent_data_ptr == -1)
864 std::cerr << "ERROR, data index is -1\n";
865 #endif
866
867 alpha_cpy[newDataPtr] = alpha_[ parent_data_ptr ];
868 apm_cpy[newDataPtr] = apm_model_[parent_data_ptr];
869
870 //update new data pointer
871 ++newDataPtr;
872 ++newInitCount;
873 ++cellsMoved;
874 }
875 }
876 return newInitCount;
877 }
878 #endif
879
880 #endif // bstm_ingest_boxm2_scene_function_hxx_
881