def slotmerge(images, outimages, outpref, geomfile, clobber, logfile, verbose): with logging(logfile, debug) as log: # are the arguments defined saltsafeio.argdefined('images', images) saltsafeio.argdefined('geomfile', geomfile) saltsafeio.argdefined('logfile', logfile) # if the input file is a list, does it exist? if images[0] == '@': saltsafeio.listexists('Input', images) # parse list of input files infiles = saltsafeio.listparse('Raw image', images, '', '', '') # check input files exist saltsafeio.filesexist(infiles, '', 'r') # load output name list: @list, * and comma separated outimages = outimages.strip() outpref = outpref.strip() if len(outpref) == 0 and len(outimages) == 0: raise SaltIOError('Output file(s) not specified') # test output @filelist exists if len(outimages) > 0 and outimages[0] == '@': saltsafeio.listexists('Output', outimages) # parse list of output files outfiles = saltsafeio.listparse('Output image', outimages, outpref, infiles, '') # are input and output lists the same length? saltsafeio.comparelists(infiles, outfiles, 'Input', 'output') # do the output files already exist? if not clobber: saltsafeio.filesexist(outfiles, '', 'w') # does CCD geometry definition file exist geomfilefile = geomfile.strip() saltsafeio.fileexists(geomfile) # read geometry definition file gap = 0 xshift = [0, 0] yshift = [0, 0] rotation = [0, 0] gap, xshift, yshift, rotation = saltsafeio.readccdgeom(geomfile) for ro in rotation: if ro != 0: log.warning('SLOTMERGE currently ignores CCD rotation') # Begin processes each file for infile, outfile in zip(infiles, outfiles): # determine the name for the output file outpath = outfile.rstrip(os.path.basename(outfile)) if (len(outpath) == 0): outpath = '.' # open each raw image struct = saltsafeio.openfits(infile) # identify instrument instrume, keyprep, keygain, keybias, keyxtalk, keyslot = saltsafekey.instrumid( struct, infile) # how many amplifiers? nccds = saltsafekey.get('NCCDS', struct[0], infile) amplifiers = nccds * 2 #if (nccds != 2): # raise SaltError('Can not currently handle more than two CCDs') # CCD geometry coefficients if instrume == 'RSS' or instrume == 'PFIS': xsh = [xshift[0], 0., xshift[1]] ysh = [yshift[0], 0., yshift[1]] rot = [rotation[0], 0., rotation[1]] refid = 1 if instrume == 'SALTICAM': xsh = [xshift[0], 0.] ysh = [yshift[0], 0.] rot = [rotation[0], 0] refid = 1 # how many extensions? nextend = saltsafekey.get('NEXTEND', struct[0], infile) # how many exposures exposures = nextend / amplifiers # CCD on-chip binning xbin, ybin = saltsafekey.ccdbin(struct[0], infile) gp = int(gap / xbin) # create output hdu structure outstruct = [None] * int(exposures + 1) outstruct[0] = struct[0] # iterate over exposures, stitch them to produce file of CCD images for i in range(exposures): # Determine the total size of the image xsize = 0 ysize = 0 for j in range(amplifiers): hdu = i * amplifiers + j + 1 try: xsize += len(struct[hdu].data[0]) if ysize < len(struct[hdu].data): ysize = len(struct[hdu].data) except: msg = 'Unable to access extension %i ' % hdu raise SaltIOError(msg) xsize += gp * (nccds - 1) maxxsh, minxsh = determineshifts(xsh) maxysh, minysh = determineshifts(ysh) xsize += (maxxsh - minxsh) ysize += (maxysh - minysh) # Determine the x and y origins for each frame xdist = 0 ydist = 0 shid = 0 x0 = np.zeros(amplifiers) y0 = np.zeros(amplifiers) for j in range(amplifiers): x0[j] = xdist + xsh[shid] - minxsh y0[j] = ysh[shid] - minysh hdu = i * amplifiers + j + 1 darr = struct[hdu].data xdist += len(darr[0]) if j % 2 == 1: xdist += gp shid += 1 # make the out image outarr = np.zeros((ysize, xsize), np.float64) # Embed each frame into the output array for j in range(amplifiers): hdu = i * amplifiers + j + 1 darr = struct[hdu].data outarr = salttran.embed(darr, x0[j], y0[j], outarr) # Add the outimage to the output structure hdu = i * amplifiers + 1 outhdu = i + 1 outstruct[outhdu] = pyfits.ImageHDU(outarr) outstruct[outhdu].header = struct[hdu].header # Fix the headers in each extension datasec = '[1:%4i,1:%4i]' % (xsize, ysize) saltsafekey.put('DATASEC', datasec, outstruct[outhdu], outfile) saltsafekey.rem('DETSIZE', outstruct[outhdu], outfile) saltsafekey.rem('DETSEC', outstruct[outhdu], outfile) saltsafekey.rem('CCDSEC', outstruct[outhdu], outfile) saltsafekey.rem('AMPSEC', outstruct[outhdu], outfile) # add housekeeping key words outstruct[outhdu] = addhousekeeping(outstruct[outhdu], outhdu, outfile) # close input FITS file saltsafeio.closefits(struct) # housekeeping keywords keymosaic = 'SLOTMERG' fname, hist = history(level=1, wrap=False) saltsafekey.housekeeping(struct[0], keymosaic, 'Amplifiers have been mosaiced', hist) #saltsafekey.history(outstruct[0],hist) # this is added for later use by saltsafekey.put('NCCDS', 0.5, outstruct[0]) saltsafekey.put('NSCIEXT', exposures, outstruct[0]) saltsafekey.put('NEXTEND', exposures, outstruct[0]) # write FITS file of mosaiced image outstruct = pyfits.HDUList(outstruct) saltsafeio.writefits(outstruct, outfile, clobber=clobber)
def slot(struct,infile,dbspeed,dbrate,dbgain,dbnoise,dbbias,dbamp,xcoeff,gaindb,xtalkfile, logfile,verbose): import saltprint, saltkey, saltio, saltstat, time # identify instrument instrume,keyprep,keygain,keybias,keyxtalk,keyslot,status = saltkey.instrumid(struct,infile,logfile) # number of image HDU nextend = 0 while (status == 0): try: struct[nextend+1].header['XTENSION'] nextend += 1 except: break nccds,status = saltkey.get('NCCDS',struct[0],infile,logfile) amplifiers = nccds * 2 if (nextend%(amplifiers) != 0): message = '\nERROR -- SALTSLOT: Number of image extensions and' message += 'number of amplifiers are not consistent' status = saltprint.err(saltlog,message) status = saltkey.new('NSCIEXT',nextend,'Number of science extensions',struct[0],infile,logfile) status = saltkey.new('NEXTEND',nextend,'Number of data extensions',struct[0],infile,logfile) # check image file and gain database are compatible if (status == 0): ngains = len(dbgain) if (int(max(dbamp)) != amplifiers): message = '\nERROR -- SALTGSLOT: ' + infile + ' contains ' + str(amplifiers) + ' amplifiers' message += ', the gaindb file ' + gaindb + ' contains ' + str(max(dbamp)) + ' amplifiers' status = saltprint.err(logfile,message) # check image file and cross talk database are compatible if (status == 0): if (len(xcoeff)-1 != amplifiers): message = '\nERROR -- SALTSLOT: ' + infile + ' contains ' + str(amplifiers) + ' amplifiers' message += ', the cross talk file ' + xtalkfile + ' contains ' + str(len(xcoeff)-1) + ' amplifiers' status = saltprint.err(logfile,message) # housekeeping keywords if (status == 0): status = saltkey.put('SAL-TLM',time.asctime(time.localtime()),struct[0],infile,logfile) status = saltkey.new(keyslot,time.asctime(time.localtime()), 'Data have been cleaned by SALTSLOT',struct[0],infile,logfile) # keywords for image extensions for i in range(nextend): hdu = i + 1 status = saltkey.new('EXTNAME','SCI','Extension name',struct[hdu],infile,logfile) status = saltkey.new('EXTVER',hdu,'Extension number',struct[hdu],infile,logfile) # log coefficent table if (status == 0): message = '%30s %5s %4s %8s' % ('HDU','Gain','Bias','Xtalk') saltprint.log(logfile,'\n ---------------------------------------------',verbose) saltprint.log(logfile,message,verbose) saltprint.log(logfile,' ---------------------------------------------',verbose) # loop over image extensions if (status == 0): for i in range(nextend/2): hdu = i * 2 + 1 amplifier = hdu%amplifiers if (amplifier == 0): amplifier = amplifiers if (status == 0): value,status = saltkey.get('NAXIS1',struct[hdu],infile,logfile) naxis1 = int(value) if (status == 0): value,status = saltkey.get('NAXIS1',struct[hdu+1],infile,logfile) naxis2 = int(value) if (status == 0 and hdu == 1): biassec, status = saltkey.get('BIASSEC',struct[hdu],infile,logfile) if (status == 0 and hdu == 1): ranges = biassec.lstrip('[').rstrip(']').split(',') x1_1 = int(ranges[0].split(':')[0]) - 1 x2_1 = int(ranges[0].split(':')[1]) - 1 y1_1 = int(ranges[1].split(':')[0]) - 1 y2_1 = int(ranges[1].split(':')[1]) - 1 if (status == 0 and hdu == 1): biassec, status = saltkey.get('BIASSEC',struct[hdu+1],infile,logfile) if (status == 0 and hdu == 1): ranges = biassec.lstrip('[').rstrip(']').split(',') x1_2 = int(ranges[0].split(':')[0]) - 1 x2_2 = int(ranges[0].split(':')[1]) - 1 y1_2 = int(ranges[1].split(':')[0]) - 1 y2_2 = int(ranges[1].split(':')[1]) - 1 if (status == 0 and hdu == 1): datasec,status = saltkey.get('DATASEC',struct[hdu],infile,logfile) if (status == 0 and hdu == 1): ranges = datasec.lstrip('[').rstrip(']').split(',') dx1_1 = int(ranges[0].split(':')[0]) - 1 dx2_1 = int(ranges[0].split(':')[1]) dy1_1 = int(ranges[1].split(':')[0]) - 1 dy2_1 = int(ranges[1].split(':')[1]) if (status == 0 and hdu == 1): datasec,status = saltkey.get('DATASEC',struct[hdu+1],infile,logfile) if (status == 0 and hdu == 1): ranges = datasec.lstrip('[').rstrip(']').split(',') dx1_2 = int(ranges[0].split(':')[0]) - 1 dx2_2 = int(ranges[0].split(':')[1]) dy1_2 = int(ranges[1].split(':')[0]) - 1 dy2_2 = int(ranges[1].split(':')[1]) if (status == 0 and dx2_1 - dx1_1 != dx2_2 - dx1_2): message = 'ERROR -- SALTSLOT: HDUs '+infile message += '['+str(hdu)+'] and '+infile+'['+str(hdu+1)+']' message += ' have different dimensions' status = saltprint.err(logfile,message) # read speed and gain of each exposure if (status == 0 and hdu == 1): gainset,status = saltkey.get('GAINSET',struct[0],infile,logfile) rospeed,status = saltkey.get('ROSPEED',struct[0],infile,logfile) if (rospeed == 'NONE'): saltprint.log(logfile," ",verbose) message = "ERROR -- SALTSLOT: Readout speed is 'NONE' in " message += "primary keywords of " + infile status = saltprint.err(logfile,message) # read raw images if (status == 0): imagedata1,status = saltio.readimage(struct,hdu,logfile) imagedata2,status = saltio.readimage(struct,hdu+1,logfile) # gain correction if (status == 0): for j in range(len(dbgain)): if (gainset == dbrate[j] and rospeed == dbspeed[j] and amplifier == int(dbamp[j])): try: gain1 = float(dbgain[j]) imagedata1 *= gain1 except: mesage = 'ERROR -- SALTSLOT: Cannot perform gain correction on image ' message += infile+'['+str(hdu)+']' status = saltprint.err(logfile,message) elif (gainset == dbrate[j] and rospeed == dbspeed[j] and amplifier + 1 == int(dbamp[j])): try: gain2 = float(dbgain[j]) imagedata2 *= gain2 except: mesage = 'ERROR -- SALTSLOT: Cannot perform gain correction on image ' message += infile+'['+str(hdu+1)+']' status = saltprint.err(logfile,message) # crosstalk correction if (status == 0): revimage1 = imagedata1 * float(xcoeff[amplifier]) revimage2 = imagedata2 * float(xcoeff[amplifier+1]) for j in range(dx2_1-dx1_1+1): imagedata1[:,j] -= revimage2[:,dx2_2-j-1] imagedata2[:,j] -= revimage1[:,dx2_1-j-1] # bias subtraction if (status == 0): overx_val_1 = [] overx_val_2 = [] for x in range(x1_1,x2_1+1): list_1 = imagedata1[y1_1:y2_1,x] * 1.0 overx_val_1.append(saltstat.median(list_1,logfile)) overlevel_1 = saltstat.median(overx_val_1,logfile) for x in range(x1_2,x2_2+1): list_2 = imagedata2[y1_2:y2_2,x] * 1.0 overx_val_2.append(saltstat.median(list_2,logfile)) overlevel_2 = saltstat.median(overx_val_2,logfile) imagedata1 -= overlevel_1 imagedata2 -= overlevel_2 # trim overscan if (status == 0): imagedata1 = imagedata1[dy1_1:dy2_1,dx1_1:dx2_1] imagedata2 = imagedata2[dy1_2:dy2_2,dx1_2:dx2_2] datasec = '[1:'+str(dx2_1-dx1_1)+',1:'+str(dy2_1-dy1_1)+']' status = saltkey.put('DATASEC',datasec,struct[hdu],infile,logfile) status = saltkey.rem('BIASSEC',struct[hdu],infile,logfile) datasec = '[1:'+str(dx2_2-dx1_2)+',1:'+str(dy2_2-dy1_2)+']' status = saltkey.put('DATASEC',datasec,struct[hdu+1],infile,logfile) status = saltkey.rem('BIASSEC',struct[hdu+1],infile,logfile) # log coefficient table if (status == 0): infilename = infile.split('/') infilename = infilename[len(infilename)-1] message = '%25s[%3d] %5.2f %4d %8.6f' % \ (infilename, hdu, gain1, overlevel_1, float(xcoeff[amplifier+1])) saltprint.log(logfile,message,verbose) message = '%25s[%3d] %5.2f %4d %8.6f' % \ (infilename, hdu+1, gain2, overlevel_2,float(xcoeff[amplifier])) saltprint.log(logfile,message,verbose) # update image in HDU structure if (status == 0): struct,status = saltio.writeimage(struct,hdu,imagedata1,logfile) struct,status = saltio.writeimage(struct,hdu+1,imagedata2,logfile) return struct, status
def slotmerge(images,outimages,outpref,geomfile,clobber,logfile,verbose): with logging(logfile,debug) as log: # are the arguments defined saltsafeio.argdefined('images',images) saltsafeio.argdefined('geomfile',geomfile) saltsafeio.argdefined('logfile',logfile) # if the input file is a list, does it exist? if images[0] == '@': saltsafeio.listexists('Input',images) # parse list of input files infiles=saltsafeio.listparse('Raw image',images,'','','') # check input files exist saltsafeio.filesexist(infiles,'','r') # load output name list: @list, * and comma separated outimages = outimages.strip() outpref = outpref.strip() if len(outpref) == 0 and len(outimages) == 0: raise SaltIOError('Output file(s) not specified') # test output @filelist exists if len(outimages) > 0 and outimages[0] == '@': saltsafeio.listexists('Output',outimages) # parse list of output files outfiles=saltsafeio.listparse('Output image',outimages,outpref,infiles,'') # are input and output lists the same length? saltsafeio.comparelists(infiles,outfiles,'Input','output') # do the output files already exist? if not clobber: saltsafeio.filesexist(outfiles,'','w') # does CCD geometry definition file exist geomfilefile = geomfile.strip() saltsafeio.fileexists(geomfile) # read geometry definition file gap = 0 xshift = [0, 0] yshift = [0, 0] rotation = [0, 0] gap, xshift, yshift, rotation=saltsafeio.readccdgeom(geomfile) for ro in rotation: if ro!=0: log.warning('SLOTMERGE currently ignores CCD rotation') # Begin processes each file for infile, outfile in zip(infiles, outfiles): # determine the name for the output file outpath = outfile.rstrip(os.path.basename(outfile)) if (len(outpath) == 0): outpath = '.' # open each raw image struct=saltsafeio.openfits(infile) # identify instrument instrume,keyprep,keygain,keybias,keyxtalk,keyslot=saltsafekey.instrumid(struct,infile) # how many amplifiers? nccds=saltsafekey.get('NCCDS',struct[0],infile) amplifiers = nccds * 2 #if (nccds != 2): # raise SaltError('Can not currently handle more than two CCDs') # CCD geometry coefficients if instrume == 'RSS' or instrume == 'PFIS': xsh = [xshift[0], 0., xshift[1]] ysh = [yshift[0], 0., yshift[1]] rot = [rotation[0], 0., rotation[1]] refid = 1 if instrume == 'SALTICAM': xsh = [xshift[0], 0.] ysh = [yshift[0], 0.] rot = [rotation[0], 0] refid = 1 # how many extensions? nextend=saltsafekey.get('NEXTEND',struct[0],infile) # how many exposures exposures = nextend/amplifiers # CCD on-chip binning xbin, ybin=saltsafekey.ccdbin(struct[0],infile) gp = int(gap / xbin) # create output hdu structure outstruct = [None] * int(exposures+1) outstruct[0]=struct[0] # iterate over exposures, stitch them to produce file of CCD images for i in range(exposures): # Determine the total size of the image xsize=0 ysize=0 for j in range(amplifiers): hdu=i*amplifiers+j+1 try: xsize += len(struct[hdu].data[0]) if ysize < len(struct[hdu].data): ysize=len(struct[hdu].data) except: msg='Unable to access extension %i ' % hdu raise SaltIOError(msg) xsize += gp* (nccds-1) maxxsh, minxsh = determineshifts(xsh) maxysh, minysh = determineshifts(ysh) xsize += (maxxsh-minxsh) ysize += (maxysh-minysh) # Determine the x and y origins for each frame xdist=0 ydist=0 shid=0 x0=np.zeros(amplifiers) y0=np.zeros(amplifiers) for j in range(amplifiers): x0[j]=xdist+xsh[shid]-minxsh y0[j]=ysh[shid]-minysh hdu=i*amplifiers+j+1 darr=struct[hdu].data xdist += len(darr[0]) if j%2==1: xdist += gp shid += 1 # make the out image outarr=np.zeros((ysize, xsize), np.float64) # Embed each frame into the output array for j in range(amplifiers): hdu=i*amplifiers+j+1 darr=struct[hdu].data outarr=salttran.embed(darr, x0[j], y0[j], outarr) # Add the outimage to the output structure hdu=i*amplifiers+1 outhdu=i+1 outstruct[outhdu] = pyfits.ImageHDU(outarr) outstruct[outhdu].header=struct[hdu].header # Fix the headers in each extension datasec='[1:%4i,1:%4i]' % (xsize, ysize) saltsafekey.put('DATASEC',datasec, outstruct[outhdu], outfile) saltsafekey.rem('DETSIZE',outstruct[outhdu],outfile) saltsafekey.rem('DETSEC',outstruct[outhdu],outfile) saltsafekey.rem('CCDSEC',outstruct[outhdu],outfile) saltsafekey.rem('AMPSEC',outstruct[outhdu],outfile) # add housekeeping key words outstruct[outhdu]=addhousekeeping(outstruct[outhdu], outhdu, outfile) # close input FITS file saltsafeio.closefits(struct) # housekeeping keywords keymosaic='SLOTMERG' fname, hist=history(level=1, wrap=False) saltsafekey.housekeeping(struct[0],keymosaic,'Amplifiers have been mosaiced', hist) #saltsafekey.history(outstruct[0],hist) # this is added for later use by saltsafekey.put('NCCDS', 0.5, outstruct[0]) saltsafekey.put('NSCIEXT', exposures, outstruct[0]) saltsafekey.put('NEXTEND', exposures, outstruct[0]) # write FITS file of mosaiced image outstruct=pyfits.HDUList(outstruct) saltsafeio.writefits(outstruct, outfile, clobber=clobber)
def slot(struct, infile, dbspeed, dbrate, dbgain, dbnoise, dbbias, dbamp, xcoeff, gaindb, xtalkfile, logfile, verbose): import saltprint, saltkey, saltio, saltstat, time # identify instrument instrume, keyprep, keygain, keybias, keyxtalk, keyslot, status = saltkey.instrumid( struct, infile, logfile) # number of image HDU nextend = 0 while (status == 0): try: struct[nextend + 1].header['XTENSION'] nextend += 1 except: break nccds, status = saltkey.get('NCCDS', struct[0], infile, logfile) amplifiers = nccds * 2 if (nextend % (amplifiers) != 0): message = '\nERROR -- SALTSLOT: Number of image extensions and' message += 'number of amplifiers are not consistent' status = saltprint.err(saltlog, message) status = saltkey.new('NSCIEXT', nextend, 'Number of science extensions', struct[0], infile, logfile) status = saltkey.new('NEXTEND', nextend, 'Number of data extensions', struct[0], infile, logfile) # check image file and gain database are compatible if (status == 0): ngains = len(dbgain) if (int(max(dbamp)) != amplifiers): message = '\nERROR -- SALTGSLOT: ' + infile + ' contains ' + str( amplifiers) + ' amplifiers' message += ', the gaindb file ' + gaindb + ' contains ' + str( max(dbamp)) + ' amplifiers' status = saltprint.err(logfile, message) # check image file and cross talk database are compatible if (status == 0): if (len(xcoeff) - 1 != amplifiers): message = '\nERROR -- SALTSLOT: ' + infile + ' contains ' + str( amplifiers) + ' amplifiers' message += ', the cross talk file ' + xtalkfile + ' contains ' + str( len(xcoeff) - 1) + ' amplifiers' status = saltprint.err(logfile, message) # housekeeping keywords if (status == 0): status = saltkey.put('SAL-TLM', time.asctime(time.localtime()), struct[0], infile, logfile) status = saltkey.new(keyslot, time.asctime(time.localtime()), 'Data have been cleaned by SALTSLOT', struct[0], infile, logfile) # keywords for image extensions for i in range(nextend): hdu = i + 1 status = saltkey.new('EXTNAME', 'SCI', 'Extension name', struct[hdu], infile, logfile) status = saltkey.new('EXTVER', hdu, 'Extension number', struct[hdu], infile, logfile) # log coefficent table if (status == 0): message = '%30s %5s %4s %8s' % ('HDU', 'Gain', 'Bias', 'Xtalk') saltprint.log(logfile, '\n ---------------------------------------------', verbose) saltprint.log(logfile, message, verbose) saltprint.log(logfile, ' ---------------------------------------------', verbose) # loop over image extensions if (status == 0): for i in range(nextend / 2): hdu = i * 2 + 1 amplifier = hdu % amplifiers if (amplifier == 0): amplifier = amplifiers if (status == 0): value, status = saltkey.get('NAXIS1', struct[hdu], infile, logfile) naxis1 = int(value) if (status == 0): value, status = saltkey.get('NAXIS1', struct[hdu + 1], infile, logfile) naxis2 = int(value) if (status == 0 and hdu == 1): biassec, status = saltkey.get('BIASSEC', struct[hdu], infile, logfile) if (status == 0 and hdu == 1): ranges = biassec.lstrip('[').rstrip(']').split(',') x1_1 = int(ranges[0].split(':')[0]) - 1 x2_1 = int(ranges[0].split(':')[1]) - 1 y1_1 = int(ranges[1].split(':')[0]) - 1 y2_1 = int(ranges[1].split(':')[1]) - 1 if (status == 0 and hdu == 1): biassec, status = saltkey.get('BIASSEC', struct[hdu + 1], infile, logfile) if (status == 0 and hdu == 1): ranges = biassec.lstrip('[').rstrip(']').split(',') x1_2 = int(ranges[0].split(':')[0]) - 1 x2_2 = int(ranges[0].split(':')[1]) - 1 y1_2 = int(ranges[1].split(':')[0]) - 1 y2_2 = int(ranges[1].split(':')[1]) - 1 if (status == 0 and hdu == 1): datasec, status = saltkey.get('DATASEC', struct[hdu], infile, logfile) if (status == 0 and hdu == 1): ranges = datasec.lstrip('[').rstrip(']').split(',') dx1_1 = int(ranges[0].split(':')[0]) - 1 dx2_1 = int(ranges[0].split(':')[1]) dy1_1 = int(ranges[1].split(':')[0]) - 1 dy2_1 = int(ranges[1].split(':')[1]) if (status == 0 and hdu == 1): datasec, status = saltkey.get('DATASEC', struct[hdu + 1], infile, logfile) if (status == 0 and hdu == 1): ranges = datasec.lstrip('[').rstrip(']').split(',') dx1_2 = int(ranges[0].split(':')[0]) - 1 dx2_2 = int(ranges[0].split(':')[1]) dy1_2 = int(ranges[1].split(':')[0]) - 1 dy2_2 = int(ranges[1].split(':')[1]) if (status == 0 and dx2_1 - dx1_1 != dx2_2 - dx1_2): message = 'ERROR -- SALTSLOT: HDUs ' + infile message += '[' + str(hdu) + '] and ' + infile + '[' + str( hdu + 1) + ']' message += ' have different dimensions' status = saltprint.err(logfile, message) # read speed and gain of each exposure if (status == 0 and hdu == 1): gainset, status = saltkey.get('GAINSET', struct[0], infile, logfile) rospeed, status = saltkey.get('ROSPEED', struct[0], infile, logfile) if (rospeed == 'NONE'): saltprint.log(logfile, " ", verbose) message = "ERROR -- SALTSLOT: Readout speed is 'NONE' in " message += "primary keywords of " + infile status = saltprint.err(logfile, message) # read raw images if (status == 0): imagedata1, status = saltio.readimage(struct, hdu, logfile) imagedata2, status = saltio.readimage(struct, hdu + 1, logfile) # gain correction if (status == 0): for j in range(len(dbgain)): if (gainset == dbrate[j] and rospeed == dbspeed[j] and amplifier == int(dbamp[j])): try: gain1 = float(dbgain[j]) imagedata1 *= gain1 except: mesage = 'ERROR -- SALTSLOT: Cannot perform gain correction on image ' message += infile + '[' + str(hdu) + ']' status = saltprint.err(logfile, message) elif (gainset == dbrate[j] and rospeed == dbspeed[j] and amplifier + 1 == int(dbamp[j])): try: gain2 = float(dbgain[j]) imagedata2 *= gain2 except: mesage = 'ERROR -- SALTSLOT: Cannot perform gain correction on image ' message += infile + '[' + str(hdu + 1) + ']' status = saltprint.err(logfile, message) # crosstalk correction if (status == 0): revimage1 = imagedata1 * float(xcoeff[amplifier]) revimage2 = imagedata2 * float(xcoeff[amplifier + 1]) for j in range(dx2_1 - dx1_1 + 1): imagedata1[:, j] -= revimage2[:, dx2_2 - j - 1] imagedata2[:, j] -= revimage1[:, dx2_1 - j - 1] # bias subtraction if (status == 0): overx_val_1 = [] overx_val_2 = [] for x in range(x1_1, x2_1 + 1): list_1 = imagedata1[y1_1:y2_1, x] * 1.0 overx_val_1.append(saltstat.median(list_1, logfile)) overlevel_1 = saltstat.median(overx_val_1, logfile) for x in range(x1_2, x2_2 + 1): list_2 = imagedata2[y1_2:y2_2, x] * 1.0 overx_val_2.append(saltstat.median(list_2, logfile)) overlevel_2 = saltstat.median(overx_val_2, logfile) imagedata1 -= overlevel_1 imagedata2 -= overlevel_2 # trim overscan if (status == 0): imagedata1 = imagedata1[dy1_1:dy2_1, dx1_1:dx2_1] imagedata2 = imagedata2[dy1_2:dy2_2, dx1_2:dx2_2] datasec = '[1:' + str(dx2_1 - dx1_1) + ',1:' + str(dy2_1 - dy1_1) + ']' status = saltkey.put('DATASEC', datasec, struct[hdu], infile, logfile) status = saltkey.rem('BIASSEC', struct[hdu], infile, logfile) datasec = '[1:' + str(dx2_2 - dx1_2) + ',1:' + str(dy2_2 - dy1_2) + ']' status = saltkey.put('DATASEC', datasec, struct[hdu + 1], infile, logfile) status = saltkey.rem('BIASSEC', struct[hdu + 1], infile, logfile) # log coefficient table if (status == 0): infilename = infile.split('/') infilename = infilename[len(infilename) - 1] message = '%25s[%3d] %5.2f %4d %8.6f' % \ (infilename, hdu, gain1, overlevel_1, float(xcoeff[amplifier+1])) saltprint.log(logfile, message, verbose) message = '%25s[%3d] %5.2f %4d %8.6f' % \ (infilename, hdu+1, gain2, overlevel_2,float(xcoeff[amplifier])) saltprint.log(logfile, message, verbose) # update image in HDU structure if (status == 0): struct, status = saltio.writeimage(struct, hdu, imagedata1, logfile) struct, status = saltio.writeimage(struct, hdu + 1, imagedata2, logfile) return struct, status