def get_posacc_cd(header): ''' Creates column data source from coordinates.fits file Merges coordinate data with fiberpos data for X,Y plotting Args: header : from data file ''' fiberpos = Table(desimodel.io.load_fiberpos()).to_pandas() fiberpos.PETAL = fiberpos.PETAL.astype(int) fiberpos.DEVICE = fiberpos.DEVICE.astype(int) fiberpos.DEVICE_TYPE = fiberpos.DEVICE_TYPE.astype(str) night = header['NIGHT'] expid = header['EXPID'] coordfile = '{}/{}/coordinates-{}.fits'.format(night, str(expid).zfill(8), str(expid).zfill(8)) # Useful for offline tests: backup location for coordfiles at NERSC. if not os.path.exists(coordfile): if 'DESI_SPECTRO_DATA' in os.environ: coordfile = os.path.join(os.environ['DESI_SPECTRO_DATA'], coordfile) if os.path.isfile(coordfile): df = Table(fitsio.read(coordfile)).to_pandas() # delete a conflicting column name if 'FIBER' in df: del df['FIBER'] if 'OFFSET_0' not in df: print( f'WARNING positioner offsets not in {coordfile}; not making positioner accuracy plots' ) return None final_move = np.sort(fnmatch.filter(df.columns, 'OFFSET_*'))[-1] df = df.merge(fiberpos, how='left', left_on=['PETAL_LOC', 'DEVICE_LOC'], right_on=['PETAL', 'DEVICE']) df = df[df['DEVICE_TYPE'] == "b'POS'"] df.reset_index(drop=True, inplace=True) print(len(df)) df['DISABLED_0'] = True df['DISABLED_1'] = True for i in [0, 1]: try: flag = 'FLAGS_COR_{}'.format(i) x = np.where(((df[flag] & 4) != 0) & (df[flag] < 65535)) df.at[x[0], 'DISABLED_{}'.format(i)] = False except Exception as e: print('Issue setting disabled positioners: ', e) df['BLIND'] = df['OFFSET_0'] * 1000 df['FINAL_MOVE'] = df[final_move] * 1000 mask = df['DISABLED_0'] == True df.loc[mask, 'BLIND'] = -1 mask = df['DISABLED_1'] == True df.loc[mask, 'FINAL_MOVE'] = -1 df['CAM'] = '' df = df.fillna(-1) return ColumnDataSource(data=df) else: return None