<commit_before>import json
import os
import pickle
import random
from itertools import cycle, product
from time import strftime, time

import numpy as np

from metal.utils import recursive_merge_dicts

class ModelTuner(object):
    """A tuner for models

    Args:
        model_class: (nn.Module class) The model class to train (uninitiated)
        module_classes: (dict) An optional dictionary of module classes
        (uninitiated), with keys corresponding to their kwargs in model class,
        e.g. "input_module" in EndModel.
        log_dir: (str) The path to the base log directory, or defaults to
            current working directory.
        run_dir: (str) The name of the sub-directory, or defaults to the date,
            strftime("%Y_%m_%d").
        run_name: (str) The name of the run, or defaults to the time,
            strftime("%H_%M_%S").
        log_writer_class: a metal.utils.LogWriter class for logging the full
            model search.
        validation_metric: The metric to use in scoring and selecting models.

        Saves model search logs and tuner report to 'log_dir/run_dir/run_name/.'
    """

    def __init__(
        self,
        model_class,
        module_classes={},
        log_dir=None,
        run_dir=None,
        run_name=None,
        log_writer_class=None,
        seed=None,
        validation_metric="accuracy",
    ):
        self.model_class = model_class
        self.module_classes = module_classes
        self.log_writer_class = log_writer_class
        self.validation_metric = validation_metric

        # Set logging subdirectory + make sure exists
        self.init_date = strftime("%Y_%m_%d")
        self.init_time = strftime("%H_%M_%S")
        self.log_dir = log_dir or os.getcwd()
        run_dir = run_dir or self.init_date
        run_name = run_name or self.init_time
        self.log_rootdir = os.path.join(self.log_dir, run_dir)
        self.log_subdir = os.path.join(self.log_dir, run_dir, run_name)

        if not os.path.exists(self.log_subdir):
            os.makedirs(self.log_subdir)

        # Set best model pkl and JSON log paths
        self.save_path = os.path.join(self.log_subdir, f"best_model.pkl")
        self.report_path = os.path.join(self.log_subdir, f"tuner_report.json")

        # Set global seed
        if seed is None:
            self.seed = 0
        else:
            random.seed(seed)
            self.seed = seed

        # Search state
        # NOTE: Must be cleared each run with self._clear_state()!
        self._clear_state()

    def _clear_state(self):
        """Clears the state, starts clock"""
        self.start_time = time()
        self.run_stats = []
        self.best_index = -1
        self.best_score = -1
        self.best_config = None

        # Note: These must be set at the start of self.search()
        self.search_space = None

    def _test_model_config(
        self,
        idx,
        config,
        dev_data,
        init_args=[],
        train_args=[],
        init_kwargs={},
        train_kwargs={},
        module_args={},
        module_kwargs={},
        verbose=False,
        **score_kwargs,
    ):

        # Integrating generated config into init kwargs and train kwargs
        init_kwargs = recursive_merge_dicts(
            init_kwargs, config, misses="insert"
        )
        train_kwargs = recursive_merge_dicts(
            train_kwargs, config, misses="insert"
        )

        # Also make sure train kwargs includes validation metric
        train_kwargs["validation_metric"] = self.validation_metric

        # Initialize modules if provided
        for module_name, module_class in self.module_classes.items():

            # Also integrate generated config into module kwargs so that module
            # hyperparameters can be searched over as well
            module_kwargs[module_name] = recursive_merge_dicts(
                module_kwargs[module_name], config, misses="insert"
            )

            # Initialize module
            init_kwargs[module_name] = module_class(
                *module_args[module_name], **module_kwargs[module_name]
            )

        # Init model
        model = self.model_class(*init_args, **init_kwargs)

        # Search params
        # Select any params in search space that have list or dict
        search_params = {}
        for k, v in config.items():
            if k in self.search_space.keys():
                if isinstance(self.search_space[k], (list, dict)):
                    search_params[k] = v

        if verbose:
            print("=" * 60)
            print(f"[{idx}] Testing {search_params}")
            print("=" * 60)

        # Initialize a new LogWriter and train the model, returning the score
        log_writer = None
        if self.log_writer_class is not None:
            log_writer = self.log_writer_class(
                log_dir=self.log_subdir,
                run_dir=".",
                run_name=f"model_search_{idx}",
            )
        model.train_model(
            *train_args,
            **train_kwargs,
            dev_data=dev_data,
            verbose=verbose,
            log_writer=log_writer,
        )

        score = model.score(
            dev_data,
            metric=self.validation_metric,
            verbose=False,  # Score is already printed in train_model above
            **score_kwargs,
        )

        # If score better than best_score, save
        if score > self.best_score:
            self.best_score = score
            self.best_index = idx
            self.best_config = config
            self._save_best_model(model)

        # Save high-level run stats (in addition to per-model log)
        time_elapsed = time() - self.start_time
        self.run_stats.append(
            {
                "idx": idx,
                "time_elapsed": time_elapsed,
                "search_params": search_params,
                "score": score,
            }
        )
        return score, model

    def _save_best_model(self, model):
        with open(self.save_path, "wb") as f:
            pickle.dump(model, f)

    def _load_best_model(self, clean_up=False):
        with open(self.save_path, "rb") as f:
            model = pickle.load(f)
        if clean_up:
            self._clean_up()
        return model

    def _clean_up(self):
        if os.path.exists(self.save_path):
            os.remove(self.save_path)

    def _save_report(self):
        with open(self.report_path, "w") as f:
            json.dump(self.run_stats, f, indent=1)

    def search(
        self,
        search_space,
        dev_data,
        init_args=[],
        train_args=[],
        init_kwargs={},
        train_kwargs={},
        module_args={},
        module_kwargs={},
        max_search=None,
        shuffle=True,
        verbose=True,
        **score_kwargs,
    ):
        """
        Args:
            search_space: see config_generator() documentation
            dev_data: a tuple of Tensors (X,Y), a Dataset, or a DataLoader of
                X (data) and Y (labels) for the dev split
            init_args: (list) positional args for initializing the model
            train_args: (list) positional args for training the model
            init_kwargs: (dict) keyword args for initializing the model
            train_kwargs: (dict) keyword args for training the model
            module_args: (dict) Dictionary of lists of module args
            module_kwargs: (dict) Dictionary of dictionaries of module kwargs
            max_search: see config_generator() documentation
            shuffle: see config_generator() documentation
        Returns:
            best_model: the highest performing trained model

        Note: Initialization is performed by ModelTuner instead of passing a
        pre-initialized model so that tuning may be performed over all model
        parameters, including the network architecture (which is defined before
        the train loop).
        """
        raise NotImplementedError()

    @staticmethod
    def config_generator(search_space, max_search, shuffle=True):
        """Generates config dicts from the given search space

        Args:
            search_space: (dict) A dictionary of parameters to search over.
                See note below for more details.
            max_search: (int) The maximum number of configurations to search.
                If max_search is None, do a full grid search of all discrete
                    parameters, filling in range parameters as needed.
                Otherwise, do a full grid search of all discrete
                    parameters and then cycle through again filling in new
                    range parameters values; if there are no range parameters,
                    stop after yielding the full cross product of parameters
                    once.
            shuffle: (bool) If True, shuffle the order of generated configs

        Yields:
            configs: each config is a dict of parameter values based on the
                provided search space

        The search_space dictionary may consist of two types of parameters:
            --discrete: a discrete parameter is either a single value or a
                list of values. Use single values, for example, to override
                a default model parameter or set a flag such as 'verbose'=True.
            --range: a range parameter is a dict of the form:
                {'range': [<min>, <max>], 'scale': <scale>}
                where <min> and <max> are the min/max values to search between
                and scale is one of ['linear', 'log'] (defaulting to 'linear')
                representing the scale to use when searching the given range

        Example:
            search_space = {
                'verbose': True,                              # discrete
                'n_epochs': 100,                              # discrete
                'momentum': [0.0, 0.9, 0.99],                       # discrete
                'l2': {'range': [0.0001, 10]}                 # linear range
                'lr': {'range': [0.001, 1], 'scale': 'log'},  # log range
            }
            If max_search is None, this will return 3 configurations (enough to
                just cover the full cross-product of discrete values, filled
                in with sampled range values)
            Otherewise, this will return max_search configurations
                (cycling through the discrete value combinations multiple
                time if necessary)
        """

        def dict_product(d):
            keys = d.keys()
            for element in product(*d.values()):
                yield dict(zip(keys, element))

        def range_param_func(v):
            scale = v.get("scale", "linear")
            mini = min(v["range"])
            maxi = max(v["range"])
            if scale == "linear":
                func = lambda rand: mini + (maxi - mini) * rand
            elif scale == "log":
                mini = np.log(mini)
                maxi = np.log(maxi)
                func = lambda rand: np.exp(mini + (maxi - mini) * rand)
            else:
                raise ValueError(
                    f"Unrecognized scale '{scale}' for " "parameter {k}"
                )
            return func

        discretes = {}
        ranges = {}
        for k, v in search_space.items():
            if isinstance(v, dict):
                ranges[k] = range_param_func(v)
            elif isinstance(v, list):
                discretes[k] = v
            else:
                discretes[k] = [v]

        discrete_configs = list(dict_product(discretes))

        if shuffle:
            random.shuffle(discrete_configs)

        # If there are range parameters and a non-None max_search, cycle
        # through the discrete_configs (with new range values) until
        # max_search is met
        if ranges and max_search:
            discrete_configs = cycle(discrete_configs)

        for i, config in enumerate(discrete_configs):
            # We may see the same config twice due to cycle
            config = config.copy()
            if max_search and i == max_search:
                break
            for k, v in ranges.items():
                config[k] = float(v(random.random()))
            yield config
<commit_msg>Update docstring<commit_after>import json
import os
import pickle
import random
from itertools import cycle, product
from time import strftime, time

import numpy as np

from metal.utils import recursive_merge_dicts

class ModelTuner(object):
    """A tuner for models

    Args:
        model_class: (nn.Module class) The model class to train (uninitiated)
        module_classes: (dict) An optional dictionary of module classes
        (uninitiated), with keys corresponding to their kwargs in model class;
        for example, with model_class=EndModel, could have:
            module_classes = {"input_module": metal.modules.LSTMModule}
        log_dir: (str) The path to the base log directory, or defaults to
            current working directory.
        run_dir: (str) The name of the sub-directory, or defaults to the date,
            strftime("%Y_%m_%d").
        run_name: (str) The name of the run, or defaults to the time,
            strftime("%H_%M_%S").
        log_writer_class: a metal.utils.LogWriter class for logging the full
            model search.
        validation_metric: The metric to use in scoring and selecting models.

        Saves model search logs and tuner report to 'log_dir/run_dir/run_name/.'
    """

    def __init__(
        self,
        model_class,
        module_classes={},
        log_dir=None,
        run_dir=None,
        run_name=None,
        log_writer_class=None,
        seed=None,
        validation_metric="accuracy",
    ):
        self.model_class = model_class
        self.module_classes = module_classes
        self.log_writer_class = log_writer_class
        self.validation_metric = validation_metric

        # Set logging subdirectory + make sure exists
        self.init_date = strftime("%Y_%m_%d")
        self.init_time = strftime("%H_%M_%S")
        self.log_dir = log_dir or os.getcwd()
        run_dir = run_dir or self.init_date
        run_name = run_name or self.init_time
        self.log_rootdir = os.path.join(self.log_dir, run_dir)
        self.log_subdir = os.path.join(self.log_dir, run_dir, run_name)

        if not os.path.exists(self.log_subdir):
            os.makedirs(self.log_subdir)

        # Set best model pkl and JSON log paths
        self.save_path = os.path.join(self.log_subdir, f"best_model.pkl")
        self.report_path = os.path.join(self.log_subdir, f"tuner_report.json")

        # Set global seed
        if seed is None:
            self.seed = 0
        else:
            random.seed(seed)
            self.seed = seed

        # Search state
        # NOTE: Must be cleared each run with self._clear_state()!
        self._clear_state()

    def _clear_state(self):
        """Clears the state, starts clock"""
        self.start_time = time()
        self.run_stats = []
        self.best_index = -1
        self.best_score = -1
        self.best_config = None

        # Note: These must be set at the start of self.search()
        self.search_space = None

    def _test_model_config(
        self,
        idx,
        config,
        dev_data,
        init_args=[],
        train_args=[],
        init_kwargs={},
        train_kwargs={},
        module_args={},
        module_kwargs={},
        verbose=False,
        **score_kwargs,
    ):

        # Integrating generated config into init kwargs and train kwargs
        init_kwargs = recursive_merge_dicts(
            init_kwargs, config, misses="insert"
        )
        train_kwargs = recursive_merge_dicts(
            train_kwargs, config, misses="insert"
        )

        # Also make sure train kwargs includes validation metric
        train_kwargs["validation_metric"] = self.validation_metric

        # Initialize modules if provided
        for module_name, module_class in self.module_classes.items():

            # Also integrate generated config into module kwargs so that module
            # hyperparameters can be searched over as well
            module_kwargs[module_name] = recursive_merge_dicts(
                module_kwargs[module_name], config, misses="insert"
            )

            # Initialize module
            init_kwargs[module_name] = module_class(
                *module_args[module_name], **module_kwargs[module_name]
            )

        # Init model
        model = self.model_class(*init_args, **init_kwargs)

        # Search params
        # Select any params in search space that have list or dict
        search_params = {}
        for k, v in config.items():
            if k in self.search_space.keys():
                if isinstance(self.search_space[k], (list, dict)):
                    search_params[k] = v

        if verbose:
            print("=" * 60)
            print(f"[{idx}] Testing {search_params}")
            print("=" * 60)

        # Initialize a new LogWriter and train the model, returning the score
        log_writer = None
        if self.log_writer_class is not None:
            log_writer = self.log_writer_class(
                log_dir=self.log_subdir,
                run_dir=".",
                run_name=f"model_search_{idx}",
            )
        model.train_model(
            *train_args,
            **train_kwargs,
            dev_data=dev_data,
            verbose=verbose,
            log_writer=log_writer,
        )

        score = model.score(
            dev_data,
            metric=self.validation_metric,
            verbose=False,  # Score is already printed in train_model above
            **score_kwargs,
        )

        # If score better than best_score, save
        if score > self.best_score:
            self.best_score = score
            self.best_index = idx
            self.best_config = config
            self._save_best_model(model)

        # Save high-level run stats (in addition to per-model log)
        time_elapsed = time() - self.start_time
        self.run_stats.append(
            {
                "idx": idx,
                "time_elapsed": time_elapsed,
                "search_params": search_params,
                "score": score,
            }
        )
        return score, model

    def _save_best_model(self, model):
        with open(self.save_path, "wb") as f:
            pickle.dump(model, f)

    def _load_best_model(self, clean_up=False):
        with open(self.save_path, "rb") as f:
            model = pickle.load(f)
        if clean_up:
            self._clean_up()
        return model

    def _clean_up(self):
        if os.path.exists(self.save_path):
            os.remove(self.save_path)

    def _save_report(self):
        with open(self.report_path, "w") as f:
            json.dump(self.run_stats, f, indent=1)

    def search(
        self,
        search_space,
        dev_data,
        init_args=[],
        train_args=[],
        init_kwargs={},
        train_kwargs={},
        module_args={},
        module_kwargs={},
        max_search=None,
        shuffle=True,
        verbose=True,
        **score_kwargs,
    ):
        """
        Args:
            search_space: see config_generator() documentation
            dev_data: a tuple of Tensors (X,Y), a Dataset, or a DataLoader of
                X (data) and Y (labels) for the dev split
            init_args: (list) positional args for initializing the model
            train_args: (list) positional args for training the model
            init_kwargs: (dict) keyword args for initializing the model
            train_kwargs: (dict) keyword args for training the model
            module_args: (dict) Dictionary of lists of module args
            module_kwargs: (dict) Dictionary of dictionaries of module kwargs
            max_search: see config_generator() documentation
            shuffle: see config_generator() documentation
        Returns:
            best_model: the highest performing trained model

        Note: Initialization is performed by ModelTuner instead of passing a
        pre-initialized model so that tuning may be performed over all model
        parameters, including the network architecture (which is defined before
        the train loop).
        """
        raise NotImplementedError()

    @staticmethod
    def config_generator(search_space, max_search, shuffle=True):
        """Generates config dicts from the given search space

        Args:
            search_space: (dict) A dictionary of parameters to search over.
                See note below for more details.
            max_search: (int) The maximum number of configurations to search.
                If max_search is None, do a full grid search of all discrete
                    parameters, filling in range parameters as needed.
                Otherwise, do a full grid search of all discrete
                    parameters and then cycle through again filling in new
                    range parameters values; if there are no range parameters,
                    stop after yielding the full cross product of parameters
                    once.
            shuffle: (bool) If True, shuffle the order of generated configs

        Yields:
            configs: each config is a dict of parameter values based on the
                provided search space

        The search_space dictionary may consist of two types of parameters:
            --discrete: a discrete parameter is either a single value or a
                list of values. Use single values, for example, to override
                a default model parameter or set a flag such as 'verbose'=True.
            --range: a range parameter is a dict of the form:
                {'range': [<min>, <max>], 'scale': <scale>}
                where <min> and <max> are the min/max values to search between
                and scale is one of ['linear', 'log'] (defaulting to 'linear')
                representing the scale to use when searching the given range

        Example:
            search_space = {
                'verbose': True,                              # discrete
                'n_epochs': 100,                              # discrete
                'momentum': [0.0, 0.9, 0.99],                       # discrete
                'l2': {'range': [0.0001, 10]}                 # linear range
                'lr': {'range': [0.001, 1], 'scale': 'log'},  # log range
            }
            If max_search is None, this will return 3 configurations (enough to
                just cover the full cross-product of discrete values, filled
                in with sampled range values)
            Otherewise, this will return max_search configurations
                (cycling through the discrete value combinations multiple
                time if necessary)
        """

        def dict_product(d):
            keys = d.keys()
            for element in product(*d.values()):
                yield dict(zip(keys, element))

        def range_param_func(v):
            scale = v.get("scale", "linear")
            mini = min(v["range"])
            maxi = max(v["range"])
            if scale == "linear":
                func = lambda rand: mini + (maxi - mini) * rand
            elif scale == "log":
                mini = np.log(mini)
                maxi = np.log(maxi)
                func = lambda rand: np.exp(mini + (maxi - mini) * rand)
            else:
                raise ValueError(
                    f"Unrecognized scale '{scale}' for " "parameter {k}"
                )
            return func

        discretes = {}
        ranges = {}
        for k, v in search_space.items():
            if isinstance(v, dict):
                ranges[k] = range_param_func(v)
            elif isinstance(v, list):
                discretes[k] = v
            else:
                discretes[k] = [v]

        discrete_configs = list(dict_product(discretes))

        if shuffle:
            random.shuffle(discrete_configs)

        # If there are range parameters and a non-None max_search, cycle
        # through the discrete_configs (with new range values) until
        # max_search is met
        if ranges and max_search:
            discrete_configs = cycle(discrete_configs)

        for i, config in enumerate(discrete_configs):
            # We may see the same config twice due to cycle
            config = config.copy()
            if max_search and i == max_search:
                break
            for k, v in ranges.items():
                config[k] = float(v(random.random()))
            yield config
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
como.core - the basic ingredients to a great battery
"""

import sys
import os
import json
import zlib
import collections
from datetime import datetime
import subprocess

from clint.textui import puts, colored, indent
from tablib import Dataset
import requests

from .battery import get_battery, get_age
from .settings import COMO_BATTERY_FILE, SERVER_URL
from .help import is_osx, is_lin, spark_string

if is_lin:
    from crontab import CronTab

class ExitStatus:
    """Exit status code constants."""
    OK = 0
    ERROR = 1

def show_error(msg):
    sys.stdout.flush()
    sys.stderr.write(msg + '\n')

def auto_upload():
    apple_plist = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.cwoebker.como-update</string>
    <key>OnDemand</key>
    <true/>
    <key>RunAtLoad</key>
    <false/>
    <key>ProgramArguments</key>
    <array>
        <string>%s</string>
        <string>upload</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
      <key>Hour</key>
      <integer>11</integer>
      <key>Minute</key>
      <integer>0</integer>
    </dict>
</dict>
</plist>"""
    if is_osx:
        plist_path = os.path.expanduser(
            "~/Library/LaunchAgents/com.cwoebker.como-update.plist")
        if os.path.exists(plist_path):
            os.system("launchctl unload %s" % plist_path)
            os.remove(plist_path)
            puts(colored.white("como will not upload data"))
        else:
            with open(plist_path, "w") as plist_file:
                plist_file.write(
                    apple_plist % os.popen('which como').read().rstrip('\n'))
            os.system("launchctl load %s" % plist_path)
            puts(colored.white("como will automatically upload the data"))
    elif is_lin:
        user_cron = CronTab()
        user_cron.read()
        if len(user_cron.find_command("como-update")) > 0:
            user_cron.remove_all("como-update")
            user_cron.write()
            puts(colored.white("como will not upload data"))
        else:
            job = user_cron.new(command="como-update")
            job.minute.every(2)
            #job.minute.on(0)
            #job.hour.on(19)
            user_cron.write()
            puts(colored.white("como will automatically upload the data"))

def auto_save():
    apple_plist = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.cwoebker.como</string>
    <key>OnDemand</key>
    <true/>
    <key>RunAtLoad</key>
    <false/>
    <key>Program</key>
    <string>%s</string>
    <key>StartCalendarInterval</key>
    <array>
        <dict>
          <key>Hour</key>
          <integer>20</integer>
          <key>Minute</key>
          <integer>0</integer>
        </dict>
        <dict>
          <key>Hour</key>
          <integer>14</integer>
          <key>Minute</key>
          <integer>0</integer>
        </dict>
        <dict>
          <key>Hour</key>
          <integer>8</integer>
          <key>Minute</key>
          <integer>0</integer>
        </dict>
    </array>
</dict>
</plist>"""
    if is_osx:
        plist_path = os.path.expanduser(
            "~/Library/LaunchAgents/com.cwoebker.como.plist")
        if os.path.exists(plist_path):
            os.system("launchctl unload %s" % plist_path)
            os.remove(plist_path)
            puts(colored.white("como will only run manually"))
        else:
            with open(plist_path, "w") as plist_file:
                plist_file.write(
                    apple_plist % os.popen('which como').read().rstrip('\n'))
            os.system("launchctl load %s" % plist_path)
            puts(colored.white("como will run automatically"))
    elif is_lin:
        user_cron = CronTab()
        user_cron.read()
        if len(user_cron.find_command("como")) > 0:
            user_cron.remove_all("como")
            user_cron.write()
            puts(colored.white("como will only run manually"))
        else:
            job = user_cron.new(command="como")
            job.minute.every(2)
            #job.minute.on(0)
            #job.hour.on(19)
            user_cron.write()
            puts(colored.white("como will run automatically"))

def cmd_save(args):
    bat = get_battery()

    data = []
    if not os.path.exists(COMO_BATTERY_FILE):
        puts(colored.yellow("Creating ~/.como"))
        open(COMO_BATTERY_FILE, 'w').close()
        data = Dataset(headers=['time', 'capacity', 'cycles'])
    else:
        with open(COMO_BATTERY_FILE, 'r') as como:
            data = Dataset(headers=['time', 'capacity', 'cycles'])
            ### WATCH OUT: when directly importing through tablib header order
            #got messed up...
            # http://stackoverflow.com/questions/10206905/
            # how-to-convert-json-string-to-dictionary-and-save-order-in-keys
            data.dict = json.loads(
                zlib.decompress(como.read()),
                object_pairs_hook=collections.OrderedDict)
    data.append([
        datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S"),
        bat['maxcap'],
        bat['cycles'],
    ])
    with open(COMO_BATTERY_FILE, 'w') as como:
        como.write(zlib.compress(data.json))

    puts(colored.white("battery info saved (%s)" % str(data['time'][-1])))

def cmd_reset(args):
    if os.path.exists(COMO_BATTERY_FILE):
        sure = raw_input("Are you sure? this will remove everything! [y/n] ")
        if sure == "y":
            os.remove(COMO_BATTERY_FILE)
            puts(colored.white("removed database"))
    else:
        puts(colored.white("no como database"))

def cmd_info(args):
    with indent(4):
        title = "Como Info"
        puts(colored.green(title))
    puts("-" * (8 + len(title)))

    bat = get_battery()

    with indent(6, quote=colored.yellow('      ')):
        puts("Battery Serial: %s" % bat['serial'])
        puts("Age of Computer: %s months" % get_age())
        puts("Number of cycles: %s" % bat['cycles'])
        puts("Design Capacity: %s" % bat['designcap'])
        puts("Max Capacity: %s" % bat['maxcap'])
        puts("Capacity: %s" % bat['curcap'])
        if is_osx:
            puts("Mac model: %s" % subprocess.check_output(
                "sysctl -n hw.model", shell=True).rstrip("\n"))
            puts("Temperature: %s ℃" % (int(bat['temp']) / 100.))
            puts("Voltage: %s" % bat['voltage'])
            puts("Amperage: %s" % bat['amperage'])
            puts("Wattage: %s" % (bat['voltage'] * bat['amperage'] / 1000000.))
        if not os.path.exists(COMO_BATTERY_FILE):
            puts(colored.yellow("No como database."))
        else:
            # Gathering data
            with open(COMO_BATTERY_FILE, 'r') as como:
                data = Dataset()
                data.json = zlib.decompress(como.read())
            puts(colored.yellow("Database:"))
            with indent(4, quote=colored.yellow('    ')):
                puts("Number of Entries: %d" % len(data))
                puts("First save: " + str(data['time'][0]))
                puts("Last save: " + str(data['time'][-1]))
                timedelta = datetime.utcnow() - datetime.strptime(
                    data['time'][0], "%Y-%m-%dT%H:%M:%S")
                puts("Age of Database: %s Days" % str(timedelta.days))
                # History Graphs
                history = []
                for element in data['capacity']:
                    history.append(int(element))
                cycles = []
                for element in data['cycles']:
                    if element:
                        cycles.append(int(element))
                    else:
                        cycles.append(element)
                history = [h - min(history) for h in history]
                cycles = [c - min(c for c in cycles if type(c) == int)
                            if type(c) == int else c for c in cycles]
                text1 = str(spark_string(history).encode('utf-8'))
                text2 = str(spark_string(cycles).encode('utf-8'))
                #print type('Star ★')
                #puts(columns([colored.yellow('Star ★'), 10]))
                puts(colored.yellow("Capacity:"))
                puts(text1)
                puts(colored.yellow("cycles:"))
                puts(text2)

def cmd_import(args):
    if not os.path.exists(COMO_BATTERY_FILE):
        puts(colored.yellow("Creating ~/.como"))
        open(COMO_BATTERY_FILE, 'w').close()
        data = []
    else:
        with open(COMO_BATTERY_FILE, 'r') as como:
            data = json.loads(
                zlib.decompress(como.read()),
                object_pairs_hook=collections.OrderedDict)
    with open(os.path.expanduser(args.get(0)), "r") as import_file:
        csv = import_file.read()
    current_dataset = Dataset(headers=['time', 'capacity', 'cycles'])
    current_dataset.dict = data
    import_dataset = Dataset()
    import_dataset.csv = csv
    new_dict = []  # need to find a way to edit dataset itself, this is stupid
    for element in import_dataset.dict:
        #if 'T' not in element['date']:
        try:
            element['date'] += "T00:00:00"
            element['loadcycles'] = None if (
                element['loadcycles'] == '-') else int(element['loadcycles'])
        except KeyError:
            element['cycles'] = None if (
                element['cycles'] == '-') else int(element['cycles'])
        element['capacity'] = int(element['capacity'])
        new_dict.append(element)
    import_dataset.dict = new_dict
    new = current_dataset.stack(import_dataset).sort('time')

    with open(COMO_BATTERY_FILE, 'w') as como:
        como.write(zlib.compress(new.json))

    puts(colored.white("battery statistics imported"))

def cmd_export(args):
    if not os.path.exists(COMO_BATTERY_FILE):
        puts(colored.red("No como database."))
    else:
        dataset = Dataset(headers=['time', 'capacity', 'cycles'])
        with open(COMO_BATTERY_FILE, 'r') as como:
            dataset.dict = json.loads(
                zlib.decompress(como.read()),
                object_pairs_hook=collections.OrderedDict)
        with open("como.csv", "w") as como:
            como.write(dataset.csv)
        puts("saved file to current directory")

def cmd_upload(args):
    if is_osx:
        url = SERVER_URL + "/upload"
        cmd = "ioreg -l | awk '/IOPlatformSerialNumber/ { split($0, line, \"\\\"\"); printf(\"%s\\n\", line[4]); }'"
        computer_serial = subprocess.check_output(
            cmd, shell=True).translate(None, '\n')
        bat = get_battery()
        model = subprocess.check_output(
            "sysctl -n hw.model", shell=True).rstrip("\n")
        data = {
            'computer': computer_serial,
            'model': model,
            'battery': bat['serial'],
            'design': bat['designcap'],
            'age': get_age()
        }
        files = {'como': open(os.path.expanduser("~/.como"), 'rb')}
        response = requests.post(url, files=files, data=data)
        if response.status_code == requests.codes.ok:
            puts("data uploaded")
        else:
            puts("upload failed")
    else:
        puts("no uploading on this operating system")

def cmd_open(args):
    cmd = "ioreg -l | awk '/IOPlatformSerialNumber/ { split($0, line, \"\\\"\"); printf(\"%s\\n\", line[4]); }'"
    os.system("open %s/battery?id=%s" % (SERVER_URL, subprocess.check_output(
        cmd, shell=True).translate(None, '\n')))
<commit_msg>refactored similar code into create/read_database functions, using mapping with import formatting<commit_after># -*- coding: utf-8 -*-
"""
como.core - the basic ingredients to a great battery
"""

import sys
import os
import json
import zlib
import collections
from datetime import datetime
import subprocess

from clint.textui import puts, colored, indent
from tablib import Dataset
import requests

from .battery import get_battery, get_age
from .settings import COMO_BATTERY_FILE, SERVER_URL
from .help import is_osx, is_lin, spark_string

if is_lin:
    from crontab import CronTab

class ExitStatus:
    """Exit status code constants."""
    OK = 0
    ERROR = 1

def show_error(msg):
    sys.stdout.flush()
    sys.stderr.write(msg + '\n')

def auto_upload():
    apple_plist = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.cwoebker.como-update</string>
    <key>OnDemand</key>
    <true/>
    <key>RunAtLoad</key>
    <false/>
    <key>ProgramArguments</key>
    <array>
        <string>%s</string>
        <string>upload</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
      <key>Hour</key>
      <integer>11</integer>
      <key>Minute</key>
      <integer>0</integer>
    </dict>
</dict>
</plist>"""
    if is_osx:
        plist_path = os.path.expanduser(
            "~/Library/LaunchAgents/com.cwoebker.como-update.plist")
        if os.path.exists(plist_path):
            os.system("launchctl unload %s" % plist_path)
            os.remove(plist_path)
            puts(colored.white("como will not upload data"))
        else:
            with open(plist_path, "w") as plist_file:
                plist_file.write(
                    apple_plist % os.popen('which como').read().rstrip('\n'))
            os.system("launchctl load %s" % plist_path)
            puts(colored.white("como will automatically upload the data"))
    elif is_lin:
        user_cron = CronTab()
        user_cron.read()
        if len(user_cron.find_command("como-update")) > 0:
            user_cron.remove_all("como-update")
            user_cron.write()
            puts(colored.white("como will not upload data"))
        else:
            job = user_cron.new(command="como-update")
            job.minute.every(2)
            #job.minute.on(0)
            #job.hour.on(19)
            user_cron.write()
            puts(colored.white("como will automatically upload the data"))

def auto_save():
    apple_plist = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.cwoebker.como</string>
    <key>OnDemand</key>
    <true/>
    <key>RunAtLoad</key>
    <false/>
    <key>Program</key>
    <string>%s</string>
    <key>StartCalendarInterval</key>
    <array>
        <dict>
          <key>Hour</key>
          <integer>20</integer>
          <key>Minute</key>
          <integer>0</integer>
        </dict>
        <dict>
          <key>Hour</key>
          <integer>14</integer>
          <key>Minute</key>
          <integer>0</integer>
        </dict>
        <dict>
          <key>Hour</key>
          <integer>8</integer>
          <key>Minute</key>
          <integer>0</integer>
        </dict>
    </array>
</dict>
</plist>"""
    if is_osx:
        plist_path = os.path.expanduser(
            "~/Library/LaunchAgents/com.cwoebker.como.plist")
        if os.path.exists(plist_path):
            os.system("launchctl unload %s" % plist_path)
            os.remove(plist_path)
            puts(colored.white("como will only run manually"))
        else:
            with open(plist_path, "w") as plist_file:
                plist_file.write(
                    apple_plist % os.popen('which como').read().rstrip('\n'))
            os.system("launchctl load %s" % plist_path)
            puts(colored.white("como will run automatically"))
    elif is_lin:
        user_cron = CronTab()
        user_cron.read()
        if len(user_cron.find_command("como")) > 0:
            user_cron.remove_all("como")
            user_cron.write()
            puts(colored.white("como will only run manually"))
        else:
            job = user_cron.new(command="como")
            job.minute.every(2)
            #job.minute.on(0)
            #job.hour.on(19)
            user_cron.write()
            puts(colored.white("como will run automatically"))

def create_database():
    puts(colored.yellow("Creating ~/.como"))
    open(COMO_BATTERY_FILE, 'w').close()
    return Dataset(headers=['time', 'capacity', 'cycles'])

def read_database():
    with open(COMO_BATTERY_FILE, 'r') as como:
        data = Dataset(headers=['time', 'capacity', 'cycles'])
        # http://stackoverflow.com/questions/10206905/
        # how-to-convert-json-string-to-dictionary-and-save-order-in-keys
        data.dict = json.loads(
            zlib.decompress(como.read()),
            object_pairs_hook=collections.OrderedDict)
        return data

def cmd_save(args):
    bat = get_battery()

    if not os.path.exists(COMO_BATTERY_FILE):
        data = create_database()
    else:
        data = read_database()
    data.append([
        datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S"),
        bat['maxcap'],
        bat['cycles'],
    ])
    with open(COMO_BATTERY_FILE, 'w') as como:
        como.write(zlib.compress(data.json))

    puts(colored.white("battery info saved (%s)" % str(data['time'][-1])))

def cmd_reset(args):
    if os.path.exists(COMO_BATTERY_FILE):
        sure = raw_input("Are you sure? this will remove everything! [y/n] ")
        if sure == "y":
            os.remove(COMO_BATTERY_FILE)
            puts(colored.white("removed database"))
    else:
        puts(colored.white("no como database"))

def cmd_info(args):
    with indent(4):
        title = "Como Info"
        puts(colored.green(title))
    puts("-" * (8 + len(title)))

    bat = get_battery()

    with indent(6, quote=colored.yellow('      ')):
        puts("Battery Serial: %s" % bat['serial'])
        puts("Age of Computer: %s months" % get_age())
        puts("Number of cycles: %s" % bat['cycles'])
        puts("Design Capacity: %s" % bat['designcap'])
        puts("Max Capacity: %s" % bat['maxcap'])
        puts("Capacity: %s" % bat['curcap'])
        if is_osx:
            puts("Mac model: %s" % subprocess.check_output(
                "sysctl -n hw.model", shell=True).rstrip("\n"))
            puts("Temperature: %s ℃" % (int(bat['temp']) / 100.))
            puts("Voltage: %s" % bat['voltage'])
            puts("Amperage: %s" % bat['amperage'])
            puts("Wattage: %s" % (bat['voltage'] * bat['amperage'] / 1000000.))
        if not os.path.exists(COMO_BATTERY_FILE):
            puts(colored.yellow("No como database."))
        else:
            data = read_database()
            puts(colored.yellow("Database:"))
            with indent(4, quote=colored.yellow('    ')):
                puts("Number of Entries: %d" % len(data))
                puts("First save: " + str(data['time'][0]))
                puts("Last save: " + str(data['time'][-1]))
                timedelta = datetime.utcnow() - datetime.strptime(
                    data['time'][0], "%Y-%m-%dT%H:%M:%S")
                puts("Age of Database: %s Days" % str(timedelta.days))
                # History Graphs
                history = []
                for element in data['capacity']:
                    history.append(int(element))
                cycles = []
                for element in data['cycles']:
                    if element:
                        cycles.append(int(element))
                    else:
                        cycles.append(element)
                history = [h - min(history) for h in history]
                cycles = [c - min(c for c in cycles if type(c) == int)
                            if type(c) == int else c for c in cycles]
                text1 = str(spark_string(history).encode('utf-8'))
                text2 = str(spark_string(cycles).encode('utf-8'))
                #print type('Star ★')
                #puts(columns([colored.yellow('Star ★'), 10]))
                puts(colored.yellow("Capacity:"))
                puts(text1)
                puts(colored.yellow("cycles:"))
                puts(text2)

def import_format(element):
    try:
        element['date'] += "T00:00:00"
        element['loadcycles'] = None if (
            element['loadcycles'] == '-') else int(element['loadcycles'])
    except KeyError:
        element['cycles'] = None if (
            element['cycles'] == 'None') else int(element['cycles'])
    element['capacity'] = int(element['capacity'])
    return element

def cmd_import(args):
    if not os.path.exists(COMO_BATTERY_FILE):
        current_dataset = create_database()
    else:
        current_dataset = read_database()
    if os.path.exists(args.get(0)):
        import_dataset = Dataset()
        with open(os.path.expanduser(args.get(0)), "r") as import_file:
            import_dataset.csv = import_file.read()
        import_dataset.dict = map(import_format, import_dataset.dict)
        new = current_dataset.stack(import_dataset).sort('time')

        with open(COMO_BATTERY_FILE, 'w') as como:
            como.write(zlib.compress(new.json))

        puts(colored.white("battery statistics imported"))
    else:
        show_error(colored.red("Couldn't open file: %s" % args.get(0)))

def cmd_export(args):
    if not os.path.exists(COMO_BATTERY_FILE):
        puts(colored.red("No como database."))
    else:
        if os.path.exists("como.csv"):
            sure = raw_input("Do you want to replace the old export file?" + \
                            " [y/n] ")
            if sure != 'y':
                return
        dataset = read_database()
        with open("como.csv", "w") as como:
            como.write(dataset.csv)
        puts("saved file to current directory")

def cmd_upload(args):
    if not os.path.exists(COMO_BATTERY_FILE):
        puts(colored.red("No como database."))
    else:
        if is_osx:
            url = SERVER_URL + "/upload"
            cmd = "ioreg -l | awk '/IOPlatformSerialNumber/ " + \
                  "{ split($0, line, \"\\\"\"); printf(\"%s\\n\", line[4]); }'"
            computer_serial = subprocess.check_output(
                cmd, shell=True).translate(None, '\n')
            bat = get_battery()
            model = subprocess.check_output(
                "sysctl -n hw.model", shell=True).rstrip("\n")
            data = {
                'computer': computer_serial,
                'model': model,
                'battery': bat['serial'],
                'design': bat['designcap'],
                'age': get_age()
            }
            files = {'como': open(COMO_BATTERY_FILE, 'rb')}
            response = requests.post(url, files=files, data=data)
            if response.status_code == requests.codes.ok:
                puts("data uploaded")
            else:
                puts("upload failed")
        else:
            puts("no uploading on this operating system")

def cmd_open(args):
    cmd = "ioreg -l | awk '/IOPlatformSerialNumber/ " + \
          "{ split($0, line, \"\\\"\"); printf(\"%s\\n\", line[4]); }'"
    os.system("open %s/battery?id=%s" % (SERVER_URL, subprocess.check_output(
        cmd, shell=True).translate(None, '\n')))
<|endoftext|>


<commit_before>
__version__ = "0.7.2"
<commit_msg>Version bump.<commit_after>
__version__ = "0.7.3"
<|endoftext|>


<commit_before>from basesprite import BaseSprite
from OpenGL.GL import *
from OpenGL.GLU import *
import math

class Ball(BaseSprite):

    def __init__(self, start_pos, size):
        BaseSprite.__init__(self, start_pos, (size, size))
        self.angle = math.radians(45)
        self.speed = 0.5

    def update(self):

        if self.pos[0] > 800:
            self.angle = - self.angle

        elif self.pos[0] < 0:
            self.angle = - self.angle

        if self.pos[1] > 600:
            self.angle = math.pi - self.angle

        elif self.pos[1] < 0:
            self.angle = math.pi - self.angle

        delta_y = self.speed * math.cos(self.angle)
        delta_x = self.speed * math.sin(self.angle)
        self.set_position(self.pos[0] + delta_x, self.pos[1] - delta_y)

    def render(self):
        glBegin(GL_QUADS)
        glColor3ub(155, 0, 0);
        glVertex2f(self.pos[0], self.pos[1]);
        glVertex2f(self.pos[0], self.pos[1] + self.size[0]);
        glVertex2f(self.pos[0] + self.size[0], self.pos[1] + self.size[0]);
        glVertex2f(self.pos[0] + self.size[0], self.pos[1]);
        glEnd()
<commit_msg>Increase default ball speed<commit_after>from basesprite import BaseSprite
from OpenGL.GL import *
from OpenGL.GLU import *
import math

class Ball(BaseSprite):

    def __init__(self, start_pos, size):
        BaseSprite.__init__(self, start_pos, (size, size))
        self.angle = math.radians(45)
        self.speed = 2.5

    def update(self):

        if self.pos[0] > 800:
            self.angle = - self.angle

        elif self.pos[0] < 0:
            self.angle = - self.angle

        if self.pos[1] > 600:
            self.angle = math.pi - self.angle

        elif self.pos[1] < 0:
            self.angle = math.pi - self.angle

        delta_y = self.speed * math.cos(self.angle)
        delta_x = self.speed * math.sin(self.angle)
        self.set_position(self.pos[0] + delta_x, self.pos[1] - delta_y)

    def render(self):
        glBegin(GL_QUADS)
        glColor3ub(155, 0, 0);
        glVertex2f(self.pos[0], self.pos[1]);
        glVertex2f(self.pos[0], self.pos[1] + self.size[0]);
        glVertex2f(self.pos[0] + self.size[0], self.pos[1] + self.size[0]);
        glVertex2f(self.pos[0] + self.size[0], self.pos[1]);
        glEnd()
<|endoftext|>


<commit_before>"""Constrained multivariate least-squares optimization"""

import warnings

from numpy import array, take, eye, triu, transpose, dot, finfo
from numpy import empty_like, sqrt, cos, sin, arcsin
from numpy import atleast_1d, shape, issubdtype, dtype
from scipy.optimize import _minpack, leastsq

def _internal2external_grad(xi, bounds):
    """
    Calculate the internal (unconstrained) to external (constained)
    parameter gradiants.
    """
    grad = empty_like(xi)
    for i, (v, bound) in enumerate(zip(xi, bounds)):
        lower, upper = bound
        if lower is None and upper is None:  # No constraints
            grad[i] = 1.0
        elif upper is None:     # only lower bound
            grad[i] = v / sqrt(v * v + 1.)
        elif lower is None:     # only upper bound
            grad[i] = -v / sqrt(v * v + 1.)
        else:   # lower and upper bounds
            grad[i] = (upper - lower) * cos(v) / 2.
    return grad

def _internal2external_func(bounds):
    """
    Make a function which converts between internal (unconstrained) and
    external (constrained) parameters.
    """
    ls = [_internal2external_lambda(b) for b in bounds]

    def convert_i2e(xi):
        xe = empty_like(xi)
        xe[:] = [l(p) for l, p in zip(ls, xi)]
        return xe

    return convert_i2e

def _internal2external_lambda(bound):
    """
    Make a lambda function which converts a single internal (uncontrained)
    parameter to a external (constrained) parameter.
    """
    lower, upper = bound

    if lower is None and upper is None:  # no constraints
        return lambda x: x
    elif upper is None:     # only lower bound
        return lambda x: lower - 1. + sqrt(x * x + 1.)
    elif lower is None:     # only upper bound
        return lambda x: upper + 1. - sqrt(x * x + 1.)
    else:
        return lambda x: lower + ((upper - lower) / 2.) * (sin(x) + 1.)

def _external2internal_func(bounds):
    """
    Make a function which converts between external (constrained) and
    internal (unconstrained) parameters.
    """
    ls = [_external2internal_lambda(b) for b in bounds]

    def convert_e2i(xe):
        xi = empty_like(xe)
        xi[:] = [l(p) for l, p in zip(ls, xe)]
        return xi

    return convert_e2i

def _external2internal_lambda(bound):
    """
    Make a lambda function which converts an single external (constrained)
    parameter to a internal (unconstrained) parameter.
    """
    lower, upper = bound

    if lower is None and upper is None:  # no constraints
        return lambda x: x
    elif upper is None:     # only lower bound
        return lambda x: sqrt((x - lower + 1.) ** 2 - 1)
    elif lower is None:     # only upper bound
        return lambda x: sqrt((upper - x + 1.) ** 2 - 1)
    else:
        return lambda x: arcsin((2. * (x - lower) / (upper - lower)) - 1.)

def _check_func(checker, argname, thefunc, x0, args, numinputs, output_shape=None):
    res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
    if (output_shape is not None) and (shape(res) != output_shape):
        if (output_shape[0] != 1):
            if len(output_shape) > 1:
                if output_shape[1] == 1:
                    return shape(res)
            msg = "%s: there is a mismatch between the input and output " \
                  "shape of the '%s' argument" % (checker, argname)
            func_name = getattr(thefunc, '__name__', None)
            if func_name:
                msg += " '%s'." % func_name
            else:
                msg += "."
            raise TypeError(msg)
    if issubdtype(res.dtype, inexact):
        dt = res.dtype
    else:
        dt = dtype(float)
    return shape(res), dt

def leastsqbound(func, x0, args=(), bounds=None, Dfun=None, full_output=0,
                 col_deriv=0, ftol=1.49012e-8, xtol=1.49012e-8,
                 gtol=0.0, maxfev=0, epsfcn=None, factor=100, diag=None):
    """
    Bounded minimization of the sum of squares of a set of equations.

    ::

        x = arg min(sum(func(y)**2,axis=0))
                 y

    Parameters
    ----------
    func : callable
        should take at least one (possibly length N vector) argument and
        returns M floating point numbers.
    x0 : ndarray
        The starting estimate for the minimization.
    args : tuple
        Any extra arguments to func are placed in this tuple.
    bounds : list
        ``(min, max)`` pairs for each element in ``x``, defining
        the bounds on that parameter. Use None for one of ``min`` or
        ``max`` when there is no bound in that direction.
    Dfun : callable
        A function or method to compute the Jacobian of func with derivatives
        across the rows. If this is None, the Jacobian will be estimated.
    full_output : bool
        non-zero to return all optional outputs.
    col_deriv : bool
        non-zero to specify that the Jacobian function computes derivatives
        down the columns (faster, because there is no transpose operation).
    ftol : float
        Relative error desired in the sum of squares.
    xtol : float
        Relative error desired in the approximate solution.
    gtol : float
        Orthogonality desired between the function vector and the columns of
        the Jacobian.
    maxfev : int
        The maximum number of calls to the function. If zero, then 100*(N+1) is
        the maximum where N is the number of elements in x0.
    epsfcn : float
        A suitable step length for the forward-difference approximation of the
        Jacobian (for Dfun=None). If epsfcn is less than the machine precision,
        it is assumed that the relative errors in the functions are of the
        order of the machine precision.
    factor : float
        A parameter determining the initial step bound
        (``factor * || diag * x||``). Should be in interval ``(0.1, 100)``.
    diag : sequence
        N positive entries that serve as a scale factors for the variables.

    Returns
    -------
    x : ndarray
        The solution (or the result of the last iteration for an unsuccessful
        call).
    cov_x : ndarray
        Uses the fjac and ipvt optional outputs to construct an
        estimate of the jacobian around the solution.  ``None`` if a
        singular matrix encountered (indicates very flat curvature in
        some direction).  This matrix must be multiplied by the
        residual standard deviation to get the covariance of the
        parameter estimates -- see curve_fit.
    infodict : dict
        a dictionary of optional outputs with the key s::

            - 'nfev' : the number of function calls
            - 'fvec' : the function evaluated at the output
            - 'fjac' : A permutation of the R matrix of a QR
                     factorization of the final approximate
                     Jacobian matrix, stored column wise.
                     Together with ipvt, the covariance of the
                     estimate can be approximated.
            - 'ipvt' : an integer array of length N which defines
                     a permutation matrix, p, such that
                     fjac*p = q*r, where r is upper triangular
                     with diagonal elements of nonincreasing
                     magnitude. Column j of p is column ipvt(j)
                     of the identity matrix.
            - 'qtf'  : the vector (transpose(q) * fvec).

    mesg : str
        A string message giving information about the cause of failure.
    ier : int
        An integer flag.  If it is equal to 1, 2, 3 or 4, the solution was
        found.  Otherwise, the solution was not found. In either case, the
        optional output variable 'mesg' gives more information.

    Notes
    -----
    "leastsq" is a wrapper around MINPACK's lmdif and lmder algorithms.

    cov_x is a Jacobian approximation to the Hessian of the least squares
    objective function.
    This approximation assumes that the objective function is based on the
    difference between some observed target data (ydata) and a (non-linear)
    function of the parameters `f(xdata, params)` ::

           func(params) = ydata - f(xdata, params)

    so that the objective function is ::

           min   sum((ydata - f(xdata, params))**2, axis=0)
         params

    Contraints on the parameters are enforced using an internal parameter list
    with appropiate transformations such that these internal parameters can be
    optimized without constraints. The transfomation between a given internal
    parameter, p_i, and a external parameter, p_e, are as follows:

    With ``min`` and ``max`` bounds defined ::

        p_i = arcsin((2 * (p_e - min) / (max - min)) - 1.)
        p_e = min + ((max - min) / 2.) * (sin(p_i) + 1.)

    With only ``max`` defined ::

        p_i = sqrt((max - p_e + 1.)**2 - 1.)
        p_e = max + 1. - sqrt(p_i**2 + 1.)

    With only ``min`` defined ::

        p_i = sqrt((p_e - min + 1.)**2 - 1.)
        p_e = min - 1. + sqrt(p_i**2 + 1.)

    These transfomations are used in the MINUIT package, and described in
    detail in the section 1.3.1 of the MINUIT User's Guide.

    To Do
    -----
    Currently the ``factor`` and ``diag`` parameters scale the
    internal parameter list, but should scale the external parameter list.

    The `qtf` vector in the infodic dictionary reflects internal parameter
    list, it should be correct to reflect the external parameter list.

    References
    ----------
    * F. James and M. Winkler. MINUIT User's Guide, July 16, 2004.

    """
    # use leastsq if no bounds are present
    if bounds is None:
        return leastsq(func, x0, args, Dfun, full_output, col_deriv,
                       ftol, xtol, gtol, maxfev, epsfcn, factor, diag)

    # create function which convert between internal and external parameters
    i2e = _internal2external_func(bounds)
    e2i = _external2internal_func(bounds)

    x0 = array(x0, ndmin=1)
    i0 = e2i(x0)
    n = len(x0)
    if len(bounds) != n:
        raise ValueError('length of x0 != length of bounds')
    if not isinstance(args, tuple):
        args = (args,)
    m, dtype = _check_func('leastsq', 'func', func, x0, args, n)
    if n > m:
        raise TypeError('Improper input: N=%s must not exceed M=%s' % (n, m))
    if epsfcn is None:
        epsfcn = sqrt(finfo(dtype).eps)

    # define a wrapped func which accept internal parameters, converts them
    # to external parameters and calls func
    def wfunc(x, *args):
        return func(i2e(x), *args)

    if Dfun is None:
        if (maxfev == 0):
            maxfev = 200 * (n + 1)
        retval = _minpack._lmdif(wfunc, i0, args, full_output, ftol, xtol,
                                 gtol, maxfev, epsfcn, factor, diag)
    else:
        if col_deriv:
            _check_func('leastsq', 'Dfun', Dfun, x0, args, n, (n, m))
        else:
            _check_func('leastsq', 'Dfun', Dfun, x0, args, n, (m, n))
        if (maxfev == 0):
            maxfev = 100 * (n + 1)

        def wDfun(x, *args):  # wrapped Dfun
            return Dfun(i2e(x), *args)

        retval = _minpack._lmder(func, wDfun, i0, args, full_output,
                                 col_deriv, ftol, xtol, gtol, maxfev,
                                 factor, diag)

    errors = {0: ["Improper input parameters.", TypeError],
              1: ["Both actual and predicted relative reductions "
                  "in the sum of squares\n  are at most %f" % ftol, None],
              2: ["The relative error between two consecutive "
                  "iterates is at most %f" % xtol, None],
              3: ["Both actual and predicted relative reductions in "
                  "the sum of squares\n  are at most %f and the "
                  "relative error between two consecutive "
                  "iterates is at \n  most %f" % (ftol, xtol), None],
              4: ["The cosine of the angle between func(x) and any "
                  "column of the\n  Jacobian is at most %f in "
                  "absolute value" % gtol, None],
              5: ["Number of calls to function has reached "
                  "maxfev = %d." % maxfev, ValueError],
              6: ["ftol=%f is too small, no further reduction "
                  "in the sum of squares\n  is possible.""" % ftol,
                  ValueError],
              7: ["xtol=%f is too small, no further improvement in "
                  "the approximate\n  solution is possible." % xtol,
                  ValueError],
              8: ["gtol=%f is too small, func(x) is orthogonal to the "
                  "columns of\n  the Jacobian to machine "
                  "precision." % gtol, ValueError],
              'unknown': ["Unknown error.", TypeError]}

    info = retval[-1]    # The FORTRAN return value

    if (info not in [1, 2, 3, 4] and not full_output):
        if info in [5, 6, 7, 8]:
            warnings.warn(errors[info][0], RuntimeWarning)
        else:
            try:
                raise errors[info][1](errors[info][0])
            except KeyError:
                raise errors['unknown'][1](errors['unknown'][0])

    mesg = errors[info][0]
    x = i2e(retval[0])  # internal params to external params

    if full_output:
        # convert fjac from internal params to external
        grad = _internal2external_grad(retval[0], bounds)
        retval[1]['fjac'] = (retval[1]['fjac'].T / take(grad,
                             retval[1]['ipvt'] - 1)).T
        cov_x = None
        if info in [1, 2, 3, 4]:
            from numpy.dual import inv
            from numpy.linalg import LinAlgError
            perm = take(eye(n), retval[1]['ipvt'] - 1, 0)
            r = triu(transpose(retval[1]['fjac'])[:n, :])
            R = dot(r, perm)
            try:
                cov_x = inv(dot(transpose(R), R))
            except LinAlgError:
                pass
        return (x, cov_x) + retval[1:-1] + (mesg, info)
    else:
        return (x, info)
<commit_msg>MAINT: minor fixes to bring leastsqbound more in line with Scipy's leastsq<commit_after>"""Constrained multivariate least-squares optimization"""

import warnings

from numpy import array, take, eye, triu, transpose, dot, finfo
from numpy import empty_like, sqrt, cos, sin, arcsin
from numpy import atleast_1d, shape, issubdtype, dtype, inexact
from scipy.optimize import _minpack, leastsq

def _internal2external_grad(xi, bounds):
    """
    Calculate the internal (unconstrained) to external (constained)
    parameter gradiants.
    """
    grad = empty_like(xi)
    for i, (v, bound) in enumerate(zip(xi, bounds)):
        lower, upper = bound
        if lower is None and upper is None:  # No constraints
            grad[i] = 1.0
        elif upper is None:     # only lower bound
            grad[i] = v / sqrt(v * v + 1.)
        elif lower is None:     # only upper bound
            grad[i] = -v / sqrt(v * v + 1.)
        else:   # lower and upper bounds
            grad[i] = (upper - lower) * cos(v) / 2.
    return grad

def _internal2external_func(bounds):
    """
    Make a function which converts between internal (unconstrained) and
    external (constrained) parameters.
    """
    ls = [_internal2external_lambda(b) for b in bounds]

    def convert_i2e(xi):
        xe = empty_like(xi)
        xe[:] = [l(p) for l, p in zip(ls, xi)]
        return xe

    return convert_i2e

def _internal2external_lambda(bound):
    """
    Make a lambda function which converts a single internal (uncontrained)
    parameter to a external (constrained) parameter.
    """
    lower, upper = bound

    if lower is None and upper is None:  # no constraints
        return lambda x: x
    elif upper is None:     # only lower bound
        return lambda x: lower - 1. + sqrt(x * x + 1.)
    elif lower is None:     # only upper bound
        return lambda x: upper + 1. - sqrt(x * x + 1.)
    else:
        return lambda x: lower + ((upper - lower) / 2.) * (sin(x) + 1.)

def _external2internal_func(bounds):
    """
    Make a function which converts between external (constrained) and
    internal (unconstrained) parameters.
    """
    ls = [_external2internal_lambda(b) for b in bounds]

    def convert_e2i(xe):
        xi = empty_like(xe)
        xi[:] = [l(p) for l, p in zip(ls, xe)]
        return xi

    return convert_e2i

def _external2internal_lambda(bound):
    """
    Make a lambda function which converts an single external (constrained)
    parameter to a internal (unconstrained) parameter.
    """
    lower, upper = bound

    if lower is None and upper is None:  # no constraints
        return lambda x: x
    elif upper is None:     # only lower bound
        return lambda x: sqrt((x - lower + 1.) ** 2 - 1)
    elif lower is None:     # only upper bound
        return lambda x: sqrt((upper - x + 1.) ** 2 - 1)
    else:
        return lambda x: arcsin((2. * (x - lower) / (upper - lower)) - 1.)

def _check_func(checker, argname, thefunc, x0, args, numinputs,
                output_shape=None):
    res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
    if (output_shape is not None) and (shape(res) != output_shape):
        if (output_shape[0] != 1):
            if len(output_shape) > 1:
                if output_shape[1] == 1:
                    return shape(res)
            msg = "%s: there is a mismatch between the input and output " \
                  "shape of the '%s' argument" % (checker, argname)
            func_name = getattr(thefunc, '__name__', None)
            if func_name:
                msg += " '%s'." % func_name
            else:
                msg += "."
            raise TypeError(msg)
    if issubdtype(res.dtype, inexact):
        dt = res.dtype
    else:
        dt = dtype(float)
    return shape(res), dt

def leastsqbound(func, x0, args=(), bounds=None, Dfun=None, full_output=0,
                 col_deriv=0, ftol=1.49012e-8, xtol=1.49012e-8,
                 gtol=0.0, maxfev=0, epsfcn=None, factor=100, diag=None):
    """
    Bounded minimization of the sum of squares of a set of equations.

    ::

        x = arg min(sum(func(y)**2,axis=0))
                 y

    Parameters
    ----------
    func : callable
        should take at least one (possibly length N vector) argument and
        returns M floating point numbers.
    x0 : ndarray
        The starting estimate for the minimization.
    args : tuple
        Any extra arguments to func are placed in this tuple.
    bounds : list
        ``(min, max)`` pairs for each element in ``x``, defining
        the bounds on that parameter. Use None for one of ``min`` or
        ``max`` when there is no bound in that direction.
    Dfun : callable
        A function or method to compute the Jacobian of func with derivatives
        across the rows. If this is None, the Jacobian will be estimated.
    full_output : bool
        non-zero to return all optional outputs.
    col_deriv : bool
        non-zero to specify that the Jacobian function computes derivatives
        down the columns (faster, because there is no transpose operation).
    ftol : float
        Relative error desired in the sum of squares.
    xtol : float
        Relative error desired in the approximate solution.
    gtol : float
        Orthogonality desired between the function vector and the columns of
        the Jacobian.
    maxfev : int
        The maximum number of calls to the function. If zero, then 100*(N+1) is
        the maximum where N is the number of elements in x0.
    epsfcn : float
        A suitable step length for the forward-difference approximation of the
        Jacobian (for Dfun=None). If epsfcn is less than the machine precision,
        it is assumed that the relative errors in the functions are of the
        order of the machine precision.
    factor : float
        A parameter determining the initial step bound
        (``factor * || diag * x||``). Should be in interval ``(0.1, 100)``.
    diag : sequence
        N positive entries that serve as a scale factors for the variables.

    Returns
    -------
    x : ndarray
        The solution (or the result of the last iteration for an unsuccessful
        call).
    cov_x : ndarray
        Uses the fjac and ipvt optional outputs to construct an
        estimate of the jacobian around the solution.  ``None`` if a
        singular matrix encountered (indicates very flat curvature in
        some direction).  This matrix must be multiplied by the
        residual standard deviation to get the covariance of the
        parameter estimates -- see curve_fit.
    infodict : dict
        a dictionary of optional outputs with the key s::

            - 'nfev' : the number of function calls
            - 'fvec' : the function evaluated at the output
            - 'fjac' : A permutation of the R matrix of a QR
                     factorization of the final approximate
                     Jacobian matrix, stored column wise.
                     Together with ipvt, the covariance of the
                     estimate can be approximated.
            - 'ipvt' : an integer array of length N which defines
                     a permutation matrix, p, such that
                     fjac*p = q*r, where r is upper triangular
                     with diagonal elements of nonincreasing
                     magnitude. Column j of p is column ipvt(j)
                     of the identity matrix.
            - 'qtf'  : the vector (transpose(q) * fvec).

    mesg : str
        A string message giving information about the cause of failure.
    ier : int
        An integer flag.  If it is equal to 1, 2, 3 or 4, the solution was
        found.  Otherwise, the solution was not found. In either case, the
        optional output variable 'mesg' gives more information.

    Notes
    -----
    "leastsq" is a wrapper around MINPACK's lmdif and lmder algorithms.

    cov_x is a Jacobian approximation to the Hessian of the least squares
    objective function.
    This approximation assumes that the objective function is based on the
    difference between some observed target data (ydata) and a (non-linear)
    function of the parameters `f(xdata, params)` ::

           func(params) = ydata - f(xdata, params)

    so that the objective function is ::

           min   sum((ydata - f(xdata, params))**2, axis=0)
         params

    Contraints on the parameters are enforced using an internal parameter list
    with appropiate transformations such that these internal parameters can be
    optimized without constraints. The transfomation between a given internal
    parameter, p_i, and a external parameter, p_e, are as follows:

    With ``min`` and ``max`` bounds defined ::

        p_i = arcsin((2 * (p_e - min) / (max - min)) - 1.)
        p_e = min + ((max - min) / 2.) * (sin(p_i) + 1.)

    With only ``max`` defined ::

        p_i = sqrt((max - p_e + 1.)**2 - 1.)
        p_e = max + 1. - sqrt(p_i**2 + 1.)

    With only ``min`` defined ::

        p_i = sqrt((p_e - min + 1.)**2 - 1.)
        p_e = min - 1. + sqrt(p_i**2 + 1.)

    These transfomations are used in the MINUIT package, and described in
    detail in the section 1.3.1 of the MINUIT User's Guide.

    To Do
    -----
    Currently the ``factor`` and ``diag`` parameters scale the
    internal parameter list, but should scale the external parameter list.

    The `qtf` vector in the infodic dictionary reflects internal parameter
    list, it should be correct to reflect the external parameter list.

    References
    ----------
    * F. James and M. Winkler. MINUIT User's Guide, July 16, 2004.

    """
    # use leastsq if no bounds are present
    if bounds is None:
        return leastsq(func, x0, args, Dfun, full_output, col_deriv,
                       ftol, xtol, gtol, maxfev, epsfcn, factor, diag)

    # create function which convert between internal and external parameters
    i2e = _internal2external_func(bounds)
    e2i = _external2internal_func(bounds)

    x0 = asarray(x0).flatten()
    i0 = e2i(x0)
    n = len(x0)
    if len(bounds) != n:
        raise ValueError('length of x0 != length of bounds')
    if not isinstance(args, tuple):
        args = (args,)
    shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
    m = shape[0]
    if n > m:
        raise TypeError('Improper input: N=%s must not exceed M=%s' % (n, m))
    if epsfcn is None:
        epsfcn = finfo(dtype).eps

    # define a wrapped func which accept internal parameters, converts them
    # to external parameters and calls func
    def wfunc(x, *args):
        return func(i2e(x), *args)

    if Dfun is None:
        if (maxfev == 0):
            maxfev = 200 * (n + 1)
        retval = _minpack._lmdif(wfunc, i0, args, full_output, ftol, xtol,
                                 gtol, maxfev, epsfcn, factor, diag)
    else:
        if col_deriv:
            _check_func('leastsq', 'Dfun', Dfun, x0, args, n, (n, m))
        else:
            _check_func('leastsq', 'Dfun', Dfun, x0, args, n, (m, n))
        if (maxfev == 0):
            maxfev = 100 * (n + 1)

        def wDfun(x, *args):  # wrapped Dfun
            return Dfun(i2e(x), *args)

        retval = _minpack._lmder(func, wDfun, i0, args, full_output,
                                 col_deriv, ftol, xtol, gtol, maxfev,
                                 factor, diag)

    errors = {0: ["Improper input parameters.", TypeError],
              1: ["Both actual and predicted relative reductions "
                  "in the sum of squares\n  are at most %f" % ftol, None],
              2: ["The relative error between two consecutive "
                  "iterates is at most %f" % xtol, None],
              3: ["Both actual and predicted relative reductions in "
                  "the sum of squares\n  are at most %f and the "
                  "relative error between two consecutive "
                  "iterates is at \n  most %f" % (ftol, xtol), None],
              4: ["The cosine of the angle between func(x) and any "
                  "column of the\n  Jacobian is at most %f in "
                  "absolute value" % gtol, None],
              5: ["Number of calls to function has reached "
                  "maxfev = %d." % maxfev, ValueError],
              6: ["ftol=%f is too small, no further reduction "
                  "in the sum of squares\n  is possible.""" % ftol,
                  ValueError],
              7: ["xtol=%f is too small, no further improvement in "
                  "the approximate\n  solution is possible." % xtol,
                  ValueError],
              8: ["gtol=%f is too small, func(x) is orthogonal to the "
                  "columns of\n  the Jacobian to machine "
                  "precision." % gtol, ValueError],
              'unknown': ["Unknown error.", TypeError]}

    info = retval[-1]    # The FORTRAN return value

    if (info not in [1, 2, 3, 4] and not full_output):
        if info in [5, 6, 7, 8]:
            warnings.warn(errors[info][0], RuntimeWarning)
        else:
            try:
                raise errors[info][1](errors[info][0])
            except KeyError:
                raise errors['unknown'][1](errors['unknown'][0])

    mesg = errors[info][0]
    x = i2e(retval[0])  # internal params to external params

    if full_output:
        # convert fjac from internal params to external
        grad = _internal2external_grad(retval[0], bounds)
        retval[1]['fjac'] = (retval[1]['fjac'].T / take(grad,
                             retval[1]['ipvt'] - 1)).T
        cov_x = None
        if info in [1, 2, 3, 4]:
            from numpy.dual import inv
            from numpy.linalg import LinAlgError
            perm = take(eye(n), retval[1]['ipvt'] - 1, 0)
            r = triu(transpose(retval[1]['fjac'])[:n, :])
            R = dot(r, perm)
            try:
                cov_x = inv(dot(transpose(R), R))
            except LinAlgError:
                pass
        return (x, cov_x) + retval[1:-1] + (mesg, info)
    else:
        return (x, info)
<|endoftext|>


<commit_before>from conans import ConanFile
import os

class VenturaConan(ConanFile):
    name = "ventura"
    version = "0.7"
    generators = "cmake"
    requires = "silicium/0.12@TyRoXx/stable"
    url="http://github.com/TyRoXx/ventura"
    license="MIT"
    exports="ventura/*"

    def package(self):
        self.copy(pattern="*.hpp", dst="include/ventura", src="ventura", keep_path=True)

    def imports(self):
        self.copy("*.dll", dst="bin", src="bin")
        self.copy("*.dylib*", dst="bin", src="lib")
<commit_msg>bump version to 0.8<commit_after>from conans import ConanFile
import os

class VenturaConan(ConanFile):
    name = "ventura"
    version = "0.8"
    generators = "cmake"
    requires = "silicium/0.12@TyRoXx/stable"
    url="http://github.com/TyRoXx/ventura"
    license="MIT"
    exports="ventura/*"

    def package(self):
        self.copy(pattern="*.hpp", dst="include/ventura", src="ventura", keep_path=True)

    def imports(self):
        self.copy("*.dll", dst="bin", src="bin")
        self.copy("*.dylib*", dst="bin", src="lib")
<|endoftext|>


<commit_before>from conans import ConanFile
from conans.tools import download, unzip
import os

VERSION = "0.0.5"

class VeraPPTargetCmakeConan(ConanFile):
    name = "verapp-cmake"
    version = os.environ.get("CONAN_VERSION_OVERRIDE", VERSION)
    generators = "cmake"
    requires = ("cmake-include-guard/master@smspillaz/cmake-include-guard",
                "tooling-find-pkg-util/master@smspillaz/tooling-find-pkg-util",
                "tooling-cmake-util/master@smspillaz/tooling-cmake-util")
    url = "http://github.com/polysquare/verapp-cmake"
    license = "MIT"
    options = {
        "dev": [True, False]
    }
    default_options = "dev=False"

    def requirements(self):
        if self.options.dev:
            self.requires("cmake-module-common/master@smspillaz/cmake-module-common")

    def source(self):
        zip_name = "verapp-cmake.zip"
        download("https://github.com/polysquare/"
                 "verapp-cmake/archive/{version}.zip"
                 "".format(version="v" + VERSION),
                 zip_name)
        unzip(zip_name)
        os.unlink(zip_name)

    def package(self):
        self.copy(pattern="Find*.cmake",
                  dst="",
                  src="verapp-cmake-" + VERSION,
                  keep_path=True)
        self.copy(pattern="*.cmake",
                  dst="cmake/verapp-cmake",
                  src="verapp-cmake-" + VERSION,
                  keep_path=True)
<commit_msg>Bump version: 0.0.5 -> 0.0.6<commit_after>from conans import ConanFile
from conans.tools import download, unzip
import os

VERSION = "0.0.6"

class VeraPPTargetCmakeConan(ConanFile):
    name = "verapp-cmake"
    version = os.environ.get("CONAN_VERSION_OVERRIDE", VERSION)
    generators = "cmake"
    requires = ("cmake-include-guard/master@smspillaz/cmake-include-guard",
                "tooling-find-pkg-util/master@smspillaz/tooling-find-pkg-util",
                "tooling-cmake-util/master@smspillaz/tooling-cmake-util")
    url = "http://github.com/polysquare/verapp-cmake"
    license = "MIT"
    options = {
        "dev": [True, False]
    }
    default_options = "dev=False"

    def requirements(self):
        if self.options.dev:
            self.requires("cmake-module-common/master@smspillaz/cmake-module-common")

    def source(self):
        zip_name = "verapp-cmake.zip"
        download("https://github.com/polysquare/"
                 "verapp-cmake/archive/{version}.zip"
                 "".format(version="v" + VERSION),
                 zip_name)
        unzip(zip_name)
        os.unlink(zip_name)

    def package(self):
        self.copy(pattern="Find*.cmake",
                  dst="",
                  src="verapp-cmake-" + VERSION,
                  keep_path=True)
        self.copy(pattern="*.cmake",
                  dst="cmake/verapp-cmake",
                  src="verapp-cmake-" + VERSION,
                  keep_path=True)
<|endoftext|>


<commit_before>from conans import ConanFile, CMake

class CausalDynamicalTriangulations(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    requires = "boost/1.68.0@conan/stable", "catch2/2.4.0@bincrafters/stable", "TBB/2018_U6@conan/stable",\
               "eigen/3.3.5@conan/stable", "docopt/0.6.2@conan/stable",\
               "date/2.4.1@bincrafters/stable", "gsl_microsoft/1.0.0@bincrafters/stable"
    generators = "cmake"
    default_options = "boost:without_thread=False"
    # default_options = "Boost:header_only=True"

    def build(self):
        cmake = CMake(self)
        cmake.verbose = True
        cmake.definitions["CMAKE_BUILD_TYPE"] = "RelWithDebInfo"
        cmake.configure(args=["CMAKE_EXPORT_COMPILE_COMMANDS=ON"])
        cmake.build()

    def build_requirements(self):
        self.build_requires("cmake_installer/3.11.3@conan/stable")<commit_msg>Revert TBB/2018_U6@conan/stable<commit_after>from conans import ConanFile, CMake

class CausalDynamicalTriangulations(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    requires = "boost/1.68.0@conan/stable", "catch2/2.4.0@bincrafters/stable", "TBB/2018_U5@conan/stable",\
               "eigen/3.3.5@conan/stable", "docopt/0.6.2@conan/stable",\
               "date/2.4.1@bincrafters/stable", "gsl_microsoft/1.0.0@bincrafters/stable"
    generators = "cmake"
    default_options = "boost:without_thread=False"
    # default_options = "Boost:header_only=True"

    def build(self):
        cmake = CMake(self)
        cmake.verbose = True
        cmake.definitions["CMAKE_BUILD_TYPE"] = "RelWithDebInfo"
        cmake.configure(args=["CMAKE_EXPORT_COMPILE_COMMANDS=ON"])
        cmake.build()

    def build_requirements(self):
        self.build_requires("cmake_installer/3.11.3@conan/stable")<|endoftext|>


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

# Note: Conan is supported on a best-effort basis. Abseil doesn't use Conan
# internally, so we won't know if it stops working. We may ask community
# members to help us debug any problems that arise.

from conans import ConanFile, CMake, tools
from conans.errors import ConanInvalidConfiguration
from conans.model.version import Version

class AbseilConan(ConanFile):
    name = "abseil"
    url = "https://github.com/abseil/abseil-cpp"
    homepage = url
    author = "Abseil <abseil-io@googlegroups.com>"
    description = "Abseil Common Libraries (C++) from Google"
    license = "Apache-2.0"
    topics = ("conan", "abseil", "abseil-cpp", "google", "common-libraries")
    exports = ["LICENSE"]
    exports_sources = ["CMakeLists.txt", "CMake/*", "absl/*"]
    generators = "cmake"
    settings = "os", "arch", "compiler", "build_type"

    def configure(self):
        if self.settings.os == "Windows" and \
           self.settings.compiler == "Visual Studio" and \
           Version(self.settings.compiler.version.value) < "14":
            raise ConanInvalidConfiguration("Abseil does not support MSVC < 14")

    def build(self):
        tools.replace_in_file("CMakeLists.txt", "project(absl CXX)", "project(absl CXX)\ninclude(conanbuildinfo.cmake)\nconan_basic_setup()")
        cmake = CMake(self)
        cmake.definitions["BUILD_TESTING"] = False
        cmake.configure()
        cmake.build()

    def package(self):
        self.copy("LICENSE", dst="licenses")
        self.copy("*.h", dst="include", src=".")
        self.copy("*.inc", dst="include", src=".")
        self.copy("*.a", dst="lib", src=".", keep_path=False)
        self.copy("*.lib", dst="lib", src=".", keep_path=False)

    def package_info(self):
        if self.settings.os == "Linux":
            self.cpp_info.libs = ["-Wl,--start-group"]
        self.cpp_info.libs.extend(tools.collect_libs(self))
        if self.settings.os == "Linux":
            self.cpp_info.libs.extend(["-Wl,--end-group", "pthread"])
<commit_msg>Fix conan build step<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Note: Conan is supported on a best-effort basis. Abseil doesn't use Conan
# internally, so we won't know if it stops working. We may ask community
# members to help us debug any problems that arise.

from conans import ConanFile, CMake, tools
from conans.errors import ConanInvalidConfiguration
from conans.model.version import Version

class AbseilConan(ConanFile):
    name = "abseil"
    url = "https://github.com/abseil/abseil-cpp"
    homepage = url
    author = "Abseil <abseil-io@googlegroups.com>"
    description = "Abseil Common Libraries (C++) from Google"
    license = "Apache-2.0"
    topics = ("conan", "abseil", "abseil-cpp", "google", "common-libraries")
    exports = ["LICENSE"]
    exports_sources = ["CMakeLists.txt", "CMake/*", "absl/*"]
    generators = "cmake"
    settings = "os", "arch", "compiler", "build_type"

    def configure(self):
        if self.settings.os == "Windows" and \
           self.settings.compiler == "Visual Studio" and \
           Version(self.settings.compiler.version.value) < "14":
            raise ConanInvalidConfiguration("Abseil does not support MSVC < 14")

    def build(self):
        tools.replace_in_file("CMakeLists.txt", "project(absl LANGUAGES CXX)", "project(absl LANGUAGES CXX)\ninclude(conanbuildinfo.cmake)\nconan_basic_setup()")
        cmake = CMake(self)
        cmake.definitions["BUILD_TESTING"] = False
        cmake.configure()
        cmake.build()

    def package(self):
        self.copy("LICENSE", dst="licenses")
        self.copy("*.h", dst="include", src=".")
        self.copy("*.inc", dst="include", src=".")
        self.copy("*.a", dst="lib", src=".", keep_path=False)
        self.copy("*.lib", dst="lib", src=".", keep_path=False)

    def package_info(self):
        if self.settings.os == "Linux":
            self.cpp_info.libs = ["-Wl,--start-group"]
        self.cpp_info.libs.extend(tools.collect_libs(self))
        if self.settings.os == "Linux":
            self.cpp_info.libs.extend(["-Wl,--end-group", "pthread"])
<|endoftext|>


<commit_before>from conans import ConanFile, CMake
from conans.tools import os_info

class EngineConan(ConanFile):
    name = "engine"
    version = "1.0-beta25"
    url = "https://github.com/DEGoodmanWilson/engine.git"
    license = "MIT"
    settings = "os", "compiler", "build_type", "arch"
    requires = "cpr/1.2.0@DEGoodmanWilson/testing", "jsoncpp/1.7.3@theirix/stable"
    options = {"build_engine_tests":    [True, False],
               "build_engine_coverage": [True, False],
               "build_engine_examples": [True, False]}
    default_options = "build_engine_tests=False", "build_engine_coverage=False", "build_engine_examples=False", "cpr:use_system_curl=True"
    generators = "cmake"
    exports = ["*"]

    def config(self):
        if self.options.build_engine_coverage:
            self.options.build_engine_tests=True

        if self.options.build_engine_tests:
            self.requires.add("gtest/1.7.0@lasote/stable", private=False)
            self.options["gtest"].shared = False
            self.requires.add("luna/2.1@DEGoodmanWilson/stable", private=False)
        else:
            if "gtest" in self.requires:
                del self.requires["gtest"]
            if "luna" in self.requires:
                del self.require["luna"]

    def build(self):
        cmake = CMake(self.settings)
        build_engine_tests = "-DBUILD_ENGINE_TESTS=ON" if self.options.build_engine_tests else "-DBUILD_ENGINE_TESTS=OFF"
        build_engine_coverage = "-DBUILD_ENGINE_COVERAGE=ON" if self.options.build_engine_coverage else "-DBUILD_ENGINE_COVERAGE=OFF"
        build_engine_examples = "-DBUILD_ENGINE_EXAMPLES=ON" if self.options.build_engine_examples else "-DBUILD_ENGINE_EXAMPLES=OFF"

        self.run('cmake %s %s %s %s' % (build_engine_tests, build_engine_coverage, build_engine_examples, cmake.command_line))
        self.run('cmake --build . %s' % cmake.build_config)

    def package(self):
        self.copy("*.h", dst="include/slack", src="slack")
        self.copy("*.hpp", dst="include/slack", src="slack")
        self.copy("*.lib", dst="lib", src="lib")
        self.copy("*.a", dst="lib", src="lib")

    def package_info(self):
        self.cpp_info.libs = ["engine"]
        if os_info.is_linux:
            self.cpp_info.libs.append("pthread")
<commit_msg>Update to newest luna to use conan provided libmicrohttpd<commit_after>from conans import ConanFile, CMake
from conans.tools import os_info

class EngineConan(ConanFile):
    name = "engine"
    version = "1.0-beta25"
    url = "https://github.com/DEGoodmanWilson/engine.git"
    license = "MIT"
    settings = "os", "compiler", "build_type", "arch"
    requires = "cpr/1.2.0@DEGoodmanWilson/testing", "jsoncpp/1.7.3@theirix/stable"
    options = {"build_engine_tests":    [True, False],
               "build_engine_coverage": [True, False],
               "build_engine_examples": [True, False]}
    default_options = "build_engine_tests=False", "build_engine_coverage=False", "build_engine_examples=False", "cpr:use_system_curl=True"
    generators = "cmake"
    exports = ["*"]

    def config(self):
        if self.options.build_engine_coverage:
            self.options.build_engine_tests=True

        if self.options.build_engine_tests:
            self.requires.add("gtest/1.7.0@lasote/stable", private=False)
            self.options["gtest"].shared = False
            self.requires.add("luna/2.4.0@DEGoodmanWilson/stable", private=False)
        else:
            if "gtest" in self.requires:
                del self.requires["gtest"]
            if "luna" in self.requires:
                del self.require["luna"]

    def build(self):
        cmake = CMake(self.settings)
        build_engine_tests = "-DBUILD_ENGINE_TESTS=ON" if self.options.build_engine_tests else "-DBUILD_ENGINE_TESTS=OFF"
        build_engine_coverage = "-DBUILD_ENGINE_COVERAGE=ON" if self.options.build_engine_coverage else "-DBUILD_ENGINE_COVERAGE=OFF"
        build_engine_examples = "-DBUILD_ENGINE_EXAMPLES=ON" if self.options.build_engine_examples else "-DBUILD_ENGINE_EXAMPLES=OFF"

        self.run('cmake %s %s %s %s' % (build_engine_tests, build_engine_coverage, build_engine_examples, cmake.command_line))
        self.run('cmake --build . %s' % cmake.build_config)

    def package(self):
        self.copy("*.h", dst="include/slack", src="slack")
        self.copy("*.hpp", dst="include/slack", src="slack")
        self.copy("*.lib", dst="lib", src="lib")
        self.copy("*.a", dst="lib", src="lib")

    def package_info(self):
        self.cpp_info.libs = ["engine"]
        if os_info.is_linux:
            self.cpp_info.libs.append("pthread")
<|endoftext|>


<commit_before>from conans import ConanFile, CMake, tools
import os, shutil

#conan remote add conan-transit https://api.bintray.com/conan/conan/conan-transit
#conan remote add hulud https://api.bintray.com/conan/hulud/libs
#conan remote add pierousseau https://api.bintray.com/conan/pierousseau/libs

class OpenEXRIdConan(ConanFile):
    name = "OpenExrId"
    version = "1.0-beta.22"
    license = "MIT"
    url = "https://github.com/MercenariesEngineering/openexrid"
    description = "OpenEXR files able to isolate any object of a CG image with a perfect antialiazing "
    settings = "os", "compiler", "build_type", "arch"
    options = {"shared": [True, False], "fPIC": [True, False] }
    default_options = "shared=False","*:shared=False","fPIC=True"
    generators = "cmake"

    def requirements(self):
        self.requires("boost/1.70.0")
        self.requires("zlib/1.2.11")
        self.requires("libpng/1.6.37@pierousseau/stable")
        self.requires("OpenFx/1.4@pierousseau/stable")
        if (self.settings.compiler == "Visual Studio" and self.settings.compiler.version == 10) or (self.settings.compiler == "gcc" and self.settings.compiler.version == 4.1):
            self.requires("OpenImageIO/1.6.18@pierousseau/stable")
            self.requires("IlmBase/2.2.0@pierousseau/stable")
            self.requires("OpenEXR/2.2.0@pierousseau/stable")
            self.requires("re2/2016-02-01@pierousseau/stable")
        else:
            self.requires("OpenImageIO/2.1.15.0@mercseng/stable")
            self.requires("OpenEXR/2.5.1@mercseng/stable")
            self.requires("re2/2019-06-01@pierousseau/stable")

    def configure(self):
        if self.settings.os == "Linux":
            # fPIC option exists only on linux
            self.options["boost"].fPIC=True
            self.options["IlmBase"].fPIC=True
            self.options["OpenEXR"].fPIC=True
            #self.options["OpenFx"].fPIC=True
            self.options["OpenImageIO"].fPIC=True
            self.options["re2"].fPIC=True
            self.options["zlib"].fPIC=True

        if self.settings.compiler == "gcc" and self.settings.compiler.version == 4.1:
            self.options["libpng"].hardware_optimizations=False

    def source(self):
        self.run("git clone http://github.com/MercenariesEngineering/openexrid.git --branch %s" % self.version)

    def build(self):
        cmake = CMake(self)
        #cmake.verbose = True
        cmake.definitions["USE_CONAN"] = True
        cmake.definitions["BUILD_LIB"] = True
        cmake.definitions["BUILD_PLUGINS"] = False
        cmake.configure(source_dir="%s/openexrid" % self.source_folder)
        cmake.build()

    def package(self):
        self.copy("*.h", dst="include/openexrid", src="openexrid/openexrid")
        self.copy("*.lib", dst="lib", keep_path=False)
        self.copy("*.a", dst="lib", keep_path=False)

    def package_info(self):
        self.cpp_info.libs = tools.collect_libs(self)
<commit_msg>[Linux] Boost 1.70.0 does not compile easily in docker environment right now, rollback to 1.67.0.<commit_after>from conans import ConanFile, CMake, tools
import os, shutil

#conan remote add conan-transit https://api.bintray.com/conan/conan/conan-transit
#conan remote add hulud https://api.bintray.com/conan/hulud/libs
#conan remote add pierousseau https://api.bintray.com/conan/pierousseau/libs

class OpenEXRIdConan(ConanFile):
    name = "OpenExrId"
    version = "1.0-beta.22"
    license = "MIT"
    url = "https://github.com/MercenariesEngineering/openexrid"
    description = "OpenEXR files able to isolate any object of a CG image with a perfect antialiazing "
    settings = "os", "compiler", "build_type", "arch"
    options = {"shared": [True, False], "fPIC": [True, False] }
    default_options = "shared=False","*:shared=False","fPIC=True"
    generators = "cmake"

    def requirements(self):
        self.requires("zlib/1.2.11")
        self.requires("libpng/1.6.37@pierousseau/stable")
        self.requires("OpenFx/1.4@pierousseau/stable")
        if (self.settings.compiler == "Visual Studio" and self.settings.compiler.version == 10) or (self.settings.compiler == "gcc" and self.settings.compiler.version == 4.1):
            self.requires("OpenImageIO/1.6.18@pierousseau/stable")
            self.requires("IlmBase/2.2.0@pierousseau/stable")
            self.requires("OpenEXR/2.2.0@pierousseau/stable")
            self.requires("re2/2016-02-01@pierousseau/stable")
        else:
            self.requires("OpenImageIO/2.1.15.0@mercseng/stable")
            self.requires("OpenEXR/2.5.1@mercseng/stable")
            self.requires("re2/2019-06-01@pierousseau/stable")

        if self.settings.os == "Linux":
            self.requires("boost/1.67.0@conan/stable")
        else:
            self.requires("boost/1.70.0")

    def configure(self):
        if self.settings.os == "Linux":
            # fPIC option exists only on linux
            self.options["boost"].fPIC=True
            self.options["IlmBase"].fPIC=True
            self.options["OpenEXR"].fPIC=True
            #self.options["OpenFx"].fPIC=True
            self.options["OpenImageIO"].fPIC=True
            self.options["re2"].fPIC=True
            self.options["zlib"].fPIC=True

        if self.settings.compiler == "gcc" and self.settings.compiler.version == 4.1:
            self.options["libpng"].hardware_optimizations=False

    def source(self):
        self.run("git clone http://github.com/MercenariesEngineering/openexrid.git --branch %s" % self.version)

    def build(self):
        cmake = CMake(self)
        #cmake.verbose = True
        cmake.definitions["USE_CONAN"] = True
        cmake.definitions["BUILD_LIB"] = True
        cmake.definitions["BUILD_PLUGINS"] = False
        cmake.configure(source_dir="%s/openexrid" % self.source_folder)
        cmake.build()

    def package(self):
        self.copy("*.h", dst="include/openexrid", src="openexrid/openexrid")
        self.copy("*.lib", dst="lib", keep_path=False)
        self.copy("*.a", dst="lib", keep_path=False)

    def package_info(self):
        self.cpp_info.libs = tools.collect_libs(self)
<|endoftext|>