def fnComputeCCF_OLD(fluxOrder, waveOrder, maskOrder, RV, BERV=0.0): ''' fluxOrder - flux of spectrum waveOrder - wavelength solution maskOrder - binary mask for the CCF ''' fnPrintLine(None, 'Computing CCF for BERV corrected RV = {:.2f}km/s'.format(RV), sameLine=True) waveResolution = waveOrder[1] - waveOrder[0] fluxOrderPlusOne = np.roll(fluxOrder, -1) waveorderPlusOne = np.roll(waveOrder, -1) nLines = 0 lines = [] CCF = 0.0 for lineIni, lineEnd, lineDepth in maskOrder: lineIniShifted = fnRVLambdaShift(RV, lineIni) lineEndShifted = fnRVLambdaShift(RV, lineEnd) if waveOrder[0] < lineIniShifted and lineEndShifted < waveOrder[-1]: linePixelIni, linePixelEnd = [ np.where(waveOrder > lineIniShifted)[0][0], np.where(waveOrder < lineEndShifted)[0][-1] ] lineFractionIni = (waveOrder[linePixelIni] - lineIniShifted) / waveResolution lineFractionEnd = (lineEndShifted - waveOrder[linePixelEnd]) / waveResolution CCF += lineDepth * ( np.nansum(fluxOrder[linePixelIni:linePixelEnd]) + (lineFractionIni) * fluxOrder[linePixelIni - 1] + (lineFractionEnd) * fluxOrder[linePixelEnd + 1]) nLines += 1 lines.append(lineIniShifted) # print ii, lines[0], lines[-1], waveOrder[0], waveOrder[-1] # raw_input() return CCF, nLines
def main_function(): # region --- Define planet parameters planetParams = clsPlanetParametersOLD(params={param: value for param, value in cfgFile.items('orbital_params')}) planetParams.sysRV = 0.0 # endregion # region --- Get files list # data files fnPrintLine('CCF', 'get ccf list') fullCCFList = sorted( [os.path.join(scienceInputFolder, fileName) for fileName in os.listdir(scienceInputFolder) \ if fileName.lower().endswith('fits')]) # region --- load fits files fnPrintLine('CCF', 'Extracting CCFs, please wait') fullCCFs = {ccfName: fnOpenHARPSFits(ccfName, headerOnly=True) for ccfName in sorted(fullCCFList)} # region --- Finding star CCF parameters fnPrintLine('CCF', 'Computing star and planet RVs') # define xxx axis mplt.ion() for ccfName in sorted(fullCCFList): fullCCFs[ccfName].PlanetPhaseFolded = ((fullCCFs[ ccfName].BJD - planetParams.t0) / planetParams.period + np.radians( planetParams.w) / (2 * np.pi)) % 1 fullCCFs[ccfName].RV = fullCCFs[ccfName].RVC = fnRVStarOrbitElipse(planetParams, fullCCFs[ ccfName].PlanetPhaseFolded - np.radians(planetParams.w) / (2 * np.pi)) # fullCCFs[ccfName].RV = fullCCFs[ccfName].RVC = fnRVStarOrbitElipse(planetParams, fullCCFs[ccfName].PlanetPhaseFolded - np.radians(planetParams.w)/(2*np.pi)) fullCCFs[ccfName].planetRV = -fullCCFs[ccfName].RV / planetParams.massRatio figTemplate, axTemplate = mplt.subplots(figsize=(12, 8)) maxFWHM = np.nanmax([fullCCFs[ccfName].FWHM for ccfName in fullCCFList]) allPoints = axTemplate.plot([fullCCFs[ccfName].PlanetPhaseFolded for ccfName in sorted(fullCCFList)], \ [fullCCFs[ccfName].planetRV for ccfName in sorted(fullCCFList)], 'bd', markersize=8) axTemplate.grid(b=True, which='major', color='k', linestyle='--', alpha=.5) axTemplate.set_ylim(-1.1 * planetParams.k2, 1.1 * planetParams.k2) axTemplate.set_yticks( np.arange(-(np.floor((1.1 * planetParams.k2) / 10) * 10), ((np.ceil(1.1 * planetParams.k2) / 10) * 10), 10)) axTemplate.axhline(0.0, label=r'$RV_{CM}$') axTemplate.axvline(0.25, label='transit', color='red') axTemplate.axvline(0.75, label='opposition', color='green') axTemplate.axhline(-2 * maxFWHM, color='blue', alpha=.5, label=r'$2 \times FWHM$') axTemplate.axhline(2 * maxFWHM, color='blue', alpha=.5, ) axTemplate.legend(loc='best', title=r'$\phi = 0$ - Ascending node') axTemplate.set_xlim(0, 1) axTemplate.set_xticks(np.arange(0, 1, .05)) axTemplate.set_title('template selection - {}'.format(str(cfgFile.get('global', 'dataFolder')))) figTemplate.show() # endregion # region --- get template file list # fnPrintLine('template', 'Use all spectra for template?') # customTemplate = raw_input('\t\tyes/no: ').lower() selectPoints = 'no' while selectPoints == 'no': templatePhaseRanges = [] phaseRange = [0, 1] print fnPrintLine('template', 'Input planet phase ranges for template') fnPrintLine(None, '(leave empty when complete)') while phaseRange: phaseRange = raw_input('\t\tmin_Phase, max_Phase: ').strip('"') if phaseRange: templatePhaseRanges.append( [float(phaseRange.strip(' ').split(',')[0]), float(phaseRange.strip(' ').split(',')[-1])]) templateCCFList = [ccfName for ccfName in sorted(fullCCFList) \ for minPhase, maxPhase in templatePhaseRanges \ if minPhase <= float(fullCCFs[ccfName].PlanetPhaseFolded) <= maxPhase \ ] selectedPoints, = axTemplate.plot( [fullCCFs[ccfName].PlanetPhaseFolded for ccfName in sorted(templateCCFList)], \ [fullCCFs[ccfName].planetRV for ccfName in sorted(templateCCFList)], 'r*', markersize=16) figTemplate.show() # mplt.plot([fullCCFs[ccfName].PlanetPhaseFolded for ccfName in sorted(fullCCFList)],\ # [fullCCFs[ccfName].planetRV for ccfName in sorted(fullCCFList)], 'bd', markersize = 8) fnPrintLine(None, 'Is the selection correct?') selectPoints = raw_input('\t\tyes/no: ').lower() axTemplate.lines.remove(selectedPoints) print # endregion # endregion figData, axData = figTemplate, axTemplate axData.set_title('data selection - {}'.format(str(cfgFile.get('global', 'dataFolder')))) figData.show() selectPoints = 'no' while selectPoints == 'no': dataRVRanges = [] phaseRange = [0, 1] print fnPrintLine('data', 'Input planet phase waveRange for planet recovery') fnPrintLine(None, '(leave empty when complete)') while phaseRange: phaseRange = raw_input('\t\tmin_Phase, max_Phase: ').strip('"') if phaseRange: dataRVRanges.append( [float(phaseRange.strip(' ').split(',')[0]), float(phaseRange.strip(' ').split(',')[-1])]) dataCCFList = [ccfName for ccfName in sorted(fullCCFList) \ for minPhase, maxPhase in dataRVRanges \ if minPhase <= float(fullCCFs[ccfName].PlanetPhaseFolded) <= maxPhase \ ] selectedPoints, = mplt.plot([fullCCFs[ccfName].PlanetPhaseFolded for ccfName in sorted(dataCCFList)], \ [fullCCFs[ccfName].planetRV for ccfName in sorted(dataCCFList)], 'r*', markersize=16) figTemplate.show() fnPrintLine(None, 'Is the selection correct?') selectPoints = raw_input('\t\tyes/no: ').lower() axData.lines.remove(selectedPoints) mplt.show() # region --- updating file lists and config fnPrintLine('config', 'updating file lists and config file') with open( os.path.join(scienceInputFolder, '{}_templateFileList.txt'.format(cfgFile.get('global', 'resultsFolder'))), 'w') as templateFileList: templateFileList.write('\n'.join([fileName.split('/')[-1] for fileName in templateCCFList])) cfgFile.set('detection_settings', 'templateFilelist', '{}_templateFileList.txt'.format(cfgFile.get('global', 'resultsFolder'))) with open(os.path.join(scienceInputFolder, '{}_dataFilelist.txt'.format(cfgFile.get('global', 'resultsFolder'))), 'w') as dataFileList: dataFileList.write('\n'.join([fileName.split('/')[-1] for fileName in dataCCFList])) cfgFile.set('detection_settings', 'dataFilelist', '{}_dataFilelist.txt'.format(cfgFile.get('global', 'resultsFolder'))) with open(os.path.abspath(sys.argv[1]), 'wb') as cfgFileName: cfgFile.write(cfgFileName) fnPrintLine('config', 'config file {} has been updated with file lists'.format(os.path.abspath(sys.argv[1])))
def __main__(): ''' Routine to generate esorex commands to reduce UVES data via ESO's reduction recipes: 1) create master bias - uves_cal_bias 2) create guess order and line tables - uves_cal_predict 3) create order table from order guess table uves_cal_orderpos 4) create master flat - uves_cal_mflat 5) create line calibration table from guess table - uves_cal_wavecal 6) reduce science frame - uves_obs_scired :return: ''' # initialise esorex try: cpl.esorex.init(source=cfgFile.get('global', 'esorexrc')) except: cpl.esorex.init() # # cpl.Recipe.path = '/usr/src/debug/uves-5.8.2/recipes' # region - Define File Lists --------------------------------------------------------------------------------------- # endregion -------------------------------------------------------------------------------------------------------- # region --- 1) create master bias - uves_cal_mbias fnPrintLine('INIT', 'Recipes to run'.format(','.join([recipe for recipe in recipes2run]))) recipe = 'uves_cal_mbias' if recipe in recipes2run: fnPrintLine('CALIB', 'starting {}, please wait...'.format(recipe)) # get input file list recipeFileLists[recipe] = fngetRecipeFileList(recipeName=recipe, \ dataList=rawData_fileList, \ keyword=recipeKeywords[recipe]['DPR_TYPE']) # setup recipe "uves_cal_mbias" clpRecipes[recipe] = fnSetRecipe(recipe, customConfig=cfgFile) # run recipe "uves_cal_predict" clpResults[recipe] = clpRecipes[recipe](raw={recipeKeywords[recipe]['TAG']: recipeFileLists[recipe]}, \ output_dir=outputFolders[recipe], tmp_dir=tmpFolder) clpResults[recipe] = None fnPrintLine('CALIB', '{} complete'.format(recipe)) # endregion -------------------------------------------------------------------------------------------------------- # region --- 2) create guess order and line tables - uves_cal_predict recipe = 'uves_cal_predict' if recipe in recipes2run: fnPrintLine('CALIB', 'starting {}, please wait...'.format(recipe)) # get input file list recipeFileLists[recipe] = fngetRecipeFileList(recipeName=recipe, \ dataList=rawData_fileList, \ keyword=recipeKeywords[recipe]['DPR_TYPE']) calibrations_fileList.update(fnUpdateProductList(baseDataFolder_reduced, productList=calibrations_fileList)) # setup recipe "uves_cal_predict" clpRecipes[recipe] = fnSetRecipe(recipe, cfgFile) # run recipe "uves_cal_predict" clpResults[recipe] = clpRecipes[recipe](raw={recipeKeywords[recipe]['TAG']: recipeFileLists[recipe]}, \ calib=calibrations_fileList, output_dir=outputFolders[recipe], tmp_dir=tmpFolder) clpResults[recipe] = None fnPrintLine('CALIB', '{} complete'.format(recipe)) # endregion -------------------------------------------------------------------------------------------------------- # region --- 3) create order table from order guess table uves_cal_orderpos recipe = 'uves_cal_orderpos' if recipe in recipes2run: fnPrintLine('CALIB', 'starting {}, please wait...'.format(recipe)) # get input file list recipeFileLists[recipe] = fngetRecipeFileList(recipeName=recipe, \ dataList=rawData_fileList, \ keyword=recipeKeywords[recipe]['DPR_TYPE']) # update calibration lists calibrations_fileList.update(fnUpdateProductList(baseDataFolder_reduced, productList=calibrations_fileList)) # setup recipe "uves_cal_orderpos" clpRecipes[recipe] = fnSetRecipe(recipe, cfgFile) # run recipe "uves_cal_predict" clpResults[recipe] = clpRecipes[recipe](raw={recipeKeywords[recipe]['TAG']: recipeFileLists[recipe]}, calib=calibrations_fileList, \ output_dir=outputFolders[recipe], tmp_dir=tmpFolder) clpResults[recipe] = None fnPrintLine('CALIB', '{} complete'.format(recipe)) # endregion -------------------------------------------------------------------------------------------------------- # region --- 4) create master flat - uves_cal_mflat recipe = 'uves_cal_mflat' if recipe in recipes2run: fnPrintLine('CALIB', 'starting {}, please wait...'.format(recipe)) # get input file list recipeFileLists[recipe] = fngetRecipeFileList(recipeName=recipe, \ dataList=rawData_fileList, \ keyword=recipeKeywords[recipe]['DPR_TYPE']) # update calibration lists calibrations_fileList.update(fnUpdateProductList(baseDataFolder_reduced, productList=calibrations_fileList)) # setup recipe clpRecipes[recipe] = fnSetRecipe(recipe, cfgFile) # run recipe "uves_cal_predict" clpResults[recipe] = clpRecipes[recipe](raw={recipeKeywords[recipe]['TAG']: recipeFileLists[recipe]}, calib=calibrations_fileList, \ output_dir=outputFolders[recipe], tmp_dir=tmpFolder) clpResults[recipe] = None fnPrintLine('CALIB', '{} complete'.format(recipe)) # endregion -------------------------------------------------------------------------------------------------------- # region --- 5) create line calibration table from guess table - uves_cal_wavecal recipe = 'uves_cal_wavecal' if recipe in recipes2run: fnPrintLine('CALIB', 'startings {}, please wait...'.format(recipe)) # get input file list recipeFileLists[recipe] = fngetRecipeFileList(recipeName=recipe, \ dataList=rawData_fileList, \ keyword=recipeKeywords[recipe]['DPR_TYPE']) # update calibration lists calibrations_fileList.update(fnUpdateProductList(baseDataFolder_reduced, productList=calibrations_fileList)) # setup recipe "uves_cal_mflat" clpRecipes[recipe] = fnSetRecipe(recipe, cfgFile) print outputFolders[recipe] # run recipe "uves_cal_predict" clpResults[recipe] = clpRecipes[recipe](raw={recipeKeywords[recipe]['TAG']: recipeFileLists[recipe]}, calib=calibrations_fileList, \ output_dir=outputFolders[recipe], tmp_dir=tmpFolder) clpResults[recipe] = None fnPrintLine('CALIB', '{} complete'.format(recipe)) # endregion -------------------------------------------------------------------------------------------------------- # region --- 6) reduce science frame - uves_obs_scired recipe = 'uves_obs_scired' if recipe in recipes2run: fnPrintLine('SCIENCE', 'starting {}, please wait...'.format(recipe)) # get input file list recipeFileLists[recipe] = fngetRecipeFileList(recipeName=recipe, \ dataList=rawData_fileList, \ keyword=recipeKeywords[recipe]['DPR_TYPE']) # update calibration lists calibrations_fileList.update(fnUpdateProductList(baseDataFolder_reduced, productList=calibrations_fileList)) # setup recipe "uves_obs_scired" clpRecipes[recipe] = fnSetRecipe(recipe, cfgFile) # run recipe "uves_obs_scired" for scienceFile in recipeFileLists[recipe]: fnPrintLine('SCIENCE', '{}: reducing {}'.format(recipe, scienceFile.split('/')[-1])) clpResults[recipe] = clpRecipes[recipe](raw={recipeKeywords[recipe]['TAG']: [scienceFile]}, calib=calibrations_fileList, \ output_dir=os.path.join(outputFolders[recipe], fits.getheader(scienceFile)['DATE-OBS']), tmp_dir=tmpFolder) clpResults[recipe] = None fnPrintLine('SCIENCE', '{} complete'.format(recipe)) # endregion # region --- 7) create blaze file recipe = 'uves_cal_blaze' if recipe in recipes2run: fnPrintLine('BLAZE', 'starting {}, please wait...'.format(recipe)) # get input file list reducedFileList = [filenameFull \ for root, dirs, files in os.walk(outputFolders['uves_obs_scired'], topdown=False) \ for filenameFull in [os.path.join(root, filename) for filename in files] \ if filenameFull.endswith('.fits')\ and 'WCALIB_FLAT'.lower() in fits.getheader(filenameFull)['HIERARCH ESO PRO CATG'].lower()\ ] for flatFile in reducedFileList: fnPrintLine('BLAZE', '{}: creating blaze from {}'.format(recipe, flatFile.split('/')[-1])) flatFits = fits.open(flatFile) blazeData = fnInferInstrumentResponse(flatFits[0].data,float(cfgFile.get(recipe, 'window'))) blazeheader = flatFits[0].header # ii=0 # for orderData, instData in zip(flatFits[0].data,blazeData): # mplt.plot(orderData, 'bo') # mplt.plot(instData, 'r') # mplt.title('order %s' %ii) # mplt.show() # ii+=1 blazeheader['HIERARCH ESO PRO CATG'] = flatFits[0].header['HIERARCH ESO PRO CATG'].replace('FLAT', 'BLAZE') blazeheader['HIERARCH BLAZE WINDOW'] = (float(cfgFile.get(recipe, 'window')), 'blaze moving average window in pixels') writeNameBlaze = os.path.join(*[outputFolders['uves_obs_scired'],flatFile.split('/')[-2],\ 'blaze_{}.fits'.format(flatFits[0].header['HIERARCH ESO PRO CATG'].split('_')[-1].lower())]) fits.writeto(writeNameBlaze,blazeData,blazeheader, clobber=True) fnPrintLine('BLAZE', '{} complete'.format(recipe)) # endregion return
def main_function(): ''' Routine to generate esorex commands to reduce UVES data via ESO's reduction recipes: 1) create master bias - uves_cal_bias 2) create guess order and line tables - uves_cal_predict 3) create order table from order guess table uves_cal_orderpos 4) create master flat - uves_cal_mflat 5) create line calibration table from guess table - uves_cal_wavecal 6) reduce science frame - uves_obs_scired :return: ''' # region - Define File Lists --------------------------------------------------------------------------------------- fnPrintLine('FILES', 'Defining file lists') # science/data files scienceFileList = [filename for filename in rawFileList \ if 'OBJECT,POINT'.lower() in fits.getheader(filename)['HIERARCH ESO DPR TYPE'].lower()] # bias files biasFileList = [filename for filename in rawFileList \ if 'BIAS'.lower() in fits.getheader(filename)['HIERARCH ESO DPR TYPE'].lower()] # flat files flatFileList = [filename for filename in rawFileList \ if 'FLAT'.lower in fits.getheader(filename)['HIERARCH ESO DPR TYPE'].lower()] esorexBaseString = 'esorex --config={esorexCfg} --recipe-config={recipeSettings} {recipeName} {fileList} \n' # endregion -------------------------------------------------------------------------------------------------------- # Generate reduction scripts # region --- 1) create master bias - uves_cal_mbiasls python fnCreateFolder('{}/masterBias/'.format(baseReducedDataFolder)) # writing file list masterBiasFileList = '{}/fileList_uves_cal_mbias.sof'.format(scriptsFolder) with open(masterBiasFileList, 'w') as writeFile: writeFile.write('\n'.join(biasFileList)) print '\n'.join(biasFileList) # writing esorex settings file with open(esorexSettings, 'r') as esorexDefaultsFile: esorexDefaults = str(esorexDefaultsFile.read()) esorexSettings_uves_cal_mbias = esorexDefaults.replace( 'DEFAULT_OUTPUT_DIR', '{}/masterBias/'.format(baseReducedDataFolder)) esorexSettings_uves_cal_mbias = esorexSettings_uves_cal_mbias.replace( 'DEFAULT_OUTPUT_PREFIX', 'masterBias') esorexSettingsFile_uves_cal_mbias = '{}/esorex_uves_cal_mbias.cfg'.format( scriptsFolder) with open(esorexSettingsFile_uves_cal_mbias, 'w') as writeFile: writeFile.write(esorexSettings_uves_cal_mbias) esorexCommands_uves_cal_mbias = esorexBaseString.format( \ esorexCfg=esorexSettingsFile_uves_cal_mbias, \ recipeSettings=os.path.abspath(settings.uves_cal_mbias), \ recipeName='uves_cal_mbias', \ fileList=masterBiasFileList) print esorexCommands_uves_cal_mbias # endregion -------------------------------------------------------------------------------------------------------- # region --- 2) create guess order and line tables - uves_cal_predict # esorex_uves_cal_predict = esorexBaseString.format(esorexSettings, recipeSettingsFile, 'uves_cal_predict', # fileListUvesObsScired)) # endregion -------------------------------------------------------------------------------------------------------- # region --- 3) create order table from order guess table uves_cal_orderpos # esorex_uves_cal_orderpos = esorexBaseString.format(esorexSettings, recipeSettingsFile, 'uves_cal_orderpos', # fileListUvesObsScired)) # endregion -------------------------------------------------------------------------------------------------------- # region --- 4) create master flat - uves_cal_mflat # esorex_uves_cal_mflat = esorexBaseString.format(esorexSettings, recipeSettingsFile, 'uves_cal_mflat', # fileListUvesObsScired)) # endregion -------------------------------------------------------------------------------------------------------- # region --- 5) create line calibration table from guess table - uves_cal_wavecal # esorex_uves_cal_wavecal = esorexBaseString.format(esorexSettings, recipeSettingsFile, 'uves_cal_wavecal', # fileListUvesObsScired)) # endregion -------------------------------------------------------------------------------------------------------- # region --- 6) reduce science frame - uves_obs_scired # esorex_uves_obs_scired = esorexBaseString.format(esorexSettings, recipeSettingsFile, 'uves_obs_scired', fileListUvesObsScired)) # endregion # print 'Create ESOREX scripts' # # # Create settings for esorex # with open('{}/scripts/defaults/esorex.cfg'.format(ReductPath)) as defaultEsorexFile: # defaultEsorex = defaultEsorexFile.read() # # # create settings for recipe # with open('{}/scripts/defaults/{}.cfg'.format(ReductPath, settings.recipeName)) as defaultRecipeFile: # customRecipe = defaultRecipeFile.read() # # with open(recipeSettings,'w') as customRecipeFile: # customRecipeFile.write(customRecipe) # # # # # Create SOF files for esorex - standard calibration files # stdCalibsString = '' # for filename in stdCalibrationFilelist: # headerSTDCalib = fits.getheader('{}/RawData/UVESCalibrationFiles/{}'.format(WorkPath,filename)) # stdCalibsString += '{}/RawData/UVESCalibrationFiles/{}\t{}\n'.format(WorkPath, filename, headerSTDCalib['HIERARCH ESO PRO CATG']) # # # # Create SOF files for esorex - raw night calibration files # rawCalibrationFileList = [filename for filename in rawFileList if 'CALIB' in fits.getheader('{}/{}'.format(baseRawDataFolder, filename))['HIERARCH ESO DPR CATG']] # rawSOFCalibrationString = stdCalibsString # # for filename in rawCalibrationFileList: # headerFile = fits.getheader('{}/{}'.format(baseRawDataFolder, filename)) # header = fnClassificationRules_UVES(headerFile) # rawSOFCalibrationString += '{}/{}\t{}\n'.format(baseRawDataFolder,filename, header['D0.CATG']) # # # # Create SOF files for esorex - raw science files # rawScienceFileList = [filename for filename in rawFileList if 'SCIENCE' in fits.getheader('{}/{}'.format(baseRawDataFolder, filename))['HIERARCH ESO DPR CATG']] # # esorexCommand = '' # for filename in rawScienceFileList: # print filename # # rawScienceFileKey = 'UVES.{}.{}'.format(header['DATE-OBS'], header['HIERARCH ESO INS PATH ']) # rawScienceString = rawSOFCalibrationString # headerFile = fits.getheader('{}/{}'.format(baseRawDataFolder, filename)) # header = fnClassificationRules_UVES(headerFile) # rawScienceString += '{}/{}\t{}\n'.format(baseRawDataFolder,filename, header['D0.CATG']) # # esorexSettings = '{}/scripts/customESOREX_{}_{}.cfg'.format( ReductPath,settings.rawDataFolder, rawScienceFileKey) # customESOREX = defaultEsorex.replace('DEFAULT_OUTPUT_DIR', '{}/reduced/{}/'.format(WorkPath, settings.rawDataFolder)) # customESOREX = customESOREX.replace('DEFAULT_OUTPUT_PREFIX', rawScienceFileKey) # # with open(esorexSettings,'w') as customEsorexFile: # customEsorexFile.write(customESOREX) # # print '\n\ncustom esorex settings file has been created: {}\n\n'.format(esorexSettings) # # # sofSettings = '{}/scripts/rawFiles2Reduce_{}_{}.sof'.format(ReductPath,settings.rawDataFolder,rawScienceFileKey) # # with open(sofSettings,'w') as sofFile: # sofFile.write(rawScienceString) # # print '\n\nlist of raw data files to be reduced has been created: {}\n\n'.format(rawScienceFileKey) # # # # # full esorex command # esorexCommand += 'esorex --config={0} --recipe-config={1} {2} {3} \n'.format(esorexSettings, recipeSettings,settings.recipeName, sofSettings ) # # # with open(esorexCommandfilename,'a') as esorexCommandFile: # esorexCommandFile.write(esorexCommand) # # # print '\n\nto reduce your data please run: {}\n\n{}\n'.format(esorexCommandfilename , esorexCommand) return
# endregion # region --- User Modules from modules.InOut import fnPrintLine from modules.recipeTools import fnSetRecipe from modules.fileManip import fngetRecipeFileList, fnUpdateProductList from modules.spectraTools import fnInferInstrumentResponse # endregion # region --- Init Terminal os.system("cls") os.system("clear") fnPrintLine(None, '') fnPrintLine(None, '', align='center', flush='=') fnPrintLine(None, 'reduce UVES data CPL wrapper \t(version: {:<})'.format(__version__), align='center') # fnPrintLine(None, '', align = 'center', flush = '=') fnPrintLine(None, '') fnPrintLine(None, 'Author:{:<} \temail: {:<}'.format(__author__, __email__), align='center') fnPrintLine(None, '') fnPrintLine(None, 'Last Update:{:<}'.format(__date__), align='center') fnPrintLine(None, '') fnPrintLine(None, '', align='center', flush='=') fnPrintLine(None, '') # endregion # region --- Parse Settings cfgFileName = sys.argv[1]
def main_function(): print 'Recover planet CCFs' fnPrintLine('CCF', 'Extracting CCFs, please wait') fullCCFList = sorted([ '{}/{}'.format(scienceInputFolder, fileName) for fileName in os.listdir(scienceInputFolder) if fileName.endswith('REDR_ccf.fits') ]) fullCCFs = { ccfName: clsUVESCCF(ccfName) for ccfName in sorted(fullCCFList) } fnPrintLine('Config', 'Extracting planet parameters') planetParams = clsPlanetParametersOLD( fnGetYOrbit('{}/{}'.format(scienceInputFolder, settings.orbitParams))) print planetParams.__dict__ # sys.exit() phaseZero = 0.5 # planetRVs = {} FIX = True # ======================================================================= fnPrintLine('CCF', 'getting planet RVS') rangeRVPixels = np.linspace(0, len(fullCCFs[fullCCFList[0]].data) - 1, len(fullCCFs[fullCCFList[0]].data)) for ccfName in sorted(fullCCFList): if FIX == True: fullCCFs[ccfName].getPhase(planetParams.period, planetParams.t0) fullCCFs[ccfName].RV = fnRVStarOrbitCircular( planetParams, phaseZero, fullCCFs[ccfName].PlanetPhaseFolded) fullCCFs[ccfName].RVC = fullCCFs[ccfName].RV else: fullCCFs[ccfName].RV -= planetParams.Sysrv + .4 fullCCFs[ccfName].RVC = fullCCFs[ccfName].RV # fullCCFs[ccfName].planetRV = -(fullCCFs[ccfName].RV )/planetParams.massratio # fullCCFs[ccfName].planetRVPixels fullCCFs[ccfName].ccfAmplitude, fullCCFs[ ccfName].ccfMeanPixel, fullCCFs[ccfName].ccfFWHMPixels, fullCCFs[ ccfName].ccfB = fnGaussianFitOLD( rangeRVPixels, fullCCFs[ccfName].data, GaussParamsInitGuess=[ max(fullCCFs[ccfName].data) - min(fullCCFs[ccfName].data), len(fullCCFs[ccfName].data) / 2, 10., max(fullCCFs[ccfName].data) ]) fullCCFs[ccfName].planetRV = -( fullCCFs[ccfName].RV) / planetParams.massratio fullCCFs[ccfName].planetRVMeanPixel = ( fullCCFs[ccfName].planetRV - fullCCFs[ccfName].RVC ) / fullCCFs[ccfName].CCFStep + fullCCFs[ccfName].ccfMeanPixel fullCCFs[ccfName].CCFWaveIni = fullCCFs[ccfName].RV - fullCCFs[ ccfName].ccfMeanPixel * fullCCFs[ccfName].CCFStep fullCCFs[ccfName].wave = np.arange(len(fullCCFs[ccfName].data), dtype=np.float64) * fullCCFs[ccfName].CCFStep + \ fullCCFs[ccfName].CCFWaveIni # print fullCCFs[ccfName].ccfMeanPixel, fullCCFs[ccfName].planetRVMeanPixel/ # ======================================================================= fnPrintLine('CCF', 'Building template') # starTemplateList = sorted(fullCCFList) #fnGetTemplateList('All', sorted(fullCCFList), fullCCFs, planetRVs.values(),planetParams) starTemplate, starTemplateWave, starTemplateMeanPixel = fnBuildStarTemplateNew( fullCCFs) templateA, templateMeanPixel, templateFWHM, templateB = fnGaussianFitOLD( rangeRVPixels, starTemplate, GaussParamsInitGuess=[ max(starTemplate) - min(starTemplate), len(starTemplate) / 2, 10., max(starTemplate) ]) # ======================================================================= planetCCF = [] for ccfName in sorted(fullCCFList): diffPixels = (templateMeanPixel - fullCCFs[ccfName].ccfMeanPixel ) # * fullCCFs[ccfName].CCFStep shiftedTemplate = fnShiftCCF(starTemplate, starTemplateWave, diffPixels) fullCCFs[ccfName].normCCF(shiftedTemplate) # fullCCFs[ccfName].data[int(starMeanPixel-25):int(starMeanPixel+25)] = None # fullCCFs[ccfName].data = fnShiftCCF(fullCCFs[ccfName].data, fullCCFs[ccfName].wave, planetRVs[ccfName] ) planetXXXRange = np.where( (fullCCFs[ccfName].wave < fullCCFs[ccfName].planetRV + 40) & (fullCCFs[ccfName].wave > fullCCFs[ccfName].planetRV - 40)) if fullCCFs[ccfName].planetRV - fullCCFs[ccfName].RV > 50: planetCCF.append(fullCCFs[ccfName].data[planetXXXRange][:80]) mplt.plot(fullCCFs[ccfName].wave, fullCCFs[ccfName].data) # fullCCFs[ccfName].data[planetXXXRange] = max(fullCCFs[ccfName].data) mplt.savefig('{}/{}_normalisedCCFs.png'.format(scienceOuputFolder, settings.ccfFolder)) mplt.clf() mplt.imshow(np.array( [fullCCFs[ccfName].data for ccfName in sorted(fullCCFList)]), cmap='Greys') mplt.savefig('{}/{}_2D_normCCFs_noOrbit.png'.format( scienceOuputFolder, settings.ccfFolder)) mplt.clf() iii = np.arange(len(fullCCFList)) for ccfName, ii in zip(sorted(fullCCFList), iii): mplt.plot(fullCCFs[ccfName].planetRVMeanPixel, ii, 'ro') mplt.ylim([len(fullCCFList) - 1, 0]) mplt.xlim([0, len(starTemplate) - 1]) mplt.savefig('{}/{}_2D_normCCFs_withOrbit.png'.format( scienceOuputFolder, settings.ccfFolder)) mplt.clf() finalCCF = np.nansum(planetCCF, axis=0) finalCCF = finalCCF / np.nanmedian(finalCCF) - 1 mplt.plot(np.linspace(-50, 50, num=len(finalCCF)), finalCCF) mplt.axhline(1.e-5, color='r') mplt.axhline(-1.e-5, color='r') axFinalCCF = mplt.gca() axFinalCCF.ticklabel_format(useOffset=False) mplt.savefig('{}/{}_FinalPlanetCCFs.png'.format(scienceOuputFolder, settings.ccfFolder)) mplt.clf()
def __main__(): # region -- getting file lists fnPrintLine('CONFIG', 'Getting file list, please wait') specType = 'WCALIB_SCI' try: fnPrintLine( 'Config', 'list of data files provided: {}'.format(settings.dataList)) scienceFiles = np.genfromtxt('{}/{}'.format(scienceInputFolder, settings.dataList), dtype=str) scienceFiles = [fileName for fileName in scienceFiles \ if specType in fits.getheader('{}/{}'.format(scienceInputFolder, fileName))[ 'HIERARCH ESO PRO CATG'] ] except: fnPrintLine( 'Config', 'no data file list file provided, creating CCF for all files.') scienceFiles = ['{}/{}'.format(root, fileName) for root, dir, fileNames in os.walk(scienceInputFolder, topdown=False) \ for fileName in fileNames \ if specType in fits.getheader('{}/{}'.format(root, fileName))['HIERARCH ESO PRO CATG'] \ ] ccfProcessedList = [ '{}/{}'.format(scienceOuputFolder, fileName) for fileName in os.listdir(scienceOuputFolder) ] # endregion # region -- processing files for fitsFile in scienceFiles: fnPrintLine('CONFIG', 'Processing: {} '.format(fitsFile)) # region -- building response curves per order blazeFile = fits.open(fitsFile.replace('resampled_science_', 'blaze_')) instrumentResponse = blazeFile[0].data # for instData in instrumentResponse: # mplt.plot(instData, 'bo') # mplt.show() # sys.exit() # endregion # region -- getting science files scienceFile = fits.open(fitsFile) # endregion # region -- setting write names rawScienceFileKey = 'UVES.{}.{}{}'.format( scienceFile[0].header['DATE-OBS'], scienceFile[0].header['HIERARCH ESO INS PATH'], scienceFile[0].header['HIERARCH ESO DET OUT1 NAME']) ccfWriteFileName = '{}/{}_ccf.fits'.format(scienceOuputFolder, rawScienceFileKey) # endregion # region -- Processing science files if ccfWriteFileName in ccfProcessedList: fnPrintLine( None, '{}_ccf.fits already been processed, skipping.'.format( rawScienceFileKey)) else: nOrders = scienceFile[0].header['NAXIS2'] fnPrintLine( 'CONFIG', '2D-Spectrum - Number of orders: {:>3} '.format(nOrders)) # region - Defining science and wave arrays scienceData = np.empty((nOrders, scienceFile[0].header['NAXIS1'])) waveData = np.empty((nOrders, scienceFile[0].header['NAXIS1'])) for order in np.arange(nOrders): scienceData[order] = scienceFile[0].data[ order] * instrumentResponse[order] waveData[order] = fnCreateWave2(scienceFile[0].header, order) fnPrintLine('Mask', 'Building mask') maskData = np.genfromtxt('{}/masks/{}.mas'.format( ReductPath, cfgFile.get('ccf', 'maskCCF'))) # endregion # region - Compute CCF fnPrintLine('CCF', 'Computing CCF for: {} '.format(fitsFile)) rangeRV = np.arange( float(cfgFile.get('ccf', 'guessRV')) - float(cfgFile.get('ccf', 'windowCCF')) - scienceFile[0].header['HIERARCH ESO QC VRAD BARYCOR'], float(cfgFile.get('ccf', 'guessRV')) + float(cfgFile.get('ccf', 'windowCCF')) - scienceFile[0].header['HIERARCH ESO QC VRAD BARYCOR'], float(cfgFile.get('ccf', 'stepCCF'))) rangeCCF = np.empty((nOrders, len(rangeRV))) nLinesPerOrder = np.empty(nOrders) for order in np.arange(nOrders): fnPrintLine( 'CCF', 'Computing CCF for order {:>3}/{:<3} '.format( order + 1, nOrders)) nonZeroRange = np.nonzero(scienceData[order]) rangeCCF[order], nLines = zip(*[ fnComputeCCF(scienceData[order][nonZeroRange], waveData[order][nonZeroRange], maskData, testRV) for testRV in rangeRV ]) nLinesPerOrder[order] = np.nanmin(nLines) fnPrintLine(None, 'Number of lines used for order {:>3}/{:<3}: {:>3.0f}'.format(\ order + 1, nOrders,nLinesPerOrder[order])) rangeRV += scienceFile[0].header['HIERARCH ESO QC VRAD BARYCOR'] rangeCCF = np.vstack((rangeCCF, np.nansum(rangeCCF, axis=0))) # endregion # region - writing CCFs to fits files CCFFits = fits.PrimaryHDU() CCFFits.header = scienceFile[0].header CCFFits.data = rangeCCF # NLines per order for order in np.arange(nOrders): CCFFits.header.set( 'HIERARCH ESO DRS CCF LINES %2.f' % order, nLinesPerOrder[order], comment='Num. lines to compute CCF for order %2.f' % order) # CCF Params CCFFits.header.set('CDELT1', float(cfgFile.get('ccf', 'stepCCF')), comment='step of CCF') CCFFits.header.set( 'CRVAL1', rangeRV[0], comment='first RV of CCF / beginning of CCF / BERV corrected') # fit gauss to summed CCF fnPrintLine( 'CONFIG', 'Fitting Gaussian to stacked ordersCCF'.format(fitsFile)) (A, mean, FWHM, B), pcov = opt.curve_fit( fnGaussian, rangeRV, rangeCCF[-1], p0=(np.nanmax(rangeCCF[-1]) - np.nanmin(rangeCCF[-1]), float(cfgFile.get('ccf', 'guessRV')), 10., np.nanmax(rangeCCF[-1])), #bounds=fitGaussBounds, ) #print cov# (A_Err, mean_Err, FWHM_Err, B_Err) = np.sqrt(np.diag(pcov)) # Gaussian fit params # CCFFits.header.set('HIERARCH ESO DRS CCF RVC', mean+ scienceFile[0].header['HIERARCH ESO QC VRAD BARYCOR'],comment='Computed Radial Velocity of target / mean of gaussian fit') CCFFits.header.set( 'HIERARCH ESO DRS CCF RV', mean + scienceFile[0].header['HIERARCH ESO QC VRAD BARYCOR'], comment= 'Computed Radial Velocity of target / mean of gaussian fit') CCFFits.header.set( 'HIERARCH ESO DRS CCF RV ERR', mean_Err, comment='error on radial velocity of target - to be revised') CCFFits.header.set( 'HIERARCH ESO DRS CCF FWHM', FWHM, comment='FWHM of fitted CCF / FWHM of gaussian fit') try: CCFFits.header.set( 'HIERARCH ESO DRS CCF FWHM ERR', FWHM_Err, comment= 'FWHM of fitted CCF / FWHM of gaussian fit - to be revised' ) except: CCFFits.header.set( 'HIERARCH ESO DRS CCF FWHM ERR', '-9999.9999', comment= 'FWHM of fitted CCF / FWHM of gaussian fit - to be revised' ) CCFFits.header.set('HIERARCH ESO DRS CCF CONTRAST', A / B, comment='Contrast of CCF') fits.writeto(ccfWriteFileName, CCFFits.data, CCFFits.header, clobber=True) # endregion # region - plotting CCFs as pdf fnPrintLine( 'PLOT', 'Saving image as pdf in {}'.format( './tmp/{}_ccfs.pdf'.format(rawScienceFileKey))) # define multipage pdf file pdfFile = PdfPages('./tmp/{}_ccfs.pdf'.format(rawScienceFileKey)) # define figures # figCCFs = mplt.figure(figsize=(50, 40), dpi=100) # figSpectra = mplt.figure(figsize=(50, 40), dpi=100) # # define titles # figCCFs.suptitle('CCF name key:{}\n'.format(rawScienceFileKey)) # figSpectra.suptitle('spectrum name key:{}\n'.format(rawScienceFileKey)) # setup axes and plot data for order in np.arange(nOrders): figOrder, [axSpectrum, axCCFs] = mplt.subplots(2, 1, figsize=(20, 15), dpi=300) # axOrderCCFs = figCCFs.add_subplot(int(nOrders / 4) + 1, 4, order + 1) # axOrderSpectra = figSpectra.add_subplot(int(nOrders / 4) + 1, 4, order + 1) # CCFs ax axCCFs.plot(rangeRV, rangeCCF[order] / np.nanmedian(rangeCCF[order]), 'b') axCCFs.set_xlabel('RV [km/s]', fontsize=20) axCCFs.set_xlim(np.nanmin(rangeRV), np.nanmax(rangeRV)) # spectra ax axSpectrum.plot( waveData[order][100:-100], scienceData[order][100:-100] / np.nanmax(scienceData[order][100:-100]), 'b') axSpectrum.set_xlabel('wavelength [$\AA$]', fontsize=20) axSpectrum.set_xlim(np.nanmin(waveData[order][100:-100]), np.nanmax(waveData[order][100:-100])) # title figOrder.suptitle(r'file name: %s' %rawScienceFileKey + '\n' + \ r'Order: %s N_lines: %.0f %.2f $\AA < \lambda < %.2f \AA$' \ % (order, nLinesPerOrder[order],waveData[order][0], waveData[order][-1])\ , fontsize = 30) figOrder.tight_layout() figOrder.subplots_adjust(top=.9) pdfFile.savefig(figOrder) mplt.close(figOrder) # axAll = figCCFs.add_subplot(int(nOrders / 4) + 1, 4, 4 * (int(nOrders / 4) + 1)) wholeCCF = rangeCCF[-1] #np.nansum(rangeCCF, axis=0) figAll, axAll = mplt.subplots(1, 1, figsize=(20, 15), dpi=300) axAll.plot(rangeRV, wholeCCF / max(wholeCCF), 'g') axAll.set_xlabel('RV [km/s]', fontsize=20) axAll.set_xlim(np.nanmin(rangeRV), np.nanmax(rangeRV)) axAll.text( 0.05, 0.05, ' Contrast: {:.2f}\n RV: {:.2f} +-{:.2f} km/s\n FWHM: {:.2f} +-{:.2f} km/s' .format(A / B, mean, mean_Err, FWHM, FWHM_Err), horizontalalignment='left', verticalalignment='bottom', transform=axAll.transAxes, fontsize=40) figAll.suptitle(r'file name: %s' %rawScienceFileKey + '\n' + \ 'All orders stacked: N_lines: %.0f $%.2f \AA < \lambda < %.2f \AA$' \ % (np.nansum(nLinesPerOrder), waveData[0][0], waveData[-1][-1]),\ fontsize = 30) figAll.tight_layout() figAll.subplots_adjust(top=.9) pdfFile.savefig(figAll) # figCCFs.tight_layout() # figSpectra.tight_layout() # pdfFile.savefig(figSpectra) # pdfFile.savefig(figCCFs) pdfFile.close() mplt.close("all")
:param FWHM: Full-Width Half-Maximum of gaussian curve :param B:fnProgress( return m * dataXXX + b ''' return B - Amp * np.exp(-4 * np.log(2) * (((dataXXX - mean) / FWHM)**2)) # endregion # endregion # region --- Init Terminal os.system('cls' if os.name == 'nt' else 'clear') os.system("cls") os.system("clear") fnPrintLine(None, '') fnPrintLine(None, '', align='center', flush='=') fnPrintLine(None, 'Create star+planet CCFs \t(version: {:<})'.format(__version__), align='center') fnPrintLine(None, '') fnPrintLine(None, 'Author:{:<} \temail: {:<}'.format(__author__, __email__), align='center') fnPrintLine(None, '') fnPrintLine(None, 'Last Update:{:<}'.format(__date__), align='center') fnPrintLine(None, '') fnPrintLine(None, '', align='center', flush='=') fnPrintLine(None, '') # endregion
def main_function(): fnPrintLine('CONFIG', 'Getting file list, please wait') if settings.specType.lower() == '1d': specType = 'RED_SCI_POINT' nOrders = 1 if settings.specType.lower() == '2d': specType = 'WCALIB_SCI_POINT' try: fnPrintLine( 'Config', 'list of data files provided: {}'.format(settings.dataList)) scienceFiles = np.genfromtxt('{}/{}'.format(scienceInputFolder, settings.dataList), dtype=str) scienceFiles = [fileName for fileName in scienceFiles \ if specType in fits.getheader('{}/{}'.format(scienceInputFolder, fileName))[ 'HIERARCH ESO PRO CATG'] ] except: fnPrintLine( 'Config', 'no data file list file provided, creating CCF for all files.') scienceFiles = [ fileName for fileName in os.listdir(scienceInputFolder) if specType in fits.getheader('{}/{}'.format( scienceInputFolder, fileName))['HIERARCH ESO PRO CATG'] ] ccfProcessedList = [ '{}/{}'.format(scienceOuputFolder, fileName) for fileName in os.listdir(scienceOuputFolder) ] # getting flats if settings.specType.lower() == '1d': specTypeFlat = 'RED_FLAT_OBJ' nOrders = 1 if settings.specType.lower() == '2d': specTypeFlat = 'WCALIB_FLAT_OBJ' fnPrintLine( 'Config', 'no data file list file provided, creating CCF for all files.') masterFlatFiles = [ fileName for fileName in os.listdir(scienceInputFolder) if specType in fits.getheader('{}/{}'.format( scienceInputFolder, fileName))['HIERARCH ESO PRO CATG'] ] ccfProcessedList = [ '{}/{}'.format(scienceOuputFolder, fileName) for fileName in os.listdir(scienceOuputFolder) ] for fitsFile in scienceFiles: # Getting science data fnPrintLine('CONFIG', 'Processing: {} '.format(fitsFile)) scienceFile = fits.open('%s/%s' % (scienceInputFolder, fitsFile)) rawScienceFileKey = 'UVES.{}.{}{}'.format( scienceFile[0].header['DATE-OBS'], scienceFile[0].header['HIERARCH ESO INS PATH'], scienceFile[0].header['HIERARCH ESO DET OUT1 NAME']) ccfWriteFileName = '{}/{}_ccf.fits'.format(scienceOuputFolder, rawScienceFileKey) if ccfWriteFileName in ccfProcessedList: fnPrintLine( None, '{}_ccf.fits already been processed, skipping.'.format( rawScienceFileKey)) else: try: nOrders = scienceFile[0].header['NAXIS2'] fnPrintLine( 'CONFIG', '2D-Spectrum - Number of orders: {:>3} '.format(nOrders)) except: nOrders = 1 fnPrintLine('CONFIG', '1D-Spectrum') # Defining science and wave arrays if nOrders == 1: scienceData = scienceFile[0].data waveData = fnCreateWave2(scienceFile[0].header, 1, numberOrders=1) # mplt.plot(waveData,scienceData) elif nOrders > 1: scienceData = np.empty( (nOrders, scienceFile[0].header['NAXIS1'])) waveData = np.empty((nOrders, scienceFile[0].header['NAXIS1'])) for order in np.arange(nOrders): scienceData[order] = scienceFile[0].data[order] waveData[order] = fnCreateWave2(scienceFile[0].header, order, numberOrders=nOrders) # for order in np.arange(nOrders): # mplt.plot(waveData[order], scienceData[order]) # # mplt.show() # sys.exit() fnPrintLine('Mask', 'Building mask') maskData = np.genfromtxt('{}/masks/{}.mas'.format( ReductPath, settings.maskCCF)) # Compute CCF fnPrintLine('CCF', 'Computing CCF for: {} '.format(fitsFile)) # rangeRV = np.arange(settings.guessRV-settings.windowCCF + scienceFile[0].header['HIERARCH ESO QC VRAD BARYCOR'], settings.guessRV+settings.windowCCF + scienceFile[0].header['HIERARCH ESO QC VRAD BARYCOR'], settings.stepCCF) rangeRV = np.arange( settings.guessRV - settings.windowCCF - scienceFile[0].header['HIERARCH ESO QC VRAD BARYCOR'], settings.guessRV + settings.windowCCF - scienceFile[0].header['HIERARCH ESO QC VRAD BARYCOR'], settings.stepCCF) if nOrders == 1: rangeCCF, nLines = zip(*[ fnComputeCCF(scienceData, waveData, maskData, testRV) for testRV in rangeRV ]) fnPrintLine( None, 'Computing CCF for BERV corrected RV = {:.2f}km/s'.format( rangeRV[-1])) mplt.plot(rangeRV, rangeCCF / max(rangeCCF)) elif nOrders > 1: rangeCCF = np.empty((nOrders, len(rangeRV))) nLinesPerOrder = np.empty(nOrders) for order in np.arange(nOrders): fnPrintLine( 'CCF', 'Computing CCF for order {:>3}/{:<3} '.format( order + 1, nOrders)) rangeCCF[order], nLines = zip(*[ fnComputeCCF(scienceData[order], waveData[order], maskData, testRV) for testRV in rangeRV ]) nLinesPerOrder[order] = np.nanmin(nLines) fnPrintLine( None, 'Number of lines used for order {:>3}/{:<3}: {:>3.0f}'. format(order + 1, nOrders, nLinesPerOrder[order])) # Fit gaussian CCF if nOrders == 1: A, mean, FWHM, B = fnGaussianFitOLD( rangeRV, rangeCCF, GaussParamsInitGuess=[ max(rangeCCF) - min(rangeCCF), settings.guessRV - scienceFile[0].header['HIERARCH ESO QC VRAD BARYCOR'], 10., max(rangeCCF) ]) elif nOrders > 1: A = np.empty(nOrders) mean = np.empty(nOrders) FWHM = np.empty(nOrders) B = np.empty(nOrders) AErr = np.empty(nOrders) meanErr = np.empty(nOrders) FWHMErr = np.empty(nOrders) BErr = np.empty(nOrders) from math_local.mathFunctions import fnGaussianFit for order in np.arange(nOrders): # A[order], mean[order], FWHM[order], B[order] = fnGaussianFitOLD(rangeRV,rangeCCF[order],GaussParamsInitGuess =[max(rangeCCF[order])- min(rangeCCF[order]), settings.guessRV , 10., max(rangeCCF[order])]) A[order], mean[order], FWHM[order], B[order], AErr[ order], meanErr[order], FWHMErr[order], BErr[ order] = fnGaussianFit( rangeRV, rangeCCF[order], GaussParamsInitGuess=[ max(rangeCCF[order]) - min(rangeCCF[order]), settings.guessRV - scienceFile[0]. header['HIERARCH ESO QC VRAD BARYCOR'], 10., max(rangeCCF[order]) ]) # building fits file CCFFits = fits.PrimaryHDU() CCFFits.header = scienceFile[0].header CCFFits.data = rangeCCF # NLines per order for order in np.arange(nOrders): CCFFits.header.set( 'HIERARCH ESO DRS CCF LINES %2.f' % order, nLinesPerOrder[order], comment='Number of lines used to compute CCF of order %2.f' % order) # CCF Params CCFFits.header.set('CDELT1', settings.stepCCF, comment='step of CCF') CCFFits.header.set('CRVAL1', rangeRV[0], comment='first RV of CCF / beginning of CCF') # Gaussian fit params # CCFFits.header.set('HIERARCH ESO DRS CCF RVC', mean+ scienceFile[0].header['HIERARCH ESO QC VRAD BARYCOR'],comment='Computed Radial Velocity of target / mean of gaussian fit') # CCFFits.header.set('HIERARCH ESO DRS CCF RV', mean+ scienceFile[0].header['HIERARCH ESO QC VRAD BARYCOR'],comment='Computed Radial Velocity of target / mean of gaussian fit') # CCFFits.header.set('HIERARCH ESO DRS CCF NOISE', meanErr ,comment='error on radial velocity of target - to be implemented') # CCFFits.header.set('HIERARCH ESO DRS CCF FWHM', FWHM ,comment='FWHM of fitted CCF / FWHM of gaussian fit') # CCFFits.header.set('HIERARCH ESO DRS CCF CONTRAST', A/B ,comment='Contrast of CCF') fits.writeto(ccfWriteFileName, CCFFits.data, CCFFits.header, clobber=True) fnPrintLine( 'PLOT', 'Saving image as pdf in {}'.format( './tmp/{}_ccfs.png'.format(rawScienceFileKey))) # mplt.ion() fig = mplt.figure(figsize=(100, 80), dpi=50) mplt.title(ccfWriteFileName.split('/')[-1]) for order in np.arange(nOrders): axOrder = fig.add_subplot(int(nOrders / 4) + 1, 4, order + 1) axOrder.plot(rangeRV, rangeCCF[order] / B[order], 'b') gaussFit = fnGauss( rangeRV, [A[order], mean[order], FWHM[order], B[order]]) axOrder.plot( rangeRV, gaussFit / B[order], 'r', ) axOrder.annotate( 'Order: %s \n N_lines: %.0f \n %.2f < lambda < %.2f' % (order, nLinesPerOrder[order], waveData[order][0], waveData[order][-1]), xy=(0.95, 0.05), xycoords='axes fraction', va='bottom', ha='right') axAll = fig.add_subplot( int(nOrders / 4) + 1, 4, 4 * (int(nOrders / 4) + 1)) wholeCCF = np.nansum(rangeCCF, axis=0) axAll.plot(rangeRV, wholeCCF / max(wholeCCF), 'g') axAll.annotate( 'All orders stacked \n N_lines: %.0f \n %.2f < lambda < %.2f' % (np.nansum(nLinesPerOrder), waveData[0][0], waveData[-1][-1]), xy=(0.95, 0.05), xycoords='axes fraction', va='bottom', ha='right') # mplt.draw() fig.savefig('./tmp/{}_ccfs.png'.format(rawScienceFileKey), format='png') mplt.close(fig)
def main_function(): # region --- Define planet parameters planetParams = clsPlanetParametersOLD(params={ param: value for param, value in cfgFile.items('orbital_params') }) # endregion # region --- Get files list # data files try: # if a list with fits files from which to recover the planet CCF has been provided dataCCFList = sorted([os.path.join(scienceInputFolder, fileName) \ for fileName in list( np.genfromtxt(os.path.join(scienceInputFolder, cfgFile.get('detection_settings', 'dataFilelist')), \ dtype=str))]) fnPrintLine('Config', 'data ccf list file provided: {}'.format( \ os.path.join(scienceInputFolder, cfgFile.get('detection_settings', 'dataFilelist')))) except: dataCCFList = sorted([os.path.join(scienceInputFolder, fileName) for fileName in os.listdir(scienceInputFolder) \ if fileName.lower().endswith('fits')]) fnPrintLine('Config', 'no data ccf list file provided, using all ccfs.') # template files try: # if a list with fits files from which to construct the template has been provided templateCCFList = sorted([os.path.join(scienceInputFolder, fileName) \ for fileName in list( np.genfromtxt(os.path.join(scienceInputFolder, cfgFile.get('detection_settings', 'templateFilelist')), \ dtype=str))]) fnPrintLine('Config', 'template ccf list file provided: {}'.format( \ os.path.join(scienceInputFolder, cfgFile.get('detection_settings', 'templateFilelist')))) except: templateCCFList = sorted( [os.path.join(scienceInputFolder, fileName) for fileName in os.listdir(scienceInputFolder) \ if fileName.lower().endswith('fits')]) fnPrintLine('Config', 'no template ccf list file provided, using all ccfs.') # all files fullCCFList = sorted(set(dataCCFList + templateCCFList)) # endregion # region --- load fits files fnPrintLine('CCF', 'Extracting CCFs, please wait') fullCCFs = { ccfName: fnOpenHARPSFits(ccfName) for ccfName in sorted(fullCCFList) } # constrain file lists try: dataCCFList = [ccfName for ccfName in dataCCFList \ if fullCCFs[ccfName].SN50 >= float(cfgFile.get('detection_settings', 'minSN50')) \ ] templateCCFList = [ccfName for ccfName in templateCCFList \ if fullCCFs[ccfName].SN50 >= float(cfgFile.get('detection_settings', 'minSN50')) \ ] except: pass # endregion # region --- Finding star CCF parameters fnPrintLine('CCF', 'finding star CCF parameters') # define xxx axis rangeRVPixels = np.linspace(0, len(fullCCFs[fullCCFList[0]].data) - 1, len(fullCCFs[fullCCFList[0]].data)) ccfPixelTrimMargins = 10. # in pixels for ccfName in sorted(fullCCFList): fullCCFs[ccfName].ccfAmplitude, fullCCFs[ccfName].ccfMeanPixel, fullCCFs[ccfName].ccfFWHMPixels, fullCCFs[ ccfName].ccfB = \ fnGaussianFitOLD(rangeRVPixels, fullCCFs[ccfName].data, \ GaussParamsInitGuess=[max(fullCCFs[ccfName].data) - min(fullCCFs[ccfName].data), \ len(fullCCFs[ccfName].data) / 2, \ 10., \ max(fullCCFs[ccfName].data)]) fullCCFs[ccfName].PlanetPhase = ( fullCCFs[ccfName].BJD - planetParams.t0 ) / planetParams.period + np.radians(planetParams.w) / (2 * np.pi) fullCCFs[ccfName].PlanetPhaseFolded = ( fullCCFs[ccfName].PlanetPhase) % 1 fullCCFs[ccfName].RV = fullCCFs[ccfName].RVC = fnRVStarOrbitElipse( planetParams, fullCCFs[ccfName].PlanetPhaseFolded - np.radians(planetParams.w) / (2 * np.pi)) fullCCFs[ ccfName].planetRV = -fullCCFs[ccfName].RV / planetParams.massRatio fullCCFs[ccfName].wave = np.arange(-fullCCFs[ccfName].ccfMeanPixel, \ len(fullCCFs[ccfName].data) - fullCCFs[ccfName].ccfMeanPixel) * \ fullCCFs[ccfName].CCFStep + \ fullCCFs[ccfName].RV # endregion # region --- build template fnPrintLine('CCF', 'build star template') fullCCFs['template'] = fnBuildStarTemplateOLD(fullCCFs, Templates=templateCCFList) fullCCFs['template'].CCFStep = fullCCFs[ccfName].CCFStep fullCCFs['template'].CCFWaveIni = -fullCCFs['template'].CCFStep * fullCCFs[ 'template'].ccfMeanPixel fullCCFs['template'].BJD = 0.0 fullCCFs['template'].PlanetPhaseFolded = 0.0 # endregion # region --- normalize CCFs by template fnPrintLine('CCF', 'normalise by star template') dataSelectedCCFList = [ ccfName for ccfName in sorted(dataCCFList) if abs(fullCCFs[ccfName].planetRV - fullCCFs[ccfName].RV) > float( cfgFile.get('detection_settings', 'distancePlanetStar')) ] for ccfName in sorted(fullCCFList): templateMeanPixel = fullCCFs['template'].ccfMeanPixel starTemplate = fullCCFs['template'].data starTemplateWave = fullCCFs['template'].wave diffPixels = (templateMeanPixel - fullCCFs[ccfName].ccfMeanPixel) shiftedTemplate = fnShiftCCF(starTemplate, starTemplateWave, diffPixels) fullCCFs[ccfName].normCCF(shiftedTemplate) # endregion # region --- searching for planet fnPrintLine('CCF', 'searching for planet, please wait') rangeRVsPlanet = {} planetWindowHalfWidth = float( cfgFile.get('detection_settings', 'planetHalfWidth')) for ccfName in sorted(dataCCFList): rangeRVsPlanet[ccfName] = np.where( \ (fullCCFs[ccfName].wave < fullCCFs[ccfName].planetRV + planetWindowHalfWidth) & \ (fullCCFs[ccfName].wave > fullCCFs[ccfName].planetRV - planetWindowHalfWidth) \ ) #fullCCFs[ccfName].planetRVRange = fullCCFs[ccfName].data[rangeRVsPlanet[ccfName]] # print fullCCFs[ccfName].planetRVRange[0], len(fullCCFs[ccfName].planetRVRange) widthPlanet = np.nanmin([ len(rangeRVsPlanet[ccfName][0]) for ccfName in sorted(dataSelectedCCFList) ]) planetCCF = np.nansum([ fullCCFs[ccfName].data[rangeRVsPlanet[ccfName]][:widthPlanet] for ccfName in sorted(dataSelectedCCFList) ], axis=0) planetWave = np.linspace(-planetWindowHalfWidth, planetWindowHalfWidth, num=len(planetCCF)) # linear fit - y = m x + c m, c = np.polyfit(planetWave, planetCCF, 1) YYY = [m * x + c for x in planetWave] planetCCF = planetCCF / YYY planetCCF /= np.nanmedian(planetCCF) # planet CCF fit ccfAmplitude, ccfMean, ccfFWHM, ccfB = fnGaussianFitOLD(planetWave, planetCCF, \ GaussParamsInitGuess=[max(planetCCF) - min(planetCCF), \ 0.0, \ 10., \ np.nanmedian(planetCCF)] ) planetFit = fnGauss(planetWave, [ccfAmplitude, ccfMean, ccfFWHM, ccfB]) # endregion # region --- correlating different nights fnPrintLine('CCF', 'correlation!!!') # delete central region of star CCF for better contrast # for ccfName in sorted(fullCCFList): nightList = sorted( set([int(fullCCFs[ccfName].BJD) for ccfName in dataCCFList])) ccfListNight = {night:[ccfName for ccfName in sorted(fullCCFList) \ if int(fullCCFs[ccfName].BJD) == night] for night in nightList} nightCorrelation = {} nightTemplates = { night: fnBuildStarTemplateOLD(fullCCFs, Templates=ccfListNight[night]) for night in nightList } print len(nightList) # remove center of CCF for night in nightList: nightTemplates[night].data[fullCCFs[ccfName].ccfMeanPixel - starWidth * fullCCFs[ccfName].ccfFWHMPixels:\ fullCCFs[ccfName].ccfMeanPixel + starWidth *fullCCFs[ccfName].ccfFWHMPixels] = None # mplt.plot(nightTemplates[night].data) # do correlation # for nightFirst, nightSecond in zip(nightList[:-1], nightList[1:] ): # print nightFirst, nightSecond # # # ratio = nightTemplates[nightFirst].data/nightTemplates[nightList[0]].data # # # mplt.plot(ratio) # # # mplt.plot() # # # mplt.show() # # correlation = []#np.correlate(nightTemplates[nightFirst].data, nightTemplates[nightSecond].data,mode='full') # # pixRVmax = 2000 # # for pixRV in waveRange(0,pixRVmax): # # # print pixRV # # correlation.append(np.corrcoef(nightTemplates[nightFirst].data[pixRV:pixRV-pixRVmax], nightTemplates[nightSecond].data[pixRVmax:])[0,1]) # # print np.corrcoef(nightTemplates[nightFirst].data[pixRV:pixRV-pixRVmax], nightTemplates[nightSecond].data[pixRVmax:]) # # print # # print np.corrcoef(nightTemplates[nightFirst].data, nightTemplates[nightSecond].data) # # mplt.plot(nightTemplates[nightFirst].data) # mplt.plot(nightTemplates[nightSecond].data) # # # mplt.plot(correlation, 'ro') # mplt.show() # mplt.show() # sys.exit() # endregion # region --- SN and phase function fnPrintLine('CCF', 'SN and phase function') expectedSN = np.sqrt( np.nansum([ fullCCFs[ccfName].nLines * (fullCCFs[ccfName].SN50**2) for ccfName in sorted(dataSelectedCCFList) ])) measuredNoise = np.nanstd(planetCCF) phaseFunction = { ccfName: fnPhaseFunction(planetParams.I, fullCCFs[ccfName].PlanetPhaseFolded - .25, model='Lambert') \ for ccfName in dataSelectedCCFList} medianPhaseFunction = np.nanmedian(phaseFunction.values()) medianStarCCFContrast = np.nanmedian( [fullCCFs[ccfName].contrast for ccfName in dataSelectedCCFList]) albedoLimitNoise = (planetParams.a / planetParams.radiusPlanet)**2 * 1 / ( medianPhaseFunction) * (measuredNoise) albedoLimitCCF = (planetParams.a / planetParams.radiusPlanet)**2 * 1 / ( medianPhaseFunction) * (ccfAmplitude / medianStarCCFContrast) # endregion # region --- PERIODOGRAMS # fnPrintLine('CCF', 'Periodograms of normalised CCFs') # # http://www.hs.uni-hamburg.de/DE/Ins/Per/Czesla/PyA/PyA/pyTimingDoc/pyPeriodDoc/examples.html # # # periodogram of template # fnPrintLine('CCF', 'Periodograms of star template') # starMask = np.ones(len(fullCCFs['template'].data), np.bool) # starMask[fullCCFs['template'].ccfMeanPixel - 3 * fullCCFs['template'].ccfFWHMPixels: \ # fullCCFs['template'].ccfMeanPixel + 3 * fullCCFs['template'].ccfFWHMPixels] = 0 # fullCCFs['template'].wave = fullCCFs['template'].wave.copy()[starMask] # fullCCFs['template'].wave = fullCCFs['template'].wave * fullCCFs['template'].CCFStep + fullCCFs['template'].CCFWaveIni # # # fullCCFs['template'].data = fullCCFs['template'].data.copy()[starMask] # # periodogramTemplateTimeSeries = pyPeriod.TimeSeries(fullCCFs['template'].wave, fullCCFs['template'].data) # periodogramTemplate = pyPeriod.LombScargle(periodogramTemplateTimeSeries, ofac=1, hifac=1) # # # # # computes the Lomb Scargle Periodogram of the RV using each frequency as a guess for the planet CCF # fnPrintLine('CCF', 'Periodograms of planet CCF') # # periodogramPlanetCCFTimeSeries = pyPeriod.TimeSeries(planetWave, planetCCF) # periodogramPlanetCCF = pyPeriod.LombScargle(periodogramPlanetCCFTimeSeries, ofac=1, hifac=1) # # # powerPeaks = [float(peak) for peak in cfgFile.get('periodograms', 'powerPeaks').strip('[]').split(',')] # print powerPeaks # # for power in powerPeaks: # print power, periodogramPlanetCCF.stats(power) # # # periodogram of RVs # fnPrintLine('CCF', 'Periodograms of RVs') # # periodogramRVTimeSeries = pyPeriod.TimeSeries(np.array([fullCCFs[ccfName].BJD for ccfName in fullCCFList]), \ # np.array([fullCCFs[ccfName].RV for ccfName in fullCCFList])) # periodogramRV = pyPeriod.LombScargle(periodogramRVTimeSeries, ofac=1, hifac=1) # endregion # region --- [PLOTS] pdfFile = PdfPages( os.path.join( resultsFolder, 'figures_{}.pdf'.format(cfgFile.get('global', 'resultsFolder')))) # region [PLOT] orbit points fnPrintLine('PLOT', 'orbit points') figPhases, axPhases = mplt.subplots(2, 1, sharex=True, figsize=(12, 8)) phasesFullOrbit = np.arange(0., 1., .01) rvFullOrbit = [ -fnRVStarOrbitElipse(planetParams, phase - np.radians(planetParams.w) / (2 * np.pi)) / planetParams.massRatio for phase in phasesFullOrbit ] for ax in axPhases: ax.plot([fullCCFs[ccfName].PlanetPhaseFolded for ccfName in sorted(fullCCFList)], \ [fullCCFs[ccfName].planetRV for ccfName in sorted(fullCCFList)], 'bd', markersize=8) ax.grid(b=True, which='major', color='k', linestyle='--', alpha=.3) # ax.set_ylim(-1.1*planetParams.k2,1.1*planetParams.k2) # ax.axhline(0.0, label= r'$RV_{CM}$') ax.axvline(0.25, label='transit', color='red') ax.axvline(0.75, label='opposition', color='green') ax.legend(loc='best', title='r$\phi = 0$ - Ascending node') ax.set_xlim(0, 1) ax.set_xticks(np.arange(0, 1, .05)) ax.plot(phasesFullOrbit, rvFullOrbit, 'b-', alpha=.3, markersize=8) # ax template axPhases[0].set_title('template points') templatePoints = axPhases[0].plot([fullCCFs[ccfName].PlanetPhaseFolded for ccfName in sorted(templateCCFList)], \ [fullCCFs[ccfName].planetRV for ccfName in sorted(templateCCFList)], \ 'r*', markersize=16, label='{} ({} points)'.format('Template', len(templateCCFList))) # ax data axPhases[1].set_title('data points') dataPoints = axPhases[1].plot([fullCCFs[ccfName].PlanetPhaseFolded for ccfName in sorted(dataCCFList)], \ [fullCCFs[ccfName].planetRV for ccfName in sorted(dataCCFList)], \ 'r*', markersize=16, label='{} ({} points)'.format('Data', len(dataCCFList))) figPhases.tight_layout() figPhases.savefig(pdfFile, format='pdf') # endregion # region [PLOT] template 2D normalised CCFS fnPrintLine('PLOT', '2D normalised CCFs') maxFlux = np.nanmax([np.nanmax((fullCCFs[ccfName].data / np.nanmedian(fullCCFs[ccfName].data) - 1) * 1000) \ for ccfName in fullCCFList]) minFlux = np.nanmin([np.nanmin((fullCCFs[ccfName].data / np.nanmedian(fullCCFs[ccfName].data) - 1) * 1000) \ for ccfName in fullCCFList]) # plot template nights 2D norm spectra fig2DNormCCFsTemplate = fnPlot2DCCFs( fullCCFs, templateCCFList, stellarCCFWidth=starWidth, title='normalised CCFs for template construction') fig2DNormCCFsTemplate.savefig(pdfFile, format='pdf') # endregion # region [PLOT] plot data nights 2D norm spectra fig2DNormCCFsPlanet = fnPlot2DCCFs(fullCCFs, dataCCFList, stellarCCFWidth = starWidth, title= 'normalised CCFs for planet recovery',\ RVRanges={ccfName:fullCCFs[ccfName].wave[rangeRVsPlanet[ccfName]] for ccfName in dataCCFList}) fig2DNormCCFsPlanet.savefig(pdfFile, format='pdf') # endregion # region [PLOT] phase function # fnPrintLine('PLOT', 'Phase function') # figPhaseFunction, axPhaseFunction = mplt.subplots() # phasefunctionFullOrbit = [fnPhaseFunction(planetParams.I, phase + .75, model='Lambert') for phase in # phasesFullOrbit] # # axPhaseFunction.plot(phasesFullOrbit, phasefunctionFullOrbit, 'k', alpha=0.5) # axPhaseFunction.plot([fullCCFs[ccfName].PlanetPhaseFolded for ccfName in dataSelectedCCFList], \ # [phaseFunction[ccfName] for ccfName in dataSelectedCCFList], 'ro') # # # axPhaseFunction.set_xlim([0, 1]) # axPhaseFunction.axvline(.75, color='green', label='Opposition') # axPhaseFunction.axvline(.25, color='red', label='Transit') # axPhaseFunction.axhline(medianPhaseFunction, color='blue', # label='average phase function:{:.2f}'.format(medianPhaseFunction)) # axPhaseFunction.set_title('Phase function') # # figPhaseFunction.savefig(pdfFile, format='pdf') # endregion # # region [PLOT] Lomb Scargle Periodogram of template ccf fnPrintLine('PLOT', 'Lomb Scargle Periodogram of template ccf') figPeriodogramNormCCFs, axPeriodogramNormCCFs = mplt.subplots(2, 1) axPeriodogramNormCCFs[0].plot(fullCCFs['template'].wave, fullCCFs['template'].data, 'ko', markersize=2) axPeriodogramNormCCFs[0].yaxis.set_major_formatter( \ FuncFormatter(lambda y, pos: '{:.0f}'.format((y - np.nanmedian(fullCCFs['template'].data)) * 1e3))) axPeriodogramNormCCFs[0].set_xlim(min(fullCCFs['template'].wave), max(fullCCFs['template'].wave)) # axPeriodogramNormCCFs[1].plot([1 / freq for freq in periodogramTemplate.freq], periodogramTemplate.power, 'r') # axLombscargleNormCCFs[1].text(0.05,0.95, 'max frequency: {:.2f} km/s'.format(periodogramStarTemplateMaxFrequency*fullCCFs[periodogramFileList[0]].CCFStep) ,\ # fontsize = 12, horizontalalignment='left', verticalalignment='top',transform=axLombscargleNormCCFs[1].transAxes) axPeriodogramNormCCFs[0].set_title('Template') axPeriodogramNormCCFs[1].set_xlabel(r'RV period [km/s]') # axPeriodogramNormCCFs[1].set_xscale('log') # try: # axPeriodogramNormCCFs[1].set_xlim(float(cfgFile.get('periodograms', 'frequencyTemplateLow')), # float(cfgFile.get('periodograms', 'frequencyTemplateHigh'))) # except: # pass figPeriodogramNormCCFs.savefig(pdfFile, format='pdf') # endregion # region [PLOT] Lomb Scargle Periodogram of recovered planet CCF fnPrintLine('PLOT', 'Lomb Scargle Periodogram of recovered planet CCF') figPeriodogramPlanetCCF, axPeriodogramPlanetCCF = mplt.subplots(2, 1) axPeriodogramPlanetCCF[0].set_title('Planet CCF') axPeriodogramPlanetCCF[0].plot(planetWave, planetCCF, 'ko', markersize=1) # axPeriodogramPlanetCCF[0].plot(planetWave, fnGauss(planetWave,[ccfAmplitude, ccfMean, ccfFWHM, ccfB]), 'r') axPeriodogramPlanetCCF[0].axhline(1 - 1e-5, color='red') axPeriodogramPlanetCCF[0].axhline(1 + 1e-5, color='red') axPeriodogramPlanetCCF[0].axhline(1 - 1e-4, color='green') axPeriodogramPlanetCCF[0].axhline(1 + 1e-4, color='green') axPeriodogramPlanetCCF[0].axvline(-3.5, color='magenta') axPeriodogramPlanetCCF[0].axvline(3.5, color='magenta') axPeriodogramPlanetCCF[0].yaxis.set_major_formatter( \ FuncFormatter(lambda y, pos: '{:.0f}'.format((y - np.nanmedian(planetCCF)) * 1e6))) axPeriodogramPlanetCCF[0].set_ylabel(r'$1-\frac{F_p}{F/*}$[ppm]') axPeriodogramPlanetCCF[0].set_xlabel(r'radial velocity [km/s]') # axPeriodogramPlanetCCF[1].plot([1 / freq for freq in periodogramPlanetCCF.freq], # [power for power in periodogramPlanetCCF.power], 'r', markersize=1) axPeriodogramPlanetCCF[1].set_xlabel(r'RV period [km/s]') # axPeriodogramPlanetCCF[1].set_xscale('log') # try: # axPeriodogramPlanetCCF[1].set_xlim(float(cfgFile.get('periodograms', 'frequencyPlanetLow')), # float(cfgFile.get('periodograms', 'frequencyPlanetHigh'))) # except: # pass figPeriodogramPlanetCCF.savefig(pdfFile, format='pdf') # endregion # region [PLOT] RVs and periodogram # figPeriodogramRV, axPeriodogramRV = mplt.subplots(2, 1) # axPeriodogramRV[0].set_title('Julian date vs Star RV') # # axPeriodogramRV[0].plot([fullCCFs[ccfName].BJD - 2.45e6 for ccfName in fullCCFList], # [fullCCFs[ccfName].RV for ccfName in fullCCFList], 'bo') # axPeriodogramRV[0].set_xlabel(r'Julian date - 2450 000 [day]') # axPeriodogramRV[1].tick_params(axis='x', which='minor', bottom='on') # axPeriodogramRV[1].plot([1 / freq for freq in periodogramRV.freq], [power for power in periodogramRV.power], 'r', # markersize=1) # minor_ticks = np.arange(0, max([1 / freq for freq in periodogramRV.freq]), 10) # axPeriodogramRV[1].set_xticks(minor_ticks, minor=True) # axPeriodogramRV[1].set_xlabel(r'period [day]') # axPeriodogramPlanetPhases[1].set_xscale('log') # # try: # axPeriodogramRV[1].set_xlim(float(cfgFile.get('periodograms', 'frequencyRVLow')), # float(cfgFile.get('periodograms', 'frequencyRVHigh'))) # except: # pass # # figPeriodogramRV.savefig(pdfFile, format='pdf') # endregion # region [PLOT] write config parameters fnPrintLine('PLOT', 'write config parameters') strFormat = ' {:<20s} = {}\n' strSettings = '' for section_name in cfgFile.sections(): strSettings += '[{}]\n'.format(section_name) for name, value in cfgFile.items(section_name): lineLenght = 60 value = '\n'.join([ value[ini:ini + lineLenght] for ini in np.arange(0, len(value), lineLenght) ]) strSettings += strFormat.format(name, value) strSettings += '\n' figSettings, axSettings = mplt.subplots(figsize=(8.27, 11.69), tight_layout=True) axSettings.text(0.05, 0.95, strSettings, fontsize=12, \ horizontalalignment='left', \ verticalalignment='top', \ ) axSettings.axis('off') figSettings.savefig(pdfFile, format='pdf') # endregion # region [PLOT] recovered parameters fnPrintLine('PLOT', 'recovered parameters') strFormat = ' {:<20s} = {}\n' strPlanetRecoveredParams = '[Gauss Parameters]\n' strPlanetRecoveredParams += strFormat.format( 'Amplitude ($A_{CCF}$)', '{:.0f} ppm'.format(ccfAmplitude * 1e6)) strPlanetRecoveredParams += strFormat.format('Mean', '{:.1f} km/s'.format(ccfMean)) strPlanetRecoveredParams += strFormat.format('FWHM', '{:.1f} km/s'.format(ccfFWHM)) strPlanetRecoveredParams += '\n[Noise]\n' strPlanetRecoveredParams += strFormat.format('expected SN50', '{:.1e}'.format(expectedSN)) strPlanetRecoveredParams += strFormat.format( 'expected noise', '{:.1e}'.format(1 / expectedSN)) strPlanetRecoveredParams += strFormat.format( 'measured noise', '{:.1e}'.format(measuredNoise)) strPlanetRecoveredParams += '\n[Albedo]\n' strPlanetRecoveredParams += strFormat.format( r'Median Phase function $g(\alpha)$', '{:.2f} (maximum at opposition; minimum at transit)'.format( medianPhaseFunction)) strPlanetRecoveredParams += strFormat.format( r'Planet radius', '{:.0f} km'.format(planetParams.radiusPlanet)) strPlanetRecoveredParams += strFormat.format( r'semi-major axis', '{:.0f} km'.format(planetParams.a)) strPlanetRecoveredParams += strFormat.format( r'Min albedo [from noise]', '{:.2f}'.format(albedoLimitNoise)) strPlanetRecoveredParams += '\n\n' + r'$A_g = \left(\frac{a}{R_p}\right)^2 \times\, \frac{1}{avg(g(\alpha))} \times\, noise_{measured}$' + '\n\n' strPlanetRecoveredParams += strFormat.format( r'median star contrast', '{:.2f}'.format(medianStarCCFContrast)) strPlanetRecoveredParams += strFormat.format( r'Min albedo [from detected "ccf"]', '{:.2f}'.format(albedoLimitCCF)) strPlanetRecoveredParams += '\n\n' + r'$A_g = \left(\frac{a}{R_p}\right)^2 \times\, \frac{1}{avg(g(\alpha))} \times\, \frac{amplitude_{planet}}{median(contrast_{star})}$' + '\n\n' strPlanetRecoveredParams += strFormat.format( r'$\left(\frac{R_p}{a} \right)^2$', '{:.1e}'.format( (planetParams.radiusPlanet / planetParams.a)**2)) figParams, axParams = mplt.subplots(figsize=(8.27, 11.69), tight_layout=True) axParams.text(0.05, 0.95, strPlanetRecoveredParams, fontsize=12, \ horizontalalignment='left', \ verticalalignment='top', \ ) axParams.axis('off') figParams.savefig(pdfFile, format='pdf') # endregion pdfFile.close() # endregion # region --- [TEXT DATA] # region [TEXT DATA] initial configuration parameters with open( os.path.join( resultsFolder, 'initConfigParams_{}.txt'.format( cfgFile.get('global', 'resultsFolder'))), 'w') as textSettings: textSettings.write(strSettings) # endregion # region [TEXT DATA] Planet CCF # strFormat = '{:.10f}\t{:.10f}\t{:.10f}\n' strPlanetData = strFormat.replace('10f', '13s').format('# RV', 'planet_flux', 'ccf_Fit') for pixWave, pixPlanet, pixFit in zip(planetWave, planetCCF, planetFit): strPlanetData += strFormat.format(pixWave, pixPlanet, pixFit) with open( os.path.join( resultsFolder, 'planetCCFData_{}.txt'.format( cfgFile.get('global', 'resultsFolder'))), 'w') as textPlanetData: textPlanetData.write(strPlanetData) # endregion # region [TEXT DATA] List of CCFs for template strFormat = '{:.50s}\t{:.10f}\t{:.10f}\t{:.10f}\t{:.10f}\n' strData = strFormat.replace('10f', '13s').format('# filename', 'BJD', 'Phase', 'star RV', 'planet RV') for ccfName in templateCCFList: strData += strFormat.format(ccfName.split('/')[-1], fullCCFs[ccfName].BJD, \ fullCCFs[ccfName].PlanetPhaseFolded, fullCCFs[ccfName].RV, \ fullCCFs[ccfName].planetRV) with open( os.path.join( resultsFolder, 'templateListData_{}.txt'.format( cfgFile.get('global', 'resultsFolder'))), 'w') as textTemplateData: textTemplateData.write(strData) # endregion # region [TEXT DATA] List of CCFs available for planet recovery strFormat = '{:.50s}\t{:.10f}\t{:.10f}\t{:.10f}\t{:.10f}\n' strData = strFormat.replace('.10f', '.13s').format('# filename', 'BJD', 'Phase', 'star RV', 'planet RV') for ccfName in dataCCFList: strData += strFormat.format(ccfName.split('/')[-1], fullCCFs[ccfName].BJD, \ fullCCFs[ccfName].PlanetPhaseFolded, fullCCFs[ccfName].RV, \ fullCCFs[ccfName].planetRV) with open( os.path.join( resultsFolder, 'planetRecoveryData_{}.txt'.format( cfgFile.get('global', 'resultsFolder'))), 'w') as textTemplateData: textTemplateData.write(strData) # endregion # region [TEXT DATA] List of CCFs selected for planet recovery strFormat = '{:.50s}\t{:.10f}\t{:.10f}\t{:.10f}\t{:.10f}\n' strData = strFormat.replace('10f', '13s').format('# filename', 'BJD', 'Phase', 'star RV', 'planet RV') for ccfName in dataSelectedCCFList: strData += strFormat.format(ccfName.split('/')[-1], fullCCFs[ccfName].BJD, \ fullCCFs[ccfName].PlanetPhaseFolded, fullCCFs[ccfName].RV, \ fullCCFs[ccfName].planetRV) with open(os.path.join(resultsFolder, \ 'selectedPlanetRecoveryData_{}.txt'.format(cfgFile.get('global', 'resultsFolder'))), 'w') as textTemplateData: textTemplateData.write(strData) # endregion # region [TEXT DATA] recovered parameters with open( os.path.join( resultsFolder, 'planetRecoveredParams_{}.txt'.format( cfgFile.get('global', 'resultsFolder'))), 'w') as textSettings: textSettings.write(strPlanetRecoveredParams)