void DigitiserCountsPlot::CheckCounts( const Archive *const_data ) { Archive *data = const_cast<Archive*>( const_data ); Reference::To<DigitiserCounts> counts = data->get<DigitiserCounts>(); if( !counts ) { if( verbose > 1 ) cerr << "Attempted to plot DigitiserCounts on an archive without a DigitiserCounts countsension" << endl; return; } int npthist = counts->get_npthist(); int ndigr = counts->get_ndigr(); int nlev = counts->get_nlev(); if( npthist == 0 || nlev == 0 || ndigr == 0 ) { if( verbose > 1 ) cerr << "Attempted to plot DigitiserCounts on an archive without parameter (npthist,ndigr,nlev)" << endl; return; } valid_data = true; }
void DigitiserCountsPlot::draw( const Archive *const_data ) { Reference::To<Archive> data = const_cast<Archive*>( const_data ); if( !valid_data ) return; Reference::To<DigitiserCounts> counts = data->get<DigitiserCounts>(); if( !counts ) return; int ndigr = counts->get_ndigr(); int npthist = counts->get_npthist(); // the range of non zero indices int nz_range = (last_nz - first_nz) + 1; // for each subint // save the old color // for each digitiser channel // for each index in the non zero range // calculate the ncounts x coord // calculate the ncounts y coord // draw a binned histogram of x and y // restore the old color float xstep = 1.0 / nz_range; for( int s = srange.first; s <= srange.second; s ++ ) { int old_col; cpgqci( &old_col ); int ncounts_col = old_col; for( int c = 0; c < ndigr; c ++ ) { float xs[ nz_range ]; float ys[ nz_range ]; for( int j = 0; j < nz_range; j ++ ) { xs[j] = j * xstep + c; ys[j] = counts->subints[s].data[(first_nz+j) + c * npthist] + y_jump * (s-srange.first); } cpgsci( ncounts_col++ ); cpgbin( nz_range, xs, ys, 1 ); } cpgsci( old_col ); } // get the viewport range including buffer float vp_y1, vp_y2; get_frame()->get_y_scale()->get_range_external( vp_y1, vp_y2 ); // Save the current viewport, so that we can adjust relative to it and restore it later. float tx_min, tx_max, ty_min, ty_max; cpgqvp( 0, &tx_min, &tx_max, &ty_min, &ty_max ); // For each digitiser channel // set the viewport to cover that channel // set the window to have x ranging from -256 to 255 // draw a box around the viewport float nx = tx_min; float xw = (tx_max-tx_min) * (1.0/ndigr); for( int c = 0; c < ndigr; c ++ ) { cpgsvp( nx, nx + xw, ty_min, ty_max ); cpgswin( first_nz - 256, last_nz - 256, vp_y1, vp_y2 ); if( nx == tx_min ) cpgbox("bcnt", 0.0, 0, "bcnt", 0.0, 0); else cpgbox("bcnt", 0.0, 0, "bct", 0.0, 0 ); char pol = char( int('A') + c ); string dig_label = string("Pol ") + tostring(pol); cpgmtxt( "T", -1, 0.01, 0, dig_label.c_str() ); nx += xw; } // Restore the original viewport cpgsvp( tx_min, tx_max, ty_min, ty_max ); }
void DigitiserCountsPlot::prepare( const Archive *const_data ) { CheckCounts( const_data ); if( !valid_data ) return; Reference::To<Archive> data = const_cast<Archive*>(const_data); if( !data ) return; Reference::To<DigitiserCounts> counts = data->get<DigitiserCounts>(); if( !counts ) return; int num_rows = counts->subints.size(); int npthist = counts->get_npthist(); int ndigr = counts->get_ndigr(); // Make sure srange.first,srange.second have the subint range we want to display if( srange.first == -1 && srange.second == -1 ) { if( subint == -1 ) { srange.first = 0; srange.second = num_rows -1; } else { srange.first = subint; srange.second = subint; } } // Should optimize this, at present just create a separate array for data thats scaled properly // adjusted_data.resize( num_rows ); // for( int s = 0; s < num_rows; s ++ ) // { // adjusted_data[s].resize( ndigr * npthist ); // for( int d = 0; d < ndigr * npthist; d ++ ) // { // adjusted_data[s][d] = float(counts->rows[s].data[d]) * counts->rows[s].data_scl + counts->rows[s].data_offs; // } // } // Determine the first and last indices with non zero data in all channels/subints // Some files have data values close to zero but negligible, treat anything under // 10 as effectively zero. first_nz = npthist; last_nz = 0; for( int s = srange.first; s <= srange.second; s ++ ) { for( int c = 0; c < ndigr; c ++ ) { for( int v = 0; v < npthist; v ++ ) { float ncounts_value = counts->subints[s].data[c*npthist + v]; if( ncounts_value > 10 ) { if( v < first_nz ) first_nz = v; break; } } for( int v = npthist - 1; v >= 0; v -- ) { float ncounts_value = counts->subints[s].data[c*npthist + v]; if( ncounts_value > 10 ) { if( v > last_nz ) last_nz = v; break; } } } } // sanity check, if first_nz >= last_nz, then we have all zeroes, just plot the whole thing if( first_nz >= last_nz ) { first_nz = 0; last_nz = npthist; } // Find the min and max counts for all subints and channels min_count = FLT_MAX; max_count = -FLT_MAX; for( int s = srange.first ; s <= srange.second; s ++ ) cyclic_minmax( counts->subints[s].data, first_nz, last_nz, min_count, max_count ); // y_range is how far up the y axis each subint goes float y_range = max_count - min_count; // y_jump is how far to increase y between subints, adjust to nearest 10,000 y_jump = y_range * 0.75; y_jump = int( y_jump / 10000 ) + 1; y_jump *= 10000; // set the ranges for the axes, we hide the axes becase we need to draw a box for // each digitiser channel later. // TODO find out why we need to hard code the buffer here get_frame()->get_y_scale()->set_minmax( min_count , max_count + y_jump * (srange.second - srange.first) ); get_frame()->get_y_scale()->set_buf_norm( 0.05 ); get_frame()->get_x_scale()->set_minmax( 0, counts->get_ndigr() ); get_frame()->hide_axes(); }
void DigitiserCountsPlot::draw( const Archive *const_data ) try { Reference::To<Archive> data = const_cast<Archive*>( const_data ); if( !valid_data ) return; Reference::To<DigitiserCounts> counts = data->get<DigitiserCounts>(); if( !counts ) return; int ndigr = counts->get_ndigr(); int npthist = counts->get_npthist(); // the range of non zero indices int nz_range = (last_nz - first_nz) + 1; // for each subint // save the old color // for each digitiser channel // for each index in the non zero range // calculate the ncounts x coord // calculate the ncounts y coord // draw a binned histogram of x and y // restore the old color float xstep = 1.0 / nz_range; for( int s = srange.first; s <= srange.second; s ++ ) { int old_col; cpgqci( &old_col ); int ncounts_col = old_col; for( int c = 0; c < ndigr; c ++ ) { float xs[ nz_range ]; float ys[ nz_range ]; for( int j = 0; j < nz_range; j ++ ) { xs[j] = j * xstep + c; ys[j] = counts->subints.at(s).data[(first_nz+j) + c * npthist] + y_jump * (s-srange.first); cerr << "y[" << j << "]=" << ys[j] << endl; if (logscale) { if (ys[j] < 1) ys[j] = -40; // effectively zero else ys[j] = log10(ys[j]); } } cpgsci( ncounts_col++ ); cpgbin( nz_range, xs, ys, 1 ); } cpgsci( old_col ); } // get the viewport range including buffer float vp_y1, vp_y2; get_frame()->get_y_scale()->get_range_external( vp_y1, vp_y2 ); // Save the current viewport, so that we can adjust relative to it and restore it later. float tx_min, tx_max, ty_min, ty_max; cpgqvp( 0, &tx_min, &tx_max, &ty_min, &ty_max ); // For each digitiser channel // set the viewport to cover that channel // set the window to have x ranging from -npthist/2 to npthist/2 // draw a box around the viewport float nx = tx_min; float xw = (tx_max-tx_min) * (1.0/ndigr); for( int c = 0; c < ndigr; c ++ ) { cpgsvp( nx, nx + xw, ty_min, ty_max ); // subtracting npthist/2 assumes offset binary encoding - WvS 23 Jan 2017 cpgswin( first_nz - npthist/2, last_nz - npthist/2, vp_y1, vp_y2 ); string yopt = "bct"; if( nx == tx_min ) yopt += "n"; if (logscale) yopt += "l"; cpgbox("bcnt", 0.0, 0, yopt.c_str(), 0.0, 0); char pol = char( int('A') + c ); string dig_label = string("Pol ") + tostring(pol); cpgmtxt( "T", -1, 0.01, 0, dig_label.c_str() ); nx += xw; } // Restore the original viewport cpgsvp( tx_min, tx_max, ty_min, ty_max ); } catch (std::exception& e) { throw Error (FailedCall, "DigitiserCountsPlot::prepare", e.what()); }
void DigitiserCountsPlot::prepare( const Archive *const_data ) try { CheckCounts( const_data ); if( !valid_data ) return; Reference::To<Archive> data = const_cast<Archive*>(const_data); if( !data ) return; Reference::To<DigitiserCounts> counts = data->get<DigitiserCounts>(); if( !counts ) return; int num_rows = counts->subints.size(); int npthist = counts->get_npthist(); int ndigr = counts->get_ndigr(); // Make sure srange.first,srange.second have the subint range we want to display if( srange.first == -1 && srange.second == -1 ) { if( subint == -1 ) { srange.first = 0; srange.second = num_rows -1; } else { srange.first = subint; srange.second = subint; } } // Should optimize this, at present just create a separate array for data thats scaled properly // adjusted_data.resize( num_rows ); // for( int s = 0; s < num_rows; s ++ ) // { // adjusted_data[s].resize( ndigr * npthist ); // for( int d = 0; d < ndigr * npthist; d ++ ) // { // adjusted_data[s][d] = float(counts->rows[s].data[d]) * counts->rows[s].data_scl + counts->rows[s].data_offs; // } // } /* Determine the first and last indices with non zero data in all channels/subints. */ first_nz = npthist; last_nz = 0; float minimum_value = 10; if (logscale) minimum_value = 1; else { /* If not plotting on a log scale, treat anything smaller than zero_threshold * the maximum histogram value as zero. */ long maxval = 0; for( int s = srange.first; s <= srange.second; s ++ ) for( int c = 0; c < ndigr; c ++ ) for( int v = 0; v < npthist; v ++ ) maxval = std::max( maxval, counts->subints.at(s).data[c*npthist + v] ); minimum_value = zero_threshold * maxval; } for( int s = srange.first; s <= srange.second; s ++ ) { for( int c = 0; c < ndigr; c ++ ) { for( int v = 0; v < npthist; v ++ ) { float ncounts_value = counts->subints.at(s).data[c*npthist + v]; if( ncounts_value >= minimum_value ) { if( v < first_nz ) first_nz = v; break; } } for( int v = npthist - 1; v >= 0; v -- ) { float ncounts_value = counts->subints.at(s).data[c*npthist + v]; if( ncounts_value >= minimum_value ) { if( v > last_nz ) last_nz = v; break; } } } } // sanity check, if first_nz >= last_nz, then we have all zeroes, just plot the whole thing bool all_zero = first_nz >= last_nz; if (all_zero) { first_nz = 0; last_nz = npthist; } // Find the min and max counts for all subints and channels min_count = FLT_MAX; max_count = -FLT_MAX; for( int s = srange.first ; s <= srange.second; s ++ ) cyclic_minmax( counts->subints.at(s).data, first_nz, last_nz, min_count, max_count ); if (logscale && !all_zero) { min_count = 0; max_count = log10(max_count); } // y_range is how far up the y axis each subint goes float y_range = max_count - min_count; // y_jump is how far to increase y between subints, adjust to nearest 10,000 y_jump = y_range * 0.75; y_jump = int( y_jump / 10000 ) + 1; y_jump *= 10000; // set the ranges for the axes, we hide the axes becase we need to draw a box for // each digitiser channel later. // TODO find out why we need to hard code the buffer here get_frame()->get_y_scale()->set_minmax( min_count , max_count + y_jump * (srange.second - srange.first) ); get_frame()->get_y_scale()->set_buf_norm( 0.05 ); get_frame()->get_x_scale()->set_minmax( 0, counts->get_ndigr() ); get_frame()->hide_axes(); } catch (std::exception& e) { throw Error (FailedCall, "DigitiserCountsPlot::prepare", e.what()); }
void DigitiserStatsPlot::prepare( const Archive *const_arch ) { Reference::To<Archive> arch = const_cast<Archive*>( const_arch ); Reference::To<DigitiserStatistics> ext = arch->get<DigitiserStatistics>(); if( CheckStats( ext ) ) { ncycsub = ext->get_ncycsub(); ndigr = ext->get_ndigr(); npar = ext->get_npar(); nsub = ext->rows.size(); AdjustSubRange(); y_min = FLT_MAX; y_max = -FLT_MAX; // The data in the file isn't how we would like it. [p1][p2][p3] etc what we want // is all the p1 values sequentially, then all the p2 etc. So create an array of // profiles [digitiser channel][parameter] then we just pass it to cpgline // when we want to draw them. Grab the min and max while we're doing this. profiles.resize( ndigr ); for( int g = 0; g < ndigr; g ++ ) { profiles[g].resize( npar ); for( int p = 0; p < npar; p ++ ) { profiles[g][p].resize( ncycsub * nsub ); for( int c = 0; c < ncycsub; c ++ ) { for( int s = srange.first; s <= srange.second; s ++ ) { float next_val = ext->rows[s].data[c*ndigr*npar + g*npar + p]; if( next_val < y_min ) y_min = next_val; if( next_val > y_max ) y_max = next_val; profiles[g][p][s*ncycsub + c] = next_val; } } } } if( !(y_min == 0 && y_max == 0) ) { valid_archive = true; // adjust the viewport to show all the data, don't overlap the subints, looks crap. get_frame()->get_y_scale()->set_minmax( y_min, y_max ); get_frame()->get_x_scale()->set_minmax( 0, ndigr ); get_frame()->get_y_scale()->set_buf_norm( .07 ); get_frame()->hide_axes(); } else { if( verbose > 1 ) cerr << "Digitiser Stats values are all zero" << endl; } } }