示例#1
0
def do_pca(data, cov=False):
    tolerance = 1.0E-5
    Nobj, Mattr = data.shape

    if cov:
        colmean = (np.sum(data,0)/Nobj)[:,np.newaxis]
        temp = np.ones((Nobj,1))
        X = data - np.dot(temp,colmean.T)
    else:
        msgs.bug("PCA without cov=True is not implemented")
        msgs.error("Unable to continue")
    A = np.dot(X.T,X)
    eigva, eigve = np.linalg.eig(A)
    indx = np.where(np.abs(eigva) <= tolerance*np.max(eigva))[0]
    if np.size(indx) != 0: eigva[indx] = 0.0
    indx = np.where(np.abs(eigve) <= tolerance*np.max(eigve))[0]
    if np.size(indx) != 0: eigve[indx] = 0.0

    # Sort by increasing eigenvalue
    indx = np.argsort(eigva)
    eigva = eigva[indx]
    eigve = eigve[:,indx]
    eigva = eigva[::-1]
    eigve = eigve.T[::-1,:]

    return eigva, eigve
示例#2
0
    def fitsol_deriv(self, xfit=None, idx=None):
        """Calculate the dispersion as a function of wavelength

        Args:
            xfit (ndarray, float): Pixel values that the user wishes to evaluate the wavelength
            idx (int): Index of the arc line detections that the user wishes to evaluate the wavelength

        Returns:
            disp (ndarray, float, None): The dispersion (Angstroms/pixel) as a function of wavelength
        """
        if xfit is None:
            xfit = self._detns
        if self._fitdict['coeff'] is not None:
            cder = np.polyder(self._fitdict["coeff"])
            if idx is None:
                return np.polyval(
                    cder,
                    xfit / self._fitdict["scale"]) / self._fitdict["scale"]
            else:
                return np.polyval(
                    cder, xfit[idx] /
                    self._fitdict["scale"]) / self._fitdict["scale"]
        else:
            msgs.bug(
                "Cannot predict wavelength value - no fit has been performed")
            return None
示例#3
0
def polyfit2d_general(x,
                      y,
                      z,
                      deg,
                      w=None,
                      function='polynomial',
                      minx=None,
                      maxx=None,
                      miny=None,
                      maxy=None):
    """
    2D Polynomimal fit

    Args:
        x (`numpy.ndarray`_):
        y (`numpy.ndarray`_):
        z (`numpy.ndarray`_): value of data at each (x,y) coordinate
        deg (tuple): degree of polynomial fit in the form [nx,ny]
        w (`numpy.ndarray`_):
        function:
        minx:
        maxx:
        miny:
        maxy:

    Returns:
        `numpy.ndarray`_:

    """
    x = np.asarray(x)
    y = np.asarray(y)
    z = np.asarray(z)
    deg = np.asarray(deg)
    # Vander
    if function == 'polynomial':
        vander = np.polynomial.polynomial.polyvander2d(x, y, deg)
    elif function == 'legendre' or function == 'chebyshev':
        xv, minx, maxx = scale_minmax(x, minx=minx, maxx=maxx)
        yv, miny, maxy = scale_minmax(y, minx=miny, maxx=maxy)
        vander = np.polynomial.legendre.legvander2d(xv, yv, deg) if function == 'legendre' \
            else np.polynomial.chebyshev.chebvander2d(xv, yv, deg)
    else:
        msgs.error("Not ready for this type of {:s}".format(function))
    # Weights
    if w is not None:
        w = np.asarray(w) + 0.0
        if w.ndim != 1:
            msgs.bug("fitting.polyfit2d - Expected 1D vector for weights")
        if len(x) != len(w) or len(y) != len(w) or len(x) != len(y):
            msgs.bug(
                "fitting.polyfit2d - Expected x, y and weights to have same length"
            )
        z = z * w
        vander = vander * w[:, np.newaxis]
    # Reshape
    vander = vander.reshape((-1, vander.shape[-1]))
    z = z.reshape((vander.shape[0], ))
    c = np.linalg.lstsq(vander, z, rcond=None)[0]
    return c.reshape(deg + 1), minx, maxx, miny, maxy
示例#4
0
def robust_regression(x, y, ordr, outfrac, maxiter=100, function='polynomial', min=None, max=None):
    """
    Deprecated
    """
    msgs.bug("PypeIt using deprecated function")
    msgs.error("Please contact the authors")
    xsize=x.size
    infrac = 1.0-outfrac
    if infrac < 0.5: infrac = 0.5
    slct = int(xsize*infrac)
    if slct == xsize: slct = xsize-1
    if ordr+1 >= slct:
        if xsize <= 1:
            msgs.error("At least 2 points are required for a statistical fit")
        elif xsize == 2:
            msgs.warn("Only a constant can be fit to 2 points")
            msgs.info("Fitting a constant instead")
            return func_fit(x,y,function,0)
        elif  ordr+1 >= xsize:
            msgs.warn("Not enough points ({0:d}) for a {1:d}th order fit".format(xsize,ordr))
            ordr = xsize-3
            slct = ordr+2
            msgs.info("Changing order to a {0:d} order {1:s} fucntion".format(ordr,function))
        else:
            slct = ordr
    indx = np.arange(xsize)
    np.random.shuffle(indx)
    ind = indx[:slct]
    i=0
    while True:
        tc = func_fit(x[ind],y[ind],function,ordr)
        diff = np.abs(y[ind]-func_val(tc,x[ind],function))
        mad = np.median(diff)
        w=np.argsort(diff)
        inds=-1
        for j in range(0,xsize-slct):
            temp = ind[w[-1]]
            ind[w[-1]] = indx[slct+j]
            indx[slct+j] = temp
            diff = np.abs(y[ind]-func_val(tc,x[ind],function))
            if np.median(diff) < mad:
                inds = j
                mad = np.median(diff)
            # Switch it back
            temp = ind[w[-1]]
            ind[w[-1]] = indx[slct+j]
            indx[slct+j] = temp
        if inds == -1 or i>maxiter: break
        temp = ind[w[-1]]
        ind[w[-1]] = indx[slct+inds]
        indx[slct+inds] = temp
        i += 1
    return tc
示例#5
0
文件: parse.py 项目: mcoughlin/PypeIt
def key_list(strlist):
    """ Check that a keyword argument is a list. Set the
    appropriate type of the list based on the supplied values.

    Parameters
    ----------
    v : str
      value of a keyword argument

    Returns
    -------
    v : list
      A value used by the settings dictionary
    """
    # Check if the input array is a null list
    if strlist == "[]" or strlist == "()":
        return []
    # Remove outer brackets and split by commas
    temp = strlist.lstrip('([').rstrip(')]').split(',')
    addarr = []
    # Find the type of the array elements
    for i in temp:
        if i.lower() == 'none':
            # None type
            addarr += [None]
        elif i.lower() == 'true' or i.lower() == 'false':
            # bool type
            addarr += [i.lower() in ['true']]
        elif ',' in i:
            # a list
            addarr += i.lstrip('([').rstrip('])').split(',')
            msgs.bug(
                "nested lists could cause trouble if elements are not strings!"
            )
        elif '.' in i:
            try:
                # Might be a float
                addarr += [float(i)]
            except ValueError:
                # Must be a string
                addarr += [i]
        else:
            try:
                # Could be an integer
                addarr += [int(i)]
            except ValueError:
                # Must be a string
                addarr += [i]
    return addarr
示例#6
0
    def fitsol_value(self, xfit=None, idx=None):
        """Calculate the wavelength at a pixel

        Args:
            xfit (ndarray, float): Pixel values that the user wishes to evaluate the wavelength
            idx (int): Index of the arc line detections that the user wishes to evaluate the wavelength

        Returns:
            disp (ndarray, float, None): The wavelength (Angstroms) of the requested pixels
        """
        if xfit is None:
            xfit = self._detns
        if self._fitdict['coeff'] is not None:
            if idx is None:
                return np.polyval(self._fitdict["coeff"],
                                  xfit / self._fitdict["scale"])
            else:
                return np.polyval(self._fitdict["coeff"],
                                  xfit[idx] / self._fitdict["scale"])
        else:
            msgs.bug(
                "Cannot predict wavelength value - no fit has been performed")
            return None
示例#7
0
    def operations(self, key, axisID):
        """Canvas operations

        Args:
            key (str): Which key has been pressed
            axisID (int): The index of the axis where the key has been pressed (see get_axisID)
        """
        # Check if the user really wants to quit
        if key == 'q' and self._qconf:
            if self._changes:
                self.update_infobox(message="WARNING: There are unsaved changes!!\nPress q again to exit", yesno=False)
                self._qconf = True
            else:
                msgs.bug("Need to change this to kill and return the results to PypeIt")
                plt.close()
        elif self._qconf:
            self.update_infobox(default=True)
            self._qconf = False

        # Manage responses from questions posed to the user.
        if self._respreq[0]:
            if key != "y" and key != "n":
                return
            else:
                # Switch off the required response
                self._respreq[0] = False
                # Deal with the response
                if self._respreq[1] == "delete_object" and key == "y":
                    self.delete_object()
                elif self._respreq[1] == "clear_anchors" and key == "y":
                    self.empty_mantrace()
                    self.replot()
                elif self._respreq[1] == "exit_update" and key == "y":
                    self._use_updates = True
                    self.print_pypeit_info()
                    self.operations("qu", None)
                elif self._respreq[1] == "exit_restore" and key == "y":
                    self._use_updates = False
                    self.operations("qr", None)
                else:
                    return
            # Reset the info box
            self.update_infobox(default=True)
            return

        if key == '?':
            self.print_help()
        elif key == 'a':
            self.add_object()
        elif key == 'c':
            if axisID == 0:
                # If this is pressed on the main window
                self.recenter()
#        elif key == 'c':
#            self._respreq = [True, "clear_anchors"]
#            self.update_infobox(message="Are you sure you want to clear the anchors", yesno=True)
        elif key == 'd':
            if self._obj_idx != -1:
                self._respreq = [True, "delete_object"]
                self.update_infobox(message="Are you sure you want to delete this object trace", yesno=True)
#        elif key == 'm':
#            if self._trcmthd != 'manual':
#                self.update_infobox(message="To add an anchor point, set the 'manual' trace method", yesno=False)
#            else:
#                self.add_anchor()
#        elif key == 'n':
#            self.remove_anchor()
        elif key == 'qu' or key == 'qr':
            if self._changes:
                self.update_infobox(message="WARNING: There are unsaved changes!!\nPress q again to exit", yesno=False)
                self._qconf = True
            else:
                plt.close()
#        elif key == '+':
#            if self._mantrace["polyorder"] < 10:
#                self._mantrace["polyorder"] += 1
#                self.update_infobox(message="Polynomial order = {0:d}".format(self._mantrace["polyorder"]), yesno=False)
#                self.fit_anchors()
#            else:
#                self.update_infobox(message="Polynomial order must be <= 10", yesno=False)
#        elif key == '-':
#            if self._mantrace["polyorder"] > 1:
#                self._mantrace["polyorder"] -= 1
#                self.update_infobox(message="Polynomial order = {0:d}".format(self._mantrace["polyorder"]), yesno=False)
#                self.fit_anchors()
#            else:
#                self.update_infobox(message="Polynomial order must be >= 1", yesno=False)
        self.replot()
示例#8
0
    def operations(self, key, axisID):
        """Canvas operations

        Args:
            key (str): Which key has been pressed
            axisID (int): The index of the axis where the key has been pressed (see get_axisID)
        """
        # Check if the user really wants to quit
        if key == 'q' and self._qconf:
            if self._changes:
                self.update_infobox(
                    message=
                    "WARNING: There are unsaved changes!!\nPress q again to exit",
                    yesno=False)
                self._qconf = True
            else:
                msgs.bug(
                    "Need to change this to kill and return the results to PypeIt"
                )
                plt.close()
        elif self._qconf:
            self.update_infobox(default=True)
            self._qconf = False

        # Manage responses from questions posed to the user.
        if self._respreq[0]:
            if key != "y" and key != "n":
                return
            else:
                # Switch off the required response
                self._respreq[0] = False
                # Deal with the response
                if self._respreq[1] == "write":
                    # First remove the old file, and save the new one
                    msgs.work("Not implemented yet!")
                    self.write()
                else:
                    return
            # Reset the info box
            self.update_infobox(default=True)
            return

        if key == '?':
            self.print_help()
        elif key == 'a':
            if self._fitdict['coeff'] is not None:
                self.auto_id()
            else:
                msgs.info("You must identify a few lines first")
        elif key == 'c':
            wclr = np.where((self._lineflg == 2) | (self._lineflg == 3))
            self._lineflg[wclr] = 0
            self.replot()
        elif key == 'd':
            self._lineflg *= 0
            self._lineids *= 0.0
            self._fitdict['coeff'] = None
            self.replot()
        elif key == 'f':
            self.fitsol_fit()
            self.replot()
        elif key == 'l':
            self.load_IDs()
        elif key == 'q':
            if self._changes:
                self.update_infobox(
                    message=
                    "WARNING: There are unsaved changes!!\nPress q again to exit",
                    yesno=False)
                self._qconf = True
            else:
                plt.close()
        elif key == 'r':
            if self._detns_idx == -1:
                msgs.info("You must select a line first")
            elif self._fitr is None:
                msgs.info("You must select a fitting region first")
            else:
                msgs.work("Feature not yet implemented")
        elif key == 's':
            self.save_IDs()
        elif key == 'w':
            self.toggle_wavepix(toggled=True)
            self.replot()
        elif key == 'z':
            self.delete_line_id()
        elif key == '+':
            if self._fitdict["polyorder"] < 10:
                self._fitdict["polyorder"] += 1
                self.update_infobox(message="Polynomial order = {0:d}".format(
                    self._fitdict["polyorder"]),
                                    yesno=False)
                self.fitsol_fit()
                self.replot()
            else:
                self.update_infobox(message="Polynomial order must be <= 10",
                                    yesno=False)
        elif key == '-':
            if self._fitdict["polyorder"] > 1:
                self._fitdict["polyorder"] -= 1
                self.update_infobox(message="Polynomial order = {0:d}".format(
                    self._fitdict["polyorder"]),
                                    yesno=False)
                self.fitsol_fit()
                self.replot()
            else:
                self.update_infobox(message="Polynomial order must be >= 1",
                                    yesno=False)
        self.canvas.draw()
示例#9
0
    def operations(self, key, axisID):
        """Canvas operations

        Args:
            key : str
                Which key has been pressed
            axisID : int
                The index of the axis where the key has been pressed (see get_axisID)
        """
        # Check if the user really wants to quit
        if key == 'q' and self._qconf:
            if self._changes:
                self.update_infobox(
                    message='WARNING: There are unsaved changes!!\nPress q '
                    'again to exit',
                    yesno=False)
                self._qconf = True
            else:
                msgs.bug(
                    "Need to change this to kill and return the results to PypeIt"
                )
                plt.close()
        elif self._qconf:
            self.update_infobox(default=True)
            self._qconf = False

        # Manage responses from questions posed to the user.
        if self._respreq[0]:
            if key != "y" and key != "n":
                return
            else:
                # Switch off the required response
                self._respreq[0] = False
                # Deal with the response
                if self._respreq[1] == "exit_update" and key == "y":
                    self._use_updates = True
                    self.operations("qu", None)
                elif self._respreq[1] == "exit_restore" and key == "y":
                    self._use_updates = False
                    self.operations("qr", None)
                else:
                    return
            # Reset the info box
            self.update_infobox(default=True)
            return

        if key == '?':
            self.print_help()
        elif key == 'd':
            if axisID == 0:
                # If this is pressed on the main window
                self.reset_regions()
        elif key == 'c':
            if axisID == 0:
                # If this is pressed on the main window
                self.recenter()
        elif key == 'qu' or key == 'qr':
            if self._changes:
                self.update_infobox(
                    message='WARNING: There are unsaved changes!!\nPress q '
                    'again to exit',
                    yesno=False)
                self._qconf = True
            else:
                plt.close()
        self.replot()
示例#10
0
文件: utils.py 项目: tbowers7/PypeIt
def polyfit_integral(x, y, dx, deg, rcond=None, full=False, w=None):
    order = int(deg) + 1
    x = np.asarray(x)
    y = np.asarray(y)

    # check arguments.
    if deg < 0:
        msgs.bug("Expected deg >= 0")
        msgs.error("Input of function arutils.polyfit_integral is incorrect")
    if x.ndim != 1:
        msgs.bug("Expected 1D vector for x")
        msgs.error("Input of function arutils.polyfit_integral is incorrect")
    if x.size == 0:
        msgs.bug("Expected non-empty vector for x")
        msgs.error("Input of function arutils.polyfit_integral is incorrect")
    if y.ndim < 1 or y.ndim > 2:
        msgs.bug("Expected 1D or 2D array for y")
        msgs.error("Input of function arutils.polyfit_integral is incorrect")
    if len(x) != len(y):
        msgs.bug("Expected x and y to have same length")
        msgs.error("Input of function arutils.polyfit_integral is incorrect")

    # set up the least squares matrices in transposed form
    lhst = np.polynomial.polynomial.polyvander(
        x + dx / 2.0, deg + 1) - np.polynomial.polynomial.polyvander(
            x - dx / 2.0, deg + 1)
    div = np.arange(1., deg + 2.).reshape(1, deg + 1).repeat(x.size, axis=0)
    lhs = (lhst[:, 1:] /
           (dx.reshape(dx.size, 1).repeat(deg + 1, axis=1) * div)).T
    rhs = y.T
    if w is not None:
        w = np.asarray(w)
        if w.ndim != 1:
            msgs.bug("Expected 1D vector for weights in arutils.polyfit2d")
        if len(x) != len(w):
            msgs.bug(
                "Expected x and weights to have same length in arutils.polyfit2d"
            )
        # apply weights. Don't use inplace operations as they
        # can cause problems with NA.
        lhs = lhs * w
        rhs = rhs * w

    # set rcond
    if rcond is None:
        rcond = len(x) * np.finfo(x.dtype).eps

    # Determine the norms of the design matrix columns.
    if issubclass(lhs.dtype.type, np.complexfloating):
        scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
    else:
        scl = np.sqrt(np.square(lhs).sum(1))
    scl[scl == 0] = 1

    # Solve the least squares problem.
    c, resids, rank, s = np.linalg.lstsq(lhs.T / scl, rhs.T, rcond)
    c = (c.T / scl).T

    # warn on rank reduction
    if rank != order and not full:
        msgs.warn(
            "The fit result of the function arutils.polyfit_integral may be poorly conditioned"
        )

    if full:
        return c, [resids, rank, s, rcond]
    else:
        return c