def validate_flat_gain_stability(results, det_names): """Valdiate the output files from the flat_gain_stability analysis""" if 'gainstability' not in get_analysis_types(): return results run = siteUtils.getRunNumber() missing_det_names = set() for det_name in det_names: file_prefix = make_file_prefix(run, det_name) results_file = f'{file_prefix}_flat_signal_sequence.pickle' if not os.path.isfile(results_file): missing_det_names.add(det_name) else: md = dict(DATA_PRODUCT='flat_gain_stability_results') results.append(siteUtils.make_fileref(results_file, metadata=md)) report_missing_data('validate_flat_gain_stability', missing_det_names) unit_id = siteUtils.getUnitId() png_files = glob.glob('*flat_gain_stability.png') for png_file in png_files: md = dict(DATA_PRODUCT='flat_gain_stability_plot') if unit_id in png_file: md['LsstId'] = unit_id results.append(siteUtils.make_fileref(png_file, metadata=md)) return results
def raft_results_task(raft_name): """Task to aggregate data for raft-level plots and results.""" import os import numpy as np import pandas as pd import matplotlib.pyplot as plt import lsst.eotest.sensor as sensorTest import lsst.eotest.raft as raftTest import siteUtils from camera_components import camera_info from bot_eo_analyses import get_raft_files_by_slot, make_file_prefix,\ get_amplifier_gains, get_analysis_types def plt_savefig(filename): plt.savefig(filename) plt.close() # Get results files for each CCD in the raft. try: results_files \ = get_raft_files_by_slot(raft_name, 'eotest_results.fits') print("results_files:", results_files) except FileNotFoundError: print("No raft-level results for", raft_name) results_files = {} # Determine the total number of pixels and number of edge rolloff # pixels for the types of CCDs in this raft and update the results # files. This info will be used in computing the pixel defect # compliance. Use one of the median bias files for this since they # should be available no matter which analysis tasks are run. bias_frames = get_raft_files_by_slot(raft_name, 'median_bias.fits', jobname='bias_frame_BOT') try: mask_files = get_raft_files_by_slot(raft_name, 'edge_rolloff_mask.fits') except FileNotFoundError: input_mask = None else: input_mask = list(mask_files.values())[0] total_num, rolloff_mask \ = sensorTest.pixel_counts(list(bias_frames.values())[0], input_mask=input_mask) # Exposure time (in seconds) for 95th percentile dark current shot # noise calculation. exptime = 15. # Update the eotest results files. analysis_types = get_analysis_types() for filename in results_files.values(): eotest_results = sensorTest.EOTestResults(filename) eotest_results.add_ccd_result('TOTAL_NUM_PIXELS', total_num) eotest_results.add_ccd_result('ROLLOFF_MASK_PIXELS', rolloff_mask) shot_noise = eotest_results['DARK_CURRENT_95'] * exptime total_noise = np.sqrt(eotest_results['READ_NOISE']**2 + shot_noise) add_max_frac_dev = ('MAX_FRAC_DEV' not in eotest_results.colnames and 'linearity' in analysis_types) for i, amp in enumerate(eotest_results['AMP']): if add_max_frac_dev: eotest_results.add_seg_result(amp, 'MAX_FRAC_DEV', 0.) eotest_results.add_seg_result(amp, 'DC95_SHOT_NOISE', np.float(shot_noise[i])) try: eotest_results['TOTAL_NOISE'][i] = total_noise[i] except KeyError: eotest_results.add_seg_result(amp, 'TOTAL_NOISE', np.float(total_noise[i])) eotest_results.write(filename) run = siteUtils.getRunNumber() file_prefix = make_file_prefix(run, raft_name) title = '{}, {}'.format(run, raft_name) gains = { slot_name: get_amplifier_gains(results_files[slot_name]) for slot_name in results_files } # Update the gains in the results files with the retrieved values. for slot_name, ccd_gains in gains.items(): try: results = sensorTest.EOTestResults(results_files[slot_name]) except KeyError: continue else: for amp, gain in ccd_gains.items(): results.add_seg_result(amp, 'GAIN', gain) results.write() # Extract dark currents for each amplifier in the raft. dark_currents = dict() for slot_name, results_file in results_files.items(): results = sensorTest.EOTestResults(results_file) try: dark_currents[slot_name] \ = dict(_ for _ in zip(results['AMP'], results['DARK_CURRENT_MEDIAN'])) except KeyError: dark_currents[slot_name] = dict({amp: 0 for amp in range(1, 17)}) png_files = [] # Median bias mosaic median_bias = raftTest.make_raft_mosaic(bias_frames, bias_subtract=False) median_bias.plot(title='%s, median bias frames' % title, annotation='ADU/pixel', rotate=180) png_files.append('{}_median_bias.png'.format(file_prefix)) plt_savefig(png_files[-1]) del median_bias # Dark mosaic dark_files = None try: dark_files = get_raft_files_by_slot(raft_name, 'median_dark_bp.fits') except FileNotFoundError: try: dark_files = get_raft_files_by_slot(raft_name, 'median_dark_current.fits') except FileNotFoundError as eobj: print(eobj) if dark_files is not None: dark_mosaic = raftTest.make_raft_mosaic(dark_files, gains=gains, bias_frames=bias_frames) dark_mosaic.plot( title='{}, medianed dark frames'.format(title), annotation='e-/pixel, gain-corrected, bias-subtracted', rotate=180) png_files.append('{}_medianed_dark.png'.format(file_prefix)) plt_savefig(png_files[-1]) del dark_mosaic # High flux superflat mosaic. try: sflat_high_files \ = get_raft_files_by_slot(raft_name, 'superflat_high.fits') except FileNotFoundError as eobj: print(eobj) else: sflat_high = raftTest.make_raft_mosaic(sflat_high_files, gains=gains, bias_frames=bias_frames, dark_currents=dark_currents) sflat_high.plot(title='%s, high flux superflat' % title, annotation='e-/pixel, gain-corrected, bias-subtracted', rotate=180) png_files.append('{}_superflat_high.png'.format(file_prefix)) plt_savefig(png_files[-1]) del sflat_high # Low flux superflat mosaic. try: sflat_low_files \ = get_raft_files_by_slot(raft_name, 'superflat_low.fits') except FileNotFoundError as eobj: print(eobj) else: sflat_low = raftTest.make_raft_mosaic(sflat_low_files, gains=gains, bias_frames=bias_frames, dark_currents=dark_currents) sflat_low.plot(title='%s, low flux superflat' % title, annotation='e-/pixel, gain-corrected, bias-subtracted', rotate=180) png_files.append('{}_superflat_low.png'.format(file_prefix)) plt_savefig(png_files[-1]) del sflat_low # QE images at various wavelengths and filters acq_jobname = siteUtils.getProcessName('BOT_acq') for wl in ('SDSSu', 'SDSSg', 'SDSSr', 'SDSSi', 'SDSSz', 'SDSSY', '480nm', '650nm', '750nm', '870nm', '950nm', '970nm'): print("Processing %s image" % wl) pattern = 'lambda_flat_{}*/*_{}_*.fits'.format(wl, raft_name) print(pattern) print(acq_jobname) files = siteUtils.dependency_glob(pattern, acq_jobname=acq_jobname) if not files: print("no files found") continue lambda_files = dict() for item in files: slot_name = os.path.basename(item).split('_')[-1].split('.')[0] lambda_files[slot_name] = item flat = raftTest.make_raft_mosaic(lambda_files, gains=gains, bias_frames=bias_frames, dark_currents=dark_currents) flat.plot(title='%s, %s' % (title, wl), annotation='e-/pixel, gain-corrected, bias-subtracted', rotate=180) png_files.append('{}_{}_flat.png'.format(file_prefix, wl)) plt_savefig(png_files[-1]) del flat # TODO: QE summary plot # Plots of read noise, nonlinearity, serial and parallel CTI, # PSF size, and gains from Fe55 and PTC. spec_plots = raftTest.RaftSpecPlots(results_files) columns = 'READ_NOISE DC95_SHOT_NOISE TOTAL_NOISE'.split() try: spec_plots.make_multi_column_plot(columns, 'noise per pixel (-e rms)', spec=9, title=title, ybounds=(-1, 100)) png_files.append('%s_total_noise.png' % file_prefix) plt_savefig(png_files[-1]) except KeyError: pass try: if 'linearity' in analysis_types: spec_plots.make_plot('MAX_FRAC_DEV', 'non-linearity (max. fractional deviation)', spec=0.03, title=title, ybounds=(0, 0.1)) png_files.append('%s_linearity.png' % file_prefix) plt_savefig(png_files[-1]) except KeyError: pass try: spec_plots.make_multi_column_plot( ('CTI_LOW_SERIAL', 'CTI_HIGH_SERIAL'), 'Serial CTI (ppm)', spec=(5e-6, 3e-5), title=title, yscaling=1e6, yerrors=True, colors='br', ybounds=(-1e-5, 6e-5)) png_files.append('%s_serial_cti.png' % file_prefix) plt_savefig(png_files[-1]) except KeyError: pass try: spec_plots.make_multi_column_plot( ('CTI_LOW_PARALLEL', 'CTI_HIGH_PARALLEL'), 'Parallel CTI (ppm)', spec=3e-6, title=title, yscaling=1e6, yerrors=True, colors='br', ybounds=(-1e-5, 6e-5)) png_files.append('%s_parallel_cti.png' % file_prefix) plt_savefig(png_files[-1]) except KeyError: pass try: spec_plots.make_plot('PSF_SIGMA', 'PSF sigma (microns)', spec=5., title=title, ybounds=(0, 5.2)) png_files.append('%s_psf_sigma.png' % file_prefix) plt_savefig(png_files[-1]) except KeyError: # PSF_SIGMA not available so skip this plot pass try: spec_plots.make_multi_column_plot(('GAIN', 'PTC_GAIN'), 'System Gain (e-/ADU)', yerrors=True, title=title, colors='br', ybounds=(0, 3)) png_files.append('%s_system_gain.png' % file_prefix) plt_savefig(png_files[-1]) except KeyError: # PTC_GAIN data not available so skip this plot. pass try: if 'dark' in analysis_types: spec_plots.make_plot('DARK_CURRENT_95', '95th percentile dark current (e-/pixel/s)', spec=0.2, title=title, ybounds=(-0.01, 1)) png_files.append('%s_dark_current.png' % file_prefix) plt_savefig(png_files[-1]) except KeyError: pass # Make bias frame stats time history plots for the current raft. pattern = f'{raft_name}_{run}_bias_frame_stats.pickle' try: stats_file = siteUtils.dependency_glob(pattern, jobname='bias_frame_BOT')[0] except IndexError: pass else: file_prefix = make_file_prefix(run, raft_name) df_raft = pd.read_pickle(stats_file) if raft_name in 'R00 R04 R40 R44': slots = 'SG0 SW1 SW0 SG1'.split() else: slots = 'S20 S21 S22 S10 S11 S12 S00 S01 S02'.split() t0 = int(np.min(df_raft['MJD'])) fig = plt.figure(figsize=(12, 12)) for i, slot in enumerate(slots, 1): fig.add_subplot(3, 3, i) df = df_raft.query(f'slot == "{slot}"') amps = sorted(list(set(df['amp']))) for amp in amps: my_df = df.query(f'amp == {amp}') plt.scatter(my_df['MJD'] - t0, my_df['mean'], s=2, label=f'{amp}') xmin, xmax, _, _ = plt.axis() plt.xlim(xmin, 1.2 * (xmax - xmin) + xmin) plt.legend(fontsize='x-small') plt.xlabel(f'MJD - {t0}') plt.ylabel('mean signal (ADU)') plt.title(slot) plt.tight_layout(rect=(0, 0, 1, 0.95)) plt.suptitle(f'{file_prefix}, bias stability, mean signal') png_file = f'{file_prefix}_bias_stability_mean.png' png_files.append(png_file) plt_savefig(png_file) fig = plt.figure(figsize=(12, 12)) for i, slot in enumerate(slots, 1): fig.add_subplot(3, 3, i) df = df_raft.query(f'slot == "{slot}"') amps = sorted(list(set(df['amp']))) for amp in amps: my_df = df.query(f'amp == {amp}') plt.scatter(my_df['MJD'] - t0, my_df['stdev'], s=2, label=f'{amp}') xmin, xmax, _, _ = plt.axis() plt.xlim(xmin, 1.2 * (xmax - xmin) + xmin) plt.legend(fontsize='x-small') plt.xlabel(f'MJD - {t0}') plt.ylabel('stdev (ADU)') plt.title(slot) plt.tight_layout(rect=(0, 0, 1, 0.95)) plt.suptitle(f'{file_prefix}, bias stability, stdev') png_file = f'{file_prefix}_bias_stability_stdev.png' png_files.append(png_file) plt_savefig(png_file) png_file_list = '{}_raft_results_task_png_files.txt'.format(raft_name) with open(png_file_list, 'w') as output: for item in png_files: if os.path.isfile(item): output.write('{}\n'.format(item)) return None
#!/usr/bin/env ipython """ Producer script for BOT tearing analysis. """ import os from camera_components import camera_info from tearing_jh_task import tearing_jh_task from raft_divisidero_tearing import raft_divisidero_tearing from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script if 'tearing' in get_analysis_types(): tearing_jh_task_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'tearing_BOT', 'v0', 'tearing_jh_task.py') run_python_task_or_cl_script(tearing_jh_task, tearing_jh_task_script) divisidero_jh_task_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'tearing_BOT', 'v0', 'raft_divisidero_tearing.py') installed_rafts = camera_info.get_installed_raft_names() run_python_task_or_cl_script(raft_divisidero_tearing, divisidero_jh_task_script, device_names=installed_rafts)
#!/usr/bin/env ipython """ Producer script for BOT flat pairs (linearity and full-well) analysis. """ import os from flat_pairs_jh_task import flat_pairs_jh_task from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script if 'linearity' in get_analysis_types(): flat_pairs_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'flat_pairs_BOT', 'v0', 'flat_pairs_jh_task.py') run_python_task_or_cl_script(flat_pairs_jh_task, flat_pairs_script)
#!/usr/bin/env ipython """ Producer script for BOT flat gain stability analysis. """ import os import siteUtils from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script from flat_gain_stability import plot_all_rafts from flat_gain_stability_jh_task import flat_gain_stability_jh_task if 'gainstability' in get_analysis_types(): flat_gain_stability_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'flat_gain_stability_BOT', 'v0', 'flat_gain_stability_jh_task.py') run_python_task_or_cl_script(flat_gain_stability_jh_task, flat_gain_stability_script) plot_all_rafts(siteUtils.getRunNumber(), y_range=None)
#!/usr/bin/env ipython """ Producer script for BOT dark current analysis. """ import os from dark_current_jh_task import dark_current_jh_task from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script if 'dark' in get_analysis_types(): dark_current_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'dark_current_BOT', 'v0', 'dark_current_jh_task.py') run_python_task_or_cl_script(dark_current_jh_task, dark_current_script)
#!/usr/bin/env ipython """ Producer script for BOT bias frame generation. """ import os import glob import pandas as pd from camera_components import camera_info import siteUtils from bias_frame_jh_task import bias_frame_jh_task from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script, \ make_file_prefix if 'bias' in get_analysis_types(): run = siteUtils.getRunNumber() bias_frame_task_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'bias_frame_BOT', 'v0', 'bias_frame_jh_task.py') run_python_task_or_cl_script(bias_frame_jh_task, bias_frame_task_script) # Combine data frames by raft. raft_names = camera_info.get_installed_raft_names() for raft_name in raft_names: pattern = f'{raft_name}*_bias_frame_stats.pickle' det_files = glob.glob(pattern) if not det_files: continue df = pd.concat([pd.read_pickle(_) for _ in det_files], ignore_index=True) file_prefix = make_file_prefix(run, raft_name)
#!/usr/bin/env ipython """ Producer script for BOT read noise analysis. """ import os from camera_components import camera_info from read_noise_jh_task import read_noise_jh_task from raft_jh_noise_correlations import raft_jh_noise_correlations from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script if 'biasnoise' in get_analysis_types(): read_noise_jh_task_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'read_noise_BOT', 'v0', 'read_noise_jh_task.py') run_python_task_or_cl_script(read_noise_jh_task, read_noise_jh_task_script) raft_jh_noise_correlations_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'read_noise_BOT', 'v0', 'raft_jh_noise_correlations.py') # Run raft-level noise correlations just on science rafts for now. installed_rafts = camera_info.installed_science_rafts run_python_task_or_cl_script(raft_jh_noise_correlations, raft_jh_noise_correlations_script, device_names=installed_rafts)
#!/usr/bin/env ipython """ Producer script for BOT brighter-fatter analysis. """ import os from bf_jh_task import bf_jh_task from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script if 'brighterfatter' in get_analysis_types(): bf_jh_task_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'brighter_fatter_BOT', 'v0', 'bf_jh_task.py') run_python_task_or_cl_script(bf_jh_task, bf_jh_task_script)
#!/usr/bin/env ipython """ Producer script for BOT bias frame generation. """ import os from persistence_jh_task import persistence_jh_task from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script if 'persistence' in get_analysis_types(): persistence_task_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'persistence_BOT', 'v0', 'persistence_jh_task.py') run_python_task_or_cl_script(persistence_jh_task, persistence_task_script)
def validate_fe55(results, det_names): """Validate and persist fe55 gain and psf results.""" run = siteUtils.getRunNumber() analysis_types = get_analysis_types() missing_det_names = set() missing_gain_stability_det_names = set() for det_name in det_names: raft, slot = det_name.split('_') file_prefix = make_file_prefix(run, det_name) # The output files from producer script. gain_file = '%(file_prefix)s_eotest_results.fits' % locals() psf_results_files \ = glob.glob('%(file_prefix)s_psf_results*.fits' % locals()) if not os.path.isfile(gain_file) or not psf_results_files: # Results for this detector are not available so note # that and continue with the others. missing_det_names.add(det_name) continue psf_results = psf_results_files[0] rolloff_mask = '%(file_prefix)s_edge_rolloff_mask.fits' % locals() output_files = psf_results, rolloff_mask # Add/update the metadata to the primary HDU of these files. for fitsfile in output_files: eotestUtils.addHeaderData(fitsfile, TESTTYPE='FE55', DATE=eotestUtils.utc_now_isoformat()) results.extend([lcatr.schema.fileref.make(x) for x in output_files]) # Persist the png files. png_file_list = '{}_fe55_task_png_files.txt'.format(det_name) with open(png_file_list, 'r') as input_: png_files = [x.strip() for x in input_] metadata = dict(TESTTYPE='FE55', TEST_CATEGORY='EO', DETECTOR=det_name, RUN=run) results.extend( siteUtils.persist_png_files('', file_prefix, png_files=png_files, metadata=metadata)) data = sensorTest.EOTestResults(gain_file) try: amps = data['AMP'] gain_data = data['GAIN'] gain_errors = data['GAIN_ERROR'] sigmas = data['PSF_SIGMA'] except KeyError: pass else: for amp, gain_value, gain_error, sigma in zip( amps, gain_data, gain_errors, sigmas): if not np.isfinite(gain_error): gain_error = -1 results.append( lcatr.schema.valid(lcatr.schema.get('fe55_BOT_analysis'), amp=amp, gain=gain_value, gain_error=gain_error, psf_sigma=sigma, slot=slot, raft=raft)) if 'gainstability' in analysis_types: try: gain_stability_file \ = glob.glob(f'{file_prefix}_gain_sequence.pickle')[0] except IndexError: missing_gain_stability_det_names.add(det_name) else: md = dict(DATA_PRODUCT='gain_stability_results') results.append( siteUtils.make_fileref(gain_stability_file, metadata=md)) # Persist raft-level gain stability plots png_files = glob.glob('*fe55_gain_stability.png') for png_file in png_files: md = dict(DATA_PRODUCT='gain_stability_results') results.append(siteUtils.make_fileref(png_file, metadata=md)) report_missing_data('validate_fe55', missing_det_names) if 'gain_stability' in analysis_types: report_missing_data('validate_gain_stability', missing_gain_stability_det_names) return results
#!/usr/bin/env ipython """ Producer script for BOT PTC analysis. """ import os from ptc_jh_task import ptc_jh_task from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script if 'ptc' in get_analysis_types(): ptc_task_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'ptc_BOT', 'v0', 'ptc_jh_task.py') run_python_task_or_cl_script(ptc_jh_task, ptc_task_script)
#!/usr/bin/env ipython """ Producer script for BOT overscan analysis. """ import os from overscan_jh_task import overscan_jh_task from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script if 'overscan' in get_analysis_types(): overscan_task_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'overscan_BOT', 'v0', 'overscan_jh_task.py') run_python_task_or_cl_script(overscan_jh_task, overscan_task_script)
#!/usr/bin/env ipython """ Producer script for BOT scan mode analysis. """ import os from camera_components import camera_info from scan_mode_analysis_jh_task import scan_mode_analysis_jh_task from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script if 'scan' in get_analysis_types(): scan_mode_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'scan_mode_analysis_BOT', 'v0', 'scan_mode_analysis_jh_task.py') installed_rafts = camera_info.get_installed_raft_names() run_python_task_or_cl_script(scan_mode_analysis_jh_task, scan_mode_script, device_names=installed_rafts)
#!/usr/bin/env ipython """ Producer script for BOT PTC analysis. """ import os from cte_jh_task import cte_jh_task from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script if 'cti' in get_analysis_types(): cte_jh_task_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'cti_BOT', 'v0', 'cte_jh_task.py') run_python_task_or_cl_script(cte_jh_task, cte_jh_task_script)
#!/usr/bin/env ipython """ Producer script for BOT Fe55 analysis. """ import os from fe55_jh_task import fe55_jh_task from gain_stability_jh_task import gain_stability_jh_task from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script job_dir = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'fe55_analysis_BOT', 'v0') analysis_types = get_analysis_types() if 'gain' in analysis_types or 'gainstability' in analysis_types: fe55_task_script = os.path.join(job_dir, 'fe55_jh_task.py') run_python_task_or_cl_script(fe55_jh_task, fe55_task_script) if 'gainstability' in analysis_types: gain_stability_script = os.path.join(job_dir, 'gain_stability_jh_task.py') run_python_task_or_cl_script(gain_stability_jh_task, gain_stability_script)
#!/usr/bin/env ipython """ Producer script for BOT trap analysis. """ import os from traps_jh_task import traps_jh_task from bot_eo_analyses import get_analysis_types, run_python_task_or_cl_script if 'traps' in get_analysis_types(): traps_jh_task_script \ = os.path.join(os.environ['EOANALYSISJOBSDIR'], 'harnessed_jobs', 'trap_analysis_BOT', 'v0', 'traps_jh_task.py') run_python_task_or_cl_script(traps_jh_task, traps_jh_task_script)