Beispiel #1
0
    def __init__(self, resp, pmodel):
        # check if response model has convolve method
        if not hasattr(resp, "convolve"):
            raise(PE.PyAAlgorithmFailure("Response model has no method 'convolve'.", \
                              where="ConvolutionModel::__init__"))

        if not isinstance(pmodel, OneDFit):
            raise(PE.PyAAlgorithmFailure("Physical model must be derived from OneDFit", \
                              where="ConvolutionModel::__init__"))

        # Copy the input models
        self.response = copy.deepcopy(resp)
        self.pmodel = copy.deepcopy(pmodel)

        if isinstance(self.response, OneDFit):
            # The response is also a funcFit model and, therefore, could
            # already contribute fitting parameters
            #
            # Change root name to "Response"
            self.response.setRootName("Response")
            # Ensure unique parameter names
            self._combineRemapping(self.response, self.pmodel)
            # List of parameters for the this (the convolved) model
            parameters = list(self.response.parameters()) + list(
                self.pmodel.parameters())
        else:
            # List of parameters for the this (the convolved) model
            parameters = list(self.pmodel.parameters())

        # Set up funcFit model and assign
        OneDFit.__init__(self, parameters)

        # Define root name
        if self.pmodel.naming._root == "":
            # Use default
            rn = "model"
        else:
            rn = self.pmodel.naming._root

        self.setRootName("Conv-" + rn)
Beispiel #2
0
 def _readData(self):
     """
     """
     # Determine number of planets in the csv file
     r = csv.DictReader(self._fs.requestFile(self.dataFileName, 'rt',
                                             gzip.open),
                        delimiter=',')
     for nplanets, x in enumerate(r):
         pass
     # Reinitialize csv file
     r = csv.DictReader(self._fs.requestFile(self.dataFileName, 'rt',
                                             gzip.open),
                        delimiter=',')
     # Determine data types for numpy recarray from columns
     # and initialize
     dtype = [(self._columns[x][0], self._columns[x][3])
              for x in range(len(self._columns))]
     self.data = np.recarray((nplanets + 1, ), dtype=dtype)
     colnotfilled = [
         self._columns[x][0] for x in six.iterkeys(self._columns)
     ]
     for i, x in enumerate(r):
         for k, v in six.iteritems(x):
             # Remove hash and white spaces from column names
             k = k.strip('#')
             k = k.strip()
             # Translate csv column name into internal column name
             if k in self._ident:
                 key = self._ident[k]
             else:
                 key = k
             if len(v) == 0:
                 v = None
             # Accept only expected fields
             if not key in self.data.dtype.names:
                 continue
             try:
                 colnotfilled.remove(key)
             except ValueError:
                 # Ignoring already removed value
                 pass
             self.data[key][i] = v
     if len(colnotfilled) > 0:
         PE.warn(
             PE.PyAAlgorithmFailure(
                 "Not all columns could be filled with data. The following columns must not be used: "
                 + ", ".join(colnotfilled),
                 where="ExoplanetEU",
                 solution=
                 "The format of the data base must be checked. Please consider issuing a bug report via github."
             ))
Beispiel #3
0
 def selectWalkers(self, ws):
   """
     Select walkers for emcee chains.
     
     Parameters
     ----------
     ws : list or array of integers
         The walker to be considered in the analysis. Counting
         starts at zero.
   """
   self._selectedWalker = np.array(ws, dtype=np.int)
   if self.dbtype == "emcee":
     # Apply burn-in to individual walkers
     self._loadEMCEEChain(burn=self.burn)
   else:
     raise(PE.PyAAlgorithmFailure("Walkers can only be selected for emcee data bases. Current data base type: " + str(self.dbtype)))
    def fit(self,
            m,
            ds,
            objf="chisqr",
            initDelta=None,
            maxIter=1e4,
            callback=None,
            nmCritLim=None):
        """
        Carry out the model fit.
        
        After the iteration, the `iterCount` attribute contains the
        number of iterations. The `maxIterReached` attribute flag is
        False, if the maximum number of iterations has not been reached
        and True otherwise. 
        
        Parameters
        ----------
        m : Instance of OneDFit
            The model to be fitted.
        ds : Instance of FufDS
            The data.
        objf : string
            The objective function to be used. Possible
            choices are "chisqr" (default), "sqrdiff", and
            "cash79".
        initDelta : dictionary, optional
            A dictionary mapping parameter names to the
            initial step width. This can be very useful, if
            the starting values are zero or very small. The
            here defined step will be added to the starting
            value to construct the simplex.
        maxIter : int, optional
            The maximum number of iterations. The default is
            10000.
        nmCritLim : float, optional
            Critical value for stopping criterion. The default is
            1e-8.
        callback : callable, optional
            If not None, "callback" will be called with the
            three parameters: number of iteration (int), current
            best parameter set (array), and current simplex (array).
        
        Returns
        -------
        Best-fit values : dictionary
            Maps parameter name to the best-fit value.
        """
        # Stopping criterion
        if not nmCritLim is None:
            self.nmCritLim = nmCritLim
        # Number of free parameters
        self._n = m.numberOfFreeParams()
        # Set objective function
        m.setObjectiveFunction(objf)
        # Assign data object
        m._fufDS = ds
        # Names of free parameters (order guaranteed)
        self._fpns = m.freeParamNames()
        # Initial simplex
        self._initSimplex(m, initDelta)
        # MaxIter flag
        self.maxIterReached = False

        self.iterCount = 0
        while (not self._stopCrit()) and (self.iterCount < maxIter):
            self.iterCount += 1
            self._step(m)
            if callback is not None:
                l = np.argmin(self._yi)
                callback(self.iterCount, self._simplex[l, ::], self._simplex)

        # Find the optimum parameter set
        l = np.argmin(self._yi)
        m.pars.setFreeParams(self._simplex[l, ::])
        # Evaluate model so that model attribute holds the best match
        m.evaluate(ds.x)

        if self.iterCount == maxIter:
            self.maxIterReached = True
            PE.warn(
                PE.PyAAlgorithmFailure(
                    "The maximum number of iterations has been reached.\n" +
                    "The fit may be inappropriate.",
                    where="NelderMead",
                    solution=[
                        "Increase number of iterations.",
                        "Change starting values.",
                        "Change algorithm parameters (e.g., alpha, beta, gamma)."
                    ]))
        # Return a dictionary with the best-bit parameters
        return dict(zip(self._fpns, self._simplex[l, ::]))
    def teffToColor_nop(self, band, teff, feH, stype="ms", noRaise=False):
        """
      Converts effective temperature into color according to Eq. 1.
      
      This method inverts Eq. 1. Note that the equation is parabolic
      in the color (i.e., X). Therefore, there are two solutions of
      which the one falling within the validity ranges specified in
      Tables 4 and 5 of RM05 is selected. If none or both of the
      solutions are valid, an exception is raised.  
      
      Parameters
      ----------
      band : string
          Band identifier.
      teff : float
          Effective temperature in K.
      feH : float
          Metallicity
      stype : string, {ms, g}
          Type of star (main sequence or giant).
      noRaise : boolean, optional
          If True, no exceptions will be raised, but warnings
          will be given Both candidate solutions will be
          returned in this case.
      
      Returns
      -------
      X : float
          Color in the specified band.
    """
        self._checkBand(band)
        self._checkST(stype)
        if stype == "ms":
            dat = self._tab2
            datp = self._tab4
        else:
            dat = self._tab3
            datp = self._tab5

        # Use warnings of 'noRaise' is True
        if noRaise:
            raiser = PE.warn
        else:

            def throw(x):
                raise (x)

            raiser = throw

        # Row of coefficients in the table.
        j = self._bands.index(band)

        c = dat[j, 0] + dat[j, 4] * feH + dat[j, 5] * feH**2 - 5040. / teff
        a13p = dat[j, 1] + dat[j, 3] * feH
        a2 = dat[j, 2]

        sq = np.sqrt(a13p**2 - 4. * a2 * c)
        X = [(-a13p + sq) / (2. * a2), (-a13p - sq) / (2. * a2)]

        # Get validity ranges to decide, which solution is correct
        mj = j * 4 + self._resolveMetallicityIndex(feH)

        xmin = datp[mj, 1]
        xmax = datp[mj, 2]
        xin = [False] * 2
        for i in smo.range(2):
            if X[i] >= xmin and X[i] <= xmax:
                xin[i] = True
        if sum(xin) == 2:
            raiser(PE.PyAAlgorithmFailure("No unique solution in inversion of teff-color relation.", \
                                         where="teffToColor_nop",\
                                         solution="Consider carefully(!) using 'noRaise'."))
            # Only relevant if 'noRaise' is True
            return tuple(X)
        if sum(xin) == 0:
            raiser(PE.PyAAlgorithmFailure("No valid solution in inversion of teff-color relation.\n" + \
                                         "Band: " + str(band) + ", Range of validity: %.4e - %.4e" % (xmin, xmax) + \
                                         ", candidate solutions: %.4e and %.4e" % tuple(X) + ", Input Teff: %5.1f" % teff, \
                                         where="teffToColor_nop",\
                                         solution="Consider carefully(!) using 'noRaise'."))
            # Only relevant if 'noRaise' is True
            return tuple(X)

        if xin[0]:
            return X[0]
        else:
            return X[1]