Skip to content

Commit 8e9db7b

Browse files
authored
Merge pull request #91 from cheesema/develop
Develop
2 parents 6787109 + 7776211 commit 8e9db7b

File tree

13 files changed

+2335
-127
lines changed

13 files changed

+2335
-127
lines changed

examples/Example_get_apr.cpp

Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ Advanced (Direct) Settings:
2626
-rel_error rel_error_value (Reasonable ranges are from .08-.15), Default: 0.1
2727
-normalize_input (flag that will rescale the input from the input data range to 80% of the output data type range, useful for float scaled datasets)
2828
-compress_level (the IO uses BLOSC for lossless compression of the APR, this can be set from 1-9, where higher increases the compression level. Note, this can come at a significant time increase.)
29+
-compress_type (Default: 0, loss-less compression of partilce intensities, (1,2) WNL (Balázs et al. 2017) - approach compression applied to particles (1 = without prediction, 2 = with)
30+
31+
-neighborhood_optimization_off turns off the neighborhood opetimization (This results in boundary Particle Cells also being increased in resolution after the Pulling Scheme step)
32+
-output_steps Writes tiff images of the individual steps (gradient magnitude, local intensity scale, and final level of the APR calculation).
33+
2934
)";
3035

3136
#include <algorithm>
@@ -43,31 +48,31 @@ int main(int argc, char **argv) {
4348
//the apr datastructure
4449
APR<uint16_t> apr;
4550

46-
APRConverter<uint16_t> apr_converter;
47-
4851
//read in the command line options into the parameters file
49-
apr_converter.par.Ip_th = options.Ip_th;
50-
apr_converter.par.rel_error = options.rel_error;
51-
apr_converter.par.lambda = options.lambda;
52-
apr_converter.par.mask_file = options.mask_file;
53-
apr_converter.par.min_signal = options.min_signal;
54-
apr_converter.par.SNR_min = options.SNR_min;
55-
apr_converter.par.normalized_input = options.normalize_input;
52+
apr.parameters.Ip_th = options.Ip_th;
53+
apr.parameters.rel_error = options.rel_error;
54+
apr.parameters.lambda = options.lambda;
55+
apr.parameters.mask_file = options.mask_file;
56+
apr.parameters.min_signal = options.min_signal;
57+
apr.parameters.SNR_min = options.SNR_min;
58+
apr.parameters.normalized_input = options.normalize_input;
59+
apr.parameters.neighborhood_optimization = options.neighborhood_optimization;
60+
apr.parameters.output_steps = options.output_steps;
5661

5762
//where things are
58-
apr_converter.par.input_image_name = options.input;
59-
apr_converter.par.input_dir = options.directory;
60-
apr_converter.par.name = options.output;
61-
apr_converter.par.output_dir = options.output_dir;
63+
apr.parameters.input_image_name = options.input;
64+
apr.parameters.input_dir = options.directory;
65+
apr.parameters.name = options.output;
66+
apr.parameters.output_dir = options.output_dir;
6267

63-
apr_converter.fine_grained_timer.verbose_flag = false;
64-
apr_converter.method_timer.verbose_flag = false;
65-
apr_converter.computation_timer.verbose_flag = false;
66-
apr_converter.allocation_timer.verbose_flag = false;
67-
apr_converter.total_timer.verbose_flag = true;
68+
apr.apr_converter.fine_grained_timer.verbose_flag = false;
69+
apr.apr_converter.method_timer.verbose_flag = false;
70+
apr.apr_converter.computation_timer.verbose_flag = false;
71+
apr.apr_converter.allocation_timer.verbose_flag = false;
72+
apr.apr_converter.total_timer.verbose_flag = true;
6873

6974
//Gets the APR
70-
if(apr_converter.get_apr(apr)){
75+
if(apr.get_apr()){
7176

7277
//Below is IO and outputting of the Implied Resolution Function through the Particle Cell level.
7378

@@ -79,18 +84,6 @@ int main(int argc, char **argv) {
7984

8085
timer.verbose_flag = true;
8186

82-
PixelData<uint16_t> level;
83-
84-
apr.interp_depth_ds(level);
85-
86-
std::cout << std::endl;
87-
88-
std::cout << "Saving down-sampled Particle Cell level as tiff image" << std::endl;
89-
90-
std::string output_path = save_loc + file_name + "_level.tif";
91-
//write output as tiff
92-
TiffUtils::saveMeshAsTiff(output_path, level);
93-
9487
std::cout << std::endl;
9588
float original_pixel_image_size = (2.0f*apr.orginal_dimensions(0)*apr.orginal_dimensions(1)*apr.orginal_dimensions(2))/(1000000.0);
9689
std::cout << "Original image size: " << original_pixel_image_size << " MB" << std::endl;
@@ -104,6 +97,8 @@ int main(int argc, char **argv) {
10497
unsigned int blosc_comp_level = options.compress_level;
10598
unsigned int blosc_shuffle = 1;
10699

100+
apr.apr_compress.set_compression_type(options.compress_type);
101+
107102
//write the APR to hdf5 file
108103
FileSizeInfo fileSizeInfo = apr.write_apr(save_loc,file_name,blosc_comp_type,blosc_comp_level,blosc_shuffle);
109104
float apr_file_size = fileSizeInfo.total_file_size;
@@ -117,6 +112,20 @@ int main(int argc, char **argv) {
117112
std::cout << "Lossy Compression Ratio: " << original_pixel_image_size/apr_file_size << std::endl;
118113
std::cout << std::endl;
119114

115+
if(options.output_steps) {
116+
117+
PixelData<uint16_t> level;
118+
119+
apr.interp_depth_ds(level);
120+
121+
std::cout << std::endl;
122+
123+
std::cout << "Saving down-sampled Particle Cell level as tiff image" << std::endl;
124+
125+
std::string output_path = save_loc + file_name + "_level.tif";
126+
//write output as tiff
127+
TiffUtils::saveMeshAsTiff(output_path, level);
128+
}
120129

121130
} else {
122131
std::cout << "Oops, something went wrong. APR not computed :(." << std::endl;
@@ -220,14 +229,25 @@ cmdLineOptions read_command_line_options(int argc, char **argv){
220229
result.compress_level = (unsigned int)std::stoi(std::string(get_command_option(argv, argv + argc, "-compress_level")));
221230
}
222231

232+
if(command_option_exists(argv, argv + argc, "-compress_type"))
233+
{
234+
result.compress_type = (unsigned int)std::stoi(std::string(get_command_option(argv, argv + argc, "-compress_type")));
235+
}
236+
223237
if(command_option_exists(argv, argv + argc, "-normalize_input"))
224238
{
225239
result.normalize_input = true;
226240
}
227241

228-
if(command_option_exists(argv, argv + argc, "-store_delta"))
242+
if(command_option_exists(argv, argv + argc, "-neighborhood_optimization_off"))
243+
{
244+
result.neighborhood_optimization = false;
245+
246+
}
247+
248+
if(command_option_exists(argv, argv + argc, "-output_steps"))
229249
{
230-
result.store_delta = true;
250+
result.output_steps = true;
231251
}
232252

233253
return result;

examples/Example_get_apr.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
#include "algorithm/APRParameters.hpp"
88
#include "data_structures/Mesh/PixelData.hpp"
9-
#include "algorithm/APRConverter.hpp"
109
#include "data_structures/APR/APR.hpp"
1110

1211

@@ -20,8 +19,10 @@ struct cmdLineOptions{
2019
std::string mask_file = "";
2120
bool stats_file = false;
2221
bool normalize_input = false;
23-
bool store_delta = false;
22+
bool neighborhood_optimization = true;
23+
bool output_steps = false;
2424
unsigned int compress_level = 2;
25+
unsigned int compress_type = 0;
2526

2627
float Ip_th = -1;
2728
float SNR_min = -1;

examples/Example_reconstruct_patch.cpp

Lines changed: 32 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Default: Piece-wise constant reconstruction
3939

4040
#include "data_structures/APR/APR.hpp"
4141
#include "io/TiffUtils.hpp"
42+
#include "numerics/APRTreeNumerics.hpp"
4243

4344

4445
struct cmdLineOptions{
@@ -186,18 +187,25 @@ int main(int argc, char **argv) {
186187
reconPatch.z_begin = options.z_begin;
187188
reconPatch.z_end = options.z_end;
188189

190+
reconPatch.level_delta = options.level_delta;
191+
192+
APRTree<uint16_t> aprTree;
193+
aprTree.init(apr);
194+
189195
// Intentionaly block-scoped since local recon_pc will be destructed when block ends and release memory.
190196
{
191197

192198
if(options.output_pc_recon) {
193199
//create mesh data structure for reconstruction
194200
PixelData<uint16_t> recon_pc;
195201

202+
ExtraParticleData<uint16_t> partsTree;
196203

204+
APRTreeNumerics::fill_tree_from_particles(apr,aprTree,apr.particles_intensities,partsTree,[] (const uint16_t& a,const uint16_t& b) {return std::max(a,b);});
197205

198206
timer.start_timer("pc interp");
199207
//perform piece-wise constant interpolation
200-
aprReconstruction.interp_image_patch(apr,recon_pc, apr.particles_intensities,reconPatch);
208+
aprReconstruction.interp_image_patch(apr,aprTree,recon_pc, apr.particles_intensities,partsTree,reconPatch);
201209
timer.stop_timer();
202210

203211
float elapsed_seconds = timer.t2 - timer.t1;
@@ -210,64 +218,39 @@ int main(int argc, char **argv) {
210218
}
211219
}
212220

213-
//////////////////////////
214-
/// Create a particle dataset with the particle type and pc construct it
215-
////////////////////////////
216-
217-
if(options.output_spatial_properties) {
218-
219-
//initialization of the iteration structures
220-
APRIterator<uint16_t> apr_iterator(apr); //this is required for parallel access
221-
222-
//create particle dataset
223-
ExtraParticleData<uint16_t> type(apr);
224-
ExtraParticleData<uint16_t> level(apr);
225-
226-
ExtraParticleData<uint16_t> x(apr);
227-
ExtraParticleData<uint16_t> y(apr);
228-
ExtraParticleData<uint16_t> z(apr);
229221

230-
timer.start_timer("APR parallel iterator loop");
231-
#ifdef HAVE_OPENMP
232-
#pragma omp parallel for schedule(static) firstprivate(apr_iterator)
233-
#endif
234-
for (uint64_t particle_number = 0; particle_number < apr_iterator.total_number_particles(); ++particle_number) {
235-
//needed step for any parallel loop (update to the next part)
236-
apr_iterator.set_iterator_to_particle_by_number(particle_number);
237-
type[apr_iterator] = apr_iterator.type();
238-
level[apr_iterator] = apr_iterator.level();
222+
{
239223

240-
x[apr_iterator] = apr_iterator.x();
241-
y[apr_iterator] = apr_iterator.y();
242-
z[apr_iterator] = apr_iterator.z();
243-
}
244-
timer.stop_timer();
224+
if(options.output_smooth_recon) {
225+
//create mesh data structure for reconstruction
226+
PixelData<uint16_t> recon_pc;
245227

246-
// Intentionaly block-scoped since local type_recon will be destructed when block ends and release memory.
247-
{
248-
PixelData<uint16_t> type_recon;
228+
ExtraParticleData<uint16_t> partsTree;
249229

250-
aprReconstruction.interp_image_patch(apr,type_recon, type,reconPatch);
251-
TiffUtils::saveMeshAsTiff(options.directory + apr.name + "_type.tif", type_recon);
230+
std::vector<float> scale = {1,1,1};
252231

253-
//level
254-
aprReconstruction.interp_image_patch(apr,type_recon, level,reconPatch);
255-
TiffUtils::saveMeshAsTiff(options.directory + apr.name + "_level.tif", type_recon);
232+
APRTreeNumerics::fill_tree_from_particles(apr,aprTree,apr.particles_intensities,partsTree,[] (const uint16_t& a,const uint16_t& b) {return std::max(a,b);});
256233

257-
//x
258-
aprReconstruction.interp_image_patch(apr,type_recon, x,reconPatch);
259-
TiffUtils::saveMeshAsTiff(options.directory + apr.name + "_x.tif", type_recon);
234+
timer.start_timer("smooth interp");
235+
//perform smooth interpolation
236+
aprReconstruction.interp_parts_smooth_patch(apr,aprTree,recon_pc, apr.particles_intensities,partsTree,reconPatch,scale);
237+
timer.stop_timer();
260238

261-
//y
262-
aprReconstruction.interp_image_patch(apr,type_recon, y,reconPatch);
263-
TiffUtils::saveMeshAsTiff(options.directory + apr.name + "_y.tif", type_recon);
239+
float elapsed_seconds = timer.t2 - timer.t1;
240+
std::cout << "Smooth recon "
241+
<< (recon_pc.x_num * recon_pc.y_num * recon_pc.z_num * 2) / (elapsed_seconds * 1000000.0f)
242+
<< " MB per second" << std::endl;
264243

265-
//z
266-
aprReconstruction.interp_image_patch(apr,type_recon, z,reconPatch);
267-
TiffUtils::saveMeshAsTiff(options.directory + apr.name + "_z.tif", type_recon);
244+
//write output as tiff
245+
TiffUtils::saveMeshAsTiff(options.directory + apr.name + "_smooth.tif", recon_pc);
268246
}
269247
}
270248

249+
//////////////////////////
250+
/// Create a particle dataset with the particle type and pc construct it
251+
////////////////////////////
252+
253+
271254
if(options.output_level) {
272255

273256
//initialization of the iteration structures
@@ -294,7 +277,7 @@ int main(int argc, char **argv) {
294277
PixelData<uint8_t> type_recon;
295278

296279
//level
297-
aprReconstruction.interp_image_patch(apr,type_recon, level,reconPatch);
280+
//aprReconstruction.interp_image_patch(apr,aprTree,type_recon, level,reconPatch);
298281
TiffUtils::saveMeshAsTiff(options.directory + apr.name + "_level.tif", type_recon);
299282

300283
}

src/algorithm/APRConverter.hpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ template<typename ImageType>
2727
class APRConverter: public LocalIntensityScale, public ComputeGradient, public LocalParticleCellSet, public PullingScheme {
2828

2929
public:
30+
31+
3032
APRParameters par;
3133
APRTimer fine_grained_timer;
3234
APRTimer method_timer;
@@ -52,20 +54,21 @@ class APRConverter: public LocalIntensityScale, public ComputeGradient, public L
5254
}
5355
};
5456

55-
private:
5657
//get apr without setting parameters, and with an already loaded image.
5758
template<typename T>
5859
bool get_apr_method(APR<ImageType> &aAPR, PixelData<T> &input_image);
5960

61+
template<typename T>
62+
void auto_parameters(const PixelData<T> &input_img);
63+
64+
private:
65+
6066
//pointer to the APR structure so member functions can have access if they need
6167
const APR<ImageType> *apr;
6268

6369
template<typename T>
6470
void init_apr(APR<ImageType>& aAPR, PixelData<T>& input_image);
6571

66-
template<typename T>
67-
void auto_parameters(const PixelData<T> &input_img);
68-
6972
template<typename T>
7073
bool get_apr_method_from_file(APR<ImageType> &aAPR, const TiffUtils::TiffInfo &aTiffFile);
7174

@@ -191,15 +194,23 @@ bool APRConverter<ImageType>::get_apr_method(APR<ImageType> &aAPR, PixelData<T>&
191194
fine_grained_timer.stop_timer();
192195

193196
#ifndef APR_USE_CUDA
194-
method_timer.verbose_flag = true;
197+
//method_timer.verbose_flag = true;
195198
method_timer.start_timer("compute_gradient_magnitude_using_bsplines");
196199
get_gradient(image_temp, grad_temp, local_scale_temp, local_scale_temp2, bspline_offset, par);
197200
method_timer.stop_timer();
198201

202+
if(par.output_steps){
203+
TiffUtils::saveMeshAsTiff(par.output_dir + "gradient_step.tif", grad_temp);
204+
}
205+
199206
method_timer.start_timer("compute_local_intensity_scale");
200207
get_local_intensity_scale(local_scale_temp, local_scale_temp2, par);
201208
method_timer.stop_timer();
202-
method_timer.verbose_flag = false;
209+
//method_timer.verbose_flag = false;
210+
211+
if(par.output_steps){
212+
TiffUtils::saveMeshAsTiff(par.output_dir + "local_intensity_scale_step.tif", local_scale_temp);
213+
}
203214
#else
204215
method_timer.start_timer("compute_gradient_magnitude_using_bsplines and local instensity scale CUDA");
205216
getFullPipeline(image_temp, grad_temp, local_scale_temp, local_scale_temp2,bspline_offset, par);
@@ -234,8 +245,6 @@ bool APRConverter<ImageType>::get_apr_method(APR<ImageType> &aAPR, PixelData<T>&
234245

235246
computation_timer.stop_timer();
236247

237-
aAPR.parameters = par;
238-
239248
total_timer.stop_timer();
240249

241250
return true;
@@ -268,6 +277,12 @@ void APRConverter<ImageType>::get_local_particle_cell_set(PixelData<ImageType> &
268277
fine_grained_timer.start_timer("compute_level_second");
269278
//incorporate other factors and compute the level of the Particle Cell, effectively construct LPC L_n
270279
compute_level_for_array(local_scale_temp,level_factor,par.rel_error);
280+
281+
if(par.output_steps){
282+
TiffUtils::saveMeshAsTiff(par.output_dir + "local_particle_set_level_step.tif", local_scale_temp);
283+
}
284+
285+
271286
fill(l_max,local_scale_temp);
272287
fine_grained_timer.stop_timer();
273288

@@ -293,7 +308,7 @@ void APRConverter<ImageType>::get_gradient(PixelData<ImageType> &image_temp, Pix
293308
// Input: full sized image.
294309
// Output: down-sampled by 2 gradient magnitude (Note, the gradient is calculated at pixel level then maximum down sampled within the loops below)
295310

296-
fine_grained_timer.verbose_flag = true;
311+
//fine_grained_timer.verbose_flag = true;
297312

298313
fine_grained_timer.start_timer("threshold");
299314

@@ -416,6 +431,8 @@ void APRConverter<ImageType>::init_apr(APR<ImageType>& aAPR,PixelData<T>& input_
416431

417432
aAPR.apr_access.level_min = levelMin;
418433
aAPR.apr_access.level_max = levelMax;
434+
435+
aAPR.parameters = par;
419436
}
420437

421438
template<typename ImageType> template<typename T>

0 commit comments

Comments
 (0)