def PNormalizeImage(SumWtImage, SumWt2, outImage, err, minWt=0.1): """ Sum an image onto Weighting accumulators Normalize SumWtImage by SumWt2 write to outImage Minimum allowed value in SumWt2 is minWt * SumWtImage = First output image, must be defined (i.e. files named) but not fully created. * SumWt2 = Second output image, like SumWtImage * outImage = Output image, must be defined. * err = Python Obit Error/message stack * minWt = minimum summed weight (lower values blanked). """ ################################################################ # Checks if not Image.PIsA(outImage): print "Actually ",outImage.__class__ raise TypeError,"outImage MUST be a Python Obit Image" if not Image.PIsA(SumWtImage): print "Actually ",SumWtImage.__class__ raise TypeError,"SumWtImage MUST be a Python Obit Image" if not Image.PIsA(SumWt2): print "Actually ",SumWt2.__class__ raise TypeError,"SumWt2 MUST be a Python Obit Image" if not OErr.OErrIsA(err): raise TypeError,"err MUST be an OErr" # # Open files Image.POpen(outImage, 2, err) Image.POpen(SumWtImage, 1, err) Image.POpen(SumWt2, 1, err) # Get descriptor to see how many planes outDesc = Image.PGetDesc(SumWtImage) outDescDict = ImageDesc.PGetDict(outDesc) outNaxis = outDescDict["inaxes"] print "Accumulation naxis",outNaxis # Get input descriptor to see how many planes inDesc = Image.PGetDesc(outImage) inDescDict = ImageDesc.PGetDict(outDesc) ndim = inDescDict["naxis"] inNaxis = inDescDict["inaxes"] #print "debug input naxis is ",inNaxis # Test if compatible if inNaxis[2] < outNaxis[2]: print "input has",inNaxis[2],"planes and output",outNaxis[2] raise RuntimeError,"input image has too few planes " if (ndim>0) and (inNaxis[2]>0): # list of planes to loop over (0-rel) planes = range(inNaxis[2]) else: planes = [0] # # Loop over planes for iPlane in planes: doPlane = [iPlane+1,1,1,1,1] # Get images Image.PGetPlane (SumWtImage, None, doPlane, err) Image.PGetPlane (SumWt2, None, doPlane, err) OErr.printErrMsg(err, "Error reading images") # Clip FArray.PClipBlank (SumWt2.FArray, minWt, 1.0e25) # Divide FArray.PDiv (SumWtImage.FArray, SumWt2.FArray, outImage.FArray) # Write Image.PPutPlane(outImage, None, doPlane, err) OErr.printErrMsg(err, "Error Writing normalized image ") # end loop over planes # close output Image.PClose(outImage, err) Image.PClose(SumWtImage, err) Image.PClose(SumWt2, err) # Write history - sorta inHistory = History.History("history", SumWtImage.List, err) outHistory = History.History("history", outImage.List, err) # Copy History History.PCopy(inHistory, outHistory, err) outHistory.Open(History.READWRITE, err) outHistory.TimeStamp(" Start Obit PNormalize",err) outHistory.Close(err)
def PWeightImageEq(inImage, factor, SumWtImage, SumWt2, err, minGain=0.1, iblc=[1,1,1], itrc=[0,0,1], restart=0, hwidth=2, doGPU=False, planeWt=False, OTFRA=None, OTFDec=None, inWtImage=None, maxRMS=None, minAccWt=0.15): """ Sum an image onto Weighting accumulators using PB corrections Version for equatorial in/output and no relative rotation Calculate the weights for an image from the primary beam pattern And accumulate into the correct locations in the accumulation images. * inImage = Image to be accumulated * factor = Additional multiplication factor, normally 1.0 >0 => use the factor/RMS of each image plane * SumWtImage = First output image, must be defined (i.e. files named) but not fully created. * SumWt2 = Second output image, like SumWtImage * err = Python Obit Error/message stack * minGain = minimum allowed gain (lower values blanked). * iblc = BLC in plane to start selection * itrc = TRC in plane to end selection * restart = restart channel no. 0-rel * hwidth = half width of interpolation kernal [1-4] default 2 * doGPU = If true and GPU enables, use a GPU for the interpolation. * NB: routine will fail if GPU is not enabled. * planeWt = if True generate weight image per input plane * OTFoffsets = if >1 then make beam using multiple pointing offsets "Aussie mode" OTF. must also go=ive OTFRA, OTFDec * OTFRA = Array of RA offsets in deg not corrected for Declination * OTFDec = Array of Declinations offsets in deg, same size as OTFRA * inWtImage = Beam (weight) image to use if not None MUST have the same size as inImage * maxRMS = if given, the maximum RMS allowed * minAccWt = min. acceptable max. weight, otherwise ignore """ ################################################################ # Checks if not Image.PIsA(inImage): print "Actually ",inImage.__class__ raise TypeError,"inImage MUST be a Python Obit Image" if not Image.PIsA(SumWtImage): print "Actually ",SumWtImage.__class__ raise TypeError,"SumWtImage MUST be a Python Obit Image" if not Image.PIsA(SumWt2): print "Actually ",SumWt2.__class__ raise TypeError,"SumWt2 MUST be a Python Obit Image" if not OErr.OErrIsA(err): raise TypeError,"err MUST be an OErr" # t0 = os.times()[4] # Initial time haveWtImage = inWtImage != None # Weight image given # Set BLC,TRC inImage.List.set("BLC",[iblc[0], iblc[1],1,1,1,1,1]) inImage.List.set("TRC",[itrc[0], itrc[1],0,0,0,0,0]) # Open accumulation files Image.POpen(inImage, Image.READONLY, err) # pythpn gets confused Image.POpen(SumWtImage, Image.READWRITE, err) Image.POpen(SumWt2, Image.READWRITE, err) # Get output descriptor to see how many planes outDesc = Image.PGetDesc(SumWtImage) outDescDict = ImageDesc.PGetDict(outDesc) outNaxis = outDescDict["inaxes"] print "Accumulation naxis",outNaxis # Get input descriptor to see how many planes inDesc = Image.PGetDesc(inImage) inDescDict = ImageDesc.PGetDict(inDesc) ndim = inDescDict["naxis"] inNaxis = inDescDict["inaxes"] finterp = None # GPU not yet enabled # Range of planes bpln = max (1,iblc[2]); epln = min (inNaxis[2], itrc[2]) if epln<bpln: epln = inNaxis[2] npln = epln-bpln+1 # Test if compatible if npln < outNaxis[2]: print "input has",npln,"planes selected and output has",outNaxis[2] raise RuntimeError,"input image has too few planes " if (ndim>0) and (inNaxis[2]>1): # list of 0-rel planes to loop over planes = range(bpln+restart-1,bpln+npln-1) else: planes = [0] # if inWtImage: inWtImage.List.set("BLC",[iblc[0], iblc[1],1,1,1,1,1]) inWtImage.List.set("TRC",[itrc[0], itrc[1],0,0,0,0,0]) inWtImage.Open(Image.READONLY,err) # Open/close to update inWtImage.Close(err) XPixelImage = None; YPixelImage = None; InterpWtImage = None;InterpWt = None InterpWtWt = None; WtImage = None # Loop over planes for iPlane in planes: doPlane = [iPlane+1,1,1,1,1] # Input plane outPlane = [iPlane+2-bpln,1,1,1,1] # output plane if not (iPlane%20): print "At plane", iPlane+1,'t=%6.1f sec'%(os.times()[4]-t0) # Get image inImage.List.set("BLC",[iblc[0], iblc[1],1,1,1,1,1]) inImage.List.set("TRC",[itrc[0], itrc[1],0,0,0,0,0]) Image.PGetPlane (inImage, None, doPlane, err) OErr.printErrMsg(err, "Error reading image "+str(iPlane)+" for "+Image.PGetName(inImage)) # # Make weight image if needed, first pass or planeWt if WtImage == None: WtImage = Image.Image("WeightImage") Image.PCloneMem(inImage, WtImage, err) # The interpolated versions if not InterpWtImage: InterpWtImage = Image.Image("InterpWtImage") Image.PClone2(inImage, SumWtImage, InterpWtImage, err) # input x, y pixels for output if (not XPixelImage) or (not YPixelImage): XPixelImage = Image.Image("XPixelImage") YPixelImage = Image.Image("YPixelImage") Image.PClone2(inImage, SumWtImage, XPixelImage, err) Image.PClone2(inImage, SumWtImage, YPixelImage, err) ImageUtil.PGetXYPixels(WtImage, InterpWtImage, XPixelImage, YPixelImage, err) # Special weighting? if factor<0.0: RMS = inImage.FArray.RMS fact = abs(factor)/RMS else: fact = factor if planeWt: pln = [iPlane+1,1,1,1,1] else: pln = [max(1,inNaxis[2]/2),1,1,1,1] if haveWtImage: # Beam provided, extract relevant plane to a memory resident WtImage OErr.printErrMsg(err, "Error reading wt image "+str(iPlane)+" for "+ Image.PGetName(inWtImage)) # Interpolate to WtImage ImageUtil.PInterpolateImage(inWtImage, WtImage, err, \ inPlane=doPlane, hwidth=hwidth, finterp=finterp) OErr.printErrMsg(err, "Error interpolating wt plane "+str(doPlane)) elif planeWt or (iPlane==0): # Normal or OTF Beam? if (OTFRA==None): ImageUtil.PPBImage(inImage, WtImage, err, minGain, outPlane=pln) pass else: ImageUtil.POTFBeam (inImage, WtImage, OTFRA, OTFDec, err, minGain, outPlane=pln) OErr.printErrMsg(err, "Error making weight image for "+Image.PGetName(inImage)) # Check maximum weight for first plane if iPlane==0: pos = [0,0] maxWt = FArray.PMax(WtImage.FArray,pos) print "Maximum weight",maxWt if maxWt<minAccWt: print "Less than minAccWt",minAccWt,"skipping" break # Interpolated weight image if not InterpWt: InterpWt = Image.Image("InterpWt") Image.PClone2(inImage, SumWtImage, InterpWt, err) # Is GPU interpolation requested? if doGPU: finterp = GPUFInterpolate.PCreate("GPUinterp", WtImage.FArray, XPixelImage.FArray, YPixelImage.FArray, hwidth, err) OErr.printErrMsg(err, "Creating GPU FInterpolator") InterpWt.Desc.Dict['inaxes'], WtImage.Desc.Dict['inaxes'] ImageUtil.PInterpolateImage(WtImage, InterpWt, err, \ XPix=XPixelImage, YPix=YPixelImage, hwidth=hwidth, finterp=finterp) OErr.printErrMsg(err, "Error interpolating wt*wt "+Image.PGetName(inImage)) # Interpolated weight image Squared if not InterpWtWt: InterpWtWt = Image.Image("InterpWtWt") Image.PClone2(inImage, SumWtImage, InterpWtWt, err) # Determine alignment inDesc = Image.PGetDesc(InterpWtImage) # get descriptors inDescDict = ImageDesc.PGetDict(inDesc) outDesc = Image.PGetDesc(SumWtImage) outDescDict = ImageDesc.PGetDict(outDesc) naxis = inDescDict["inaxes"] # find input center pixel in output pos1 = [int(naxis[0]*0.5+0.5), int(naxis[1]*0.5+0.5)] xpos1 = [float(pos1[0]),float(pos1[1])] xpos2 = ImageDesc.PCvtPixel (inDesc, xpos1, outDesc, err) pos2 = [int(xpos2[0]+0.5), int(xpos2[1]+0.5)] # Is GPU interpolation requested? if doGPU: del finterp finterp = GPUFInterpolate.PCreate("GPUinterp", inImage.FArray, XPixelImage.FArray, YPixelImage.FArray, hwidth, err) OErr.printErrMsg(err, "Creating GPU FInterpolator") # End init wt image # Special weighting or editing? if (factor<0.0) or maxRMS: # Get image Image.PGetPlane (inImage, None, doPlane, err) OErr.printErrMsg(err, "Error reading image "+str(iPlane)+" for "+Image.PGetName(inImage)) RMS = inImage.FArray.RMS # This plane acceptable? if maxRMS and ((RMS>maxRMS) or (RMS<=0.0)): #print 'drop plane',doPlane[0],'RMS',RMS continue if (factor<0.0): fact = abs(factor)/RMS else: fact = factor if not (iPlane%20): print "Factor",fact, "plane",iPlane,"RMS",RMS else: fact = factor # Interpolate image plane ImageUtil.PInterpolateImage(inImage, InterpWtImage, err, \ inPlane=doPlane, XPix=XPixelImage, YPix=YPixelImage, hwidth=hwidth, finterp=finterp) OErr.printErrMsg(err, "Error interpolating plane "+str(doPlane)) # Interpolated image times beam FArray.PMul(InterpWtImage.FArray, InterpWt.FArray, InterpWtImage.FArray) # # Read accumulation image planes Image.PGetPlane(SumWtImage, None, outPlane, err) OErr.printErrMsg(err, "Error reading accumulation image ") # # Accumulate FArray.PShiftAdd (SumWtImage.FArray, pos2, InterpWtImage.FArray, pos1, fact, SumWtImage.FArray) Image.PPutPlane(SumWtImage, None, outPlane, err) OErr.printErrMsg(err, "Error writing accumulation image ") # Square weight image Image.PGetPlane(SumWt2, None, outPlane, err) FArray.PMul(InterpWt.FArray, InterpWt.FArray, InterpWtWt.FArray) # Blank weight whereever image is blank or zero FArray.PInClip(InterpWt.FArray, -1.0e-20, 1.0e-20, FArray.PGetBlank()) # Blank weight squared where image * Wt is blanked FArray.PBlank (InterpWtWt.FArray, InterpWt.FArray, InterpWtWt.FArray); # Accumulate Wt*Wt FArray.PShiftAdd (SumWt2.FArray, pos2, InterpWtWt.FArray,pos1, fact, SumWt2.FArray) # # Write output Image.PPutPlane(SumWt2, None, outPlane, err) OErr.printErrMsg(err, "Error writing accumulation image ") # Cleanup if doing a weight image per plane (continuum) if planeWt: del WtImage, XPixelImage, YPixelImage; WtImage = None;XPixelImage=None; YPixelImage=None; # end loop over planes # close output Image.PClose(inImage, err) Image.PClose(SumWtImage, err) Image.PClose(SumWt2, err) del XPixelImage, YPixelImage, InterpWtImage, InterpWtWt, if WtImage: del WtImage; WtImage = None if finterp!=None: del finterp
outDisk = 1 equinox = 2000.0 # Debug print "input",inFile # Convert file into Images inImage = Image.newPImage(inFile, inFile, inDisk, 1, err) OErr.printErrMsg(err, "Error initializing image") # Open/get descriptor Image.POpen(inImage, 3, err) desc = Image.PGetDesc(inImage) # update descriptor descDict = ImageDesc.PGetDict(desc) # Get descriptor as Python Dict descDict["epoch"] = equinox # Update "epoch" descDict["equinox"] = equinox # Update equinox descDict["origin"] = "Obit to fix equinox" # Update origin ImageDesc.PSetDict(desc, descDict) # update descriptor Image.PClose(inImage, err) # Close to update disk OErr.printErrMsg(err, "Error writing updated header for "+Image.PGetName(inImage)) # Say something print "Updated Equinox (EPOCH) in",inFile,"to",equinox # Shutdown Obit OErr.printErr(err) del ObitSys
def PMakeMaster(template, size, SumWtImage, SumWt2, err): """ Create a pair of images to accumulation of partial products Create an image to contain the Sum of the input Images times the weights, and another for the sum of the weights squared. The descriptive material is from image template * template = Image with position etc, to be copied * size = output image size in pixels, e.g. [200,200] * SumWtImage = First output image, must be defined (i.e. files named) but not fully created. * SumWt2 = Second output image, like SumWtImage * err = Python Obit Error/message stack """ ################################################################ # Checks if not Image.PIsA(template): print "Actually ",template.__class__ raise TypeError,"template MUST be a Python Obit Image" if not Image.PIsA(SumWtImage): print "Actually ",SumWtImage.__class__ raise TypeError,"SumWtImage MUST be a Python Obit Image" if not Image.PIsA(SumWt2): print "Actually ",SumWt2.__class__ raise TypeError,"SumWt2 MUST be a Python Obit Image" if not OErr.OErrIsA(err): raise TypeError,"err MUST be an OErr" # # Get image info from template Image.POpen (template, 1, err) Image.PRead (template, err) desc = Image.PGetDesc(template) descDict = ImageDesc.PGetDict(desc) # Python dict object listDict = template.Desc.List.Dict Image.PClose (template, err) #OErr.printErrMsg(err, "Error reading input image "+Image.PGetName(template)) # # Create zero filled array for data outArray = FArray.FArray("Initial array", size) # # Modify the descriptor for output. naxis = size[0:3] # Update reference pixel, pixel shift an integral number dim = descDict["inaxes"] pixOff = [naxis[0]/2-dim[0]/2, naxis[1]/2-dim[1]/2] crpix = descDict["crpix"] crpix[0] = crpix[0] + pixOff[0] crpix[1] = crpix[1] + pixOff[1] # Update size dim[0] = naxis[0]; dim[1] = naxis[1] #print "debug dim",dim descDict["inaxes"] = dim descDict["bitpix"] = -32 # output floating # # Do SumWtImage desc = Image.PGetDesc(SumWtImage) InfoList.PSetDict(desc.List, listDict) # Copy list stuff ImageDesc.PSetDict(desc, descDict) # set output descriptor # Write output image Image.POpen(SumWtImage, 2, err) nplane = template.Desc.Dict["inaxes"][2] for iplane in range(1,(nplane+1)): plane = [iplane,1,1,1,1] SumWtImage.PutPlane(outArray, plane, err) Image.PClose(SumWtImage, err) #OErr.printErrMsg(err, "Error writing image for "+Image.PGetName(SumWtImage)) # # Do SumWt2Image desc = Image.PGetDesc(SumWt2) InfoList.PSetDict(desc.List, listDict) # Copy list stuff ImageDesc.PSetDict(desc, descDict) # set output descriptor # Write output image Image.POpen(SumWt2, 2, err) for iplane in range(1,(nplane+1)): plane = [iplane,1,1,1,1] SumWt2.PutPlane(outArray, plane, err) Image.PClose(SumWt2, err) #OErr.printErrMsg(err, "Error writing image for "+Image.PGetName(SumWt2)) # Write history - sorta inHistory = History.History("history", template.List, err) outHistory = History.History("history", SumWtImage.List, err) # Copy History History.PCopy(inHistory, outHistory, err) outHistory.Open(History.READWRITE, err) outHistory.TimeStamp(" Start Obit PMakeMaster",err) outHistory.Close(err)
def PScaleImage(inImage, scale, err): """ Scale the pixel values in an image Scale image, optionally by plane, scales any CC tables, writes history * inImage = Obit Python Image * scale = Scaling factor, if scalar, multiply all pixels, otherwise one value per image plane. * err = Python Obit Error/message stack """ ################################################################ # Checks if not Image.PIsA(inImage): raise TypeError("inImage MUST be a Python Obit Image") if not err.IsA(): raise TypeError("err MUST be an OErr") # # Open image Image.POpen(inImage, Image.READWRITE, err) # Get input descriptor to see how many planes inDesc = Image.PGetDesc(inImage) inDescDict = ImageDesc.PGetDict(inDesc) ndim = inDescDict["naxis"] inNaxis = inDescDict["inaxes"] # Work buffer inImageArray = Image.PGetFArray(inImage) ImageBuffer = FArray.PCopy(inImageArray, err) # Reset max/min inDescDict["minval"] = 1.0e20 inDescDict["maxval"] = -1.0e20 inImage.Desc.Dict = inDescDict # Update descriptor on image Image.PDirty(inImage) # Force update Image.PClose(inImage, err) # list of planes to loop over (0-rel) if (ndim > 0) and (inNaxis[2] > 0): planes = list(range(inNaxis[2])) else: planes = [0] # Loop over planes for iPlane in planes: doPlane = [iPlane + 1, 1, 1, 1, 1] # Get image plane Image.PGetPlane(inImage, ImageBuffer, doPlane, err) # Scaling factor if type(scale) == list: scl = scale[iPlane] else: scl = scale # Scale FArray.PSMul(ImageBuffer, scl) # Write output Image.PPutPlane(inImage, ImageBuffer, doPlane, err) # Scale any CC table highVer = Image.PGetHighVer(inImage, "AIPS CC") if (iPlane + 1 <= highVer): CCTab = Image.PImageGetTable(inImage, Image.READWRITE, "AIPS CC", iPlane + 1, err) PCCScale(CCTab, 1, 0, scl, err) # end loop over planes # Write history inHistory = History.History("history", inImage.List, err) # Add this programs history inHistory.Open(History.READWRITE, err) inHistory.TimeStamp(" Start Obit ScaleImage", err) if type(scale) == list: i = -1 for iPlane in planes: i = i + 1 scl = scale[i] inHistory.WriteRec( -1, "ScaleImage / scale[" + str(i + 1) + "] = " + str(scl), err) else: inHistory.WriteRec(-1, "ScaleImage / scale = " + str(scale), err) inHistory.Close(err)