4 bool bothspaces(
char lhs,
char rhs) {
return (lhs == rhs) && (lhs ==
' '); }
19 if (str ==
"stride")
return xstride;
20 if (str ==
"span")
return xspan;
23 if (str ==
"nscales")
return xnscales;
59 wavegraph::add_node(const
int nodeidx, const
int timeidx, const
int freqidx, const
int scaleidx,
60 const
double value_avg, const
double value_stdev,
61 const
bool endnode, const
nodeids& node_ancestors) {
94 graph.push_back(node);
118 std::cout <<
"debug flag1 create: open file\n";
127 std::cout <<
"debug flag2 create: read file\n";
134 while ( std::getline(source,line) ){
145 if ((line[0] ==
'%')&(line[1] ==
'%')) {
149 std::string::iterator line_end = std::unique(line.begin(), line.end(),
bothspaces);
150 line.erase(line_end, line.end());
152 std::string delimiter_fields =
" ";
153 std::string delimiter_values =
"=";
154 size_t pos_field = 0;
158 pos_field = line.find(delimiter_fields);
159 std::string field = line.substr(0, pos_field);
167 size_t pos_value = field.find(delimiter_values);
168 std::string
token = field.substr(0, pos_value);
169 field.erase(0, pos_value + delimiter_values.length());
170 std::string
value = field.substr(0, pos_value);
175 stride=atoi(value.c_str());
178 span=atoi(value.c_str());
193 std::cout <<
"Invalid token: " << token <<
"\n";
194 throw std::invalid_argument(
"Error: Graph file has an invalid header");
198 if (pos_field == std::string::npos)
202 line.erase(0, pos_field + delimiter_fields.length());
206 std::cout <<
"header: stride= " <<
stride <<
" span=" <<
span;
216 std::cout << line <<
"\n";
221 std::stringstream streamline(line);
227 if (nodeid != count_nodes)
228 throw std::invalid_argument(
"Error: Invalid file");
232 streamline >> time_idx;
236 streamline >> freq_idx;
240 streamline >> scale_idx;
244 streamline >> value_avg;
248 streamline >> value_stdev;
252 streamline >> endnode_flag;
257 bool read_ok =
static_cast<bool> (streamline >> node);
260 ancestors.insert(node);
264 add_node(nodeid, time_idx, freq_idx, scale_idx, value_avg, value_stdev, endnode_flag, ancestors);
281 std::cout <<
"stride=" <<
stride <<
" span=" <<
span;
285 for (
int node_id=0; node_id !=
graph.size(); ++node_id) {
286 std::cout << node_id <<
" (" <<
nodeid(node_id) <<
"): ";
289 std::cout <<
" [no ancestor] \n";
293 nodeids::iterator anc;
295 std::cout << *anc <<
" ";
311 std::set<int> marked_nodes;
327 marked_nodes.insert(
nodeid);
332 nodeids::iterator anc;
335 if ( marked_nodes.find(*anc) == marked_nodes.end() )
339 marked_nodes.insert(
nodeid);
349 std::vector<int>& best_ancestor,
const std::vector<double> weights) {
364 std::cout <<
"debug flag1 heaviest_path: looking at node " <<
nodeid <<
":";
370 if (ancestors.empty()) {
372 std::cout <<
"[no ancestors]\n";
376 best_ancestor[
nodeid] = -1;
381 nodeids::const_iterator first = ancestors.begin();
382 if (ancestors.size() == 1) {
384 std::cout <<
"[one ancestor] select " << *first <<
"\n";
386 total_weight.at(nodeid) = total_weight.at(*first)+weights.at(nodeid);
387 total_length.at(nodeid) = total_length.at(*first)+1;
388 best_ancestor.at(nodeid) = *first;
393 std::cout <<
"[many ancestors] find max ";
397 double best_weight = total_weight.at(*first);
398 int best_length = total_length.at(*first);
399 int best_anc = *first;
400 for (nodeids::const_iterator anc = ancestors.begin(); anc != ancestors.end(); ++anc) {
402 if (total_weight.at(*anc) > best_weight) {
403 best_weight = total_weight.at(*anc);
404 best_length = total_length.at(*anc);
410 std::cout <<
"select " << best_anc <<
"\n";
413 total_weight.at(nodeid) = best_weight+weights.at(nodeid);
414 total_length.at(nodeid) = best_length+1;
415 best_ancestor.at(nodeid) = best_anc;
427 std::cout <<
"data scalemin= " << log2(
get_scale(data.front())) <<
", graph scalemin= " <<
scalemin <<
"\n";
430 std::cerr <<
"Error: min scale of graph does not match that of data\n";
437 std::cout <<
"data scalemax= " << log2(
get_scale(data.back())) <<
", graph scalemax= " <<
scalemax <<
"\n";
440 std::cerr <<
"Error: max scale of graph does not match that of data\n";
446 std::cout <<
"data nscales= " << data.size() <<
", graph nscales= " <<
nscales <<
"\n";
449 std::cerr <<
"Error: scale axis of graph does not match that of data\n";
454 std::cerr <<
"Error: scale axis sampling is not contiguous\n";
459 std::cerr <<
"Error: sampling frequency of the graph does not match that of data\n";
469 size_t n = vec.size() / 2;
470 nth_element(vec.begin(), vec.begin()+
n, vec.end());
475 wavegraph::clustering(
const double threshold,
const std::vector<
WSeries<double>* >& data,
const double strip_edges,
const int path_halfwidth,
const double penal_factor,
const std::vector<double>& energy_thresholds){
502 throw std::invalid_argument(
"Error: graph and data are incompatible");
505 int strip_scalemax = 0;
507 strip_scalemax = strip_edges*(2*data.back()->resolution());
510 std::cout <<
"debug flag0 clustering: main loop\n";
511 std::cout <<
"strip_max = " << strip_scalemax <<
"\n";
515 std::vector < std::vector<double> > noise_levels;
516 for (
int k=0;
k<data.size();
k++) {
519 std::vector<double> non_zero_data;
523 non_zero_data.push_back(value);
525 if (non_zero_data.empty())
526 noise_level.push_back(0.0);
528 noise_level.push_back(
median(non_zero_data));
530 noise_levels.push_back(noise_level);
534 std::cout <<
"noise level estimates:\n";
535 for (
int k=0;
k<noise_levels.size();
k++) {
536 std::cout <<
"scale=" <<
k <<
": ";
537 for (
int m=0;
m<noise_levels[
k].size();
m++) {
538 std::cout << noise_levels[
k].at(
m) <<
" ";
548 std::vector<wavepath> selected_paths;
551 for (
int block_offset_scalemax = strip_scalemax; block_offset_scalemax <= end_scalemax; block_offset_scalemax +=
get_stride()) {
554 std::cout <<
"debug flag1 clustering: feed weight table\n";
558 std::vector<double> weights(
size(),0.0);
566 std::cout <<
"debug flag2 clustering: accessing pixel t=" << node_offset+
time(
nodeid);
567 std::cout <<
" f=" <<
freq(
nodeid) <<
" scale=" <<
scale(
nodeid) <<
" with block_offset=" << block_offset_scalemax <<
"/" << end_scalemax <<
"\n";
571 throw std::string(
"Error: requested position exceed allocated limits");
575 weights[
nodeid]= pixel_data > energy_thresholds.at(
scale(
nodeid)) ? pixel_data : 0.0 ;
577 for (
int n=1;
n<=path_halfwidth; ++
n) {
579 weights[
nodeid]+= pixel_data > energy_thresholds.at(
scale(
nodeid)) ? pixel_data : 0.0 ;
581 weights[
nodeid]+= pixel_data > energy_thresholds.at(
scale(
nodeid)) ? pixel_data : 0.0 ;
587 std::cout <<
"debug flag2 clustering: dynamic programming\n";
591 std::vector<double> total_weights(
size());
592 std::vector<int> total_lengths(
size());;
593 std::vector<int> best_ancestors(
size());;
594 heaviest_path(total_weights,total_lengths,best_ancestors,weights);
597 std::cout <<
"debug flag3 clustering: select and reconstruct best paths\n";
602 double best_weight=0;
603 for (
int node_id=0; node_id !=
size(); ++node_id) {
606 if (
is_endnode(node_id) & (total_weights[node_id] >= total_lengths[node_id]*(2*path_halfwidth+1)*threshold)) {
607 if (total_weights[node_id] > best_weight) {
608 best_weight = total_weights[node_id];
609 best_node_id = node_id;
615 if (best_node_id>0) {
619 int node=best_node_id;
624 std::cout <<
"path: " << node;
627 node = best_ancestors.at(node);
629 std::cout <<
"->" << node;
641 selected_paths.push_back(path);
645 std::cout << selected_paths.size() <<
" paths selected\n";
653 std::cout <<
"debug flag4 clustering: sort selected paths\n";
657 std::sort(selected_paths.begin(), selected_paths.end(),
compare_paths);
660 std::cout << selected_paths.size() <<
" selected paths\n";
667 std::vector<cluster> clusters;
668 std::vector<wavepath>::const_iterator this_path;
669 for (this_path = selected_paths.begin(); this_path != selected_paths.end(); ++this_path)
670 clusters.push_back(((
wavepath) *this_path).convert_to_cluster(log2(
get_scale(data.front())),data.back()->resolution(),path_halfwidth));
673 std::cout << clusters.size() <<
" selected clusters\n";
677 std::vector<cluster> univocal_clusters;
681 std::cout << univocal_clusters.size() <<
" univocal clusters\n";
682 if ( !univocal_clusters.empty() ) {
683 cluster best_cluster=univocal_clusters.front();
684 std::cout <<
"best cluster is:\n";
685 cluster::const_iterator this_pixel;
686 for (this_pixel=best_cluster.begin(); this_pixel != best_cluster.end(); ++this_pixel) {
687 std::cout <<
"timeix=" << ((
pixel) *this_pixel).timeix <<
" freqix=" << ((
pixel) *this_pixel).freqix <<
" scaleix=" << ((
pixel) *this_pixel).scaleix <<
" : ";
688 std::cout <<
" time=" << ((
pixel) *this_pixel).time <<
" freq=" << ((
pixel) *this_pixel).freq <<
" log_2 scale=" << ((
pixel) *this_pixel).log2scale <<
"\n";
693 return univocal_clusters;
std::vector< cluster > clustering(const double threshold, const std::vector< WSeries< double > * > &data, const double strip_edges, const int path_halfwidth, const double penal_factor, const std::vector< double > &energy_thresholds)
bool is_compatible(const std::vector< WSeries< double > * > &data)
std::vector< pixel > cluster
int num_of_time_bins(WSeries< double > *WS)
double median(std::vector< double > &vec)
std::vector< cluster > select_clusters_distinct_in_time(std::vector< cluster > &sorted_clusters, const double precision)
void heaviest_path(std::vector< double > &total_weight, std::vector< int > &total_length, std::vector< int > &best_ancestor, const std::vector< double > weights)
float get_map00(WSeries< double > *WS, int index)
void init(const wavenode node, const int offset, const int refscaleidx, const double path_weight)
wavenode get_node(int id)
bool is_topologically_sorted()
int num_of_freq_bins(WSeries< double > *WS)
bool bothspaces(char lhs, char rhs)
void add_node(const int nodeidx, const int timeidx, const int freqidx, const int scaleidx, const double value_avg, const double value_stdev, const bool endnode, const nodeids &ancestors)
nodeids get_ancestors(int id)
void create(const std::string &srcfile)
int get_scale(WSeries< double > *WS)
bool compare_paths(const wavepath &path1, const wavepath &path2)
void add_node(const wavenode node)
graph_header_code header_hash(std::string const &str)