def testPhotoplotOutput(self):
     dataObject = MockDataObject.DataObject(self.fileLocation)
     dataObject.setFlag("Photoplot")
     
     sliceOne = Slice(2905, 562, "Test star 1", 50, 1.2)
     sliceOne.setYh(612)
     sliceOne.setYl(512)
     sliceOne.setBrightnessDiff(200.25)
     dataObject.addSlice(sliceOne)
     sliceTwo = Slice(2986, 1514, "Test star 2", 30, 1.6)
     sliceTwo.setYh(1544)
     sliceTwo.setYl(1484)
     sliceTwo.setBrightnessDiff(120.46)
     dataObject.addSlice(sliceTwo)
     
     dataObject.setMeanCalibrationFactor(0.4)
     
     figure = DataOutput.newImage(dataObject.getImageData(), 6500, 6700)
     
     dataObject.setPhotoplotImage(figure)
     
     DataOutput.outputDataToFile(dataObject, "PhotoplotTest", self.saveLocation)
Ejemplo n.º 2
0
class DataObject:
    def __init__(self, fitFile, flag, snr):
        #Initially sets values to None
        self.img = None
        self.imgHeader = None
        self.flag = None
        self.snr = None

        #Initialises fields for candidate data
        self.candGt = ()  #Initialises tuples to being empty
        self.candLt = ()
        self.imgStd = None
        self.diffImg = None

        #validates snr
        if (not isinstance(snr, float)):
            raise IncorrectTypeException("snr must be of type float")
        self.snr = snr

        #reads fit file
        try:
            with fits.open(
                    fitFile
            ) as imghdul:  #using the with keyword means that the file will be closed even if an exception is thrown
                self.img = imghdul[0].data
                self.imgHeader = imghdul[0].header
        except ValueError:
            raise EmptyFileException('Img filename is empty')
        except OSError:
            raise EmptyFileException(
                'Img file is not the correct format or is corrupted')

        if self.img is None:
            raise EmptyFileException('Img is null')

        #validates flag
        if (not ((flag == 'Photoplot') or (flag == 'Publication') or
                 (flag == 'CheckPixels') or (flag == 'Simulate') or
                 (flag == 'Zoomed') or (flag == 'Orbits'))):
            raise InvalidFlagException(
                "Flag must be Photoplot, Publication, CheckPixels, Simulate, Zoomed or Orbits"
            )
        self.flag = flag

        #Initialises fields for selected flag
        if (self.flag == 'Photoplot'):
            #Initialise Photoplot fields
            self.Slices = []  #Initialises slice list to an empty list
            self.currSlice = None
            self.meanCalibrationFactor = 0.0  #Will be used for the output of the Photometry component
            self.photoImage = None  #Will be used for image with slices marked
        elif (self.flag == 'Publication'):
            #Initialise Publication fields
            self.annotated = None  #Output for Publication component
        elif (self.flag == 'CheckPixels'):
            self.checkX = -1  #Data for CheckPixels component, initialised to invalid values
            self.checkY = -1
            self.checkFactor = 0.0  #Zoom factor to use, named this to avoid confusion with that of the zoomed image component
            self.pixelImage = None  #Output for CheckPixels component
            self.padTop = 0
            self.padBottom = 0
            self.padLeft = 0
            self.padRight = 0
            self.height = 0
            self.width = 0
        elif (self.flag == 'Simulate'):
            self.simulateImage = None  #Output for Simulate component
        elif (self.flag == 'Zoomed'):
            #Initialise Zoomed fields
            self.zoomFactor = 0.0  #Data for CheckPixels component, initialised to invalid values
            self.zoomedImages = None  #Output from CreateZoomedImage component
        elif (self.flag == 'Orbits'):
            #Initialise Orbits fields
            self.tleData = None  #Initialises input
            self.tleLength = None
            self.wcsinfo = None
            self.orbitPlot = None  #Output from Orbits component

#Getters for input data

    def getImageData(self):
        return self.img

    def getImageData16(self):
        return (self.img).astype(np.int16)

    def getImageHeader(self):
        return self.imgHeader

    def getFlag(self):
        return self.flag

    def getSNR(self):
        return self.snr

#Setters and getters for generic data

    def setCandGt(self, incandGt):
        if (not isinstance(incandGt, tuple)):  #checks that input is a tuple
            raise IncorrectTypeException('Value must be a tuple')
        if (not len(incandGt) == 2):  #Checks that tuple has exactly 2 elements
            raise InvalidSizeException('Size must be 2')
        if (not isinstance(incandGt[0], np.ndarray)
                and not isinstance(incandGt[1], np.ndarray)
            ):  #Checks that tuple elements are ndarrays
            raise IncorrectTypeException('Tuple elements must be ndarrays')
        try:
            if (not isinstance(incandGt[0][0], np.int64)
                ):  #Checks that the array elements are of type int64
                raise IncorrectTypeException(
                    'Values in tuple must be of type int64')
        except IndexError:
            pass  #There were no candidates detected
        if (not len(incandGt[0]) == len(incandGt[1])):
            raise InvalidSizeException('Arrays must be of equal size')
        self.candGt = incandGt

    def getCandGt(self):
        return self.candGt

    def setCandLt(self, incandLt):
        if (not isinstance(incandLt, tuple)):
            raise IncorrectTypeException('Value must be a tuple')
        if (not len(incandLt) == 2):
            raise InvalidSizeException('Size must be 2')
        if (not isinstance(incandLt[0], np.ndarray)
                and not isinstance(incandLt[1], np.ndarray)):
            raise IncorrectTypeException('Tuple elements must be ndarrays')
        try:
            if (not isinstance(incandLt[0][0], np.int64)):
                raise IncorrectTypeException(
                    'Values in tuple must be of type int64')
        except IndexError:
            pass  #There were no candidates detected
        if (not len(incandLt[0]) == len(incandLt[1])):
            raise InvalidSizeException('Arrays must be of equal size')
        self.candLt = incandLt

    def getCandLt(self):
        return self.candLt

    def setImgStd(self, inImgStd):
        if (not isinstance(inImgStd, np.float64)):
            raise IncorrectTypeException('Value must be a float64')
        self.imgStd = inImgStd

    def getImgStd(self):
        return self.imgStd

    def setDiffImg(self, inDiffImg):
        if (not isinstance(inDiffImg, np.ndarray)):
            raise IncorrectTypeException('Value must be an ndarray')
        self.diffImg = inDiffImg

    def getDiffImg(self):
        return self.diffImg

#Setters and getters for Photoplot
#Initial slice input to add a slice to the list

    def setSlice(self, x, y, name, width, brightness):
        if (not (self.flag == 'Photoplot')):
            raise InvalidFlagException(
                "This function is for Photoplot flag only")
        if ((not isinstance(x, int)) or (not isinstance(y, int))
                or (not isinstance(width, int))
                or (not isinstance(brightness, float))):
            raise IncorrectTypeException(
                'x, y and width must be integers and brightness must be float')
        self.currSlice = Slice(x, y, name, width, brightness)
        self.Slices.append(self.currSlice)

    #Retrieves the current slice
    def getCurrSlice(self):
        if (not (self.flag == 'Photoplot')):
            raise InvalidFlagException(
                "This function is for Photoplot flag only")
        return self.currSlice

    #The next three functions are used to set slice output
    def setSliceYl(self, yl):
        if (not (self.flag == 'Photoplot')):
            raise InvalidFlagException(
                "This function is for Photoplot flag only")
        if (self.currSlice == None):
            raise NoSliceException('No slice to set data for')
        if (not isinstance(yl, int)):
            raise IncorrectTypeException('Value must be an Integer')
        self.currSlice.setYl(yl)

    def setSliceYh(self, yh):
        if (not (self.flag == 'Photoplot')):
            raise InvalidFlagException(
                "This function is for Photoplot flag only")
        if (self.currSlice == None):
            raise NoSliceException('No slice to set data for')
        if (not isinstance(yh, int)):
            raise IncorrectTypeException('Value must be an Integer')
        self.currSlice.setYh(yh)

    def setSliceBrightnessDiff(self, brightnessDiff):
        if (not (self.flag == 'Photoplot')):
            raise InvalidFlagException(
                "This function is for Photoplot flag only")
        if (self.currSlice == None):
            raise NoSliceException('No slice to set data for')
        if (not isinstance(brightnessDiff, int)):
            raise IncorrectTypeException('Value must be an Integer')
        self.currSlice.setBrightnessDiff(brightnessDiff)

    #Used by the Data Output component to retrieve the slice list details
    def getSliceList(self):
        if (not (self.flag == 'Photoplot')):
            raise InvalidFlagException(
                "This function is for Photoplot flag only")
        return self.Slices

    def setMeanCalibrationFactor(self, meanCalibrationFactor):
        if (not (self.flag == 'Photoplot')):
            raise InvalidFlagException(
                "This function is for Photoplot flag only")
        if (not isinstance(meanCalibrationFactor, float)):
            raise IncorrectTypeException(
                'Mean Calibration Factor must be a float')
        self.meanCalibrationFactor = meanCalibrationFactor

    def getMeanCalibrationFactor(self):
        if (not (self.flag == 'Photoplot')):
            raise InvalidFlagException(
                "This function is for Photoplot flag only")
        return self.meanCalibrationFactor

    def setPhotoplotImage(self, inPhotoImage):
        if (not (self.flag == 'Photoplot')):
            raise InvalidFlagException(
                'This function is for Photoplot flag only')
        if (not isinstance(inPhotoImage, plt.figure.Figure)):
            raise IncorrectTypeException(
                "Photoplot Image must be a matplotlib.figure.Figure")
        self.photoImage = inPhotoImage

    def getPhotoplotImage(self):
        if (not (self.flag == 'Photoplot')):
            raise InvalidFlagException(
                'This function is for Photoplot flag only')
        return self.photoImage

#Setters and getters for Publication

    def setAnnotatedImage(self, inAnnotatedImage):
        if (not (self.flag == 'Publication')):
            raise InvalidFlagException(
                "This function is for Publication flag only")
        if (not isinstance(inAnnotatedImage, plt.figure.Figure)):
            raise IncorrectTypeException(
                "Annotated Image must be a matplotlib.figure.Figure")
        self.annotated = inAnnotatedImage

    def getAnnotatedImage(self):
        if (not (self.flag == 'Publication')):
            raise InvalidFlagException(
                "This function is for Publication flag only")
        return self.annotated

#Setters and getters for CheckPixels

    def setCheckX(self, inCheckX):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for Check Pixels flag only")
        if (not isinstance(inCheckX, int)):
            raise IncorrectTypeException("Coordinate must be int")
        yMax, xMax = self.img.shape
        if (not ((inCheckX > 0) and (inCheckX < xMax))):
            raise InvalidCoordException(
                "x Coordinate is out of bounds. Must be from 0 to {}.".format(
                    xMax))
        self.checkX = inCheckX

    def getCheckX(self):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for Check Pixels flag only")
        return self.checkX

    def setCheckY(self, inCheckY):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for Check Pixels flag only")
        if (not isinstance(inCheckY, int)):
            raise IncorrectTypeException("Coordinate must be int")
        yMax, xMax = self.img.shape
        if (not ((inCheckY > 0) and (inCheckY < yMax))):
            raise InvalidCoordException(
                "y Coordinate is out of bounds. Must be from 0 to {}.".format(
                    yMax))
        self.checkY = inCheckY

    def getCheckY(self):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for Check Pixels flag only")
        return self.checkY

    def setCheckFactor(self, inCheckFactor):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for Check Pixels flag only")
        if (not isinstance(inCheckFactor, float)):
            raise IncorrectTypeException("Check Zoom Factor must be float")
        if (not inCheckFactor > 0.0):
            raise InvalidZoomFactorException(
                "Check Zoom Factor must be positive")
        self.checkFactor = inCheckFactor

    def getCheckFactor(self):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for Check Pixels flag only")
        return self.checkFactor

    def setPixelImage(self, inPixelImage):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for Check Pixels flag only")
        if (not isinstance(inPixelImage, plt.figure.Figure)):
            raise IncorrectTypeException("Pixel image must be a Figure")
        self.pixelImage = inPixelImage

    def getPixelImage(self):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for Check Pixels flag only")
        return self.pixelImage

    def setPadTop(self, inPadTop):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for CheckPixels flag only")
        if (not isinstance(inPadTop, int)):
            raise IncorrectTypeException("inPadTop must be an int")
        self.padTop = inPadTop

    def getPadTop(self):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for CheckPixels flag only")
        return self.padTop

    def setPadBottom(self, inPadBottom):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for CheckPixels flag only")
        if (not isinstance(inPadBottom, int)):
            raise IncorrectTypeException("inPadTop must be an int")
        self.padBottom = inPadBottom

    def getPadBottom(self):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for CheckPixels flag only")
        return self.padBottom

    def setPadLeft(self, inPadLeft):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for CheckPixels flag only")
        if (not isinstance(inPadLeft, int)):
            raise IncorrectTypeException("inPadTop must be an int")
        self.padLeft = inPadLeft

    def getPadLeft(self):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for CheckPixels flag only")
        return self.padLeft

    def setPadRight(self, inPadRight):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for CheckPixels flag only")
        if (not isinstance(inPadRight, int)):
            raise IncorrectTypeException("inPadTop must be an int")
        self.padRight = inPadRight

    def getPadRight(self):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for CheckPixels flag only")
        return self.padRight

    def setHeight(self, inHeight):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for CheckPixels flag only")
        if (not isinstance(inHeight, int)):
            raise IncorrectTypeException("inHeight must be an int")
        self.height = inHeight

    def getHeight(self):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for CheckPixels flag only")
        return self.height

    def setWidth(self, inWidth):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for CheckPixels flag only")
        if (not isinstance(inWidth, int)):
            raise IncorrectTypeException("inWidth must be an int")
        self.width = inWidth

    def getWidth(self):
        if (not (self.flag == 'CheckPixels')):
            raise InvalidFlagException(
                "This function is for CheckPixels flag only")
        return self.width

#Setters and getters for Simulate

    def setSimulateImage(self, inSimulateImage):
        if (not (self.flag == 'Simulate')):
            raise InvalidFlagException(
                "This function is for Simulate flag only")
        if (not isinstance(inSimulateImage, np.ndarray)):
            raise IncorrectTypeException(
                "Simulate Image must be a numpy.ndarray")
        if (not (inSimulateImage.ndim == 2)):
            raise InvalidSizeException("Must be 2d")
        self.simulateImage = inSimulateImage

    def getSimulateImage(self):
        if (not (self.flag == 'Simulate')):
            raise InvalidFlagException(
                "This function is for Simulate flag only")
        return self.simulateImage

#Setters and getters for Zoomed

    def setZoomFactor(self, inZoomFactor):
        if (not (self.flag == 'Zoomed')):
            raise InvalidFlagException("This function is for Zoomed flag only")
        if (not isinstance(inZoomFactor, float)):
            raise IncorrectTypeException("Zoom Factor must be float")
        if (not inZoomFactor > 0.0):
            raise InvalidZoomFactorException("Zoom Factor must be positive")
        self.zoomFactor = inZoomFactor

    def getZoomFactor(self):
        if (not (self.flag == 'Zoomed')):
            raise InvalidFlagException("This function is for Zoomed flag only")
        return self.zoomFactor

    def setZoomedImages(self, inZoomedImages):
        if (not (self.flag == 'Zoomed')):
            raise InvalidFlagException("This function is for Zoomed flag only")
        if (not isinstance(inZoomedImages, list)):
            raise IncorrectTypeException(
                "ZoomedImages must be a list of zoomed images")
        try:
            if (not isinstance(inZoomedImages[0], ZoomObject)):
                raise IncorrectTypeException(
                    "Individual list elements must be ZoomObjects")
            self.zoomedImages = inZoomedImages
        except IndexError:
            self.zoomedImages = []

    def getZoomedImages(self):
        if (not (self.flag == 'Zoomed')):
            raise InvalidFlagException("This function is for Zoomed flag only")
        return self.zoomedImages

#Setters and getters for Orbits

    def setTle(self, tleFile):
        if (not (self.flag == 'Orbits')):
            raise InvalidFlagException("This function is for Orbits flag only")
        #reads tle file
        try:
            if (not os.path.isfile(tleFile)):
                raise EmptyFileException('Tle file does not exist')
            if (not validateTle(tleFile)):
                raise EmptyFileException('Tle file is not correctly formatted')
            with open(tleFile) as tle:
                self.tleData = tle.readlines()
                self.tleLength = len(self.tleData)
        except ValueError:
            raise EmptyFileException('Tle filename is empty')

        if ((self.tleData is None) | (self.tleLength is None)):
            raise EmptyFileException('Tle is null')

    def getTleData(self):
        if (not (self.flag == 'Orbits')):
            raise InvalidFlagException("This function is for Orbits flag only")
        return self.tleData

    def getTleLength(self):
        if (not (self.flag == 'Orbits')):
            raise InvalidFlagException("This function is for Orbits flag only")
        return self.tleLength

    def setFits(self, fitsFile):
        if (not (self.flag == 'Orbits')):
            raise InvalidFlagException("This function is for Orbits flag only")
        #reads fits file
        try:
            with fits.open(fitsFile):
                self.wcsinfo = wcs.WCS(fitsFile)
        except ValueError:
            raise EmptyFileException('Wcs filename is empty')
        except OSError:
            raise EmptyFileException(
                'Wcs file is not the correct format or is corrupted')

        if self.wcsinfo is None:
            raise EmptyFileException('Wcs is null')

    def getWcsInfo(self):
        if (not (self.flag == 'Orbits')):
            raise InvalidFlagException("This function is for Orbits flag only")
        return self.wcsinfo

    def setOrbitPlot(self, inOrbitPlot):
        if (not (self.flag == 'Orbits')):
            raise InvalidFlagException("This function is for Orbits flag only")
        if (not isinstance(inOrbitPlot, plt.figure.Figure)):
            raise IncorrectTypeException(
                "OrbitPlot must be of type matplotlib.figure.Figure")
        self.orbitPlot = inOrbitPlot

    def getOrbitPlot(self):
        if (not (self.flag == 'Orbits')):
            raise InvalidFlagException("This function is for Orbits flag only")
        return self.orbitPlot