diff --git a/meson.build b/meson.build
index 22a8aeb53891f488c93ee57ee4be4c65fd5de42d..c9e2a774808f0677541491c302ab01c3b5c49525 100644
--- a/meson.build
+++ b/meson.build
@@ -10,20 +10,25 @@ if shared_only
   message('Building only the RTBF shared library')
 else
   message('Builidng the RTBF library *and* unit tests')
-  message('PGPLOT is a required dependency for unit tests')
 endif
 
-if not shared_only
-  #### plot deps
-  pgplot_dep = cc.find_library('pgplot', required: true)
-  cpgplot_dep = cc.find_library('cpgplot', required: true)
-
-  gfortran_dep = cc.find_library('gfortran')
-  x11_dep = dependency('X11')
-  png_dep = dependency('libpng')
-  zlib_dep = dependency('zlib')
+use_pgplot = get_option('USE_PGPLOT')
+plot_deps = []
+if not shared_only and use_pgplot
+  # deps for plotting in unit tests
+  pgplot_dep = cc.find_library('pgplot', required: false)
+  cpgplot_dep = cc.find_library('cpgplot', required: false)
+  if pgplot_dep.found() and cpgplot_dep.found()
+    gfortran_dep = cc.find_library('gfortran')
+    x11_dep = dependency('X11')
+    png_dep = dependency('libpng')
+    zlib_dep = dependency('zlib')
+    plot_deps = [cpgplot_dep, pgplot_dep, gfortran_dep, x11_dep, png_dep, zlib_dep]
+    use_pgplot = true
+  else
+    message('PGPLOT is a required dependency for unit tests with plotting')
+  endif
 
-  plot_deps = [cpgplot_dep, pgplot_dep, gfortran_dep, x11_dep, png_dep, zlib_dep]
 endif
 
 m_dep = cc.find_library('m')
@@ -48,8 +53,14 @@ rtbf_cdata.set('RTBF_NTIME', rtbf_ntime)
 rtbf_cdata.set('RTBF_NBEAM', rtbf_nbeam)
 rtbf_cdata.set('RTBF_STI_LENGTH', rtbf_sti_length)
 rtbf_cdata.set('RTBF_STI_GPU_BLOC', rtbf_sti_gpu_block)
+rtbf_cdata.set10('HAVE_PGPLOT', use_pgplot, description: 'include plotting code in unit tests')
 
 if not meson.is_subproject()
+  ninput_per_fid = get_option('XB_INPUT_PER_FID')
+  ntime_per_pkt  = get_option('XB_TIME_PER_FID')
+  rtbf_cdata.set10('HAVE_SYSTEM_CONF', true, description: 'indicates that a system rtbf_config.h is used')
+  rtbf_cdata.set('F_ELES_PER_PKT', ninput_per_fid, description: 'number of inputs per FID')
+  rtbf_cdata.set('F_TIME_PER_PKT', ntime_per_pkt, description: 'number of time samples per FID packet (mcount)')
   configure_file(output: 'rtbf_config.h', configuration: rtbf_cdata)
 endif
 
@@ -80,7 +91,6 @@ executable(
   install: true)
 
 if not shared_only
-
   executable(
     'demortbf', demo_rtbf_src,
     link_with: rtbf_lib,
diff --git a/meson_options.txt b/meson_options.txt
index 4bb1ce3e47b362d7e7dcf6214c1f41840b696fd7..74552db28283b21bd483e2602cc992731c60782a 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -8,4 +8,12 @@ option('RTBF_STI_GPU_BLOCK', type: 'integer', min : 8,   max : 1024,  value : 32
 
 option('CUDA_ARCH', type:'string', value:'sm_86', description: 'cuda architecture')
 
-option('LIB_ONLY', type:'boolean', value:'false', description: 'to build unit tests with plotting')
+option('LIB_ONLY',   type:'boolean', value:'false', description: 'build unit tests')
+option('USE_PGPLOT', type:'boolean', value:'false', description: 'include plotting code in unit tests')
+
+# needed for building to benchmark using standalone demo code
+option('XB_INPUT_PER_FID', type: 'integer', min: 2, max: 16, value: 12,
+  description: 'inputs (antennas) per fid')
+
+option('XB_TIME_PER_FID',  type: 'integer', min: 1, value: 14,
+  description: 'time samples per network packet')
diff --git a/src/corr_demo.c b/src/corr_demo.c
index b05e73ca214c76c6db9bdb754c64110ef7eb2bd3..35fdbd679f1e400bb14f8c31db7918bddf81ed0d 100644
--- a/src/corr_demo.c
+++ b/src/corr_demo.c
@@ -9,28 +9,35 @@
 #include <complex.h>
 
 #include "cublas_beamformer.h"
+
+#if HAVE_PGPLOT
 #include "cpgplot.h"
+#endif // HAVE_PGPLOT
 
 #define ELAPSED_MS(start,stop) \
   ((((int64_t)stop.tv_sec-start.tv_sec)*1000*1000*1000+(stop.tv_nsec-start.tv_nsec))/1e6)
 
-//#define RUN_UNIT_TEST
-#ifdef RUN_UNIT_TEST
-
-// TODO figure out how to get these into the program without tons of args
-// unit test definition
-#define INPUT_PER_FID 4      // inputs per fid
-#define NUM_FIDS      2      // number of fids
-#define TIME_PER_PKT  10     // time per network packet
-#define MCNT_PER_BLK  40     // mcounts per block
-
-#else
-// xb system definition
-#define INPUT_PER_FID 12     // inputs per fid
-#define NUM_FIDS      12     // number of fids
-#define TIME_PER_PKT  14     // time per network packet
-#define MCNT_PER_BLK  384    // mcounts per block
-#endif
+#ifndef HAVE_SYSTEM_CONF
+// FID (packet) and xb engine block definitions that do not come baked into cublas_beamformer.h
+// TODO these are rather annoying to need ot have and are only here to create
+// meaningful data that isn't noise for the beamformer tests.
+//
+// The other less meaningful reason is that with the transpose kernel baked into
+// the rtbf we need to provide values to at context creation. But since the
+// products must equal what the library is compiled for only a small set of
+// configurations work and so it would be better to just use a build time
+// configuration rather then changing hardcoded values or taking commadline args
+
+// ALPACA specifications
+#define F_ELES_PER_PKT     12  // elements per fengine
+#define F_TIME_PER_PKT     14  // time samples per packet mcount
+#endif// HAVE_SYSTEM_CONF
+
+// map from system conf name to local definitions as used in this compilation unit
+#define INPUT_PER_FID   F_ELES_PER_PKT                 // inputs per fid
+#define TIME_PER_PKT    F_TIME_PER_PKT                 // time per network packet
+#define MCNT_PER_BLK    (RTBF_NTIME/F_TIME_PER_PKT)    // mcounts per block
+#define NUM_FIDS        (RTBF_NANTENNA/F_ELES_PER_PKT) // number of fids
 
 #ifndef MAX
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
@@ -339,8 +346,10 @@ int main(int argc, char* argv[]) {
     clock_gettime(CLOCK_MONOTONIC, &stop);
     total += ELAPSED_MS(start, stop);
     printf("run_correlator() time = %f ms\n", (float) ELAPSED_MS(start,stop));
+#if HAVE_PGPLOT
     // check
     if (doDump && verbose && mode==BEAM_OP_COR) {
+
       cpgopen("/xwin"); // docs say cpgopen should be used over beg now
       cpgask(1);
 
@@ -427,6 +436,7 @@ int main(int argc, char* argv[]) {
       free(bin_matrix_power);
       cpgend();
     }
+#endif // HAVE_PGPLOT
     // clear integration buffer on dump
     if (doDump) {
       doDump = 0;
diff --git a/src/rtbf_demo.c b/src/rtbf_demo.c
index da22242de1513e7688f34674d20321d7cf12a061..5eda9a3a281f3d9d0930a7380844d4c4c2381d88 100644
--- a/src/rtbf_demo.c
+++ b/src/rtbf_demo.c
@@ -9,28 +9,35 @@
 #include <complex.h>
 
 #include "cublas_beamformer.h"
+
+#if HAVE_PGPLOT
 #include "cpgplot.h"
+#endif // HAVE_PGPLOT
 
 #define ELAPSED_MS(start,stop) \
   ((((int64_t)stop.tv_sec-start.tv_sec)*1000*1000*1000+(stop.tv_nsec-start.tv_nsec))/1e6)
 
-//#define RUN_UNIT_TEST
-#ifdef RUN_UNIT_TEST
-
-// TODO figure out how to get these into the program without tons of args
-// unit test definition
-#define INPUT_PER_FID 4      // inputs per fid
-#define NUM_FIDS      2      // number of fids
-#define TIME_PER_PKT  10     // time per network packet
-#define MCNT_PER_BLK  40     // mcounts per block
-
-#else
-// xb system definition
-#define INPUT_PER_FID 12     // inputs per fid
-#define NUM_FIDS      12     // number of fids
-#define TIME_PER_PKT  14     // time per network packet
-#define MCNT_PER_BLK  384    // mcounts per block
-#endif
+#ifndef HAVE_SYSTEM_CONF
+// FID (packet) and xb engine block definitions that do not come baked into cublas_beamformer.h
+// TODO these are rather annoying to need ot have and are only here to create
+// meaningful data that isn't noise for the beamformer tests.
+//
+// The other less meaningful reason is that with the transpose kernel baked into
+// the rtbf we need to provide values to at context creation. But since the
+// products must equal what the library is compiled for only a small set of
+// configurations work and so it would be better to just use a build time
+// configuration rather then changing hardcoded values or taking commadline args
+
+// ALPACA specifications
+#define F_ELES_PER_PKT     12  // elements per fengine
+#define F_TIME_PER_PKT     14  // time samples per packet mcount
+#endif// HAVE_SYSTEM_CONF
+
+// map from system conf name to local definitions as used in this compilation unit
+#define INPUT_PER_FID   F_ELES_PER_PKT                 // inputs per fid
+#define TIME_PER_PKT    F_TIME_PER_PKT                 // time per network packet
+#define MCNT_PER_BLK    (RTBF_NTIME/F_TIME_PER_PKT)    // mcounts per block
+#define NUM_FIDS        (RTBF_NANTENNA/F_ELES_PER_PKT) // number of fids
 
 void rtbfFillDataBlock(complex16_t *array_input_data, RTBFContext *context) {
   static int blockcounter = -1;
@@ -274,6 +281,7 @@ int main(int argc, char* argv[]) {
   int NT = rtbf_info.ntime;           // time per block
   long long unsigned int S = rtbf_info.array_len; // number of complex elements in a block size
 
+  printf("INPUT_PER_FID=%d, Ni=%d, Nf=%d\n", INPUT_PER_FID, Ni, Nf);
   // validate test xb-engine system parameters with library compiled parameters
   if (Ni*Nf != Ne) {
     printf("Element configuration error:\n"
@@ -423,6 +431,7 @@ int main(int argc, char* argv[]) {
       }
     }
 
+#if HAVE_PGPLOT
     // check output for RAW (by plotting)
     if (verbose && mode==BEAM_OP_RAW) {
       cpgopen("/xwin"); // docs say cpgopen should be used over beg now
@@ -510,6 +519,7 @@ int main(int argc, char* argv[]) {
       free(angles_pattern);
       cpgend();
     }
+#endif
 
     // check output for beam power
     if (verbose && mode==BEAM_OP_PSD) {
diff --git a/src/unit_beam_op_raw.c b/src/unit_beam_op_raw.c
index f4e0baf061e5f62b65dc6d137207930686fb046a..95b330d700193fdab14ab4b90a5209f2e47733cc 100644
--- a/src/unit_beam_op_raw.c
+++ b/src/unit_beam_op_raw.c
@@ -10,27 +10,35 @@
 
 #include "cublas_beamformer.h"
 
+#if HAVE_PGPLOT
 #include "cpgplot.h"
+#endif // HAVE_PGPLOT
 
 //#define RUN_UNIT_TEST
-#ifdef RUN_UNIT_TEST
-#include "unit_test.h"
-
-// unit test definition
-#define Ni 4        // inputs per fid
-#define Nf 2        // number of fids
-#define Nt 10       // time per network packet
-#define Nm 40       // mcounts per block
-#define Bk 1        // number of data blocks
-
-#else
-// xb system definition
-#define Ni 10     // inputs per fid
-#define Nf 16     // number of fids
-#define Nt 14     // time per network packet
-#define Nm 336    // mcounts per block
-#define Bk 1      // number of data blocks
-#endif
+//#ifdef RUN_UNIT_TEST
+//#include "unit_test.h"
+
+#ifndef HAVE_SYSTEM_CONF
+// FID (packet) and xb engine block definitions that do not come baked into cublas_beamformer.h
+// TODO these are rather annoying to need ot have and are only here to create
+// meaningful data that isn't noise for the beamformer tests.
+//
+// The other less meaningful reason is that with the transpose kernel baked into
+// the rtbf we need to provide values to at context creation. But since the
+// products must equal what the library is compiled for only a small set of
+// configurations work and so it would be better to just use a build time
+// configuration rather then changing hardcoded values or taking commadline args
+
+// ALPACA specifications
+#define F_ELES_PER_PKT     12  // elements per fengine
+#define F_TIME_PER_PKT     14  // time samples per packet mcount
+#endif// HAVE_SYSTEM_CONF
+
+// map from system conf name to local definitions as used in this compilation unit
+#define INPUT_PER_FID   F_ELES_PER_PKT                 // inputs per fid
+#define TIME_PER_PKT    F_TIME_PER_PKT                 // time per network packet
+#define MCNT_PER_BLK    (RTBF_NTIME/F_TIME_PER_PKT)    // mcounts per block
+#define NUM_FIDS        (RTBF_NANTENNA/F_ELES_PER_PKT) // number of fids
 
 typedef struct {
   float re;
@@ -43,6 +51,11 @@ int main(int argc, char* argv[]) {
   RTBFInfo rtbf_info;
   rtbfInfo(&rtbf_info);
 
+  int Ni = INPUT_PER_FID;
+  int Nf = NUM_FIDS;
+  int Nt = TIME_PER_PKT;
+  int Nm = MCNT_PER_BLK;
+
   int Ne = rtbf_info.narray_elements; // elements in array
   int Nc = rtbf_info.nbin;            // frequency channels (bins)
   int Nb = rtbf_info.nbeam;           // single pol. formed beams
@@ -232,6 +245,7 @@ int main(int argc, char* argv[]) {
     }
   }
 
+#if HAVE_PGPLOT
   // LET's PLOT
   // prepare cpgplot
   if (1)
@@ -305,7 +319,9 @@ int main(int argc, char* argv[]) {
 
     cpgend();
   }
+#endif // HAVE_PGPLOT
 
+/* old code from early work to quickly make, compare/test outputs */
   // dump bytes for creating unit test
   // `./a.out | xxd -i >> unit_test.h`
   if (0) {
diff --git a/src/unit_loadweight_raw.c b/src/unit_loadweight_raw.c
index d52179bd49cbe7544c4273e5fd3f0ca24bca1c33..6251bbfce2515f479bbef9e83499f1cb8fbc5627 100644
--- a/src/unit_loadweight_raw.c
+++ b/src/unit_loadweight_raw.c
@@ -10,27 +10,35 @@
 
 #include "cublas_beamformer.h"
 
+#if HAVE_PGPLOT
 #include "cpgplot.h"
+#endif // HAVE_PGPLOT
 
 //#define RUN_UNIT_TEST
-#ifdef RUN_UNIT_TEST
-#include "unit_test.h"
-
-// unit test definition
-#define Ni 4        // inputs per fid
-#define Nf 2        // number of fids
-#define Nt 10       // time per network packet
-#define Nm 40       // mcounts per block
-#define Bk 1        // number of data blocks
-
-#else
-// xb system definition
-#define Ni 10     // inputs per fid
-#define Nf 16     // number of fids
-#define Nt 14     // time per network packet
-#define Nm 336    // mcounts per block
-#define Bk 1      // number of data blocks
-#endif
+//#ifdef RUN_UNIT_TEST
+//#include "unit_test.h"
+
+#ifndef HAVE_SYSTEM_CONF
+// FID (packet) and xb engine block definitions that do not come baked into cublas_beamformer.h
+// TODO these are rather annoying to need ot have and are only here to create
+// meaningful data that isn't noise for the beamformer tests.
+//
+// The other less meaningful reason is that with the transpose kernel baked into
+// the rtbf we need to provide values to at context creation. But since the
+// products must equal what the library is compiled for only a small set of
+// configurations work and so it would be better to just use a build time
+// configuration rather then changing hardcoded values or taking commadline args
+
+// ALPACA specifications
+#define F_ELES_PER_PKT     12  // elements per fengine
+#define F_TIME_PER_PKT     14  // time samples per packet mcount
+#endif// HAVE_SYSTEM_CONF
+
+// map from system conf name to local definitions as used in this compilation unit
+#define INPUT_PER_FID   F_ELES_PER_PKT                 // inputs per fid
+#define TIME_PER_PKT    F_TIME_PER_PKT                 // time per network packet
+#define MCNT_PER_BLK    (RTBF_NTIME/F_TIME_PER_PKT)    // mcounts per block
+#define NUM_FIDS        (RTBF_NANTENNA/F_ELES_PER_PKT) // number of fids
 
 typedef struct {
   float re;
@@ -44,6 +52,11 @@ int main(int argc, char* argv[]) {
   RTBFInfo rtbf_info;
   rtbfInfo(&rtbf_info);
 
+  int Ni = INPUT_PER_FID;
+  int Nf = NUM_FIDS;
+  int Nt = TIME_PER_PKT;
+  int Nm = MCNT_PER_BLK;
+
   int Ne = rtbf_info.narray_elements; // elements in array
   int Nc = rtbf_info.nbin;            // frequency channels (bins)
   int Nb = rtbf_info.nbeam;           // single pol. formed beams
@@ -237,6 +250,7 @@ int main(int argc, char* argv[]) {
     }
   }
 
+#if HAVE_PGPLOT
   // LET's PLOT
   // prepare cpgplot
   if (1)
@@ -310,7 +324,9 @@ int main(int argc, char* argv[]) {
 
     cpgend();
   }
+#endif // HAVE_PGPLOT
 
+/* old code from early work to quickly make, compare/test outputs */
   // dump bytes for creating unit test
   // `./a.out | xxd -i >> unit_test.h`
   if (0) {