def atd9(): """ Verify that transformation preserve flux. The test creates a mosaic from an input AstroData object and displays it in the DS9 display. Using IRAF imexam we measure objects that are on the the middle block for GMOS or the lower left block for GSAOI. We also measure the same objects in the input amplifers. We calculate the magnitude difference. """ from astrodata import AstroData from gempy.adlibrary.mosaicAD import MosaicAD # This is the default Mosaic function from gempy.mosaic.gemMosaicFunction import gemini_mosaic_function try: from stsci.numdisplay import display except ImportError: from numdisplay import display print '\n atd9 REQUIREMENT.......' print ('***** From a given AstroData object, the system shall conserve flux' ' after "transforming"') ad = AstroData(file) # Now make a mosaicAD object using the input ad # and the default mosaic function named # gemini_mosaic_function. mo = MosaicAD(ad, gemini_mosaic_function) mosaic_data = mo.mosaic_image_data() display(mosaic_data,frame=1) # display input amplifier 3. Assumning that there is one # amplifier per block display(ad['SCI',3].data,frame=2)
def atd6(): """ Verify that a MosaicAD method can create a block from a given extension name. The test creates a mosaic ndarray from the MosaicAD method mosaic_image_data with the block parameter value (0,0), indicating to output the lower left block. NOTE: Having one amp per block, the actual extension data is not the same as the block since it would be trim by the DATASEC image section. gmos_file='../data/gS20120420S0033.fits' gsaoi_file='../data/guS20120413S0048.fits' """ from astrodata import AstroData from gempy.adlibrary.mosaicAD import MosaicAD # This is the default Mosaic function from gempy.mosaic.gemMosaicFunction import gemini_mosaic_function print '\n atd6 REQUIREMENT.......' print ('***** From a given AstroData object, the system shall create a block from ' 'a given extension name') gmos_file='../data/gS20120420S0033.fits' gsaoi_file='../data/guS20120413S0048.fits' for file in [gmos_file,gsaoi_file]: ad = AstroData(file) print 'Instrument: ',ad.instrument() mo = MosaicAD(ad, gemini_mosaic_function) # Now use the mosaic_image_data method to generate # an output block by using the parameter block and # value as a tuple (col,row) (0-based) of the block # you want returned. For GMOS the block values are # (0,0), (1,0), (2,0). block=(1,0) block_data = mo.mosaic_image_data(block=block,tile=True) # Get the shape: (height, width) in pixels. print 'block_data.shape:',block_data.shape extn = block[0] + block[1]*mo.geometry.mosaic_grid[0] + 1 print 'Input shape for 1-amp per detector:',ad['SCI',extn].data.shape # Check values of the lower 2x2 pixels print 'Output block [0:2,0:2] pixels:\n',block_data[:2,:2] if ad.instrument() == 'GSAOI': # GSAOI FITS extension 1 correspond to block (1,0) # and extension 2 to block (0,0). DETSEC image section # indicates this. extn = [2,1,3,4][extn-1] # To get the correct segment we need to look at # DATASEC, in case the data is trimm -as it appears in data_list. x1,x2,y1,y2 = ad.data_section().as_dict()['SCI',extn] print 'Input amp DATASEC[x1:x1+2 pixels:\n',\ ad['SCI',extn].data[x1:x1+2,y1:y1+2] print '\n'
def atd2(): """ AT-mosaicAD-1 Verify that mosaicAD can create a mosaic from extensions of a given name. The test uses the MosaicAD method mosaic_image_data to create a mosaic using the extension name 'SCI'. """ import numpy as np from astrodata import AstroData from gempy.adlibrary.mosaicAD import MosaicAD # This is a user's Mosaic_function from gempy.mosaic.gemMosaicFunction import gemini_mosaic_function print '\n atd2 REQUIREMENT.......' print ('***** From a given extension name in the input AstroData object, the system' ' shall create a mosaic') gmos_file = '../data/gS20120420S0033.fits' ad = AstroData(gmos_file) mo = MosaicAD(ad, gemini_mosaic_function) # Now use the mosaic_image_data method to create # the mosaic ndarray. mosaic_data = mo.mosaic_image_data(extname='SCI') # Get blocksize, gap_list and number of blocks in x and y # values from the MosaicGeometry object. blksz_x,blksz_y = mo.geometry.blocksize gap_dict = mo.geometry.gap_dict nblkx,nblky = mo.geometry.mosaic_grid # Success Criteria 1. mszx,mszy=0,0 for k in range(nblkx): gx,gy = gap_dict['transform_gaps'][(k,0)] mszx += blksz_x + gx for k in range(nblky): gx,gy = gap_dict['transform_gaps'][(0,k)] mszy += blksz_y + gy # print the shape of the resulting mosaic and (ny,nx) print mosaic_data.shape,' should be equal to:',(mszy,mszx) # Success Criteria 2. # Check the mean of the input AD for each 'SCI' extension in_mean = [] for ext in ad['SCI']: in_mean.append(np.mean(ext.data)) print 'Mean of input data:',np.mean(in_mean) # Get the coordinates of data areas. Does not count # gaps nor no-data areas. g = np.where(mo.mask == 0) print 'Mean of mosaic:',np.mean(mosaic_data[g])
def atd8(): """ From a given AstroData object, the system shall offer an option to prevent the creation of merged table associations. The test creates an output AstroData object using the method as_astrodata with the parameter 'return_associated_bintables' set to False which prevents the creation of associated binary tables to the reference image extension name. Resources: file: N20120121S0175_ccMeasured.fits. Contains SCI,VAR,DQ OBJCAT (Bintable) and REFFACT (Bintable) """ from astrodata import AstroData from gempy.adlibrary.mosaicAD import MosaicAD # This is the default Mosaic function from gempy.mosaic.gemMosaicFunction import gemini_mosaic_function print '\n atd8 REQUIREMENT.......' print ('***** From a given AstroData object, the system shall offer an option to prevent the creation of merged table associations') file = '../data/N20120121S0175_ccMeasured.fits' ad = AstroData(file) # Creates a mosaicAD object using the input ad # and the default mosaic function named # gemini_mosaic_function. 'SCI' is the default extname mo = MosaicAD(ad, gemini_mosaic_function) outad = mo.as_astrodata() print '.......OUTPUT AD with all extensions' print outad.info() outad = mo.as_astrodata(return_associated_bintables=False) # The tester should see that there is no BINTABLE # extension name associated with the reference image # extension name in this output. print '.......OUTPUT AD with no associated BINTABLE extensions' print outad.info()
def mosaicADdetectors(self,rc): # Uses python MosaicAD script """ This primitive will mosaic the SCI frames of the input images, along with the VAR and DQ frames if they exist. :param tile: tile images instead of mosaic :type tile: Python boolean (True/False), default is False """ log = logutils.get_logger(__name__) # Log the standard "starting primitive" debug message log.debug(gt.log_message("primitive", "mosaicADdetectors", "starting")) # Define the keyword to be used for the time stamp for this primitive timestamp_key = self.timestamp_keys["mosaicADdetectors"] # Initialize the list of output AstroData objects adoutput_list = [] # Loop over each input AstroData object in the input list for ad in rc.get_inputs_as_astrodata(): # Validate Data #if (ad.phu_get_key_value('GPREPARE')==None) and \ # (ad.phu_get_key_value('PREPARE')==None): # raise Errors.InputError("%s must be prepared" % ad.filename) # Check whether the mosaicDetectors primitive has been run # previously if ad.phu_get_key_value(timestamp_key): log.warning("No changes will be made to %s, since it has " \ "already been processed by mosaicDetectors" \ % (ad.filename)) # Append the input AstroData object to the list of output # AstroData objects without further processing adoutput_list.append(ad) continue # If the input AstroData object only has one extension, there is no # need to mosaic the detectors if ad.count_exts("SCI") == 1: log.stdinfo("No changes will be made to %s, since it " \ "contains only one extension" % (ad.filename)) # Append the input AstroData object to the list of output # AstroData objects without further processing adoutput_list.append(ad) continue # Get the necessary parameters from the RC tile = rc["tile"] log.stdinfo("Mosaicking %s ..."%ad.filename) log.stdinfo("MosaicAD: Using tile: %s ..."%tile) #t1 = time.time() mo = MosaicAD(ad, mosaic_ad_function=gemini_mosaic_function, dq_planes=rc['dq_planes']) adout = mo.as_astrodata(tile=tile) #t2 = time.time() #print '%s took %0.3f ms' % ('as_astrodata', (t2-t1)*1000.0) # Verify mosaicAD was actually run on the file # then log file names of successfully reduced files if adout.phu_get_key_value("MOSAIC"): log.fullinfo("File "+adout.filename+\ " was successfully mosaicked") # Add the appropriate time stamps to the PHU gt.mark_history(adinput=adout, keyword=timestamp_key) # Change the filename adout.filename = gt.filename_updater( adinput=ad, suffix=rc["suffix"], strip=True) # Append the output AstroData object to the list # of output AstroData objects adoutput_list.append(adout) # Report the list of output AstroData objects to the reduction # context rc.report_output(adoutput_list) yield rc
def mosaicADdetectors(self, rc): # Uses python MosaicAD script """ This primitive will mosaic the SCI frames of the input images, along with the VAR and DQ frames if they exist. :param tile: tile images instead of mosaic :type tile: Python boolean (True/False), default is False """ log = logutils.get_logger(__name__) # Log the standard "starting primitive" debug message log.debug(gt.log_message("primitive", "mosaicADdetectors", "starting")) # Define the keyword to be used for the time stamp for this primitive timestamp_key = self.timestamp_keys["mosaicADdetectors"] # Initialize the list of output AstroData objects adoutput_list = [] # Loop over each input AstroData object in the input list for ad in rc.get_inputs_as_astrodata(): # Validate Data #if (ad.phu_get_key_value('GPREPARE')==None) and \ # (ad.phu_get_key_value('PREPARE')==None): # raise Errors.InputError("%s must be prepared" % ad.filename) # Check whether the mosaicDetectors primitive has been run # previously if ad.phu_get_key_value(timestamp_key): log.warning("No changes will be made to %s, since it has " \ "already been processed by mosaicDetectors" \ % (ad.filename)) # Append the input AstroData object to the list of output # AstroData objects without further processing adoutput_list.append(ad) continue # If the input AstroData object only has one extension, there is no # need to mosaic the detectors if ad.count_exts("SCI") == 1: log.stdinfo("No changes will be made to %s, since it " \ "contains only one extension" % (ad.filename)) # Append the input AstroData object to the list of output # AstroData objects without further processing adoutput_list.append(ad) continue # Get the necessary parameters from the RC tile = rc["tile"] log.stdinfo("Mosaicking %s ..." % ad.filename) log.stdinfo("MosaicAD: Using tile: %s ..." % tile) #t1 = time.time() mo = MosaicAD(ad, mosaic_ad_function=gemini_mosaic_function, dq_planes=rc['dq_planes']) adout = mo.as_astrodata(tile=tile) #t2 = time.time() #print '%s took %0.3f ms' % ('as_astrodata', (t2-t1)*1000.0) # Verify mosaicAD was actually run on the file # then log file names of successfully reduced files if adout.phu_get_key_value("MOSAIC"): log.fullinfo("File "+adout.filename+\ " was successfully mosaicked") # Add the appropriate time stamps to the PHU gt.mark_history(adinput=adout, primname=self.myself(), keyword=timestamp_key) # Change the filename adout.filename = gt.filename_updater(adinput=ad, suffix=rc["suffix"], strip=True) # Append the output AstroData object to the list # of output AstroData objects adoutput_list.append(adout) # Report the list of output AstroData objects to the reduction # context rc.report_output(adoutput_list) yield rc
def atd5(): """ Verify that mosaicAD gives the correct WCS information for the mosaiced data. Given a GMOS input file, the MosaicAD object method as_astrodata creates an output AstroData object. This object 'SCI' header have the CRPIX1 and CPRIX2 for the reference extension header. The value CRPIX1 should match the value explained in the Success Criteria section. The value CRPIX2 is unchanged. Resources: gmos_file='../data/gS20120420S0033.fits' gsaoi_file='../data/guS20120413S0048.fits' ds9 running """ import pywcs try: from stsci.numdisplay import display except ImportError: from numdisplay import display print '\n atd5 REQUIREMENT.......' print ('***** Given an AstroData object, the system shall update the header keywords ' ' CRPIX1 and CRPIX2 in the output mosaiced AD object to match the requested ' 'transformations') gmos_file='../data/gS20120420S0033.fits' gsaoi_file='../data/guS20120413S0048.fits' from astrodata import AstroData from gempy.adlibrary.mosaicAD import MosaicAD # This is the default Mosaic function from gempy.mosaic.gemMosaicFunction import gemini_mosaic_function ad = AstroData(gmos_file) # Creates a mosaicAD object using the input ad and the # default mosaic function name gemini_mosaic_function. # 'SCI' is the default extname. mo = MosaicAD(ad, gemini_mosaic_function) # outad = mo.as_astrodata() # NOTE: The ref_ext is the left most amplifier in # reference block. For GMOS the reference block # (2,1). E.G. for a 6-amp GMOS exposure the left # most exposure is 3. refblk = mo.geometry.ref_block col,row = refblk[0], refblk[1] amp_per_block = mo._amps_per_block ref_ext = col*amp_per_block+1 ocrpix1 = ad['SCI',ref_ext].header['CRPIX1'] xgap = mo.geometry.gap_dict['transform_gaps'][col,row][0] blksz_x,blksz_y = mo.geometry.blocksize # Success Criteria 1. # Get the x2 value from coords['amp_mosaic_coord'][refblk] xoff = mo.coords['amp_mosaic_coord'][max(0,col-1)][1] print ocrpix1 + xoff + xgap, 'should match: ' print outad['SCI',1].header['CRPIX1'] # Success Criteria 2. # For a GSAOI file, ad = AstroData(gsaoi_file) if ad.instrument() != 'GSAOI': print '******** file is not GSAOI ************' mo = MosaicAD(ad, gemini_mosaic_function) outad = mo.as_astrodata() outhdr = outad['SCI'].header inhdr = ad['SCI',2].header # The values should be the same. print 'Crpix1 values (in,out):',inhdr["CRPIX1"],outhdr['CRPIX1'] print 'Crpix2 values (in,out):',inhdr["CRPIX2"],outhdr['CRPIX2'] # Success Criteria 3. # For a GMOS file in extension #2 hdr = ad['SCI',2].header wcs = pywcs.WCS(hdr) import pysao # Bring up a ds9 display by instantiating the pysao object ds9 = pysao.ds9() # Display the image ds9.view(ad['SCI',2].data, frame=1) # display(ad['SCI',2].data,frame=1) print 'Click on any object:' X,Y,f,k = ds9.readcursor() # Get X,Y values from an object on the ds9 display # Get ra,dec ra,dec = wcs.wcs_pix2sky(X,Y,1) # Generate the mosaic_data for this ad using # as_astrodata method. # Display the mosaic mosaic_data for the 'SCI' extension mosaic_data = mo.mosaic_image_data() # Display the mosaic ds9.view(mosaic_data,frame=2) # display(ad['SCI',2].data,frame=1) print 'Click on the same object:' MX,MY,f,k = ds9.readcursor() #display(mosaic_data,frame=2) # Measure X,Y of the same object, named this MX,MY # Get the wcs from the mosaic header mhdr = outad['SCI'].header mwcs = pywcs.WCS(mhdr) mra,mdec = mwcs.wcs_pix2sky(MX,MY,1) print 'These RA,DEC should be pretty close:',(ra[0],mra[0]),(dec[0],mdec[0])
def atd4(): """ Verify that a mosaicAD class method can create a tiled array from extensions of a given name. The test creates a mosaic ndarray using the method mosaic_image_data with the parameter 'tile=True' which avoids the transformation step. """ from astrodata import AstroData from gempy.adlibrary.mosaicAD import MosaicAD # This is the default Mosaic function from gempy.mosaic.gemMosaicFunction import gemini_mosaic_function print '\n atd4 REQUIREMENT.......' print ('***** Given an AstroData object, the system shall tile all IMAGE extensions ' 'matching a given extension name') gmos_file='../data/gS20120420S0033.fits' gsaoi_file='../data/guS20120413S0048.fits' ad = AstroData(gmos_file) mo = MosaicAD(ad, gemini_mosaic_function) # Now use the mosaic_image_data method to create # the mosaic tile array from the 'SCI' extname. tile_data = mo.mosaic_image_data(tile=True, extname='SCI') # ----- Comparing input and output. GMOS image # The tester should feel free to verify any input and output # pixel location. # For example: A GMOS image: # The lower left corner (2x2) pixels the first GMOS # data extension. For a GSAOI is the second extension corner_gmos = ad['SCI',1].data # For a GMOS file print 'ad["SCI",1].data[:2,:2]\n',corner_gmos[:2,:2] # From the output mosaic. We should get the same values. print 'tile_data[:2,:2]\n',tile_data[:2,:2] # The top right corner of the mosaic nexts = ad.count_exts('SCI') block = ad['SCI',nexts].data # There is one amp per block print '\nad["SCI",last].data[-2:-2]\n',block[-2:,-2:] # The mosaic top corner print '\ntile_data[-2:,-2:]\n',tile_data[-2:,-2:] # ----- GSAOI data ad = AstroData(gsaoi_file) mo = MosaicAD(ad, gemini_mosaic_function) # Now use the mosaic_image_data method to create # the mosaic tile array from the 'SCI' extname. tile_data = mo.mosaic_image_data(tile=True, extname='SCI') print '\nGSAOI data' corner_gsaoi = ad['SCI',2].data # For a GSAOI file print 'ad["SCI",2].data\n',corner_gsaoi[:2,:2] print 'tile_data[:2,:2]\n', tile_data[:2,:2] # The top right corner of the mosaic block4 = ad['SCI',4].data # There is one amp per block print '\nblock4[-2:,-2:]\n',block4[-2:,-2:] print 'tile_data[-2:,-2:]\n',tile_data[-2:,-2:]
def atd3(): """ Verify that MosaicAD can merge associated binary tables Create a mosaic from the input AD object. It is up to the tester to see if there is one IMAGE extension name 'SCI' and one BINTABLE extension with the same number and values of EXTVER -these are associated. The as_astrodata method creates the mosaic. Please see the Procedure for the steps performed to verify the correctness of the merging. Resources: 1) gmos_file = '../data/N20120121S0175_ccMeasured.fits' 2) Uses pysao """ from astrodata import AstroData from gempy.adlibrary.mosaicAD import MosaicAD # This is the default Mosaic function from gempy.mosaic.gemMosaicFunction import gemini_mosaic_function print '\n atd3 REQUIREMENT.......' print ('***** Given an AstroData object with associated binary table, the system ' 'shall merge the tables') gmos_file = '../data/N20120121S0175_ccMeasured.fits' ad = AstroData(gmos_file) # 1) Make sure that we have an IMAGE and BINTABLE extension # with the same number and values of extver in one IMAGE and # BINTABLE extension. # 2) Creates a mosaicAD object using the input AD and the # default mosaic function named gemini_mosaic_function. # 3) The 'column_names' parameter in MosaicAD has as # default values the X_IMAGE, Y_IMAGE and X_WORLD, # Y_WORLD column names. The reference catalog have # RAJ2000 and DEJ2000. For more information please the # documentation about MosaicAD. mo = MosaicAD(ad, gemini_mosaic_function) # Now create the output AstroData object. outad = mo.as_astrodata() # Check that the output table has been merged correctly by # verifying that the duplicates rows are deleted and that the # new X,Y values for objects have been calculated correctly # based on the new WCS. # # Get input rows and remove duplicates. Output the content # of the resulting AD object which should show the # associated IMAGE and BINTABLE extensions. print outad.info() # Save to a filename from os import path nn = path.basename(ad.filename) outad.write(path.splitext(nn)[0]+'_AD.fits',clobber=True) # Verify that (X,Y) values in the merged tables correspond # the object positions. # The output catalog table name should be 'OBJCAT' and # pixel coordinates X_IMAGE and Y_IMAGE with corresponding # world coordinates Y_WORLD and Y_WORLD. tab = outad['OBJCAT'].data # Form a list of tuples (x_pixel,y_pixel) xy=[(x,y) for x,y in zip(tab.field('X_IMAGE'), tab.field('Y_IMAGE'))] # Now you can use any program to draw points and check for # location of the xy points on the objects. # Using DS9 PYSAO module # Assuming you have the module in your PYTHONPATH import pysao # Bring up a ds9 display by instantiating the pysao object ds9 = pysao.ds9() # Display the image ds9.view(outad['SCI'].data) # ***NOTE*** # Use file tab to display the 'SCI' extension of file # you save previously. Check for some of these pixel # coordinates with DS9. # Now draw the point tmp=[ds9.set_region('arrow point '+str(x)+' '+str(y)) for x,y in xy] # Verify for correctly removing duplicates when merging. # Use python sets() # Get the first all extensions from the input # AstroData object. Form a list of tuples (ra,dec) # from the reference tables in all extensions. # test for 'REFCAT' existance if ad['REFCAT'] == None: raise ValueError('"REFCAT" extension is not in the AstroData object') rd = [] for tab in ad['REFCAT']: rd += [(x,y) for x,y in zip(tab.data.field('RAJ2000'),\ tab.data.field('DEJ2000'))] # Turning rd list to a set will eliminate duplicates. print 'Number of unique elements from the list:',len(set(rd)) # Now from the outad object tab = outad['REFCAT'].data radec=[(x,y) for x,y in zip(tab.field('RAJ2000'), tab.field('DEJ2000'))] # The number of elements in the output table print 'The number of elements in the output table:',len(radec) jj = raw_input("Press Enter to exit the test")