<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2005-2009 University of Deusto
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.
#
# This software consists of contributions made by many individuals,
# listed below:
#
# Author: Pablo Orduña <pablo@ordunya.com>
#         Jaime Irurzun <jaime.irurzun@gmail.com>
#

from voodoo.gen.caller_checker import caller_check
from voodoo.log import logged
from voodoo.override import Override
from weblab.exceptions.experiment.experiments.ud_xilinx_experiment import UdXilinxExperimentExceptions
from weblab.experiment.experiments.ud_xilinx_experiment.UdXilinxCommandSenders import UdXilinxCommandSender
from weblab.experiment.experiments.ud_xilinx_experiment.UdXilinxProgrammers import UdXilinxProgrammer
import os
import tempfile
import voodoo.log as log
import weblab.data.ServerType as ServerType
import weblab.exceptions.experiment.ExperimentExceptions as ExperimentExceptions
import weblab.experiment.Experiment as Experiment
import weblab.experiment.Util as ExperimentUtil
import weblab.experiment.devices.xilinx_impact.XilinxDevices as XilinxDevices
import weblab.experiment.devices.xilinx_impact.XilinxImpact as XilinxImpact
import weblab.experiment.experiments.ud_xilinx_experiment.UdBoardCommand as UdBoardCommand

#TODO: which exceptions should the user see and which ones should not?
class UdXilinxExperiment(Experiment.Experiment):

    def __init__(self, coord_address, locator, cfg_manager, *args, **kwargs):
        super(UdXilinxExperiment,self).__init__(*args, **kwargs)
        self._coord_address = coord_address
        self._locator = locator
        self._cfg_manager = cfg_manager

        self._xilinx_device_name, self._xilinx_device = self._load_xilinx_device()
        self._xilinx_impact = XilinxImpact.create(self._xilinx_device, cfg_manager)

        self._programmer = self._load_programmer()
        self._command_sender = self._load_command_sender()
        self.webcam_url = self._load_webcam_url()

    def _load_xilinx_device(self):
        device_name = self._cfg_manager.get_value('weblab_xilinx_experiment_xilinx_device')
        devices = [ i for i in XilinxDevices.getXilinxDevicesValues() if i.name == device_name ]
        if len(devices) == 1:
            return device_name, devices[0]
        else:
            raise UdXilinxExperimentExceptions.InvalidXilinxDeviceException(device_name)

    def _load_programmer(self):
        device_name = self._cfg_manager.get_value('xilinx_device_to_program')
        return UdXilinxProgrammer.create(device_name, self._cfg_manager, self._xilinx_impact)

    def _load_command_sender(self):
        device_name = self._cfg_manager.get_value('xilinx_device_to_send_commands')
        return UdXilinxCommandSender.create(device_name, self._cfg_manager)

    def _load_webcam_url(self):
        cfg_webcam_url = "%s_webcam_url" % self._xilinx_device_name.lower()
        return self._cfg_manager.get_value(cfg_webcam_url, "http://localhost")

    @Override(Experiment.Experiment)
    @caller_check(ServerType.Laboratory)
    @logged("info",except_for='file_content')
    def do_send_file_to_device(self, file_content, file_info):
        try:
            fd, file_name = tempfile.mkstemp(prefix='ud_xilinx_experiment_program', suffix='.' + self._xilinx_impact.get_suffix())
            try:
                try:
                    #TODO: encode? utf8?
                    if isinstance(file_content, unicode):
                        file_content_encoded = file_content.encode('utf8')
                    else:
                        file_content_encoded = file_content
                    file_content_recovered = ExperimentUtil.deserialize(file_content_encoded)
                    os.write(fd, file_content_recovered)
                finally:
                    os.close(fd)
                self._programmer.program(file_name)
            finally:
                os.remove(file_name)
        except Exception, e:
            #TODO: test me
            log.log(
                UdXilinxExperiment,
                log.LogLevel.Info,
                "Exception joining sending program to device: %s" % e.args[0]
            )
            log.log_exc(
                UdXilinxExperiment,
                log.LogLevel.Debug
            )
            raise ExperimentExceptions.SendingFileFailureException(
                    "Error sending file to device: %s" % e
                )
        self._clear()

    def _clear(self):
        # Kludge!!
        if self._xilinx_device_name == "PLD":
            try:
                for i in range(10):
                    self._command_sender.send_command(str(UdBoardCommand.ChangeSwitchCommand("on",i)))
                    self._command_sender.send_command(str(UdBoardCommand.ChangeSwitchCommand("off",i)))
            except Exception, e:
                raise ExperimentExceptions.SendingCommandFailureException(
                    "Error sending command to device: %s" % e
                )
        else:
            try:
                self._command_sender.send_command("CleanInputs")
            except Exception, e:
                raise ExperimentExceptions.SendingCommandFailureException(
                    "Error sending command to device: %s" % e
                )

    @logged("info")
    @Override(Experiment.Experiment)
    @caller_check(ServerType.Laboratory)
    def do_send_command_to_device(self, command):
        try:
            if command == 'WEBCAMURL':
                reply = "WEBCAMURL=" + self.webcam_url
                return reply
            self._command_sender.send_command(command)
        except Exception, e:
            raise ExperimentExceptions.SendingCommandFailureException(
                    "Error sending command to device: %s" % e
                )<commit_msg>Small last refactoring in UdXilinxExperiment.<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2005-2009 University of Deusto
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.
#
# This software consists of contributions made by many individuals,
# listed below:
#
# Author: Pablo Orduña <pablo@ordunya.com>
#         Jaime Irurzun <jaime.irurzun@gmail.com>
#

from voodoo.gen.caller_checker import caller_check
from voodoo.log import logged
from voodoo.override import Override
from weblab.exceptions.experiment.experiments.ud_xilinx_experiment import UdXilinxExperimentExceptions
from weblab.experiment.experiments.ud_xilinx_experiment.UdXilinxCommandSenders import UdXilinxCommandSender
from weblab.experiment.experiments.ud_xilinx_experiment.UdXilinxProgrammers import UdXilinxProgrammer
import os
import tempfile
import voodoo.log as log
import weblab.data.ServerType as ServerType
import weblab.exceptions.experiment.ExperimentExceptions as ExperimentExceptions
import weblab.experiment.Experiment as Experiment
import weblab.experiment.Util as ExperimentUtil
import weblab.experiment.devices.xilinx_impact.XilinxDevices as XilinxDevices
import weblab.experiment.devices.xilinx_impact.XilinxImpact as XilinxImpact
import weblab.experiment.experiments.ud_xilinx_experiment.UdBoardCommand as UdBoardCommand

#TODO: which exceptions should the user see and which ones should not?
class UdXilinxExperiment(Experiment.Experiment):

    def __init__(self, coord_address, locator, cfg_manager, *args, **kwargs):
        super(UdXilinxExperiment,self).__init__(*args, **kwargs)
        self._coord_address = coord_address
        self._locator = locator
        self._cfg_manager = cfg_manager

        self._xilinx_device, self._xilinx_impact = self._load_xilinx_device()
        self._programmer = self._load_programmer()
        self._command_sender = self._load_command_sender()
        self.webcam_url = self._load_webcam_url()

    def _load_xilinx_device(self):
        device_name = self._cfg_manager.get_value('weblab_xilinx_experiment_xilinx_device')
        devices = [ i for i in XilinxDevices.getXilinxDevicesValues() if i.name == device_name ]
        if len(devices) == 1:
            return devices[0], XilinxImpact.create(devices[0], self._cfg_manager)
        else:
            raise UdXilinxExperimentExceptions.InvalidXilinxDeviceException(device_name)

    def _load_programmer(self):
        device_name = self._cfg_manager.get_value('xilinx_device_to_program')
        return UdXilinxProgrammer.create(device_name, self._cfg_manager, self._xilinx_impact)

    def _load_command_sender(self):
        device_name = self._cfg_manager.get_value('xilinx_device_to_send_commands')
        return UdXilinxCommandSender.create(device_name, self._cfg_manager)

    def _load_webcam_url(self):
        cfg_webcam_url = "%s_webcam_url" % self._xilinx_device.name.lower()
        return self._cfg_manager.get_value(cfg_webcam_url, "http://localhost")

    @Override(Experiment.Experiment)
    @caller_check(ServerType.Laboratory)
    @logged("info",except_for='file_content')
    def do_send_file_to_device(self, file_content, file_info):
        try:
            fd, file_name = tempfile.mkstemp(prefix='ud_xilinx_experiment_program', suffix='.' + self._xilinx_impact.get_suffix())
            try:
                try:
                    #TODO: encode? utf8?
                    if isinstance(file_content, unicode):
                        file_content_encoded = file_content.encode('utf8')
                    else:
                        file_content_encoded = file_content
                    file_content_recovered = ExperimentUtil.deserialize(file_content_encoded)
                    os.write(fd, file_content_recovered)
                finally:
                    os.close(fd)
                self._programmer.program(file_name)
            finally:
                os.remove(file_name)
        except Exception, e:
            #TODO: test me
            log.log(
                UdXilinxExperiment,
                log.LogLevel.Info,
                "Exception joining sending program to device: %s" % e.args[0]
            )
            log.log_exc(
                UdXilinxExperiment,
                log.LogLevel.Debug
            )
            raise ExperimentExceptions.SendingFileFailureException(
                    "Error sending file to device: %s" % e
                )
        self._clear()

    def _clear(self):
        # Kludge!!
        # As soon as our PLD hardware supports the CleanInputs command, we'll be able to remove this
        if self._xilinx_device == XilinxDevices.PLD:
            try:
                for i in range(10):
                    self._command_sender.send_command(str(UdBoardCommand.ChangeSwitchCommand("on",i)))
                    self._command_sender.send_command(str(UdBoardCommand.ChangeSwitchCommand("off",i)))
            except Exception, e:
                raise ExperimentExceptions.SendingCommandFailureException(
                    "Error sending command to device: %s" % e
                )
        else:
            try:
                self._command_sender.send_command("CleanInputs")
            except Exception, e:
                raise ExperimentExceptions.SendingCommandFailureException(
                    "Error sending command to device: %s" % e
                )

    @logged("info")
    @Override(Experiment.Experiment)
    @caller_check(ServerType.Laboratory)
    def do_send_command_to_device(self, command):
        try:
            if command == 'WEBCAMURL':
                reply = "WEBCAMURL=" + self.webcam_url
                return reply
            self._command_sender.send_command(command)
        except Exception, e:
            raise ExperimentExceptions.SendingCommandFailureException(
                    "Error sending command to device: %s" % e
                )<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2005-2009 University of Deusto
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.
#
# This software consists of contributions made by many individuals,
# listed below:
#
# Author: Pablo Orduña <pablo@ordunya.com>
#
import threading
import tempfile

import os
from voodoo.log import logged
import voodoo.log as log

import weblab.experiment.experiments.ud_xilinx_experiment.UdBoardCommand as UdBoardCommand

import weblab.experiment.Experiment                         as Experiment
import weblab.experiment.Util                               as ExperimentUtil
import weblab.experiment.devices.xilinx_impact.XilinxImpact as XilinxImpact
import weblab.experiment.devices.serial_port.SerialPort     as SerialPort
import weblab.experiment.devices.jtag_blazer.JTagBlazer     as JTagBlazer
import weblab.experiment.devices.http_device.HttpDevice     as HttpDevice
import weblab.experiment.devices.digilent_adept.DigilentAdept as DigilentAdept

import weblab.experiment.devices.xilinx_impact.XilinxDevices as XilinxDevices

import weblab.data.ServerType                                as ServerType

import weblab.exceptions.experiment.ExperimentExceptions as ExperimentExceptions

from voodoo.gen.caller_checker import caller_check

from voodoo.override import Override

DEBUG = False

mofaca = open("/tmp/mofaca", "w+")
def printar(msg):
   mofaca.write(msg)
   mofaca.flush()

#TODO: which exceptions should the user see and which ones should not?
class UdXilinxExperiment(Experiment.Experiment):

    def __init__(self, coord_address, locator, cfg_manager, *args, **kwargs):
        super(UdXilinxExperiment,self).__init__(*args, **kwargs)

        self._cfg_manager = cfg_manager

        xilinx_device = cfg_manager.get_value('weblab_xilinx_experiment_xilinx_device')

        # Expect a certain name for the webcam url config depending on the device name.
        cfg_webcam_url = "%s_webcam_url" % xilinx_device.lower()
        try:
            self.webcam_url = cfg_manager.get_value(cfg_webcam_url)
            if DEBUG:
                print "[DEBUG] Webcam set: " + self.webcam_url
                print "[DEBUG] Var name: " + cfg_webcam_url
        except:
            if DEBUG:
                print "[DEBUG] Couldn't set webcam url properly."
                self.webcam_url = "http://localhost"

        devices = [ i for i in XilinxDevices.getXilinxDevicesValues() if i.name == xilinx_device ]
        if len(devices) == 1:
            self._xilinx_device = devices[0]
        else:
            self._xilinx_device = None

        self._use_jtag_blazer = cfg_manager.get_value('xilinx_use_jtag_blazer_to_program')
        self._use_digilent_adept = cfg_manager.get_value('xilinx_use_digilent_adept_to_program')
        self._use_http = cfg_manager.get_value('xilinx_use_http_to_send_commands')

        self._xilinx_impact = self._create_xilinx_impact(self._xilinx_device, cfg_manager)
        if self._use_jtag_blazer:
            self._jtag_blazer = self._create_jtag_blazer(cfg_manager)
	elif self._use_digilent_adept:
            self._digilent_adept = self._create_digilent_adept(cfg_manager)

        if self._use_http:
            http_ip = cfg_manager.get_value('xilinx_http_device_ip_' + self._xilinx_device.name)
            http_port = cfg_manager.get_value('xilinx_http_device_port_' + self._xilinx_device.name)
            http_app = cfg_manager.get_value('xilinx_http_device_app_' + self._xilinx_device.name)
            self._http_device = self._create_http_device(http_ip, http_port, http_app)
        else:
            self._port_number = cfg_manager.get_value('weblab_xilinx_experiment_port_number')
            self._serial_port = self._create_serial_port()

        self._serial_port_lock = threading.Lock()

    def _create_xilinx_impact(self, xilinx_device, cfg_manager):
        return XilinxImpact.create(xilinx_device, cfg_manager)

    def _create_serial_port(self):
        return SerialPort.SerialPort()

    def _create_jtag_blazer(self, cfg_manager):
        return JTagBlazer.JTagBlazer(cfg_manager)

    def _create_digilent_adept(self, cfg_manager):
        return DigilentAdept.DigilentAdept(cfg_manager)

    def _create_http_device(self, ip, port, app):
        return HttpDevice.HttpDevice(ip, port, app)

    def _program_device(self, file_name):
        if self._use_jtag_blazer:
            self._xilinx_impact.source2svf(file_name)
            svf_file_name = file_name.replace("."+self._xilinx_impact.get_suffix(), ".svf")
            device_ip = self._cfg_manager.get_value('xilinx_jtag_blazer_device_ip_' + self._xilinx_device.name)
            self._jtag_blazer.program_device(svf_file_name, device_ip)
        elif self._use_digilent_adept:
            self._xilinx_impact.source2svf(file_name)
            svf_file_name = file_name.replace("."+self._xilinx_impact.get_suffix(), ".svf")
            self._digilent_adept.program_device(svf_file_name)
        else:
            self._xilinx_impact.program_device(file_name)

    def _send_command_to_device(self, command):
        if self._use_http:
            self._http_device.send_message(command)
        else:
            cmd = UdBoardCommand.UdBoardCommand(command)
            codes = cmd.get_codes()
            self._serial_port_lock.acquire()
            try:
                self._serial_port.open_serial_port(self._port_number)
                for i in codes:
                    self._serial_port.send_code(i)
                self._serial_port.close_serial_port()
            finally:
                self._serial_port_lock.release()

    @Override(Experiment.Experiment)
    @caller_check(ServerType.Laboratory)
    @logged("info",except_for='file_content')
    def do_send_file_to_device(self, file_content, file_info):
        try:
            fd, file_name = tempfile.mkstemp(prefix='ud_xilinx_experiment_program', suffix='.' + self._xilinx_impact.get_suffix())
            try:
                try:
                    #TODO: encode? utf8?
                    if isinstance(file_content, unicode):
                        file_content_encoded = file_content.encode('utf8')
                    else:
                        file_content_encoded = file_content
                    file_content_recovered = ExperimentUtil.deserialize(file_content_encoded)
                    os.write(fd, file_content_recovered)
                finally:
                    os.close(fd)
                self._program_device(file_name)
            finally:
                os.remove(file_name)
        except Exception, e:
            #TODO: test me
            log.log(
                UdXilinxExperiment,
                log.LogLevel.Info,
                "Exception joining sending program to device: %s" % e.args[0]
            )
            log.log_exc(
                UdXilinxExperiment,
                log.LogLevel.Debug
            )
            raise ExperimentExceptions.SendingFileFailureException(
                    "Error sending file to device: %s" % e
                )
        self._clear()

    def _clear(self):
        # Kludge!!
        xilinx_device = self._cfg_manager.get_value('weblab_xilinx_experiment_xilinx_device')
        if xilinx_device == "PLD":
	        try:
	            for i in range(10):
	                self._send_command_to_device(str(UdBoardCommand.ChangeSwitchCommand("on",i)))
	                self._send_command_to_device(str(UdBoardCommand.ChangeSwitchCommand("off",i)))
	        except Exception, e:
	            raise ExperimentExceptions.SendingCommandFailureException(
	                    "Error sending command to device: %s" % e
	                )
	else:
		try:
		    self._send_command_to_device("CleanInputs")
		except Exception, e:
                    raise ExperimentExceptions.SendingCommandFailureException(
                            "Error sending command to device: %s" % e
                        )

    @logged("info")
    @Override(Experiment.Experiment)
    @caller_check(ServerType.Laboratory)
    def do_send_command_to_device(self, command):
        try:
            if command == 'WEBCAMURL':
                reply = "WEBCAMURL=" + self.webcam_url
                if DEBUG:
                    print '[Debug] Sending WEBCAMURL command: ' + reply
                return reply
            self._send_command_to_device(command)
        except Exception, e:
            raise ExperimentExceptions.SendingCommandFailureException(
                    "Error sending command to device: %s" % e
                )
<commit_msg>Fixing the build.<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2005-2009 University of Deusto
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.
#
# This software consists of contributions made by many individuals,
# listed below:
#
# Author: Pablo Orduña <pablo@ordunya.com>
#
import threading
import tempfile

import os
from voodoo.log import logged
import voodoo.log as log

import weblab.experiment.experiments.ud_xilinx_experiment.UdBoardCommand as UdBoardCommand

import weblab.experiment.Experiment                         as Experiment
import weblab.experiment.Util                               as ExperimentUtil
import weblab.experiment.devices.xilinx_impact.XilinxImpact as XilinxImpact
import weblab.experiment.devices.serial_port.SerialPort     as SerialPort
import weblab.experiment.devices.jtag_blazer.JTagBlazer     as JTagBlazer
import weblab.experiment.devices.http_device.HttpDevice     as HttpDevice
import weblab.experiment.devices.digilent_adept.DigilentAdept as DigilentAdept

import weblab.experiment.devices.xilinx_impact.XilinxDevices as XilinxDevices

import weblab.data.ServerType                                as ServerType

import weblab.exceptions.experiment.ExperimentExceptions as ExperimentExceptions

from voodoo.gen.caller_checker import caller_check

from voodoo.override import Override

DEBUG = False

#TODO: which exceptions should the user see and which ones should not?
class UdXilinxExperiment(Experiment.Experiment):

    def __init__(self, coord_address, locator, cfg_manager, *args, **kwargs):
        super(UdXilinxExperiment,self).__init__(*args, **kwargs)

        self._cfg_manager = cfg_manager

        xilinx_device = cfg_manager.get_value('weblab_xilinx_experiment_xilinx_device')

        # Expect a certain name for the webcam url config depending on the device name.
        cfg_webcam_url = "%s_webcam_url" % xilinx_device.lower()
        try:
            self.webcam_url = cfg_manager.get_value(cfg_webcam_url)
            if DEBUG:
                print "[DEBUG] Webcam set: " + self.webcam_url
                print "[DEBUG] Var name: " + cfg_webcam_url
        except:
            if DEBUG:
                print "[DEBUG] Couldn't set webcam url properly."
                self.webcam_url = "http://localhost"

        devices = [ i for i in XilinxDevices.getXilinxDevicesValues() if i.name == xilinx_device ]
        if len(devices) == 1:
            self._xilinx_device = devices[0]
        else:
            self._xilinx_device = None

        self._use_jtag_blazer = cfg_manager.get_value('xilinx_use_jtag_blazer_to_program')
        self._use_digilent_adept = cfg_manager.get_value('xilinx_use_digilent_adept_to_program')
        self._use_http = cfg_manager.get_value('xilinx_use_http_to_send_commands')

        self._xilinx_impact = self._create_xilinx_impact(self._xilinx_device, cfg_manager)
        if self._use_jtag_blazer:
            self._jtag_blazer = self._create_jtag_blazer(cfg_manager)
	elif self._use_digilent_adept:
            self._digilent_adept = self._create_digilent_adept(cfg_manager)

        if self._use_http:
            http_ip = cfg_manager.get_value('xilinx_http_device_ip_' + self._xilinx_device.name)
            http_port = cfg_manager.get_value('xilinx_http_device_port_' + self._xilinx_device.name)
            http_app = cfg_manager.get_value('xilinx_http_device_app_' + self._xilinx_device.name)
            self._http_device = self._create_http_device(http_ip, http_port, http_app)
        else:
            self._port_number = cfg_manager.get_value('weblab_xilinx_experiment_port_number')
            self._serial_port = self._create_serial_port()

        self._serial_port_lock = threading.Lock()

    def _create_xilinx_impact(self, xilinx_device, cfg_manager):
        return XilinxImpact.create(xilinx_device, cfg_manager)

    def _create_serial_port(self):
        return SerialPort.SerialPort()

    def _create_jtag_blazer(self, cfg_manager):
        return JTagBlazer.JTagBlazer(cfg_manager)

    def _create_digilent_adept(self, cfg_manager):
        return DigilentAdept.DigilentAdept(cfg_manager)

    def _create_http_device(self, ip, port, app):
        return HttpDevice.HttpDevice(ip, port, app)

    def _program_device(self, file_name):
        if self._use_jtag_blazer:
            self._xilinx_impact.source2svf(file_name)
            svf_file_name = file_name.replace("."+self._xilinx_impact.get_suffix(), ".svf")
            device_ip = self._cfg_manager.get_value('xilinx_jtag_blazer_device_ip_' + self._xilinx_device.name)
            self._jtag_blazer.program_device(svf_file_name, device_ip)
        elif self._use_digilent_adept:
            self._xilinx_impact.source2svf(file_name)
            svf_file_name = file_name.replace("."+self._xilinx_impact.get_suffix(), ".svf")
            self._digilent_adept.program_device(svf_file_name)
        else:
            self._xilinx_impact.program_device(file_name)

    def _send_command_to_device(self, command):
        if self._use_http:
            self._http_device.send_message(command)
        else:
            cmd = UdBoardCommand.UdBoardCommand(command)
            codes = cmd.get_codes()
            self._serial_port_lock.acquire()
            try:
                self._serial_port.open_serial_port(self._port_number)
                for i in codes:
                    self._serial_port.send_code(i)
                self._serial_port.close_serial_port()
            finally:
                self._serial_port_lock.release()

    @Override(Experiment.Experiment)
    @caller_check(ServerType.Laboratory)
    @logged("info",except_for='file_content')
    def do_send_file_to_device(self, file_content, file_info):
        try:
            fd, file_name = tempfile.mkstemp(prefix='ud_xilinx_experiment_program', suffix='.' + self._xilinx_impact.get_suffix())
            try:
                try:
                    #TODO: encode? utf8?
                    if isinstance(file_content, unicode):
                        file_content_encoded = file_content.encode('utf8')
                    else:
                        file_content_encoded = file_content
                    file_content_recovered = ExperimentUtil.deserialize(file_content_encoded)
                    os.write(fd, file_content_recovered)
                finally:
                    os.close(fd)
                self._program_device(file_name)
            finally:
                os.remove(file_name)
        except Exception, e:
            #TODO: test me
            log.log(
                UdXilinxExperiment,
                log.LogLevel.Info,
                "Exception joining sending program to device: %s" % e.args[0]
            )
            log.log_exc(
                UdXilinxExperiment,
                log.LogLevel.Debug
            )
            raise ExperimentExceptions.SendingFileFailureException(
                    "Error sending file to device: %s" % e
                )
        self._clear()

    def _clear(self):
        # Kludge!!
        xilinx_device = self._cfg_manager.get_value('weblab_xilinx_experiment_xilinx_device')
        if xilinx_device == "PLD":
	        try:
	            for i in range(10):
	                self._send_command_to_device(str(UdBoardCommand.ChangeSwitchCommand("on",i)))
	                self._send_command_to_device(str(UdBoardCommand.ChangeSwitchCommand("off",i)))
	        except Exception, e:
	            raise ExperimentExceptions.SendingCommandFailureException(
	                    "Error sending command to device: %s" % e
	                )
	else:
		try:
		    self._send_command_to_device("CleanInputs")
		except Exception, e:
                    raise ExperimentExceptions.SendingCommandFailureException(
                            "Error sending command to device: %s" % e
                        )

    @logged("info")
    @Override(Experiment.Experiment)
    @caller_check(ServerType.Laboratory)
    def do_send_command_to_device(self, command):
        try:
            if command == 'WEBCAMURL':
                reply = "WEBCAMURL=" + self.webcam_url
                if DEBUG:
                    print '[Debug] Sending WEBCAMURL command: ' + reply
                return reply
            self._send_command_to_device(command)
        except Exception, e:
            raise ExperimentExceptions.SendingCommandFailureException(
                    "Error sending command to device: %s" % e
                )
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""Module for generating visibility recv compose files."""

import json

from .utils import load_template, validate_config, load_json_file

def generate(config):
    """Generate Docker compose file for the visibility ingest workflow stage.

    This is expected to be run using Docker Swarm as an Execution Engine.

    Args:
        config (dict): Workflow stage configuraion.

    Return:
        string, Docker compose file string for use with Docker Swarm.

    """
    # Validate the workflow stage configuration
    validate_config(config, stage_type='vis_ingest', ee_type='docker_swarm')

    # Get local configuration object references
    ee_config = config['ee_config']
    app_config = config['app_config']

    # TODO(BM) Validate the ee and app configuration schema

    app_args_file = app_config['command_args']['json_file']
    json_args = json.dumps(load_json_file(app_args_file))

    template_params = dict(
        json_config=json_args,
        buffer_path=ee_config['buffer_path'],
        num_receivers=ee_config['num_receivers']
    )

    # Render the compose template for the ingest serivce configuration
    compose_template = load_template(ee_config['compose_template'])
    compose_file = compose_template.render(**template_params)

    return compose_file
<commit_msg>fixed typo<commit_after># -*- coding: utf-8 -*-
"""Module for generating visibility recv compose files."""

import json

from .utils import load_template, validate_config, load_json_file

def generate(config):
    """Generate Docker compose file for the visibility ingest workflow stage.

    This is expected to be run using Docker Swarm as an Execution Engine.

    Args:
        config (dict): Workflow stage configuration.

    Return:
        string, Docker compose file string for use with Docker Swarm.

    """
    # Validate the workflow stage configuration
    validate_config(config, stage_type='vis_ingest', ee_type='docker_swarm')

    # Get local configuration object references
    ee_config = config['ee_config']
    app_config = config['app_config']

    # TODO(BM) Validate the ee and app configuration schema

    app_args_file = app_config['command_args']['json_file']
    json_args = json.dumps(load_json_file(app_args_file))

    template_params = dict(
        json_config=json_args,
        buffer_path=ee_config['buffer_path'],
        num_receivers=ee_config['num_receivers']
    )

    # Render the compose template for the ingest serivce configuration
    compose_template = load_template(ee_config['compose_template'])
    compose_file = compose_template.render(**template_params)

    return compose_file
<|endoftext|>


<commit_before>#! /usr/env/python
"""

This tests the overland flow and shear stress generator.

"""

import landlab
from landlab.components.overland_flow.overland_flow_generator import OverlandFlow
from landlab.components.uniform_precip.generate_uniform_precip import PrecipitationDistribution
from landlab.io import read_esri_ascii
from matplotlib import pyplot as plt
import numpy as np
import os
import time

def main():
    """
    initialize DEM
    Get storm info
    Generate hydrograph
    """

    start_time = time.time()

    dem_name = 'HalfFork.asc'
    input_file = 'input_data.txt'
    IT_FILE = os.path.join(os.path.dirname(__file__), input_file)

    # Create and initialize a raster model grid by reading a DEM
    DATA_FILE = os.path.join(os.path.dirname(__file__), dem_name)
    print('Reading data from "'+str(DATA_FILE)+'"')
    (rg, z) = read_esri_ascii(DATA_FILE)
    nodata_val=-9999
    # Modify the grid DEM to set all nodata nodes to inactive boundaries
    rg.set_nodata_nodes_to_inactive(z, nodata_val) # set nodata nodes to inactive bounds

    print('DEM has ' +
          str(rg.number_of_node_rows) + ' rows, ' +
          str(rg.number_of_node_columns) + ' columns, and cell size ' +
          str(rg.dx))

    # Select point to sample at.

    study_row = 110
    study_column = 150

    study_node = rg.grid_coords_to_node_id(study_row, study_column)

    ## Set outlet point to set boundary conditions.
    the_outlet_row = 240
    the_outlet_column = 215
    the_outlet_node = rg.grid_coords_to_node_id(the_outlet_row, the_outlet_column)

    rg.set_fixed_value_boundaries(the_outlet_node)

    # Get a 2D array version of the elevations for plotting purposes
    elev_raster = rg.node_vector_to_raster(z,True)

    # Everything below plots the topography and sampling points

    levels = []
    x_up = 1990
    while x_up !=2200:
        levels.append(x_up)
        x_up+=1
    s = plt.contourf(elev_raster, levels, colors='k')#('r','g','b'))
    plt.set_cmap('bone')
    cb = plt.colorbar()

    plt.plot([150],[109],'cs', label= 'Study Node')
    plt.plot([215],[9], 'wo', label= 'Outlet')
    plt.legend(loc=3)

    of=OverlandFlow(IT_FILE,rg,0)

    ## (-,-,-,-,how long we route overland flow, intensity in m/s, duration of storm) ##

    ## Trial 1, 10 year storm ##
    of.run_one_step(rg,z,study_node,9000,(7.167*(10**-6)), 2916)

    plt.show()

if __name__ == "__main__":
    main()
<commit_msg>More modifications in line with landlab style<commit_after>#! /usr/env/python
"""

This tests the overland flow and shear stress generator.

"""

import landlab
from landlab.components.overland_flow.generate_overland_flow import OverlandFlow
from landlab.components.uniform_precip.generate_uniform_precip import PrecipitationDistribution
from landlab.io import read_esri_ascii
from matplotlib import pyplot as plt
import numpy as np
import os
import time

def main():
    """
    initialize DEM
    Get storm info
    Generate hydrograph
    """

    start_time = time.time()

    dem_name = 'HalfFork.asc'
    input_file = 'input_data.txt'
    IT_FILE = os.path.join(os.path.dirname(__file__), input_file)

    # Create and initialize a raster model grid by reading a DEM
    DATA_FILE = os.path.join(os.path.dirname(__file__), dem_name)
    print('Reading data from "'+str(DATA_FILE)+'"')
    (rg, z) = read_esri_ascii(DATA_FILE)
    nodata_val=-9999
    # Modify the grid DEM to set all nodata nodes to inactive boundaries
    rg.set_nodata_nodes_to_inactive(z, nodata_val) # set nodata nodes to inactive bounds

    print('DEM has ' +
          str(rg.number_of_node_rows) + ' rows, ' +
          str(rg.number_of_node_columns) + ' columns, and cell size ' +
          str(rg.dx))

    # Select point to sample at.

    study_row = 110
    study_column = 150

    study_node = rg.grid_coords_to_node_id(study_row, study_column)

    ## Set outlet point to set boundary conditions.
    the_outlet_row = 240
    the_outlet_column = 215
    the_outlet_node = rg.grid_coords_to_node_id(the_outlet_row, the_outlet_column)

    rg.set_fixed_value_boundaries(the_outlet_node)

    # Get a 2D array version of the elevations for plotting purposes
    elev_raster = rg.node_vector_to_raster(z,True)

    # Everything below plots the topography and sampling points

    levels = []
    x_up = 1990
    while x_up !=2200:
        levels.append(x_up)
        x_up+=1
    s = plt.contourf(elev_raster, levels, colors='k')#('r','g','b'))
    plt.set_cmap('bone')
    cb = plt.colorbar()

    plt.plot([150],[109],'cs', label= 'Study Node')
    plt.plot([215],[9], 'wo', label= 'Outlet')
    plt.legend(loc=3)

    of=OverlandFlow(IT_FILE,rg,0)

    ## (-,-,-,-,how long we route overland flow, intensity in m/s, duration of storm) ##

    ## Trial 1, 10 year storm ##
    of.generate_overland_flow_at_one_point(rg,z,study_node,9000,(7.167*(10**-6)), 2916)

    plt.show()

if __name__ == "__main__":
    main()
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
try:
    import ovh
    import ovh.exceptions
    from ovh.exceptions import APIError
    HAS_OVH = True
except ImportError:
    HAS_OVH = False

# import module snippets
from ansible.module_utils.basic import *

DOCUMENTATION = '''
---
module: ovh_ip_loadbalancing_backend
short_description: Manage OVH IP LoadBalancing backends
description:
    - Manage OVH (French European hosting provider) LoadBalancing IP backends
version_added: "2.0"
author: Pascal HERAUD @pascalheraud
notes:
    - Uses the python OVH Api U(https://github.com/ovh/python-ovh). \
    You have to create an application (a key and secret) with a consummer \
    key as described into U(https://eu.api.ovh.com/g934.first_step_with_api)
requirements:
    - ovh >  0.3.5
options:
    name:
        required: true
        description:
            - Name of the LoadBalancing internal name (ip-X.X.X.X)
    backend:
        required: true
        description:
            - The IP address of the backend to update / modify / delete
    state:
        required: false
        default: present
        choices: ['present', 'absent']
        description:
            - Determines wether the backend is to be created/modified \
            or deleted
    probe:
        required: false
        default: none
        choices: ['none', 'http', 'icmp' , 'oco']
        description:
            - Determines the type of probe to use for this backend
    weight:
        required: false
        default: 8
        description:
            - Determines the weight for this backend
    endpoint:
        required: true
        description:
            - The endpoint to use ( for instance ovh-eu)
    application_key:
        required: true
        description:
            - The applicationKey to use
    application_secret:
        required: true
        description:
            - The application secret to use
    consumer_key:
        required: true
        description:
            - The consumer key to use
    timeout:
        required: false
        type: "int"
        default: 120
        description:
            - The timeout in seconds used to wait for a task to be \
            completed. Default is 120 seconds.

'''

EXAMPLES = '''
# Adds or modify a backend to a loadbalancing
- ovh_ip_loadbalancing name=ip-1.1.1.1 ip=212.1.1.1 state=present \
probe=none weight=8 \
endpoint=ovh-eu application_key=yourkey \
application_secret=yoursecret consumer_key=yourconsumerkey

# Removes a backend from a loadbalancing
- ovh_ip_loadbalancing name=ip-1.1.1.1 ip=212.1.1.1 state=absent \
endpoint=ovh-eu application_key=yourkey \
application_secret=yoursecret consumer_key=yourconsumerkey
'''

def getOvhClient(ansibleModule):
    endpoint = ansibleModule.params.get('endpoint')
    application_key = ansibleModule.params.get('application_key')
    application_secret = ansibleModule.params.get('application_secret')
    consumer_key = ansibleModule.params.get('consumer_key')

    return ovh.Client(
        endpoint=endpoint,
        application_key=application_key,
        application_secret=application_secret,
        consumer_key=consumer_key
    )

def waitForNoTask(client, name, timeout):
    currentTimeout = timeout
    while len(client.get('/ip/loadBalancing/{}/task'.format(name))) > 0:
        time.sleep(1)  # Delay for 1 sec
        currentTimeout -= 1
        if currentTimeout < 0:
            return False
    return True

def main():
    module = AnsibleModule(
        argument_spec=dict(
            name=dict(required=True),
            backend=dict(required=True),
            weight=dict(default=8, type='int'),
            probe=dict(default='none',
                       choices=['none', 'http', 'icmp', 'oco']),
            state=dict(default='present', choices=['present', 'absent']),
            endpoint=dict(required=True),
            application_key=dict(required=True),
            application_secret=dict(required=True),
            consumer_key=dict(required=True),
            timeout=dict(default=120, type='int')
        )
    )

    if not HAS_OVH:
        module.fail_json(msg='ovh-api python module\
        is required to run this module ')

    # Get parameters
    name = module.params.get('name')
    state = module.params.get('state')
    backend = module.params.get('backend')
    weight = long(module.params.get('weight'))
    probe = module.params.get('probe')
    timeout = module.params.get('timeout')

    # Connect to OVH API
    client = getOvhClient(module)

    # Check that the load balancing exists
    try:
        loadBalancings = client.get('/ip/loadBalancing')
    except APIError as apiError:
        module.fail_json(
            msg='Unable to call OVH api for getting the list of loadBalancing, \
            check application key, secret, consumerkey and parameters. \
            Error returned by OVH api was : {}'.format(apiError))

    if name not in loadBalancings:
        module.fail_json(msg='IP LoadBalancing {} does not exist'.format(name))

    # Check that no task is pending before going on
    try:
        if not waitForNoTask(client, name, timeout):
            module.fail_json(
                msg='Timeout of {} seconds while waiting for no pending \
                tasks before executing the module '.format(timeout))
    except APIError as apiError:
        module.fail_json(
            msg='Unable to call OVH api for getting the list of pending tasks \
            of the loadBalancing, check application key, secret, consumerkey \
            and parameters. Error returned by OVH api was : {}\
            '.format(apiError))

    try:
        backends = client.get('/ip/loadBalancing/{}/backend'.format(name))
    except APIError as apiError:
        module.fail_json(
            msg='Unable to call OVH api for getting the list of backends \
            of the loadBalancing, check application key, secret, consumerkey \
            and parameters. Error returned by OVH api was : {}\
            '.format(apiError))

    backendExists = backend in backends
    moduleChanged = False
    if state == "absent":
        if backendExists:
            # Remove backend
            try:
                client.delete(
                    '/ip/loadBalancing/{}/backend/{}'.format(name, backend))
                if not waitForNoTask(client, name, timeout):
                    module.fail_json(
                        msg='Timeout of {} seconds while waiting for completion \
                        of removing backend task'.format(timeout))
            except APIError as apiError:
                module.fail_json(
                    msg='Unable to call OVH api for deleting the backend, \
                    check application key, secret, consumerkey and \
                    parameters. Error returned by OVH api was : {}\
                    '.format(apiError))
            moduleChanged = True
    else:
        if backendExists:
            # Get properties
            try:
                backendProperties = client.get(
                    '/ip/loadBalancing/{}/backend/{}'.format(name, backend))
            except APIError as apiError:
                module.fail_json(
                    msg='Unable to call OVH api for getting the backend properties, \
                    check application key, secret, consumerkey and \
                    parameters. Error returned by OVH api was : {}\
                    '.format(apiError))

            if (backendProperties['weight'] != weight):
                # Change weight
                try:
                    client.post(
                        '/ip/loadBalancing/{}/backend/{}/setWeight\
                        '.format(name, backend), weight=weight)
                    if not waitForNoTask(client, name, timeout):
                        module.fail_json(
                            msg='Timeout of {} seconds while waiting for completion \
                            of setWeight to backend task'.format(timeout))
                except APIError as apiError:
                    module.fail_json(
                        msg='Unable to call OVH api for updating the weight of the \
                        backend, check application key, secret, consumerkey \
                        and parameters. Error returned by OVH api was : {}\
                        '.format(apiError))
                moduleChanged = True

            if (backendProperties['probe'] != probe):
                # Change probe
                backendProperties['probe'] = probe
                try:
                    client.put(
                        '/ip/loadBalancing/{}/backend/{}\
                        '.format(name, backend), probe=probe)
                    if not waitForNoTask(client, name, timeout):
                        module.fail_json(
                            msg='Timeout of {} seconds while waiting for completion of \
                            setProbe to backend task'.format(timeout))
                except APIError as apiError:
                    module.fail_json(
                        msg='Unable to call OVH api for updating the propbe of \
                        the backend, check application key, secret, \
                        consumerkey and parameters. Error returned by OVH api \
                        was : {}\
                        '.format(apiError))
                moduleChanged = True

        else:
            # Creates backend
            try:
                try:
                    client.post('/ip/loadBalancing/{}/backend'.format(name),
                                ipBackend=backend, probe=probe, weight=weight)
                except APIError as apiError:
                    module.fail_json(
                        msg='Unable to call OVH api for creating the backend, check \
                        application key, secret, consumerkey and parameters. \
                        Error returned by OVH api was : {}'.format(apiError))

                if not waitForNoTask(client, name, timeout):
                    module.fail_json(
                        msg='Timeout of {} seconds while waiting for completion of \
                        backend creation task'.format(timeout))
            except APIError as apiError:
                module.fail_json(
                    msg='Unable to call OVH api for creating the backend, check \
                    application key, secret, consumerkey and parameters. \
                    Error returned by OVH api was : {}'.format(apiError))
            moduleChanged = True

    module.exit_json(changed=moduleChanged)

    # We should never reach here
    module.fail_json(msg='Internal ovh_ip_loadbalancing_backend module error')

main()
<commit_msg>Changed licence and main()<commit_after>#!/usr/bin/python
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
import sys
try:
    import ovh
    import ovh.exceptions
    from ovh.exceptions import APIError
    HAS_OVH = True
except ImportError:
    HAS_OVH = False

# import module snippets
from ansible.module_utils.basic import *

DOCUMENTATION = '''
---
module: ovh_ip_loadbalancing_backend
short_description: Manage OVH IP LoadBalancing backends
description:
    - Manage OVH (French European hosting provider) LoadBalancing IP backends
version_added: "2.0"
author: Pascal HERAUD @pascalheraud
notes:
    - Uses the python OVH Api U(https://github.com/ovh/python-ovh). \
    You have to create an application (a key and secret) with a consummer \
    key as described into U(https://eu.api.ovh.com/g934.first_step_with_api)
requirements:
    - ovh >  0.3.5
options:
    name:
        required: true
        description:
            - Name of the LoadBalancing internal name (ip-X.X.X.X)
    backend:
        required: true
        description:
            - The IP address of the backend to update / modify / delete
    state:
        required: false
        default: present
        choices: ['present', 'absent']
        description:
            - Determines wether the backend is to be created/modified \
            or deleted
    probe:
        required: false
        default: none
        choices: ['none', 'http', 'icmp' , 'oco']
        description:
            - Determines the type of probe to use for this backend
    weight:
        required: false
        default: 8
        description:
            - Determines the weight for this backend
    endpoint:
        required: true
        description:
            - The endpoint to use ( for instance ovh-eu)
    application_key:
        required: true
        description:
            - The applicationKey to use
    application_secret:
        required: true
        description:
            - The application secret to use
    consumer_key:
        required: true
        description:
            - The consumer key to use
    timeout:
        required: false
        type: "int"
        default: 120
        description:
            - The timeout in seconds used to wait for a task to be \
            completed. Default is 120 seconds.

'''

EXAMPLES = '''
# Adds or modify a backend to a loadbalancing
- ovh_ip_loadbalancing name=ip-1.1.1.1 ip=212.1.1.1 state=present \
probe=none weight=8 \
endpoint=ovh-eu application_key=yourkey \
application_secret=yoursecret consumer_key=yourconsumerkey

# Removes a backend from a loadbalancing
- ovh_ip_loadbalancing name=ip-1.1.1.1 ip=212.1.1.1 state=absent \
endpoint=ovh-eu application_key=yourkey \
application_secret=yoursecret consumer_key=yourconsumerkey
'''

def getOvhClient(ansibleModule):
    endpoint = ansibleModule.params.get('endpoint')
    application_key = ansibleModule.params.get('application_key')
    application_secret = ansibleModule.params.get('application_secret')
    consumer_key = ansibleModule.params.get('consumer_key')

    return ovh.Client(
        endpoint=endpoint,
        application_key=application_key,
        application_secret=application_secret,
        consumer_key=consumer_key
    )

def waitForNoTask(client, name, timeout):
    currentTimeout = timeout
    while len(client.get('/ip/loadBalancing/{}/task'.format(name))) > 0:
        time.sleep(1)  # Delay for 1 sec
        currentTimeout -= 1
        if currentTimeout < 0:
            return False
    return True

def main():
    module = AnsibleModule(
        argument_spec=dict(
            name=dict(required=True),
            backend=dict(required=True),
            weight=dict(default=8, type='int'),
            probe=dict(default='none',
                       choices=['none', 'http', 'icmp', 'oco']),
            state=dict(default='present', choices=['present', 'absent']),
            endpoint=dict(required=True),
            application_key=dict(required=True),
            application_secret=dict(required=True),
            consumer_key=dict(required=True),
            timeout=dict(default=120, type='int')
        )
    )

    if not HAS_OVH:
        module.fail_json(msg='ovh-api python module\
        is required to run this module ')

    # Get parameters
    name = module.params.get('name')
    state = module.params.get('state')
    backend = module.params.get('backend')
    weight = long(module.params.get('weight'))
    probe = module.params.get('probe')
    timeout = module.params.get('timeout')

    # Connect to OVH API
    client = getOvhClient(module)

    # Check that the load balancing exists
    try:
        loadBalancings = client.get('/ip/loadBalancing')
    except APIError as apiError:
        module.fail_json(
            msg='Unable to call OVH api for getting the list of loadBalancing, \
            check application key, secret, consumerkey and parameters. \
            Error returned by OVH api was : {}'.format(apiError))

    if name not in loadBalancings:
        module.fail_json(msg='IP LoadBalancing {} does not exist'.format(name))

    # Check that no task is pending before going on
    try:
        if not waitForNoTask(client, name, timeout):
            module.fail_json(
                msg='Timeout of {} seconds while waiting for no pending \
                tasks before executing the module '.format(timeout))
    except APIError as apiError:
        module.fail_json(
            msg='Unable to call OVH api for getting the list of pending tasks \
            of the loadBalancing, check application key, secret, consumerkey \
            and parameters. Error returned by OVH api was : {}\
            '.format(apiError))

    try:
        backends = client.get('/ip/loadBalancing/{}/backend'.format(name))
    except APIError as apiError:
        module.fail_json(
            msg='Unable to call OVH api for getting the list of backends \
            of the loadBalancing, check application key, secret, consumerkey \
            and parameters. Error returned by OVH api was : {}\
            '.format(apiError))

    backendExists = backend in backends
    moduleChanged = False
    if state == "absent":
        if backendExists:
            # Remove backend
            try:
                client.delete(
                    '/ip/loadBalancing/{}/backend/{}'.format(name, backend))
                if not waitForNoTask(client, name, timeout):
                    module.fail_json(
                        msg='Timeout of {} seconds while waiting for completion \
                        of removing backend task'.format(timeout))
            except APIError as apiError:
                module.fail_json(
                    msg='Unable to call OVH api for deleting the backend, \
                    check application key, secret, consumerkey and \
                    parameters. Error returned by OVH api was : {}\
                    '.format(apiError))
            moduleChanged = True
    else:
        if backendExists:
            # Get properties
            try:
                backendProperties = client.get(
                    '/ip/loadBalancing/{}/backend/{}'.format(name, backend))
            except APIError as apiError:
                module.fail_json(
                    msg='Unable to call OVH api for getting the backend properties, \
                    check application key, secret, consumerkey and \
                    parameters. Error returned by OVH api was : {}\
                    '.format(apiError))

            if (backendProperties['weight'] != weight):
                # Change weight
                try:
                    client.post(
                        '/ip/loadBalancing/{}/backend/{}/setWeight\
                        '.format(name, backend), weight=weight)
                    if not waitForNoTask(client, name, timeout):
                        module.fail_json(
                            msg='Timeout of {} seconds while waiting for completion \
                            of setWeight to backend task'.format(timeout))
                except APIError as apiError:
                    module.fail_json(
                        msg='Unable to call OVH api for updating the weight of the \
                        backend, check application key, secret, consumerkey \
                        and parameters. Error returned by OVH api was : {}\
                        '.format(apiError))
                moduleChanged = True

            if (backendProperties['probe'] != probe):
                # Change probe
                backendProperties['probe'] = probe
                try:
                    client.put(
                        '/ip/loadBalancing/{}/backend/{}\
                        '.format(name, backend), probe=probe)
                    if not waitForNoTask(client, name, timeout):
                        module.fail_json(
                            msg='Timeout of {} seconds while waiting for completion of \
                            setProbe to backend task'.format(timeout))
                except APIError as apiError:
                    module.fail_json(
                        msg='Unable to call OVH api for updating the propbe of \
                        the backend, check application key, secret, \
                        consumerkey and parameters. Error returned by OVH api \
                        was : {}\
                        '.format(apiError))
                moduleChanged = True

        else:
            # Creates backend
            try:
                try:
                    client.post('/ip/loadBalancing/{}/backend'.format(name),
                                ipBackend=backend, probe=probe, weight=weight)
                except APIError as apiError:
                    module.fail_json(
                        msg='Unable to call OVH api for creating the backend, check \
                        application key, secret, consumerkey and parameters. \
                        Error returned by OVH api was : {}'.format(apiError))

                if not waitForNoTask(client, name, timeout):
                    module.fail_json(
                        msg='Timeout of {} seconds while waiting for completion of \
                        backend creation task'.format(timeout))
            except APIError as apiError:
                module.fail_json(
                    msg='Unable to call OVH api for creating the backend, check \
                    application key, secret, consumerkey and parameters. \
                    Error returned by OVH api was : {}'.format(apiError))
            moduleChanged = True

    module.exit_json(changed=moduleChanged)

    # We should never reach here
    module.fail_json(msg='Internal ovh_ip_loadbalancing_backend module error')

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>from itertools import combinations
import uuid
from scipy.stats import ttest_ind
from multiprocessing import Pool
from functools import partial
import os
import pandas as pd
from tqdm import tqdm
import numpy as np
from os.path import join

from SCNIC.annotate_correls import get_modules_across_rs

def get_module_sizes_across_rs(modules_across_rs):
    module_sizes_across_rs = dict()
    for min_r, modules in modules_across_rs.items():
        module_sizes = list()
        for module, otus in modules.items():
            module_sizes.append(len(otus))
        module_sizes_across_rs[min_r] = set(module_sizes)
    return module_sizes_across_rs

def get_modules_to_keep(folders_to_keep_loc):
    with open(folders_to_keep_loc) as f:
        folders_to_keep = list()
        for line in f:
            folders_to_keep.append(line.strip())
        return folders_to_keep

def perm(random_module_otus, correls, min_r):
    pairs = list()
    for pair in combinations(random_module_otus, 2):
        pairs.append(tuple(sorted(pair)))
    random_module_correls = correls.loc[pairs]
    non_cor_correls = correls.loc[~correls['correlated_%s' % min_r]]
    # pd stuff
    pd_res, _ = ttest_ind(random_module_correls.PD, non_cor_correls.PD)
    # pd ko stuff
    pd_ko_res, _ = ttest_ind(random_module_correls['residual_%s' % min_r], non_cor_correls['residual_%s' % min_r])
    return pd_res, pd_ko_res

def filter_correls(correls, to_keep):
    cols_to_keep = list(correls.columns[:3])
    for column in correls.columns[3:]:
        if 'gamma' in column:
            params = '_'.join(column.split('_')[-4:])
        else:
            params = '_'.join(column.split('_')[-2:])
        if params in to_keep:
            cols_to_keep.append(column)
    return correls[cols_to_keep]

def run_perms(correls, perms, procs, module_sizes, output_loc):
    current_milli_time = uuid.uuid4()
    all_otus = tuple(set([otu for pair in correls.index for otu in pair]))
    os.makedirs(output_loc, exist_ok=True)
    for min_r in tqdm(module_sizes.keys()):
        # perms
        correls_perm = filter_correls(correls, min_r)
        pd_stats_dict = dict()
        pd_ko_stats_dict = dict()
        for size in tqdm(module_sizes[min_r]):
            if size < 3:
                continue
            pool = Pool(processes=procs)
            partial_func = partial(perm, correls=correls_perm, min_r=min_r)
            results = pool.map(partial_func, (np.random.choice(all_otus, size, replace=False) for _ in range(perms)))
            pool.close()
            pool.join()
            pd_stats_dict[size] = np.array([i[0] for i in results])
            pd_ko_stats_dict[size] = np.array([i[1] for i in results])

        # print dict to file
        with open(join(output_loc, 'pd_stats_dict_%s.txt' % current_milli_time), 'a') as f:
            for key, values in pd_stats_dict.items():
                f.write('%s\t%s\t%s\n' % (min_r, key, '\t'.join([str(i) for i in values])))
        with open(join(output_loc, 'pd_ko_stats_dict_%s.txt' % current_milli_time), 'a') as f:
            for key, values in pd_ko_stats_dict.items():
                f.write('%s\t%s\t%s\n' % (min_r, key, '\t'.join([str(i) for i in values])))
    print('\n')

def do_multiprocessed_perms(correls_loc, perms, procs, modules_directory_loc, output_loc, folders_to_keep_loc):
    modules_across_rs = get_modules_across_rs(modules_directory_loc)
    print("%s modules found" % len(modules_across_rs))
    if folders_to_keep_loc is not None:
        modules_to_keep = get_modules_to_keep(folders_to_keep_loc)
        modules_across_rs = {key: value for key, value in modules_across_rs.items() if key in modules_to_keep}
        print("%s modules kept" % len(modules_across_rs))
    module_sizes_across_rs = get_module_sizes_across_rs(modules_across_rs)
    print("got module sizes")
    correls = pd.read_table(correls_loc, index_col=(0, 1))
    correls.index = pd.MultiIndex.from_tuples([tuple(sorted((str(i), str(j)))) for i, j in correls.index])
    print("read correls")
    run_perms(correls, perms, procs, module_sizes_across_rs, output_loc)
<commit_msg>Tuple passed to filter_correls in run_perms, filter correls at start<commit_after>from itertools import combinations
import uuid
from scipy.stats import ttest_ind
from multiprocessing import Pool
from functools import partial
import os
import pandas as pd
from tqdm import tqdm
import numpy as np
from os.path import join

from SCNIC.annotate_correls import get_modules_across_rs

def get_module_sizes_across_rs(modules_across_rs):
    module_sizes_across_rs = dict()
    for min_r, modules in modules_across_rs.items():
        module_sizes = list()
        for module, otus in modules.items():
            module_sizes.append(len(otus))
        module_sizes_across_rs[min_r] = set(module_sizes)
    return module_sizes_across_rs

def get_modules_to_keep(folders_to_keep_loc):
    with open(folders_to_keep_loc) as f:
        folders_to_keep = list()
        for line in f:
            folders_to_keep.append(line.strip())
        return folders_to_keep

def perm(random_module_otus, correls, min_r):
    pairs = list()
    for pair in combinations(random_module_otus, 2):
        pairs.append(tuple(sorted(pair)))
    random_module_correls = correls.loc[pairs]
    non_cor_correls = correls.loc[~correls['correlated_%s' % min_r]]
    # pd stuff
    pd_res, _ = ttest_ind(random_module_correls.PD, non_cor_correls.PD)
    # pd ko stuff
    pd_ko_res, _ = ttest_ind(random_module_correls['residual_%s' % min_r], non_cor_correls['residual_%s' % min_r])
    return pd_res, pd_ko_res

def filter_correls(correls, to_keep):
    cols_to_keep = list(correls.columns[:3])
    for column in correls.columns[3:]:
        if 'gamma' in column:
            params = '_'.join(column.split('_')[-4:])
        else:
            params = '_'.join(column.split('_')[-2:])
        if params in to_keep:
            cols_to_keep.append(column)
    return correls[cols_to_keep]

def run_perms(correls, perms, procs, module_sizes, output_loc):
    current_milli_time = uuid.uuid4()
    all_otus = tuple(set([otu for pair in correls.index for otu in pair]))
    os.makedirs(output_loc, exist_ok=True)
    for min_r in tqdm(module_sizes.keys()):
        # perms
        correls_perm = filter_correls(correls, (min_r,))
        pd_stats_dict = dict()
        pd_ko_stats_dict = dict()
        for size in tqdm(module_sizes[min_r]):
            if size < 3:
                continue
            pool = Pool(processes=procs)
            partial_func = partial(perm, correls=correls_perm, min_r=min_r)
            results = pool.map(partial_func, (np.random.choice(all_otus, size, replace=False) for _ in range(perms)))
            pool.close()
            pool.join()
            pd_stats_dict[size] = np.array([i[0] for i in results])
            pd_ko_stats_dict[size] = np.array([i[1] for i in results])

        # print dict to file
        with open(join(output_loc, 'pd_stats_dict_%s.txt' % current_milli_time), 'a') as f:
            for key, values in pd_stats_dict.items():
                f.write('%s\t%s\t%s\n' % (min_r, key, '\t'.join([str(i) for i in values])))
        with open(join(output_loc, 'pd_ko_stats_dict_%s.txt' % current_milli_time), 'a') as f:
            for key, values in pd_ko_stats_dict.items():
                f.write('%s\t%s\t%s\n' % (min_r, key, '\t'.join([str(i) for i in values])))
    print('\n')

def do_multiprocessed_perms(correls_loc, perms, procs, modules_directory_loc, output_loc, folders_to_keep_loc):
    modules_across_rs = get_modules_across_rs(modules_directory_loc)
    print("%s modules found" % len(modules_across_rs))
    if folders_to_keep_loc is not None:
        modules_to_keep = get_modules_to_keep(folders_to_keep_loc)
        modules_across_rs = {key: value for key, value in modules_across_rs.items() if key in modules_to_keep}
        print("%s modules kept" % len(modules_across_rs))
    module_sizes_across_rs = get_module_sizes_across_rs(modules_across_rs)
    print("got module sizes")
    correls = pd.read_table(correls_loc, index_col=(0, 1))
    correls.index = pd.MultiIndex.from_tuples([tuple(sorted((str(i), str(j)))) for i, j in correls.index])
    if folders_to_keep_loc is not None:
        correls = filter_correls(correls, modules_to_keep)
    print("read correls")
    run_perms(correls, perms, procs, module_sizes_across_rs, output_loc)
<|endoftext|>


<commit_before>from __future__ import annotations

import numpy as np

from .base import (
    BaseRegularization,
    LeastSquaresRegularization,
    RegularizationMesh,
    Small,
    SmoothDeriv,
)
from .. import utils

class BaseSparse(BaseRegularization):
    """
    Base class for building up the components of the Sparse Regularization
    """

    def __init__(self, mesh, norm=2.0, irls_scaled=True, irls_threshold=1e-8, **kwargs):
        super().__init__(mesh=mesh, **kwargs)
        self.norm = norm
        self.irls_scaled = irls_scaled
        self.irls_threshould = irls_threshold

    @property
    def irls_scaled(self) -> bool:
        """
        Scale irls weights.
        """
        return self._irls_scaled

    @irls_scaled.setter
    def irls_scaled(self, value: bool):
        if not isinstance(value, bool):
            raise TypeError(
                "'irls_scaled must be of type 'bool'. "
                f"Value of type {type(value)} provided."
            )
        self._irls_scaled = value

    @property
    def irls_threshold(self):
        """
        Constant added to the denominator of the IRLS weights for stability.
        """
        return self._irls_threshold

    @irls_threshold.setter
    def irls_threshold(self, value):
        value = float(value)
        if value <= 0:
            raise ValueError("Value of 'irls_threshold' should be larger than 0.")
        self._irls_threshold = value

    @property
    def norm(self):
        """
        Value of the norm
        """
        return self._norm

    @norm.setter
    def norm(self, value: float | np.ndarray | None):
        if value is None:
            value = 2.0
        else:
            if isinstance(value, (float, int)):
                value = np.ones(self._weights_shapes[0]) * value

            if np.any(value < 0) or np.any(value > 2):
                raise ValueError(
                    "Value provided for 'norm' should be in the interval [0, 2]"
                )
        self._norm = value

    def get_lp_weights(self, f_m):
        """
        Utility function to get the IRLS weights.
        By default, the weights are scaled by the gradient of the IRLS on
        the max of the l2-norm.
        """
        lp_scale = np.ones_like(f_m)
        if self.irls_scaled:
            # Scale on l2-norm gradient: f_m.max()
            l2_max = np.ones_like(f_m) * np.abs(f_m).max()
            # Compute theoretical maximum gradients for p < 1
            l2_max[self.norm < 1] = self.irls_threshold / np.sqrt(
                1.0 - self.norm[self.norm < 1]
            )
            lp_values = l2_max / (l2_max ** 2.0 + self.irls_threshold ** 2.0) ** (
                1.0 - self.norm / 2.0
            )
            lp_scale[lp_values != 0] = np.abs(f_m).max() / lp_values[lp_values != 0]

        return lp_scale / (f_m ** 2.0 + self.irls_threshold ** 2.0) ** (
            1.0 - self.norm / 2.0
        )

class SparseSmall(BaseSparse, Small):
    """
    Sparse smallness regularization

    **Inputs**

    :param int norm: norm on the smallness
    """

    _multiplier_pair = "alpha_s"

    def update_weights(self, m):
        """
        Compute and store the irls weights.
        """
        f_m = self.f_m(m)
        self.set_weights(irls=self.get_lp_weights(f_m))

class SparseDeriv(BaseSparse, SmoothDeriv):
    """
    Base Class for sparse regularization on first spatial derivatives
    """

    def __init__(self, mesh, orientation="x", gradient_type="total", **kwargs):
        if "gradientType" in kwargs:
            self.gradientType = kwargs.pop("gradientType")
        else:
            self.gradient_type = gradient_type
        super().__init__(mesh=mesh, orientation=orientation, **kwargs)

    def update_weights(self, m):
        """
        Compute and store the irls weights.
        """
        if self.gradient_type == "total":
            if self.reference_model_in_smooth:
                delta_m = self.mapping * self._delta_m(m)
            else:
                delta_m = self.mapping * m

            f_m = np.zeros_like(delta_m)
            for ii, comp in enumerate("xyz"):
                if self.regularization_mesh.dim > ii:
                    Ave = getattr(self.regularization_mesh, f"aveCC2F{comp}")
                    length_scales = Ave * (
                        self.regularization_mesh.Pac.T
                        * self.regularization_mesh.mesh.h_gridded[:, ii]
                    )
                    dm = (
                        getattr(self.regularization_mesh, f"cell_gradient_{comp}")
                        * delta_m
                    )

                    if self.units == "radian":
                        dm = utils.mat_utils.coterminal(dm)

                    dm_dl = dm / length_scales

                    f_m += np.abs(
                        getattr(self.regularization_mesh, f"aveF{comp}2CC") * dm_dl
                    )

            f_m = getattr(self.regularization_mesh, f"aveCC2F{self.orientation}") * f_m

        else:
            f_m = self.f_m(m)

        self.set_weights(irls=self.get_lp_weights(f_m))

    @property
    def gradient_type(self) -> str:
        """
        Choice of gradient measure used in the irls weights
        """
        return self._gradient_type

    @gradient_type.setter
    def gradient_type(self, value: str):
        if value not in ["total", "components"]:
            raise TypeError(
                "Value for 'gradient_type' must be 'total' or 'components'. "
                f"Value {value} provided."
            )
        self._gradient_type = value

    gradientType = utils.code_utils.deprecate_property(
        gradient_type, "gradientType", "0.x.0", error=False, future_warn=False
    )

class Sparse(LeastSquaresRegularization):
    """
    The regularization is:

    .. math::

        R(m) = \\frac{1}{2}\\mathbf{(m-m_\\text{ref})^\\top W^\\top R^\\top R
        W(m-m_\\text{ref})}

    where the IRLS weight

    .. math::

        R = \\eta TO FINISH LATER!!!

    So the derivative is straight forward:

    .. math::

        R(m) = \\mathbf{W^\\top R^\\top R W (m-m_\\text{ref})}

    The IRLS weights are recomputed after each beta solves.
    It is strongly recommended to do a few Gauss-Newton iterations
    before updating.
    """

    def __init__(
        self,
        mesh,
        active_cells=None,
        norms=None,
        gradient_type="total",
        irls_scaled=True,
        irls_threshold=1e-8,
        **kwargs,
    ):
        if not isinstance(mesh, RegularizationMesh):
            mesh = RegularizationMesh(mesh)

        if not isinstance(mesh, RegularizationMesh):
            TypeError(
                f"'regularization_mesh' must be of type {RegularizationMesh} or {BaseMesh}. "
                f"Value of type {type(mesh)} provided."
            )
        self._regularization_mesh = mesh
        if active_cells is not None:
            self._regularization_mesh.active_cells = active_cells

        objfcts = [
            SparseSmall(mesh=self.regularization_mesh),
            SparseDeriv(mesh=self.regularization_mesh, orientation="x"),
        ]

        if mesh.dim > 1:
            objfcts.append(SparseDeriv(mesh=self.regularization_mesh, orientation="y"))

        if mesh.dim > 2:
            objfcts.append(SparseDeriv(mesh=self.regularization_mesh, orientation="z"))

        gradientType = kwargs.pop("gradientType", None)
        super().__init__(
            self.regularization_mesh,
            objfcts=objfcts,
            **kwargs,
        )
        if norms is None:
            norms = [1] * (mesh.dim + 1)
        self.norms = norms

        if gradientType is not None:
            # Trigger deprecation warning
            self.gradientType = gradientType
        else:
            self.gradient_type = gradient_type

    @property
    def gradient_type(self) -> str:
        """
        Choice of gradient measure used in the irls weights
        """
        return self._gradient_type

    @gradient_type.setter
    def gradient_type(self, value: str):
        for fct in self.objfcts:
            if hasattr(fct, "gradient_type"):
                fct.gradient_type = value

        self._gradient_type = value

    gradientType = utils.code_utils.deprecate_property(
        gradient_type, "gradientType", "0.x.0", error=False, future_warn=False
    )

    @property
    def norms(self):
        """
        Value of the norm
        """
        return self._norms

    @norms.setter
    def norms(self, values: list | np.ndarray | None):
        if values is not None:
            if len(values) != len(self.objfcts):
                raise ValueError(
                    "The number of values provided for 'norms' does not "
                    "match the number of regularization functions."
                )

            for val, fct in zip(values, self.objfcts):
                fct.norm = val

        self._norms = values

    @property
    def irls_scaled(self) -> bool:
        """
        Scale irls weights.
        """
        return self._irls_scaled

    @irls_scaled.setter
    def irls_scaled(self, value: bool):
        if not isinstance(value, bool):
            raise TypeError(
                "'irls_scaled must be of type 'bool'. "
                f"Value of type {type(value)} provided."
            )
        for fct in self.objfcts:
            fct.irls_scaled = value
        self._irls_scaled = value

    @property
    def irls_threshold(self):
        """
        Constant added to the denominator of the IRLS weights for stability.
        """
        return self._irls_threshold

    @irls_threshold.setter
    def irls_threshold(self, value):
        value = float(value)
        if value <= 0:
            raise ValueError("Value of 'irls_threshold' should be greater than 0.")

        self._irls_threshold = value

        for fct in self.objfcts:
            fct.irls_threshold = value

    def update_weights(self, model):
        """
        Trigger irls update on all children
        """
        for fct in self.objfcts:
            fct.update_weights(model)
<commit_msg>set irls_threshold and irls_scaled on __init__ of Sparse class<commit_after>from __future__ import annotations

import numpy as np

from .base import (
    BaseRegularization,
    LeastSquaresRegularization,
    RegularizationMesh,
    Small,
    SmoothDeriv,
)
from .. import utils

class BaseSparse(BaseRegularization):
    """
    Base class for building up the components of the Sparse Regularization
    """

    def __init__(self, mesh, norm=2.0, irls_scaled=True, irls_threshold=1e-8, **kwargs):
        super().__init__(mesh=mesh, **kwargs)
        self.norm = norm
        self.irls_scaled = irls_scaled
        self.irls_threshold = irls_threshold

    @property
    def irls_scaled(self) -> bool:
        """
        Scale irls weights.
        """
        return self._irls_scaled

    @irls_scaled.setter
    def irls_scaled(self, value: bool):
        if not isinstance(value, bool):
            raise TypeError(
                "'irls_scaled must be of type 'bool'. "
                f"Value of type {type(value)} provided."
            )
        self._irls_scaled = value

    @property
    def irls_threshold(self):
        """
        Constant added to the denominator of the IRLS weights for stability.
        """
        return self._irls_threshold

    @irls_threshold.setter
    def irls_threshold(self, value):
        value = float(value)
        if value <= 0:
            raise ValueError("Value of 'irls_threshold' should be larger than 0.")
        self._irls_threshold = value

    @property
    def norm(self):
        """
        Value of the norm
        """
        return self._norm

    @norm.setter
    def norm(self, value: float | np.ndarray | None):
        if value is None:
            value = 2.0
        else:
            if isinstance(value, (float, int)):
                value = np.ones(self._weights_shapes[0]) * value

            if np.any(value < 0) or np.any(value > 2):
                raise ValueError(
                    "Value provided for 'norm' should be in the interval [0, 2]"
                )
        self._norm = value

    def get_lp_weights(self, f_m):
        """
        Utility function to get the IRLS weights.
        By default, the weights are scaled by the gradient of the IRLS on
        the max of the l2-norm.
        """
        lp_scale = np.ones_like(f_m)
        if self.irls_scaled:
            # Scale on l2-norm gradient: f_m.max()
            l2_max = np.ones_like(f_m) * np.abs(f_m).max()
            # Compute theoretical maximum gradients for p < 1
            l2_max[self.norm < 1] = self.irls_threshold / np.sqrt(
                1.0 - self.norm[self.norm < 1]
            )
            lp_values = l2_max / (l2_max ** 2.0 + self.irls_threshold ** 2.0) ** (
                1.0 - self.norm / 2.0
            )
            lp_scale[lp_values != 0] = np.abs(f_m).max() / lp_values[lp_values != 0]

        return lp_scale / (f_m ** 2.0 + self.irls_threshold ** 2.0) ** (
            1.0 - self.norm / 2.0
        )

class SparseSmall(BaseSparse, Small):
    """
    Sparse smallness regularization

    **Inputs**

    :param int norm: norm on the smallness
    """

    _multiplier_pair = "alpha_s"

    def update_weights(self, m):
        """
        Compute and store the irls weights.
        """
        f_m = self.f_m(m)
        self.set_weights(irls=self.get_lp_weights(f_m))

class SparseDeriv(BaseSparse, SmoothDeriv):
    """
    Base Class for sparse regularization on first spatial derivatives
    """

    def __init__(self, mesh, orientation="x", gradient_type="total", **kwargs):
        if "gradientType" in kwargs:
            self.gradientType = kwargs.pop("gradientType")
        else:
            self.gradient_type = gradient_type
        super().__init__(mesh=mesh, orientation=orientation, **kwargs)

    def update_weights(self, m):
        """
        Compute and store the irls weights.
        """
        if self.gradient_type == "total":
            if self.reference_model_in_smooth:
                delta_m = self.mapping * self._delta_m(m)
            else:
                delta_m = self.mapping * m

            f_m = np.zeros_like(delta_m)
            for ii, comp in enumerate("xyz"):
                if self.regularization_mesh.dim > ii:
                    Ave = getattr(self.regularization_mesh, f"aveCC2F{comp}")
                    length_scales = Ave * (
                        self.regularization_mesh.Pac.T
                        * self.regularization_mesh.mesh.h_gridded[:, ii]
                    )
                    dm = (
                        getattr(self.regularization_mesh, f"cell_gradient_{comp}")
                        * delta_m
                    )

                    if self.units == "radian":
                        dm = utils.mat_utils.coterminal(dm)

                    dm_dl = dm / length_scales

                    f_m += np.abs(
                        getattr(self.regularization_mesh, f"aveF{comp}2CC") * dm_dl
                    )

            f_m = getattr(self.regularization_mesh, f"aveCC2F{self.orientation}") * f_m

        else:
            f_m = self.f_m(m)

        self.set_weights(irls=self.get_lp_weights(f_m))

    @property
    def gradient_type(self) -> str:
        """
        Choice of gradient measure used in the irls weights
        """
        return self._gradient_type

    @gradient_type.setter
    def gradient_type(self, value: str):
        if value not in ["total", "components"]:
            raise TypeError(
                "Value for 'gradient_type' must be 'total' or 'components'. "
                f"Value {value} provided."
            )
        self._gradient_type = value

    gradientType = utils.code_utils.deprecate_property(
        gradient_type, "gradientType", "0.x.0", error=False, future_warn=False
    )

class Sparse(LeastSquaresRegularization):
    """
    The regularization is:

    .. math::

        R(m) = \\frac{1}{2}\\mathbf{(m-m_\\text{ref})^\\top W^\\top R^\\top R
        W(m-m_\\text{ref})}

    where the IRLS weight

    .. math::

        R = \\eta TO FINISH LATER!!!

    So the derivative is straight forward:

    .. math::

        R(m) = \\mathbf{W^\\top R^\\top R W (m-m_\\text{ref})}

    The IRLS weights are recomputed after each beta solves.
    It is strongly recommended to do a few Gauss-Newton iterations
    before updating.
    """

    def __init__(
        self,
        mesh,
        active_cells=None,
        norms=None,
        gradient_type="total",
        irls_scaled=True,
        irls_threshold=1e-8,
        **kwargs,
    ):
        if not isinstance(mesh, RegularizationMesh):
            mesh = RegularizationMesh(mesh)

        if not isinstance(mesh, RegularizationMesh):
            TypeError(
                f"'regularization_mesh' must be of type {RegularizationMesh} or {BaseMesh}. "
                f"Value of type {type(mesh)} provided."
            )
        self._regularization_mesh = mesh
        if active_cells is not None:
            self._regularization_mesh.active_cells = active_cells

        objfcts = [
            SparseSmall(mesh=self.regularization_mesh),
            SparseDeriv(mesh=self.regularization_mesh, orientation="x"),
        ]

        if mesh.dim > 1:
            objfcts.append(SparseDeriv(mesh=self.regularization_mesh, orientation="y"))

        if mesh.dim > 2:
            objfcts.append(SparseDeriv(mesh=self.regularization_mesh, orientation="z"))

        gradientType = kwargs.pop("gradientType", None)
        super().__init__(
            self.regularization_mesh,
            objfcts=objfcts,
            **kwargs,
        )
        if norms is None:
            norms = [1] * (mesh.dim + 1)
        self.norms = norms

        if gradientType is not None:
            # Trigger deprecation warning
            self.gradientType = gradientType
        else:
            self.gradient_type = gradient_type

        self.irls_scaled = irls_scaled
        self.irls_threshold = irls_threshold

    @property
    def gradient_type(self) -> str:
        """
        Choice of gradient measure used in the irls weights
        """
        return self._gradient_type

    @gradient_type.setter
    def gradient_type(self, value: str):
        for fct in self.objfcts:
            if hasattr(fct, "gradient_type"):
                fct.gradient_type = value

        self._gradient_type = value

    gradientType = utils.code_utils.deprecate_property(
        gradient_type, "gradientType", "0.x.0", error=False, future_warn=False
    )

    @property
    def norms(self):
        """
        Value of the norm
        """
        return self._norms

    @norms.setter
    def norms(self, values: list | np.ndarray | None):
        if values is not None:
            if len(values) != len(self.objfcts):
                raise ValueError(
                    "The number of values provided for 'norms' does not "
                    "match the number of regularization functions."
                )

            for val, fct in zip(values, self.objfcts):
                fct.norm = val

        self._norms = values

    @property
    def irls_scaled(self) -> bool:
        """
        Scale irls weights.
        """
        return self._irls_scaled

    @irls_scaled.setter
    def irls_scaled(self, value: bool):
        if not isinstance(value, bool):
            raise TypeError(
                "'irls_scaled must be of type 'bool'. "
                f"Value of type {type(value)} provided."
            )
        for fct in self.objfcts:
            fct.irls_scaled = value
        self._irls_scaled = value

    @property
    def irls_threshold(self):
        """
        Constant added to the denominator of the IRLS weights for stability.
        """
        return self._irls_threshold

    @irls_threshold.setter
    def irls_threshold(self, value):
        value = float(value)
        if value <= 0:
            raise ValueError("Value of 'irls_threshold' should be greater than 0.")

        self._irls_threshold = value

        for fct in self.objfcts:
            fct.irls_threshold = value

    def update_weights(self, model):
        """
        Trigger irls update on all children
        """
        for fct in self.objfcts:
            fct.update_weights(model)
<|endoftext|>