<commit_before>#
# Copyright 2016 The BigDL Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import sys

from bigdl.nn.layer import Layer, Container
from bigdl.util.common import callBigDlFunc, JTensor

if sys.version >= '3':
    long = int
    unicode = str

class KerasLayer(Layer):
    def jvm_class_constructor(self):
        name = "createKeras" + self.__class__.__name__
        print("creating: " + name)
        return name

class Sequential(Container):
    def __init__(self, bigdl_type="float"):
        super(Sequential, self).__init__(None, bigdl_type, True)

class InputLayer(KerasLayer):
    def __init__(self, input_shape=None, bigdl_type="float"):
        super(InputLayer, self).__init__(None, bigdl_type,
                                         list(input_shape) if input_shape else None)

class Dense(KerasLayer):
    """
    A densely-connected NN layer.
    When you use this layer as the first layer of a model, you need to provide the argument
    inputShape (a Single Shape, does not include the batch dimension).
    The most common input is 2D.

    # Arguments
    output_dim: The size of output dimension.
    init: String representations of initialization method for the weights of the layer.
          Default is 'glorot_uniform'.
    activation: String representations of activation function to use (such as 'relu' or 'sigmoid').
                Default is None.
    W_regularizer: An instance of [[Regularizer]], (eg. L1 or L2 regularization),
                   applied to the input weights matrices. Default is None.
    b_regularizer: An instance of [[Regularizer]], applied to the bias. Default is None.
    bias: Whether to include a bias (i.e. make the layer affine rather than linear). Default is True.

    >>> dense = Dense(10, input_shape=(3, 4))
    creating: createKerasDense
    """
    def __init__(self, output_dim, init='glorot_uniform', activation=None,
                 W_regularizer=None, b_regularizer=None,
                 bias=True, input_shape=None, bigdl_type="float"):
        super(Dense, self).__init__(None, bigdl_type,
                                    output_dim,
                                    init,
                                    activation,
                                    W_regularizer,
                                    b_regularizer,
                                    bias,
                                    list(input_shape) if input_shape else None)

class Embedding(KerasLayer):
    """
    >>> embedding = Embedding(1000, 32, input_shape=(10, ))
    creating: createKerasEmbedding
    """
    def __init__(self, input_dim, output_dim, init='uniform',
                 W_regularizer=None, input_shape=None, bigdl_type="float"):
        super(Embedding, self).__init__(None, bigdl_type,
                                        input_dim,
                                        output_dim,
                                        init,
                                        W_regularizer,
                                        list(input_shape) if input_shape else None)

class BatchNormalization(KerasLayer):
    """
    >>> batchNormalization = BatchNormalization(input_shape=(3, 12, 12))
    creating: createKerasBatchNormalization
    """
    def __init__(self, epsilon=0.001, momentum=0.99, beta_init='zero', gamma_init='one',
                 dim_ordering="th", input_shape=None, bigdl_type="float"):
        super(BatchNormalization, self).__init__(None, bigdl_type,
                                                 epsilon,
                                                 momentum,
                                                 beta_init,
                                                 gamma_init,
                                                 dim_ordering,
                                                 list(input_shape) if input_shape else None)

    def set_running_mean(self, running_mean):
        callBigDlFunc(self.bigdl_type, "setKerasRunningMean",
                      self.value, JTensor.from_ndarray(running_mean))
        return self

    def set_running_std(self, running_std):
        callBigDlFunc(self.bigdl_type, "setKerasRunningStd",
                      self.value, JTensor.from_ndarray(running_std))
        return self

    def get_running_mean(self):
        return callBigDlFunc(self.bigdl_type, "getKerasRunningMean",
                             self.value).to_ndarray()

    def get_running_std(self):
        return callBigDlFunc(self.bigdl_type, "getKerasRunningStd",
                      self.value).to_ndarray()
<commit_msg>Keras-like API Merge and Wrappers (#2263)<commit_after>#
# Copyright 2016 The BigDL Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import sys

from bigdl.nn.layer import Layer, Container
from bigdl.util.common import callBigDlFunc, JTensor

if sys.version >= '3':
    long = int
    unicode = str

class KerasLayer(Layer):
    def jvm_class_constructor(self):
        name = "createKeras" + self.__class__.__name__
        print("creating: " + name)
        return name

class Sequential(Container):
    """
    >>> sequential = Sequential()
    creating: createSequential
    """
    def __init__(self, bigdl_type="float"):
        super(Sequential, self).__init__(None, bigdl_type, True)

class InputLayer(KerasLayer):
    """
    >>> inputLayer = InputLayer(input_shape=(3, 5))
    creating: createKerasInputLayer
    """
    def __init__(self, input_shape=None, bigdl_type="float"):
        super(InputLayer, self).__init__(None, bigdl_type,
                                         list(input_shape) if input_shape else None)

class Dense(KerasLayer):
    """
    A densely-connected NN layer.
    When you use this layer as the first layer of a model, you need to provide the argument
    inputShape (a Single Shape, does not include the batch dimension).
    The most common input is 2D.

    # Arguments
    output_dim: The size of output dimension.
    init: String representations of initialization method for the weights of the layer.
          Default is 'glorot_uniform'.
    activation: String representations of activation function to use (such as 'relu' or 'sigmoid').
                Default is None.
    W_regularizer: An instance of [[Regularizer]], (eg. L1 or L2 regularization),
                   applied to the input weights matrices. Default is None.
    b_regularizer: An instance of [[Regularizer]], applied to the bias. Default is None.
    bias: Whether to include a bias (i.e. make the layer affine rather than linear). Default is True.

    >>> dense = Dense(10, input_shape=(3, 4))
    creating: createKerasDense
    """
    def __init__(self, output_dim, init='glorot_uniform', activation=None,
                 W_regularizer=None, b_regularizer=None,
                 bias=True, input_shape=None, bigdl_type="float"):
        super(Dense, self).__init__(None, bigdl_type,
                                    output_dim,
                                    init,
                                    activation,
                                    W_regularizer,
                                    b_regularizer,
                                    bias,
                                    list(input_shape) if input_shape else None)

class Embedding(KerasLayer):
    """
    >>> embedding = Embedding(1000, 32, input_shape=(10, ))
    creating: createKerasEmbedding
    """
    def __init__(self, input_dim, output_dim, init='uniform',
                 W_regularizer=None, input_shape=None, bigdl_type="float"):
        super(Embedding, self).__init__(None, bigdl_type,
                                        input_dim,
                                        output_dim,
                                        init,
                                        W_regularizer,
                                        list(input_shape) if input_shape else None)

class BatchNormalization(KerasLayer):
    """
    >>> batchNormalization = BatchNormalization(input_shape=(3, 12, 12))
    creating: createKerasBatchNormalization
    """
    def __init__(self, epsilon=0.001, momentum=0.99, beta_init='zero', gamma_init='one',
                 dim_ordering="th", input_shape=None, bigdl_type="float"):
        super(BatchNormalization, self).__init__(None, bigdl_type,
                                                 epsilon,
                                                 momentum,
                                                 beta_init,
                                                 gamma_init,
                                                 dim_ordering,
                                                 list(input_shape) if input_shape else None)

    def set_running_mean(self, running_mean):
        callBigDlFunc(self.bigdl_type, "setKerasRunningMean",
                      self.value, JTensor.from_ndarray(running_mean))
        return self

    def set_running_std(self, running_std):
        callBigDlFunc(self.bigdl_type, "setKerasRunningStd",
                      self.value, JTensor.from_ndarray(running_std))
        return self

    def get_running_mean(self):
        return callBigDlFunc(self.bigdl_type, "getKerasRunningMean",
                             self.value).to_ndarray()

    def get_running_std(self):
        return callBigDlFunc(self.bigdl_type, "getKerasRunningStd",
                      self.value).to_ndarray()

class Merge(KerasLayer):
    """
    >>> l1 = InputLayer(input_shape=(3, 5))
    creating: createKerasInputLayer
    >>> l2 = InputLayer(input_shape=(3, 5))
    creating: createKerasInputLayer
    >>> merge = Merge(layers=[l1, l2], mode='sum')
    creating: createKerasMerge
    """
    def __init__(self, layers=None, mode='sum', concat_axis=-1,
                 input_shape=None, bigdl_type="float"):
        super(Merge, self).__init__(None, bigdl_type,
                                    list(layers) if layers else None,
                                    mode,
                                    concat_axis,
                                    input_shape)
<|endoftext|>


<commit_before>from EXOSIMS.Prototypes.SurveySimulation import SurveySimulation
import astropy.units as u
import numpy as np
from ortools.linear_solver import pywraplp
from scipy.optimize import minimize,minimize_scalar

class SLSQPScheduler(SurveySimulation):
    """SLSQPScheduler

    This class implements a continuous optimization of integration times
    using the scipy minimize function with method SLSQP.  ortools with the CBC
    linear solver is used to find an initial solution consistent with the constraints.
    For details see Savransky et al. 2017 (SPIE).

    Args:
        \*\*specs:
            user specified values

    Notes:
        Due to the time costs of the current comp_per_inttime calculation in GarrettCompleteness
        this should be used with BrownCompleteness.

        Requires ortools

    """

    def __init__(self, optt0=None, staticOptTimes=False, **specs):

        #initialize the prototype survey
        SurveySimulation.__init__(self, **specs)

        assert isinstance(staticOptTimes, bool), 'staticOptTimes must be boolean.'
        self.staticOptTimes = staticOptTimes

        self._outspec['staticOptTimes'] = self.staticOptTimes

        #some global defs
        self.detmode = filter(lambda mode: mode['detectionMode'] == True, self.OpticalSystem.observingModes)[0]
        self.ohTimeTot = self.Observatory.settlingTime + self.detmode['syst']['ohTime']
        self.maxTime = self.TimeKeeping.missionLife*self.TimeKeeping.missionPortion

        self.constraints = {'type':'ineq',
                            'fun': lambda x: self.maxTime.to(u.d).value - np.sum(x[x*u.d > 0.1*u.s]) -
                                             np.sum(x*u.d > 0.1*u.s).astype(float)*self.ohTimeTot.to(u.d).value,
                            'jac':lambda x: np.ones(len(x))*-1.}

        if optt0 is None:
            #find nominal background counts for all targets in list
            _, Cbs, Csps = self.OpticalSystem.Cp_Cb_Csp(self.TargetList, range(self.TargetList.nStars),
                    self.ZodiacalLight.fZ0, self.ZodiacalLight.fEZ0, 25.0, self.WAint, self.detmode)

            #find baseline solution with dMagLim-based integration times
            self.vprint('Finding baseline fixed-time optimal target set.')
            t0 = self.OpticalSystem.calc_intTime(self.TargetList, range(self.TargetList.nStars),
                    self.ZodiacalLight.fZ0, self.ZodiacalLight.fEZ0, self.dMagint, self.WAint, self.detmode)
            comp0 = self.Completeness.comp_per_intTime(t0, self.TargetList, range(self.TargetList.nStars),
                    self.ZodiacalLight.fZ0, self.ZodiacalLight.fEZ0, self.WAint, self.detmode, C_b=Cbs, C_sp=Csps)

            solver = pywraplp.Solver('SolveIntegerProblem',pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
            xs = [ solver.IntVar(0.0,1.0, 'x'+str(j)) for j in range(len(comp0)) ]

            #constraint is x_i*t_i < maxtime
            constraint = solver.Constraint(-solver.infinity(),self.maxTime.to(u.day).value)
            for j,x in enumerate(xs):
                constraint.SetCoefficient(x, t0[j].to(u.day).value + self.ohTimeTot.to(u.day).value)

            #objective is max x_i*comp_i
            objective = solver.Objective()
            for j,x in enumerate(xs):
                objective.SetCoefficient(x, comp0[j])
            objective.SetMaximization()

            cpres = solver.Solve()
            x0 = np.array([x.solution_value() for x in xs])
            self.scomp0 = np.sum(comp0*x0)
            self.t0 = t0

            #now find the optimal eps baseline and use whichever gives you the highest starting completeness
            self.vprint('Finding baseline fixed-eps optimal target set.')
            def totCompfeps(eps):
                compstars,tstars,x = self.inttimesfeps(eps, Cbs.to('1/d').value, Csps.to('1/d').value)
                return -np.sum(compstars*x)
            epsres = minimize_scalar(totCompfeps,method='bounded',bounds = [0,1],options = {'disp':True})
            comp_epsmax,t_epsmax,x_epsmax = self.inttimesfeps(epsres['x'],Cbs.to('1/d').value, Csps.to('1/d').value)
            if np.sum(comp_epsmax*x_epsmax) > self.scomp0:
                x0 = x_epsmax
                self.scomp0 = np.sum(comp_epsmax*x_epsmax)
                self.t0 = t_epsmax*u.day

            #now optimize the solution
            self.vprint('Optimizing baseline integration times.')
            sInds = np.arange(self.TargetList.nStars)
            fZ = np.array([self.ZodiacalLight.fZ0.value]*len(sInds))*self.ZodiacalLight.fZ0.unit
            bounds = [(0,self.maxTime.to(u.d).value) for i in range(len(sInds))]
            initguess = x0*self.t0.to(u.d).value
            ires = minimize(self.objfun, initguess, jac=self.objfun_deriv, args=(sInds,fZ),
                    constraints=self.constraints, method='SLSQP', bounds=bounds, options={'maxiter':100,'ftol':1e-4})

            assert ires['success'], "Initial time optimization failed."

            self.t0 = ires['x']*u.d
            self.scomp0 = -ires['fun']
        else:
            self.t0 = optt0
            sInds = np.arange(self.TargetList.nStars)
            fZ = np.array([self.ZodiacalLight.fZ0.value]*len(sInds))*self.ZodiacalLight.fZ0.unit
            self.scomp0 = -self.objfun(self.t0.to(u.d).value,sInds,fZ)

    def inttimesfeps(self,eps,Cb,Csp):
        """
        Compute the optimal subset of targets for a given epsilon value
        where epsilon is the maximum completeness gradient.

        Everything is in units of days
        """

        tstars = (-Cb*eps*np.sqrt(np.log(10)) + np.sqrt((Cb*eps)**2.*np.log(10) +
                   5*Cb*Csp**2.*eps))/(2.0*Csp**2.*eps*np.log(10))
        compstars = self.Completeness.comp_per_intTime(tstars*u.day, self.TargetList,
                np.arange(self.TargetList.nStars), self.ZodiacalLight.fZ0,
                self.ZodiacalLight.fEZ0, self.WAint, self.detmode, C_b=Cb/u.d, C_sp=Csp/u.d)

        solver = pywraplp.Solver('SolveIntegerProblem',pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
        xs = [ solver.IntVar(0.0,1.0, 'x'+str(j)) for j in range(len(compstars)) ]
        constraint = solver.Constraint(-solver.infinity(), self.maxTime.to(u.d).value)

        for j,x in enumerate(xs):
            constraint.SetCoefficient(x, tstars[j] + self.ohTimeTot.to(u.day).value)

        objective = solver.Objective()
        for j,x in enumerate(xs):
            objective.SetCoefficient(x, compstars[j])
        objective.SetMaximization()

        cpres = solver.Solve()

        x = np.array([x.solution_value() for x in xs])

        return compstars,tstars,x

    def objfun(self,t,sInds,fZ):
        """
        Objective Function for SLSQP minimization. Purpose is to maximize summed completeness

        Args:
            t (ndarray):
                Integration times in days. NB: NOT an astropy quantity.
            sInds (ndarray):
                Target star indices (of same size as t)
            fZ (astropy Quantity):
                Surface brightness of local zodiacal light in units of 1/arcsec2
                Same size as t

        """
        good = t*u.d >= 0.1*u.s

        comp = self.Completeness.comp_per_intTime(t[good]*u.d, self.TargetList, sInds[good], fZ[good],
                self.ZodiacalLight.fEZ0, self.WAint[sInds][good], self.detmode)

        return -comp.sum()

    def objfun_deriv(self,t,sInds,fZ):
        """
        Jacobian of objective Function for SLSQP minimization.

        Args:
            t (astropy Quantity):
                Integration times in days. NB: NOT an astropy quantity.
            sInds (ndarray):
                Target star indices (of same size as t)
            fZ (astropy Quantity):
                Surface brightness of local zodiacal light in units of 1/arcsec2
                Same size as t

        """
        good = t*u.d >= 0.1*u.s

        tmp = self.Completeness.dcomp_dt(t[good]*u.d, self.TargetList, sInds[good], fZ[good],
                self.ZodiacalLight.fEZ0, self.WAint[sInds][good], self.detmode).to("1/d").value

        jac = np.zeros(len(t))
        jac[good] = tmp
        return -jac

    def calc_targ_intTime(self, sInds, startTimes, mode):
        """
        Given a subset of targets, calculate their integration times given the
        start of observation time.

        This implementation updates the optimized times based on current conditions and
        mission time left.

        Note: next_target filter will discard targets with zero integration times.

        Args:
            sInds (integer array):
                Indices of available targets
            startTimes (astropy quantity array):
                absolute start times of observations.
                must be of the same size as sInds
            mode (dict):
                Selected observing mode for detection

        Returns:
            intTimes (astropy Quantity array):
                Integration times for detection
                same dimension as sInds
        """

        if self.staticOptTimes:
            intTimes = self.t0[sInds]
        else:
            # assumed values for detection
            fZ = self.ZodiacalLight.fZ(self.Observatory, self.TargetList, sInds, startTimes, mode)

            timeLeft = (self.TimeKeeping.missionFinishNorm - self.TimeKeeping.currentTimeNorm)*self.TimeKeeping.missionPortion
            bounds = [(0,timeLeft.to(u.d).value) for i in range(len(sInds))]

            initguess = self.t0[sInds].to(u.d).value
            ires = minimize(self.objfun, initguess, jac=self.objfun_deriv, args=(sInds,fZ), constraints=self.constraints,
                    method='SLSQP', bounds=bounds, options={'maxiter':100,'ftol':1e-4})

            #update default times for these targets
            self.t0[sInds] = ires['x']*u.d

            intTimes = ires['x']*u.d

        intTimes[intTimes < 0.1*u.s] = 0.0*u.d

        return intTimes

    def choose_next_target(self, old_sInd, sInds, slewTimes, intTimes):
        """

        Given a subset of targets (pre-filtered by method next_target or some
        other means), select the best next one.

        Args:
            old_sInd (integer):
                Index of the previous target star
            sInds (integer array):
                Indices of available targets
            slewTimes (astropy quantity array):
                slew times to all stars (must be indexed by sInds)
            intTimes (astropy Quantity array):
                Integration times for detection in units of day

        Returns:
            sInd (integer):
                Index of next target star

        """

        # calcualte completeness values for current intTimes
        fZ = self.ZodiacalLight.fZ(self.Observatory, self.TargetList, sInds,
                self.TimeKeeping.currentTimeAbs + slewTimes[sInds], self.detmode)
        comps = self.Completeness.comp_per_intTime(intTimes, self.TargetList, sInds, fZ,
                self.ZodiacalLight.fEZ0, self.WAint[sInds], self.detmode)

        # choose target with maximum completeness
        sInd = np.random.choice(sInds[comps == max(comps)])

        return sInd

<commit_msg>adding caching to SLSQPscheduler and increasing verbosity on optimization runs<commit_after>from EXOSIMS.Prototypes.SurveySimulation import SurveySimulation
import astropy.units as u
import numpy as np
from ortools.linear_solver import pywraplp
from scipy.optimize import minimize,minimize_scalar
import hashlib
import inspect,os
try:
    import cPickle as pickle
except:
    import pickle

class SLSQPScheduler(SurveySimulation):
    """SLSQPScheduler

    This class implements a continuous optimization of integration times
    using the scipy minimize function with method SLSQP.  ortools with the CBC
    linear solver is used to find an initial solution consistent with the constraints.
    For details see Savransky et al. 2017 (SPIE).

    Args:
        \*\*specs:
            user specified values

    Notes:
        Due to the time costs of the current comp_per_inttime calculation in GarrettCompleteness
        this should be used with BrownCompleteness.

        Requires ortools

    """

    def __init__(self, cacheOptTimes=False, staticOptTimes=False, **specs):

        #initialize the prototype survey
        SurveySimulation.__init__(self, **specs)

        assert isinstance(staticOptTimes, bool), 'staticOptTimes must be boolean.'
        self.staticOptTimes = staticOptTimes
        self._outspec['staticOptTimes'] = self.staticOptTimes

        assert isinstance(cacheOptTimes, bool), 'cacheOptTimes must be boolean.'
        self._outspec['cacheOptTimes'] = cacheOptTimes

        #some global defs
        self.detmode = filter(lambda mode: mode['detectionMode'] == True, self.OpticalSystem.observingModes)[0]
        self.ohTimeTot = self.Observatory.settlingTime + self.detmode['syst']['ohTime']
        self.maxTime = self.TimeKeeping.missionLife*self.TimeKeeping.missionPortion

        self.constraints = {'type':'ineq',
                            'fun': lambda x: self.maxTime.to(u.d).value - np.sum(x[x*u.d > 0.1*u.s]) -
                                             np.sum(x*u.d > 0.1*u.s).astype(float)*self.ohTimeTot.to(u.d).value,
                            'jac':lambda x: np.ones(len(x))*-1.}

        self.t0 = None
        if cacheOptTimes:
            cachefname = ''
            mods =  ['PlanetPopulation','PlanetPhysicalModel','Completeness','TargetList','OpticalSystem']
            for mod in mods: cachefname += self.modules[mod].__module__.split(".")[-1]
            cachefname += hashlib.md5(str(self.TargetList.Name)+str(self.TargetList.tint0.to(u.d).value)).hexdigest()
            cachefname = os.path.join(os.path.split(inspect.getfile(self.__class__))[0],cachefname+os.extsep+'t0')

            if os.path.isfile(cachefname):
                self.vprint("Loading cached t0 from %s"%cachefname)
                with open(cachefname, 'rb') as f:
                    self.t0 = pickle.load(f)
                sInds = np.arange(self.TargetList.nStars)
                fZ = np.array([self.ZodiacalLight.fZ0.value]*len(sInds))*self.ZodiacalLight.fZ0.unit
                self.scomp0 = -self.objfun(self.t0.to(u.d).value,sInds,fZ)

        if self.t0 is None:
            #find nominal background counts for all targets in list
            _, Cbs, Csps = self.OpticalSystem.Cp_Cb_Csp(self.TargetList, range(self.TargetList.nStars),
                    self.ZodiacalLight.fZ0, self.ZodiacalLight.fEZ0, 25.0, self.WAint, self.detmode)

            #find baseline solution with dMagLim-based integration times
            self.vprint('Finding baseline fixed-time optimal target set.')
            t0 = self.OpticalSystem.calc_intTime(self.TargetList, range(self.TargetList.nStars),
                    self.ZodiacalLight.fZ0, self.ZodiacalLight.fEZ0, self.dMagint, self.WAint, self.detmode)
            comp0 = self.Completeness.comp_per_intTime(t0, self.TargetList, range(self.TargetList.nStars),
                    self.ZodiacalLight.fZ0, self.ZodiacalLight.fEZ0, self.WAint, self.detmode, C_b=Cbs, C_sp=Csps)

            solver = pywraplp.Solver('SolveIntegerProblem',pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
            xs = [ solver.IntVar(0.0,1.0, 'x'+str(j)) for j in range(len(comp0)) ]

            #constraint is x_i*t_i < maxtime
            constraint = solver.Constraint(-solver.infinity(),self.maxTime.to(u.day).value)
            for j,x in enumerate(xs):
                constraint.SetCoefficient(x, t0[j].to(u.day).value + self.ohTimeTot.to(u.day).value)

            #objective is max x_i*comp_i
            objective = solver.Objective()
            for j,x in enumerate(xs):
                objective.SetCoefficient(x, comp0[j])
            objective.SetMaximization()

            cpres = solver.Solve()
            x0 = np.array([x.solution_value() for x in xs])
            self.scomp0 = np.sum(comp0*x0)
            self.t0 = t0

            #now find the optimal eps baseline and use whichever gives you the highest starting completeness
            self.vprint('Finding baseline fixed-eps optimal target set.')
            def totCompfeps(eps):
                compstars,tstars,x = self.inttimesfeps(eps, Cbs.to('1/d').value, Csps.to('1/d').value)
                return -np.sum(compstars*x)
            epsres = minimize_scalar(totCompfeps,method='bounded',bounds = [0,1],options = {'disp':True})
            comp_epsmax,t_epsmax,x_epsmax = self.inttimesfeps(epsres['x'],Cbs.to('1/d').value, Csps.to('1/d').value)
            if np.sum(comp_epsmax*x_epsmax) > self.scomp0:
                x0 = x_epsmax
                self.scomp0 = np.sum(comp_epsmax*x_epsmax)
                self.t0 = t_epsmax*u.day

            #now optimize the solution
            self.vprint('Optimizing baseline integration times.')
            sInds = np.arange(self.TargetList.nStars)
            fZ = np.array([self.ZodiacalLight.fZ0.value]*len(sInds))*self.ZodiacalLight.fZ0.unit
            bounds = [(0,self.maxTime.to(u.d).value) for i in range(len(sInds))]
            initguess = x0*self.t0.to(u.d).value
            ires = minimize(self.objfun, initguess, jac=self.objfun_deriv, args=(sInds,fZ),
                    constraints=self.constraints, method='SLSQP', bounds=bounds, options={'maxiter':100,'ftol':1e-4})

            assert ires['success'], "Initial time optimization failed."

            self.t0 = ires['x']*u.d
            self.scomp0 = -ires['fun']

            if cacheOptTimes:
                with open(cachefname,'wb') as f:
                    pickle.dump(self.t0, f)
                self.vprint("Saved cached optimized t0 to %s"%cachefname)

    def inttimesfeps(self,eps,Cb,Csp):
        """
        Compute the optimal subset of targets for a given epsilon value
        where epsilon is the maximum completeness gradient.

        Everything is in units of days
        """

        tstars = (-Cb*eps*np.sqrt(np.log(10)) + np.sqrt((Cb*eps)**2.*np.log(10) +
                   5*Cb*Csp**2.*eps))/(2.0*Csp**2.*eps*np.log(10))
        compstars = self.Completeness.comp_per_intTime(tstars*u.day, self.TargetList,
                np.arange(self.TargetList.nStars), self.ZodiacalLight.fZ0,
                self.ZodiacalLight.fEZ0, self.WAint, self.detmode, C_b=Cb/u.d, C_sp=Csp/u.d)

        solver = pywraplp.Solver('SolveIntegerProblem',pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
        xs = [ solver.IntVar(0.0,1.0, 'x'+str(j)) for j in range(len(compstars)) ]
        constraint = solver.Constraint(-solver.infinity(), self.maxTime.to(u.d).value)

        for j,x in enumerate(xs):
            constraint.SetCoefficient(x, tstars[j] + self.ohTimeTot.to(u.day).value)

        objective = solver.Objective()
        for j,x in enumerate(xs):
            objective.SetCoefficient(x, compstars[j])
        objective.SetMaximization()

        cpres = solver.Solve()

        x = np.array([x.solution_value() for x in xs])

        return compstars,tstars,x

    def objfun(self,t,sInds,fZ):
        """
        Objective Function for SLSQP minimization. Purpose is to maximize summed completeness

        Args:
            t (ndarray):
                Integration times in days. NB: NOT an astropy quantity.
            sInds (ndarray):
                Target star indices (of same size as t)
            fZ (astropy Quantity):
                Surface brightness of local zodiacal light in units of 1/arcsec2
                Same size as t

        """
        good = t*u.d >= 0.1*u.s

        comp = self.Completeness.comp_per_intTime(t[good]*u.d, self.TargetList, sInds[good], fZ[good],
                self.ZodiacalLight.fEZ0, self.WAint[sInds][good], self.detmode)

        return -comp.sum()

    def objfun_deriv(self,t,sInds,fZ):
        """
        Jacobian of objective Function for SLSQP minimization.

        Args:
            t (astropy Quantity):
                Integration times in days. NB: NOT an astropy quantity.
            sInds (ndarray):
                Target star indices (of same size as t)
            fZ (astropy Quantity):
                Surface brightness of local zodiacal light in units of 1/arcsec2
                Same size as t

        """
        good = t*u.d >= 0.1*u.s

        tmp = self.Completeness.dcomp_dt(t[good]*u.d, self.TargetList, sInds[good], fZ[good],
                self.ZodiacalLight.fEZ0, self.WAint[sInds][good], self.detmode).to("1/d").value

        jac = np.zeros(len(t))
        jac[good] = tmp
        return -jac

    def calc_targ_intTime(self, sInds, startTimes, mode):
        """
        Given a subset of targets, calculate their integration times given the
        start of observation time.

        This implementation updates the optimized times based on current conditions and
        mission time left.

        Note: next_target filter will discard targets with zero integration times.

        Args:
            sInds (integer array):
                Indices of available targets
            startTimes (astropy quantity array):
                absolute start times of observations.
                must be of the same size as sInds
            mode (dict):
                Selected observing mode for detection

        Returns:
            intTimes (astropy Quantity array):
                Integration times for detection
                same dimension as sInds
        """

        if self.staticOptTimes:
            intTimes = self.t0[sInds]
        else:
            # assumed values for detection
            fZ = self.ZodiacalLight.fZ(self.Observatory, self.TargetList, sInds, startTimes, mode)

            timeLeft = (self.TimeKeeping.missionFinishNorm - self.TimeKeeping.currentTimeNorm)*self.TimeKeeping.missionPortion
            bounds = [(0,timeLeft.to(u.d).value) for i in range(len(sInds))]

            initguess = self.t0[sInds].to(u.d).value
            ires = minimize(self.objfun, initguess, jac=self.objfun_deriv, args=(sInds,fZ), constraints=self.constraints,
                    method='SLSQP', bounds=bounds, options={'disp':True,'maxiter':100,'ftol':1e-4})

            #update default times for these targets
            self.t0[sInds] = ires['x']*u.d

            intTimes = ires['x']*u.d

        intTimes[intTimes < 0.1*u.s] = 0.0*u.d

        return intTimes

    def choose_next_target(self, old_sInd, sInds, slewTimes, intTimes):
        """

        Given a subset of targets (pre-filtered by method next_target or some
        other means), select the best next one.

        Args:
            old_sInd (integer):
                Index of the previous target star
            sInds (integer array):
                Indices of available targets
            slewTimes (astropy quantity array):
                slew times to all stars (must be indexed by sInds)
            intTimes (astropy Quantity array):
                Integration times for detection in units of day

        Returns:
            sInd (integer):
                Index of next target star

        """

        # calcualte completeness values for current intTimes
        fZ = self.ZodiacalLight.fZ(self.Observatory, self.TargetList, sInds,
                self.TimeKeeping.currentTimeAbs + slewTimes[sInds], self.detmode)
        comps = self.Completeness.comp_per_intTime(intTimes, self.TargetList, sInds, fZ,
                self.ZodiacalLight.fEZ0, self.WAint[sInds], self.detmode)

        # choose target with maximum completeness
        sInd = np.random.choice(sInds[comps == max(comps)])

        return sInd

<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Helps to compile IronPython scripts, using pyc.py.

This library helps you compile your IronPython scripts requiring the
Python standard library (or third-party pure-Python modules) into a
.NET assembly, using pyc.py.

.. note :: This library should be used on **CPython**, not IronPython,
           because :mod:`modulefinder` of IronPython does not work
           correctly.
"""

__author__ = "Hamukichi (Nombiri)"
__version__ = "0.9.0alpha"
__date__ = "2014-03-23"
__licence__ = "MIT License"

<commit_msg>Re-corrected __version__<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Helps to compile IronPython scripts, using pyc.py.

This library helps you compile your IronPython scripts requiring the
Python standard library (or third-party pure-Python modules) into a
.NET assembly, using pyc.py.

.. note :: This library should be used on **CPython**, not IronPython,
           because :mod:`modulefinder` of IronPython does not work
           correctly.
"""

__author__ = "Hamukichi (Nombiri)"
__version__ = "0.9.0.alpha"
__date__ = "2014-03-23"
__licence__ = "MIT License"

<|endoftext|>


<commit_before>import django_filters
from django_filters.fields import Lookup
from django_filters.filterset import STRICTNESS
from django.db.models import Q
from django import forms

from isisdata.models import *
from zotero.models import ImportAccession
from isisdata.helper_methods import strip_punctuation
import six, iso8601
from unidecode import unidecode
from curation.tracking import TrackingWorkflow
from django_filters import filters

filters.LOOKUP_TYPES = [
    ('', '---------'),
    ('exact', 'Is equal to'),
    ('not_exact', 'Is not equal to'),
    ('lt', 'Lesser than'),
    ('gt', 'Greater than'),
    ('gte', 'Greater than or equal to'),
    ('lte', 'Lesser than or equal to'),
    ('startswith', 'Starts with'),
    ('endswith', 'Ends with'),
    ('icontains', 'Contains'),
    ('not_contains', 'Does not contain'),
]

# class ChoiceMethodFilter(django_filters.MethodFilter, django_filters.ChoiceFilter):
#     pass

def filter_in_collections(queryset, value):
    if not value:
        return queryset
    q = Q()
    for collection in value:
        q |= Q(in_collections=collection)

    return queryset.filter(q)

class CitationFilter(django_filters.FilterSet):
    strict = STRICTNESS.RETURN_NO_RESULTS
    # strict = STRICTNESS.RAISE_VALIDATION_ERROR

    # id = django_filters.MethodFilter(name='id', lookup_type='exact')
    id = django_filters.CharFilter(method='filter_id')
    # title = django_filters.MethodFilter(name='title', lookup_type='icontains')
    title = django_filters.CharFilter(method='filter_title')
    type_controlled = django_filters.ChoiceFilter(choices=[('', 'All')] + list(Citation.TYPE_CHOICES))
    # publication_date_from = django_filters.MethodFilter()
    publication_date_from = django_filters.CharFilter(method='filter_publication_date_from')
    # publication_date_to = django_filters.MethodFilter()
    publication_date_to = django_filters.CharFilter(method='filter_publication_date_to')
    # abstract = django_filters.MethodFilter(name='abstract', lookup_type='icontains')
    abstract = django_filters.CharFilter(method='filter_abstract')
    # description = django_filters.MethodFilter(name='description', lookup_type='icontains')
    description = django_filters.CharFilter(method='filter_description')

    # author_or_editor = django_filters.MethodFilter()
    author_or_editor = django_filters.CharFilter(method='filter_author_or_editor')
    # periodical = django_filters.MethodFilter()
    periodical = django_filters.CharFilter(method='filter_periodical')
    # publisher = django_filters.MethodFilter()
    publisher = django_filters.CharFilter(method='filter_publisher')
    # subject = django_filters.MethodFilter()
    subject = django_filters.CharFilter(method='filter_subject')

    record_status = django_filters.ChoiceFilter(name='record_status_value', choices=[('', 'All')] + list(CuratedMixin.STATUS_CHOICES))
    in_collections = django_filters.CharFilter(method='filter_in_collections', widget=forms.HiddenInput())
    zotero_accession = django_filters.CharFilter(widget=forms.HiddenInput())
    belongs_to = django_filters.CharFilter(widget=forms.HiddenInput())

    tracking_state = django_filters.ChoiceFilter(choices=[('', 'All')] + list(Tracking.TYPE_CHOICES), method='filter_tracking_state')

    # language = django_filters.ModelChoiceFilter(name='language', queryset=Language.objects.all())

    # order = ChoiceMethodFilter(name='order', choices=order_by)

    def __init__(self, *args, **kwargs):
        super(CitationFilter, self).__init__(*args, **kwargs)

        in_coll = self.data.get('in_collections', None)
        if in_coll:
            try:
                collection = CitationCollection.objects.get(pk=in_coll)
                if collection:
                    self.collection_name = collection.name
            except CitationCollection.DoesNotExist:
                self.collection_name = "Collection could not be found."

        zotero_acc = self.data.get('zotero_accession', None)

        if zotero_acc:
            try:
                accession = ImportAccession.objects.get(pk=zotero_acc)
                if accession:
                    self.zotero_accession_name = accession.name
                    self.zotero_accession_date = accession.imported_on
            except ImportAccession.DoesNotExist:
                self.zotero_accession_name = "Zotero accession could not be found."

        dataset = self.data.get('belongs_to', None)
        if dataset:
            try:
                ds = Dataset.objects.get(pk=dataset)
                if ds:
                    self.dataset_name = ds.name
            except Dataset.DoesNotExist:
                self.dataset_name = "Dataset could not be found."

    class Meta:
        model = Citation
        fields = [
            'id', 'title', 'abstract', 'description',
            'publication_date_from', 'publication_date_to',
            'author_or_editor', 'periodical', 'record_status',
            'belongs_to', 'zotero_accession', 'in_collections',
            'tracking_state'
        ]
        # order_by = [
        #     ('publication_date', 'Publication date (ascending)'),
        #     ('-publication_date', 'Publication date (descending)'),
        #     ('title_for_sort', 'Title (ascending)'),
        #     ('-title_for_sort', 'Title (descending)')
        # ]
    o = filters.OrderingFilter(
        # tuple-mapping retains order
        fields=(
            ('publication_date', 'publication_date'),
            ('title', 'title_for_sort'),
            ('part_details__page_begin', 'start_page')
        ),

        # labels do not need to retain order
        field_labels={
            'publication_date': 'Publication date',
            'title': 'Title',
            'start_page': 'Start page',
        }
    )

    # def get_ordering_field(self):
    #     if self._meta.order_by:
    #         if isinstance(self._meta.order_by, (list, tuple)):
    #             if isinstance(self._meta.order_by[0], (list, tuple)):
    #                 # e.g. (('field', 'Display name'), ...)
    #                 choices = [(f[0], f[1]) for f in self._meta.order_by]
    #             else:
    #                 choices = []
    #                 for f in self._meta.order_by:
    #                     if f[0] == '-':
    #                         label = _('%s (descending)' % capfirst(f[1:]))
    #                     else:
    #                         label = capfirst(f)
    #                     choices.append((f, label))
    #         else:
    #             # add asc and desc field names
    #             # use the filter's label if provided
    #             choices = []
    #             for f, fltr in self.filters.items():
    #                 choices.extend([
    #                     (f, fltr.label or capfirst(f)),
    #                     ("-%s" % (f), _('%s (descending)' % (fltr.label or capfirst(f))))
    #                 ])
    #         return forms.ChoiceField(widget=forms.HiddenInput(attrs={'value':"publication_date"}), choices=choices, initial="publication_date")

    def filter_id(self, queryset, name, value):
        if not value:
            return queryset

        ids = [i.strip() for i in value.split(',')]
        queryset = queryset.filter(pk__in=ids)
        return queryset

    def filter_title(self, queryset, name, value):
        value = unidecode(value)
        if not value:
            return queryset
        for part in value.split():
            queryset = queryset.filter(title_for_sort__icontains=part)
        return queryset

    def filter_abstract(self, queryset, name, value):
        if not value:
            return queryset
        for part in value.split():
            queryset = queryset.filter(abstract__icontains=part)
        return queryset

    def filter_description(self, queryset, name, value):
        if not value:
            return queryset
        for part in value.split():
            queryset = queryset.filter(description__icontains=part)
        return queryset

    def filter_publication_date_from(self, queryset, name, value):
        try:
            date = iso8601.parse_date(value)
        except:
            return queryset
        return queryset.filter(publication_date__gte=date)

    def filter_publication_date_to(self, queryset, name, value):
        try:
            date = iso8601.parse_date(value)
        except:
            return queryset
        return queryset.filter(publication_date__lte=date)

    def filter_author_or_editor(self, queryset, name, value):
        if not value:
            return queryset
        for part in value.split():
            queryset = queryset.filter(
                        acrelation__authority__name__icontains=part,
                        acrelation__type_controlled__in=[
                                    ACRelation.AUTHOR,
                                    ACRelation.EDITOR])
        return queryset

    def filter_periodical(self, queryset, name, value):
        if not value:
            return queryset
        return queryset.filter(acrelation__authority__name__icontains=value,
                               acrelation__type_controlled__in=[
                                    ACRelation.PERIODICAL,
                                    ACRelation.BOOK_SERIES])

    def filter_publisher(self, queryset, name, value):
        if not value:
            return queryset
        return queryset.filter(acrelation__authority__name__icontains=value,
                               acrelation__type_controlled=ACRelation.PUBLISHER)

    def filter_subject(self, queryset, name, value):
        if not value:
            return queryset
        return queryset.filter(acrelation__authority__name__icontains=value,
                               acrelation__type_controlled=ACRelation.SUBJECT)

    def filter_tracking_state(self, queryset, field, value):
        if not value:
            return queryset

        q = Q(tracking_records__type_controlled=value)

        next_state = TrackingWorkflow.stages.get(value)
        # if next_state:
        #     q &= ~Q(tracking_records__type_controlled=next_state)
        return queryset.filter(q)

class AuthorityFilter(django_filters.FilterSet):
    strict = STRICTNESS.RAISE_VALIDATION_ERROR # RETURN_NO_RESULTS

    id = django_filters.CharFilter(name='id', lookup_expr='exact')
    # name = django_filters.MethodFilter()
    name = django_filters.CharFilter(method='filter_name')
    type_controlled = django_filters.ChoiceFilter(choices=[('', 'All')] + list(Authority.TYPE_CHOICES))
    description = django_filters.CharFilter(name='description', lookup_expr='icontains')
    classification_system = django_filters.ChoiceFilter(name='classification_system', choices=[('', 'All')] + list(Authority.CLASS_SYSTEM_CHOICES))
    classification_code = django_filters.AllValuesFilter(name='classification_code')
    classification_hierarchy = django_filters.AllValuesFilter(name='classification_hierarchy')
    # linked_data = django_filters.MethodFilter()
    linked_data = django_filters.CharFilter(method='filter_linked_data')

    record_status_value = django_filters.ChoiceFilter(name='record_status_value', choices=[('', 'All')] + list(CuratedMixin.STATUS_CHOICES))

    datasets = Dataset.objects.all()
    dataset_list = [(ds.pk, ds.name) for ds in datasets ]
    belongs_to = django_filters.ChoiceFilter(choices=[('', 'All')] + dataset_list)

    class Meta:
        model = Authority
        fields = [
            'id', 'name', 'type_controlled', 'description',
            'classification_system', 'classification_code',
            'classification_hierarchy', 'zotero_accession',
            'belongs_to']

        # order_by = [
        #     ('', 'None'),
        #     ('name_for_sort', 'Name (ascending)'),
        #     ('-name_for_sort', 'Name (descending)')
        # ]

    o = filters.OrderingFilter(
        # tuple-mapping retains order
        fields=(
            ('name', 'name_for_sort'),
        ),

        # labels do not need to retain order
        field_labels={
            'name': 'Name'
        }
    )

    def filter_name(self, queryset, name, value):
        value = unidecode(value)
        if not value:
            return queryset
        for part in value.split():
            queryset = queryset.filter(name_for_sort__icontains=part)

        return queryset

    def filter_linked_data(self, queryset, name, value):
        if not value:
            return queryset
        authority_ids = LinkedData.objects\
                            .filter(universal_resource_name__contains=value)\
                            .values_list('authorities__id', flat=True)\
                            .distinct()

        if len(authority_ids) == 1 and authority_ids[0] is None:
            return queryset.none()
        return queryset.filter(pk__in=authority_ids)
<commit_msg>hotfix for citationfilter<commit_after>import django_filters
from django_filters.fields import Lookup
from django_filters.filterset import STRICTNESS
from django.db.models import Q
from django import forms

from isisdata.models import *
from zotero.models import ImportAccession
from isisdata.helper_methods import strip_punctuation
import six, iso8601
from unidecode import unidecode
from curation.tracking import TrackingWorkflow
from django_filters import filters

filters.LOOKUP_TYPES = [
    ('', '---------'),
    ('exact', 'Is equal to'),
    ('not_exact', 'Is not equal to'),
    ('lt', 'Lesser than'),
    ('gt', 'Greater than'),
    ('gte', 'Greater than or equal to'),
    ('lte', 'Lesser than or equal to'),
    ('startswith', 'Starts with'),
    ('endswith', 'Ends with'),
    ('icontains', 'Contains'),
    ('not_contains', 'Does not contain'),
]

# class ChoiceMethodFilter(django_filters.MethodFilter, django_filters.ChoiceFilter):
#     pass

class CitationFilter(django_filters.FilterSet):
    strict = STRICTNESS.RETURN_NO_RESULTS
    # strict = STRICTNESS.RAISE_VALIDATION_ERROR

    # id = django_filters.MethodFilter(name='id', lookup_type='exact')
    id = django_filters.CharFilter(method='filter_id')
    # title = django_filters.MethodFilter(name='title', lookup_type='icontains')
    title = django_filters.CharFilter(method='filter_title')
    type_controlled = django_filters.ChoiceFilter(choices=[('', 'All')] + list(Citation.TYPE_CHOICES))
    # publication_date_from = django_filters.MethodFilter()
    publication_date_from = django_filters.CharFilter(method='filter_publication_date_from')
    # publication_date_to = django_filters.MethodFilter()
    publication_date_to = django_filters.CharFilter(method='filter_publication_date_to')
    # abstract = django_filters.MethodFilter(name='abstract', lookup_type='icontains')
    abstract = django_filters.CharFilter(method='filter_abstract')
    # description = django_filters.MethodFilter(name='description', lookup_type='icontains')
    description = django_filters.CharFilter(method='filter_description')

    # author_or_editor = django_filters.MethodFilter()
    author_or_editor = django_filters.CharFilter(method='filter_author_or_editor')
    # periodical = django_filters.MethodFilter()
    periodical = django_filters.CharFilter(method='filter_periodical')
    # publisher = django_filters.MethodFilter()
    publisher = django_filters.CharFilter(method='filter_publisher')
    # subject = django_filters.MethodFilter()
    subject = django_filters.CharFilter(method='filter_subject')

    record_status = django_filters.ChoiceFilter(name='record_status_value', choices=[('', 'All')] + list(CuratedMixin.STATUS_CHOICES))
    in_collections = django_filters.CharFilter(method='filter_in_collections', widget=forms.HiddenInput())
    zotero_accession = django_filters.CharFilter(widget=forms.HiddenInput())
    belongs_to = django_filters.CharFilter(widget=forms.HiddenInput())

    tracking_state = django_filters.ChoiceFilter(choices=[('', 'All')] + list(Tracking.TYPE_CHOICES), method='filter_tracking_state')

    # language = django_filters.ModelChoiceFilter(name='language', queryset=Language.objects.all())

    # order = ChoiceMethodFilter(name='order', choices=order_by)

    def __init__(self, *args, **kwargs):
        super(CitationFilter, self).__init__(*args, **kwargs)

        in_coll = self.data.get('in_collections', None)
        if in_coll:
            try:
                collection = CitationCollection.objects.get(pk=in_coll)
                if collection:
                    self.collection_name = collection.name
            except CitationCollection.DoesNotExist:
                self.collection_name = "Collection could not be found."

        zotero_acc = self.data.get('zotero_accession', None)

        if zotero_acc:
            try:
                accession = ImportAccession.objects.get(pk=zotero_acc)
                if accession:
                    self.zotero_accession_name = accession.name
                    self.zotero_accession_date = accession.imported_on
            except ImportAccession.DoesNotExist:
                self.zotero_accession_name = "Zotero accession could not be found."

        dataset = self.data.get('belongs_to', None)
        if dataset:
            try:
                ds = Dataset.objects.get(pk=dataset)
                if ds:
                    self.dataset_name = ds.name
            except Dataset.DoesNotExist:
                self.dataset_name = "Dataset could not be found."

    class Meta:
        model = Citation
        fields = [
            'id', 'title', 'abstract', 'description',
            'publication_date_from', 'publication_date_to',
            'author_or_editor', 'periodical', 'record_status',
            'belongs_to', 'zotero_accession', 'in_collections',
            'tracking_state'
        ]
        # order_by = [
        #     ('publication_date', 'Publication date (ascending)'),
        #     ('-publication_date', 'Publication date (descending)'),
        #     ('title_for_sort', 'Title (ascending)'),
        #     ('-title_for_sort', 'Title (descending)')
        # ]
    o = filters.OrderingFilter(
        # tuple-mapping retains order
        fields=(
            ('publication_date', 'publication_date'),
            ('title', 'title_for_sort'),
            ('part_details__page_begin', 'start_page')
        ),

        # labels do not need to retain order
        field_labels={
            'publication_date': 'Publication date',
            'title': 'Title',
            'start_page': 'Start page',
        }
    )

    # def get_ordering_field(self):
    #     if self._meta.order_by:
    #         if isinstance(self._meta.order_by, (list, tuple)):
    #             if isinstance(self._meta.order_by[0], (list, tuple)):
    #                 # e.g. (('field', 'Display name'), ...)
    #                 choices = [(f[0], f[1]) for f in self._meta.order_by]
    #             else:
    #                 choices = []
    #                 for f in self._meta.order_by:
    #                     if f[0] == '-':
    #                         label = _('%s (descending)' % capfirst(f[1:]))
    #                     else:
    #                         label = capfirst(f)
    #                     choices.append((f, label))
    #         else:
    #             # add asc and desc field names
    #             # use the filter's label if provided
    #             choices = []
    #             for f, fltr in self.filters.items():
    #                 choices.extend([
    #                     (f, fltr.label or capfirst(f)),
    #                     ("-%s" % (f), _('%s (descending)' % (fltr.label or capfirst(f))))
    #                 ])
    #         return forms.ChoiceField(widget=forms.HiddenInput(attrs={'value':"publication_date"}), choices=choices, initial="publication_date")

    def filter_id(self, queryset, name, value):
        if not value:
            return queryset

        ids = [i.strip() for i in value.split(',')]
        queryset = queryset.filter(pk__in=ids)
        return queryset

    def filter_title(self, queryset, name, value):
        value = unidecode(value)
        if not value:
            return queryset
        for part in value.split():
            queryset = queryset.filter(title_for_sort__icontains=part)
        return queryset

    def filter_abstract(self, queryset, name, value):
        if not value:
            return queryset
        for part in value.split():
            queryset = queryset.filter(abstract__icontains=part)
        return queryset

    def filter_description(self, queryset, name, value):
        if not value:
            return queryset
        for part in value.split():
            queryset = queryset.filter(description__icontains=part)
        return queryset

    def filter_publication_date_from(self, queryset, name, value):
        try:
            date = iso8601.parse_date(value)
        except:
            return queryset
        return queryset.filter(publication_date__gte=date)

    def filter_publication_date_to(self, queryset, name, value):
        try:
            date = iso8601.parse_date(value)
        except:
            return queryset
        return queryset.filter(publication_date__lte=date)

    def filter_author_or_editor(self, queryset, name, value):
        if not value:
            return queryset
        for part in value.split():
            queryset = queryset.filter(
                        acrelation__authority__name__icontains=part,
                        acrelation__type_controlled__in=[
                                    ACRelation.AUTHOR,
                                    ACRelation.EDITOR])
        return queryset

    def filter_periodical(self, queryset, name, value):
        if not value:
            return queryset
        return queryset.filter(acrelation__authority__name__icontains=value,
                               acrelation__type_controlled__in=[
                                    ACRelation.PERIODICAL,
                                    ACRelation.BOOK_SERIES])

    def filter_publisher(self, queryset, name, value):
        if not value:
            return queryset
        return queryset.filter(acrelation__authority__name__icontains=value,
                               acrelation__type_controlled=ACRelation.PUBLISHER)

    def filter_subject(self, queryset, name, value):
        if not value:
            return queryset
        return queryset.filter(acrelation__authority__name__icontains=value,
                               acrelation__type_controlled=ACRelation.SUBJECT)

    def filter_tracking_state(self, queryset, field, value):
        if not value:
            return queryset

        q = Q(tracking_records__type_controlled=value)

        next_state = TrackingWorkflow.stages.get(value)
        # if next_state:
        #     q &= ~Q(tracking_records__type_controlled=next_state)
        return queryset.filter(q)

    def filter_in_collections(self, queryset, field, value):
        if not value:
            return queryset
        q = Q()
        for collection in value:
            q |= Q(in_collections=collection)

        return queryset.filter(q)

class AuthorityFilter(django_filters.FilterSet):
    strict = STRICTNESS.RAISE_VALIDATION_ERROR # RETURN_NO_RESULTS

    id = django_filters.CharFilter(name='id', lookup_expr='exact')
    # name = django_filters.MethodFilter()
    name = django_filters.CharFilter(method='filter_name')
    type_controlled = django_filters.ChoiceFilter(choices=[('', 'All')] + list(Authority.TYPE_CHOICES))
    description = django_filters.CharFilter(name='description', lookup_expr='icontains')
    classification_system = django_filters.ChoiceFilter(name='classification_system', choices=[('', 'All')] + list(Authority.CLASS_SYSTEM_CHOICES))
    classification_code = django_filters.AllValuesFilter(name='classification_code')
    classification_hierarchy = django_filters.AllValuesFilter(name='classification_hierarchy')
    # linked_data = django_filters.MethodFilter()
    linked_data = django_filters.CharFilter(method='filter_linked_data')

    record_status_value = django_filters.ChoiceFilter(name='record_status_value', choices=[('', 'All')] + list(CuratedMixin.STATUS_CHOICES))

    datasets = Dataset.objects.all()
    dataset_list = [(ds.pk, ds.name) for ds in datasets ]
    belongs_to = django_filters.ChoiceFilter(choices=[('', 'All')] + dataset_list)

    class Meta:
        model = Authority
        fields = [
            'id', 'name', 'type_controlled', 'description',
            'classification_system', 'classification_code',
            'classification_hierarchy', 'zotero_accession',
            'belongs_to']

        # order_by = [
        #     ('', 'None'),
        #     ('name_for_sort', 'Name (ascending)'),
        #     ('-name_for_sort', 'Name (descending)')
        # ]

    o = filters.OrderingFilter(
        # tuple-mapping retains order
        fields=(
            ('name', 'name_for_sort'),
        ),

        # labels do not need to retain order
        field_labels={
            'name': 'Name'
        }
    )

    def filter_name(self, queryset, name, value):
        value = unidecode(value)
        if not value:
            return queryset
        for part in value.split():
            queryset = queryset.filter(name_for_sort__icontains=part)

        return queryset

    def filter_linked_data(self, queryset, name, value):
        if not value:
            return queryset
        authority_ids = LinkedData.objects\
                            .filter(universal_resource_name__contains=value)\
                            .values_list('authorities__id', flat=True)\
                            .distinct()

        if len(authority_ids) == 1 and authority_ids[0] is None:
            return queryset.none()
        return queryset.filter(pk__in=authority_ids)
<|endoftext|>


<commit_before># Copyright 2016 TransCirrus Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# this is just for the reactive handlers and calls into the charm.
from __future__ import absolute_import

import charms.reactive as reactive
import charmhelpers.core.hookenv as hookenv

# This charm's library contains all of the handler code associated with trove
import charm.openstack.trove as trove

# use a synthetic state to ensure that it get it to be installed independent of
# the install hook.
@reactive.when_not('charm.installed')
def install_packages():
    trove.install()
    reactive.set_state('charm.installed')

@reactive.when('amqp.connected')
def setup_amqp_req(amqp):
    """Use the amqp interface to request access to the amqp broker using our
    local configuration.
    """
    amqp.request_access(username=hookenv.config('rabbit-user'),
                        vhost=hookenv.config('rabbit-vhost'))
    trove.assess_status()

@reactive.when('shared-db.connected')
def setup_database(database):
    """On receiving database credentials, configure the database on the
    interface.
    """
    database.configure(hookenv.config('database'),
                       hookenv.config('database-user'),
                       hookenv.unit_private_ip())
    trove.assess_status()

@reactive.when('identity-service.connected')
def setup_endpoint(keystone):
    trove.setup_endpoint(keystone)
    trove.assess_status()

@reactive.when('shared-db.available')
@reactive.when('identity-service.available')
@reactive.when('amqp.available')
def render_stuff(*args):
    """Render the configuration for Barbican when all the interfaces are
    available.

    Note that the HSM interface is optional (hence the @when_any) and thus is
    only used if it is available.
    """
    # Get the optional hsm relation, if it is available for rendering.
    hsm = reactive.RelationBase.from_state('hsm.available')
    if hsm is not None:
        args = args + (hsm, )
    trove.render_configs(args)
    trove.assess_status()

@reactive.when('config.changed')
def config_changed():
    """When the configuration changes, assess the unit's status to update any
    juju state required"""
    trove.assess_status()

@reactive.when('identity-service.available')
def configure_ssl(keystone):
    """Configure SSL access to Barbican if requested"""
    trove.configure_ssl(keystone)

<commit_msg>Added notes for shashaa<commit_after># Copyright 2016 TransCirrus Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# this is just for the reactive handlers and calls into the charm.
from __future__ import absolute_import

import charms.reactive as reactive
import charmhelpers.core.hookenv as hookenv

# This charm's library contains all of the handler code associated with trove
import charm.openstack.trove as trove

# use a synthetic state to ensure that it get it to be installed independent of
# the install hook.
@reactive.when_not('charm.installed')
def install_packages():
    trove.install()
    reactive.set_state('charm.installed')

@reactive.when('amqp.connected')
def setup_amqp_req(amqp):
    """Use the amqp interface to request access to the amqp broker using our
    local configuration.
    """
    amqp.request_access(username=hookenv.config('rabbit-user'),
                        vhost=hookenv.config('rabbit-vhost'))
    trove.assess_status()

@reactive.when('shared-db.connected')
def setup_database(database):
    """On receiving database credentials, configure the database on the
    interface.
    """
    database.configure(hookenv.config('database'),
                       hookenv.config('database-user'),
                       hookenv.unit_private_ip())
    trove.assess_status()

#This is for the HA cluster DB for the HA requeroment. I think we need to use this and not shared-db
#@reactive.when('cluster.available')

#this is to check if ha is running
#@reactive.when('ha.connected')

@reactive.when('identity-service.connected')
def setup_endpoint(keystone):
    trove.setup_endpoint(keystone)
    trove.assess_status()

@reactive.when('shared-db.available')
@reactive.when('identity-service.available')
@reactive.when('amqp.available')
def render_stuff(*args):
    """Render the configuration for Barbican when all the interfaces are
    available.

    Note that the HSM interface is optional (hence the @when_any) and thus is
    only used if it is available.
    """
    # Get the optional hsm relation, if it is available for rendering.
    trove.render_configs(args)
    trove.assess_status()

@reactive.when('config.changed')
def config_changed():
    """When the configuration changes, assess the unit's status to update any
    juju state required"""
    trove.assess_status()

@reactive.when('identity-service.available')
def configure_ssl(keystone):
    """Configure SSL access to Barbican if requested"""
    trove.configure_ssl(keystone)

#when cloud-compute.available

#when image-service.available

#when cinder - I need to find out what juju calls this

#when heat - I need to find out what juju calls this

#when ceph.available
<|endoftext|>


<commit_before>"""Computes the least-squares optimal Keplerian elements for a sequence of
   cartesian position observations.
"""

import math
#import numpy as np
#Thinly-wrapped numpy
import autograd.numpy as np
import matplotlib.pyplot as plt
from autograd import grad
from autograd import jacobian
from autograd import elementwise_grad as egrad

# convention:
# a: semi-major axis
# e: eccentricity
# eps: mean longitude at epoch
# taup: time of pericenter passage
# Euler angles:
# I: inclination
# Omega: longitude of ascending node
# omega: argument of pericenter

#rotation about the z-axis about an angle `ang`
def rotz(ang):
    cos_ang = np.cos(ang)
    sin_ang = np.sin(ang)
    return np.array(((cos_ang,-sin_ang,0.0), (sin_ang, cos_ang,0.0), (0.0,0.0,1.0)))

#rotation about the x-axis about an angle `ang`
def rotx(ang):
    cos_ang = np.cos(ang)
    sin_ang = np.sin(ang)
    return np.array(((1.0,0.0,0.0), (0.0,cos_ang,-sin_ang), (0.0,sin_ang,cos_ang)))

#rotation from the orbital plane to the inertial frame
#it is composed of the following rotations, in that order:
#1) rotation about the z axis about an angle `omega` (argument of pericenter)
#2) rotation about the x axis about an angle `I` (inclination)
#3) rotation about the z axis about an angle `Omega` (longitude of ascending node)
def orbplane2frame_(omega,I,Omega):
    P2_mul_P3 = np.matmul(rotx(I),rotz(omega))
    return np.matmul(rotz(Omega),P2_mul_P3)

def orbplane2frame(x):
    return orbplane2frame_(x[0],x[1],x[2])

def kep_r_(a, e, f):
    return a*(1.0-e**2)/(1.0+e*np.cos(f))

def kep_r(x):
    return kep_r_(x[0],x[1],x[2])

def xyz_orbplane_(a, e, f):
    r = kep_r_(a, e, f)
    return np.array((r*np.cos(f),r*np.sin(f),0.0))

def xyz_orbplane(x):
    return xyz_orbplane_(x[0],x[1],x[2])

def xyz_frame_(a,e,f,omega,I,Omega):
    return np.matmul( orbplane2frame_(omega,I,Omega) , xyz_orbplane_(a, e, f) )

def xyz_frame(x):
    return np.matmul( orbplane2frame(x[3:6]) , xyz_orbplane(x[0:3]) )

def meanmotion(mu,a):
    return np.sqrt(mu/(a**3))

# # TODO:
# # write function to compute range as a function of orbital elements: DONE
# # write function to compute true anomaly as a function of time-of-fly
# # the following transformation is needed: from time t, to mean anomaly M,
# # to eccentric anomaly E, to true anomaly f
# # t -> M=n*(t-taup) -> M=E-e*sin(E) (invert) ->
# # -> f = 2*atan(  sqrt((1+e)/(1-e))*tan(E/2)  )
# # write function which takes observed values and computes the difference wrt expected-to-be-observed values as a function of unknown orbital elements (to be fitted)
# # compute Q as a function of unknown orbital elements (to be fitted)
# # optimize Q -> return fitted orbital elements (requires an ansatz: take input from minimalistic Gibb's?)

# NOTES:
# matrix multiplication of numpy's 2-D arrays is done through `np.matmul`

omega = np.radians(31.124)
I = np.radians(75.0)
Omega = np.radians(60.0)

# rotation matrix from orbital plane to inertial frame
# two ways to compute it; result should be the same
P_1 = rotz(omega) #rotation about z axis by an angle `omega`
P_2 = rotx(I) #rotation about x axis by an angle `I`
P_3 = rotz(Omega) #rotation about z axis by an angle `Omega`

Rot1 = np.matmul(P_3,np.matmul(P_2,P_1))
Rot2 = orbplane2frame_(omega,I,Omega)

v = np.array((3.0,-2.0,1.0))

print(I)
print(omega)
print(Omega)

print(Rot1)

print(np.matmul(Rot1,v))

print(Rot2)

# #import autograd.numpy as np  # Thinly-wrapped numpy
# #from autograd import grad    # The only autograd function you may ever need
# def tanh(x):                 # Define a function
#     y = np.exp(-2.0 * x)
#     return (1.0 - y) / (1.0 + y)

# grad_tanh = grad(tanh)       # Obtain its gradient function
# print(grad_tanh(1.0))

# def mycos(x):
#     return np.cos(x)

# drotz = grad(mycos)

# print(drotz(0.1))

drotz = jacobian(orbplane2frame_)
drotz2 = jacobian(orbplane2frame)

print('op2f=',orbplane2frame_(np.radians(10.0),np.radians(-31.124),np.radians(200.001)))

# print('drotz=',drotz(np.radians(10.0),np.radians(-31.124),np.radians(200.001)))

bbb= np.array( (np.radians(10.0),np.radians(-31.124),np.radians(200.001)) )
#bbb= np.array( (np.radians(0.0),np.radians(0.0),np.radians(0.0)) )
print('drotz2(bbb)=',drotz2( bbb ))

#print(dkep_r)
#print(kep_r_(1.0,0.1,np.radians(-29.99)))
#print(dkep_r(1.0,0.1,np.radians(-29.99)))

aaa = np.array((1.0,0.45,np.radians(1.0)))
# def printz(x):
#     return print(str(x)+' = ',x)
# printz(aaa)

print('aaa = ', aaa)
print('kep_r(aaa) = ',kep_r(aaa))

dkep_r = grad(kep_r)

print('dkep_r(aaa) = ',dkep_r(aaa))

print('xyz_orbplane(aaa) = ',xyz_orbplane(aaa))

dxyz_orbplane = jacobian(xyz_orbplane)

print('dxyz_orbplane(aaa) = ',dxyz_orbplane(aaa))

dxyz_orbplane_ = jacobian(xyz_orbplane_)

print('dxyz_orbplane_(aaa) = ',dxyz_orbplane_(aaa[0],aaa[1],aaa[2]))

ccc = np.array((aaa[0],aaa[1],aaa[2],bbb[0],bbb[1],bbb[2]))

print('xyz_frame(ccc) = ',xyz_frame(ccc))

print('xyz_frame_((aaa[0],aaa[1],aaa[2],bbb[0],bbb[1],bbb[2])) = ',xyz_frame((aaa[0],aaa[1],aaa[2],bbb[0],bbb[1],bbb[2])))

dxyz_frame = jacobian(xyz_frame)

print('dxyz_frame(ccc) = ',dxyz_frame(ccc))

print('meanmotion(1.0,1.1) = ', meanmotion(1.0,1.1))
<commit_msg>Add mean/eccentric/true anomalies methods<commit_after>"""Computes the least-squares optimal Keplerian elements for a sequence of
   cartesian position observations.
"""

import math
#import numpy as np
#Thinly-wrapped numpy
import autograd.numpy as np
import matplotlib.pyplot as plt
from autograd import grad
from autograd import jacobian
from autograd import elementwise_grad as egrad

# convention:
# a: semi-major axis
# e: eccentricity
# eps: mean longitude at epoch
# taup: time of pericenter passage
# Euler angles:
# I: inclination
# Omega: longitude of ascending node
# omega: argument of pericenter

#rotation about the z-axis about an angle `ang`
def rotz(ang):
    cos_ang = np.cos(ang)
    sin_ang = np.sin(ang)
    return np.array(((cos_ang,-sin_ang,0.0), (sin_ang, cos_ang,0.0), (0.0,0.0,1.0)))

#rotation about the x-axis about an angle `ang`
def rotx(ang):
    cos_ang = np.cos(ang)
    sin_ang = np.sin(ang)
    return np.array(((1.0,0.0,0.0), (0.0,cos_ang,-sin_ang), (0.0,sin_ang,cos_ang)))

#rotation from the orbital plane to the inertial frame
#it is composed of the following rotations, in that order:
#1) rotation about the z axis about an angle `omega` (argument of pericenter)
#2) rotation about the x axis about an angle `I` (inclination)
#3) rotation about the z axis about an angle `Omega` (longitude of ascending node)
def orbplane2frame_(omega,I,Omega):
    P2_mul_P3 = np.matmul(rotx(I),rotz(omega))
    return np.matmul(rotz(Omega),P2_mul_P3)

def orbplane2frame(x):
    return orbplane2frame_(x[0],x[1],x[2])

# get Keplerian range
def kep_r_(a, e, f):
    return a*(1.0-e**2)/(1.0+e*np.cos(f))

def kep_r(x):
    return kep_r_(x[0],x[1],x[2])

# get cartesian positions wrt orbital plane
def xyz_orbplane_(a, e, f):
    r = kep_r_(a, e, f)
    return np.array((r*np.cos(f),r*np.sin(f),0.0))

def xyz_orbplane(x):
    return xyz_orbplane_(x[0],x[1],x[2])

# get cartesian positions wrt inertial frame from orbital elements
def xyz_frame_(a,e,f,omega,I,Omega):
    return np.matmul( orbplane2frame_(omega,I,Omega) , xyz_orbplane_(a, e, f) )

def xyz_frame(x):
    return np.matmul( orbplane2frame(x[3:6]) , xyz_orbplane(x[0:3]) )

# get mean motion from mass parameter (mu) and semimajor axis (a)
def meanmotion(mu,a):
    return np.sqrt(mu/(a**3))

# get mean anomaly from mean motion (n), time (t) and time of pericenter passage (taup)
def meananomaly(n, t, taup):
    return n*(t-taup)

# compute eccentric anomaly (E) from eccentricity (e) and mean anomaly (M)
def eccentricanomaly(e,M):
    M0 = np.mod(M,2*np.pi)
    E0 = M0 + np.sign(np.sin(M0))*0.85*e #Murray-Dermotts' initial estimate
    # successive approximations via Newtons' method
    for i in range(0,4):
        #TODO: implement modified Newton's method for Kepler's equation (Murray-Dermott)
        Eans = E0 - (E0-e*np.sin(E0)-M0)/(1.0-e*np.cos(E0))
        E0 = Eans
    return E0

#compute true anomaly (f) from eccentricity (e) and eccentric anomaly (E)
def trueanomaly(e,E):
    Enew = np.mod(E,2*np.pi)
    return 2*np.arctan(  np.sqrt((1.0+e)/(1.0-e))*np.tan(Enew/2)  )

# # TODO:
# # write function to compute range as a function of orbital elements: DONE
# # write function to compute true anomaly as a function of time-of-fly
# # the following transformation is needed: from time t, to mean anomaly M,
# # to eccentric anomaly E, to true anomaly f
# # t -> M=n*(t-taup) -> M=E-e*sin(E) (invert) ->
# # -> f = 2*atan(  sqrt((1+e)/(1-e))*tan(E/2)  )
# # write function which takes observed values and computes the difference wrt expected-to-be-observed values as a function of unknown orbital elements (to be fitted)
# # compute Q as a function of unknown orbital elements (to be fitted)
# # optimize Q -> return fitted orbital elements (requires an ansatz: take input from minimalistic Gibb's?)

# NOTES:
# matrix multiplication of numpy's 2-D arrays is done through `np.matmul`

omega = np.radians(31.124)
I = np.radians(75.0)
Omega = np.radians(60.0)

# rotation matrix from orbital plane to inertial frame
# two ways to compute it; result should be the same
P_1 = rotz(omega) #rotation about z axis by an angle `omega`
P_2 = rotx(I) #rotation about x axis by an angle `I`
P_3 = rotz(Omega) #rotation about z axis by an angle `Omega`

Rot1 = np.matmul(P_3,np.matmul(P_2,P_1))
Rot2 = orbplane2frame_(omega,I,Omega)

v = np.array((3.0,-2.0,1.0))

print(I)
print(omega)
print(Omega)

print(Rot1)

print(np.matmul(Rot1,v))

print(Rot2)

# #import autograd.numpy as np  # Thinly-wrapped numpy
# #from autograd import grad    # The only autograd function you may ever need
# def tanh(x):                 # Define a function
#     y = np.exp(-2.0 * x)
#     return (1.0 - y) / (1.0 + y)

# grad_tanh = grad(tanh)       # Obtain its gradient function
# print(grad_tanh(1.0))

# def mycos(x):
#     return np.cos(x)

# drotz = grad(mycos)

# print(drotz(0.1))

drotz = jacobian(orbplane2frame_)
drotz2 = jacobian(orbplane2frame)

print('op2f=',orbplane2frame_(np.radians(10.0),np.radians(-31.124),np.radians(200.001)))

# print('drotz=',drotz(np.radians(10.0),np.radians(-31.124),np.radians(200.001)))

bbb= np.array( (np.radians(10.0),np.radians(-31.124),np.radians(200.001)) )
#bbb= np.array( (np.radians(0.0),np.radians(0.0),np.radians(0.0)) )
print('drotz2(bbb)=',drotz2( bbb ))

#print(dkep_r)
#print(kep_r_(1.0,0.1,np.radians(-29.99)))
#print(dkep_r(1.0,0.1,np.radians(-29.99)))

aaa = np.array((1.0,0.45,np.radians(1.0)))
# def printz(x):
#     return print(str(x)+' = ',x)
# printz(aaa)

print('aaa = ', aaa)
print('kep_r(aaa) = ',kep_r(aaa))

dkep_r = grad(kep_r)

print('dkep_r(aaa) = ',dkep_r(aaa))

print('xyz_orbplane(aaa) = ',xyz_orbplane(aaa))

dxyz_orbplane = jacobian(xyz_orbplane)

print('dxyz_orbplane(aaa) = ',dxyz_orbplane(aaa))

dxyz_orbplane_ = jacobian(xyz_orbplane_)

print('dxyz_orbplane_(aaa) = ',dxyz_orbplane_(aaa[0],aaa[1],aaa[2]))

ccc = np.array((aaa[0],aaa[1],aaa[2],bbb[0],bbb[1],bbb[2]))

print('xyz_frame(ccc) = ',xyz_frame(ccc))

print('xyz_frame_((aaa[0],aaa[1],aaa[2],bbb[0],bbb[1],bbb[2])) = ',xyz_frame((aaa[0],aaa[1],aaa[2],bbb[0],bbb[1],bbb[2])))

dxyz_frame = jacobian(xyz_frame)

print('dxyz_frame(ccc) = ',dxyz_frame(ccc))

print('meanmotion(1.0,1.1) = ', meanmotion(1.0,1.1))

mye = 0.3134123
myM = -21.98*np.pi
myEans = eccentricanomaly(mye,myM)
print('myEans-mye*np.sin(myEans)-np.mod(myM,2*np.pi) = ', myEans-mye*np.sin(myEans)-np.mod(myM,2*np.pi))

print('eccentricanomaly(mye,myM) = ', eccentricanomaly(mye,myM))

print('trueanomaly(0.1, 0.16*np.pi) = ', trueanomaly(0.1, 0.16*np.pi)/np.pi, '*pi')
print('trueanomaly(0.1, 0.56*np.pi) = ', trueanomaly(0.1, 0.56*np.pi)/np.pi, '*pi')
print('trueanomaly(0.1, 1.16*np.pi) = ', trueanomaly(0.1, 1.16*np.pi)/np.pi, '*pi')
print('trueanomaly(0.1, 1.56*np.pi) = ', trueanomaly(0.1, 1.56*np.pi)/np.pi, '*pi')
print('trueanomaly(0.1, 1.99*np.pi) = ', trueanomaly(0.1, 1.99*np.pi)/np.pi, '*pi')

<|endoftext|>


<commit_before># Copyright (c) 2014 - 2018, Carlos Millett
# All rights reserved.
#
# This software may be modified and distributed under the terms
# of the Simplified BSD License.  See the LICENSE file for details.

#
# Import
#
import os
import re

from itertools import zip_longest
from shutil import move

from . import error

#
# Class
#
class LocalPath():
    def __init__(self, filename):
        self._curFileName = os.path.basename(filename)
        self._dirName = os.path.dirname(filename)
        self._fileNameExt = os.path.splitext(filename)[-1]
        self._newFileName = None

    @property
    def curFileName(self):
        return self._curFileName

    @property
    def dirName(self):
        return self._dirName

    @property
    def fileNameExt(self):
        return self._fileNameExt

    @property
    def newFileName(self):
        return self._newFileName

    @newFileName.setter
    def newFileName(self, newName):
        new = self._sanitizeName(newName)
        self._newFileName = '{}{}'.format(new, self.fileNameExt)

    def rename(self):
        cur = os.path.join(self.dirName, self.curFileName)
        new = os.path.join(self.dirName, self._newFileName)
        if cur == new:
            strerr = ("Same file:\n"
                      "{}\n"
                      "{}.")
            raise error.SameFileError(strerr.format(cur, new))
        move(cur, new)

    def _sanitizeName(self, name):
        table = {
            ord('á'): 'a',
            ord('à'): 'a',
            ord('ã'): 'a',
            ord('â'): 'a',
            ord('é'): 'e',
            ord('è'): 'e',
            ord('ẽ'): 'e',
            ord('ê'): 'e',
            ord('í'): 'i',
            ord('ì'): 'i',
            ord('ĩ'): 'i',
            ord('î'): 'i',
            ord('ó'): 'o',
            ord('ò'): 'o',
            ord('õ'): 'o',
            ord('ô'): 'o',
            ord('ú'): 'u',
            ord('ù'): 'u',
            ord('ũ'): 'u',
            ord('û'): 'u',
            ord('ç'): 'c',
            ord('ñ'): 'n',
            ord(':'): ' -',
            ord('>'): None,
            ord('<'): None,
            ord('?'): None,
            ord('!'): None,
            ord('*'): None,
            ord('#'): None,
            ord('/'): None,
            ord('\\'): None,
            ord('\''): None,
            ord('\''): None
        }
        return name.translate(table)

    def _formatName(self, name):
        reSep = re.compile(r'[\W]+')
        reYear = re.compile('[12][0-9]{3}')
        reCountry = re.compile('[A-Z]{2}')
        countryCodes = [
            'AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AO', 'AQ', 'AR', 'AS',
            'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG',
            'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ', 'BR', 'BS', 'BT',
            'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI',
            'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CW', 'CX', 'CY',
            'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'EH',
            'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'UK',
            'GD', 'GE', 'GF', 'GG', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ',
            'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT',
            'HU', 'ID', 'IE', 'IL', 'IM', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT',
            'JE', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KP',
            'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS',
            'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH',
            'MK', 'ML', 'MM', 'MN', 'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU',
            'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NF', 'NG', 'NI',
            'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG',
            'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PS', 'PT', 'PW', 'PY', 'QA',
            'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG',
            'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'SS', 'ST',
            'SV', 'SX', 'SY', 'SZ', 'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', 'TK',
            'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TW', 'TZ', 'UA', 'UG', 'UM',
            'US', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI', 'VN', 'VU',
            'WF', 'WS', 'YE', 'YT', 'ZA', 'ZM', 'ZW'
        ]

        nameOnly = country = year = None
        tmp = name

        if reCountry.search(name):
            match = reCountry.findall(name)[0]

            if match in countryCodes:
                country = 'GB' if match == 'UK' else match
                tmp = reCountry.sub('', name)

        if reYear.search(name):
            match = reYear.findall(name)
            year = match[0]

        nameOnly = reSep.sub(' ', reYear.sub('', tmp)).strip()
        return {
            'title': nameOnly.title(),
            'country': country,
            'year': year
        }

class SerieFile(LocalPath):
    def __init__(self, filename):
        super().__init__(filename)
        rSceneRule = re.compile(r'[ .]S(\d{2})((E\d{2}-?)+)[ .]', re.I)
        rPreFormat = re.compile(r' (\d{2})x((\d{2}-?)+) ')
        rAltFormat = re.compile(r'\.(\d{4}.)?(\d{3,})\.')

        if rSceneRule.search(self.curFileName):
            show, season, info = rSceneRule.split(self.curFileName)[:3]
            eps = re.findall(r'\d{2}', info)

        elif rPreFormat.search(self.curFileName):
            show, season, info = rPreFormat.split(self.curFileName)[:3]
            eps = re.findall(r'\d{2}', info)

        elif rAltFormat.search(self.curFileName):
            show_piece, year, info = rAltFormat.split(self.curFileName)[:3]
            show = '{}{}'.format(show_piece, year) if year else show_piece

            info_lst = list(info)
            info_lst.reverse()
            info_itr = [iter(info_lst)] * 2
            info_grp = zip_longest(*info_itr, fillvalue='0')
            info_lst = list(info_grp)
            s_num, s_dec = info_lst.pop()
            info_lst.reverse()

            season = '{}{}'.format(s_dec, s_num)
            eps = ['{}{}'.format(e_dec, e_num) for e_num, e_dec in info_lst]

        else:
            strerror = "Can't find show pattern for {}".format(self.curFileName)
            raise error.MatchNotFoundError(strerror)

        self._show = super()._formatName(show)
        self._show['season'] = '{:0>2}'.format(season)
        self._show['episodes'] = eps
        self._identifier = None

    def __eq__(self, other):
        if isinstance(self, other.__class__):
            return self.identifier == other.identifier
        return False

    @property
    def title(self):
        return self._show.get('title')

    @property
    def country(self):
        return self._show.get('country')

    @property
    def year(self):
        return self._show.get('year')

    @property
    def season(self):
        return self._show.get('season')

    @property
    def episodes(self):
        return self._show.get('episodes')

    @property
    def identifier(self):
        if not self._identifier:
            identifier = re.sub(r'\W', '', self._show['title'])
            self._identifier = identifier.upper()
        return self._identifier
<commit_msg>prevent substrings from matching as country code<commit_after># Copyright (c) 2014 - 2018, Carlos Millett
# All rights reserved.
#
# This software may be modified and distributed under the terms
# of the Simplified BSD License.  See the LICENSE file for details.

#
# Import
#
import os
import re

from itertools import zip_longest
from shutil import move

from . import error

#
# Class
#
class LocalPath():
    def __init__(self, filename):
        self._curFileName = os.path.basename(filename)
        self._dirName = os.path.dirname(filename)
        self._fileNameExt = os.path.splitext(filename)[-1]
        self._newFileName = None

    @property
    def curFileName(self):
        return self._curFileName

    @property
    def dirName(self):
        return self._dirName

    @property
    def fileNameExt(self):
        return self._fileNameExt

    @property
    def newFileName(self):
        return self._newFileName

    @newFileName.setter
    def newFileName(self, newName):
        new = self._sanitizeName(newName)
        self._newFileName = '{}{}'.format(new, self.fileNameExt)

    def rename(self):
        cur = os.path.join(self.dirName, self.curFileName)
        new = os.path.join(self.dirName, self._newFileName)
        if cur == new:
            strerr = ("Same file:\n"
                      "{}\n"
                      "{}.")
            raise error.SameFileError(strerr.format(cur, new))
        move(cur, new)

    def _sanitizeName(self, name):
        table = {
            ord('á'): 'a',
            ord('à'): 'a',
            ord('ã'): 'a',
            ord('â'): 'a',
            ord('é'): 'e',
            ord('è'): 'e',
            ord('ẽ'): 'e',
            ord('ê'): 'e',
            ord('í'): 'i',
            ord('ì'): 'i',
            ord('ĩ'): 'i',
            ord('î'): 'i',
            ord('ó'): 'o',
            ord('ò'): 'o',
            ord('õ'): 'o',
            ord('ô'): 'o',
            ord('ú'): 'u',
            ord('ù'): 'u',
            ord('ũ'): 'u',
            ord('û'): 'u',
            ord('ç'): 'c',
            ord('ñ'): 'n',
            ord(':'): ' -',
            ord('>'): None,
            ord('<'): None,
            ord('?'): None,
            ord('!'): None,
            ord('*'): None,
            ord('#'): None,
            ord('/'): None,
            ord('\\'): None,
            ord('\''): None,
            ord('\''): None
        }
        return name.translate(table)

    def _formatName(self, name):
        reSep = re.compile(r'[\W]+')
        reYear = re.compile('[12][0-9]{3}')
        reCountry = re.compile(r'[\W]([A-Z]{2})[\W]?')
        countryCodes = [
            'AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AO', 'AQ', 'AR', 'AS',
            'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG',
            'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ', 'BR', 'BS', 'BT',
            'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI',
            'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CW', 'CX', 'CY',
            'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'EH',
            'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'UK',
            'GD', 'GE', 'GF', 'GG', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ',
            'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT',
            'HU', 'ID', 'IE', 'IL', 'IM', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT',
            'JE', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KP',
            'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS',
            'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH',
            'MK', 'ML', 'MM', 'MN', 'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU',
            'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NF', 'NG', 'NI',
            'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG',
            'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PS', 'PT', 'PW', 'PY', 'QA',
            'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG',
            'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'SS', 'ST',
            'SV', 'SX', 'SY', 'SZ', 'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', 'TK',
            'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TW', 'TZ', 'UA', 'UG', 'UM',
            'US', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI', 'VN', 'VU',
            'WF', 'WS', 'YE', 'YT', 'ZA', 'ZM', 'ZW'
        ]

        nameOnly = country = year = None
        tmp = name

        if reCountry.search(name):
            match = reCountry.findall(name)[0]

            if match in countryCodes:
                country = 'GB' if match == 'UK' else match
                tmp = reCountry.sub('', name)

        if reYear.search(name):
            match = reYear.findall(name)
            year = match[0]

        nameOnly = reSep.sub(' ', reYear.sub('', tmp)).strip()
        return {
            'title': nameOnly.title(),
            'country': country,
            'year': year
        }

class SerieFile(LocalPath):
    def __init__(self, filename):
        super().__init__(filename)
        rSceneRule = re.compile(r'[ .]S(\d{2})((E\d{2}-?)+)[ .]', re.I)
        rPreFormat = re.compile(r' (\d{2})x((\d{2}-?)+) ')
        rAltFormat = re.compile(r'\.(\d{4}.)?(\d{3,})\.')

        if rSceneRule.search(self.curFileName):
            show, season, info = rSceneRule.split(self.curFileName)[:3]
            eps = re.findall(r'\d{2}', info)

        elif rPreFormat.search(self.curFileName):
            show, season, info = rPreFormat.split(self.curFileName)[:3]
            eps = re.findall(r'\d{2}', info)

        elif rAltFormat.search(self.curFileName):
            show_piece, year, info = rAltFormat.split(self.curFileName)[:3]
            show = '{}{}'.format(show_piece, year) if year else show_piece

            info_lst = list(info)
            info_lst.reverse()
            info_itr = [iter(info_lst)] * 2
            info_grp = zip_longest(*info_itr, fillvalue='0')
            info_lst = list(info_grp)
            s_num, s_dec = info_lst.pop()
            info_lst.reverse()

            season = '{}{}'.format(s_dec, s_num)
            eps = ['{}{}'.format(e_dec, e_num) for e_num, e_dec in info_lst]

        else:
            strerror = "Can't find show pattern for {}".format(self.curFileName)
            raise error.MatchNotFoundError(strerror)

        self._show = super()._formatName(show)
        self._show['season'] = '{:0>2}'.format(season)
        self._show['episodes'] = eps
        self._identifier = None

    def __eq__(self, other):
        if isinstance(self, other.__class__):
            return self.identifier == other.identifier
        return False

    @property
    def title(self):
        return self._show.get('title')

    @property
    def country(self):
        return self._show.get('country')

    @property
    def year(self):
        return self._show.get('year')

    @property
    def season(self):
        return self._show.get('season')

    @property
    def episodes(self):
        return self._show.get('episodes')

    @property
    def identifier(self):
        if not self._identifier:
            identifier = re.sub(r'\W', '', self._show['title'])
            self._identifier = identifier.upper()
        return self._identifier
<|endoftext|>